genhtml can switch between pages
[can-benchmark.git] / gw-tests / genhtml / genhtml.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 import os;
4 import dircache;
5 import sys;
6 import urllib
7
8 class DimValue:
9     def __init__(self, dim, value):
10         self.dim = dim
11         self.value = value
12     def __str__(self):
13         return str(self.value)
14     def __repr__(self):
15         return repr(self.value)
16     def htmlLabel(self):
17         return self.dim.htmlLabel(self.value)
18
19 class DimValues(list):
20     def replace(self, val):
21         for i in xrange(len(self)):
22             if self[i].dim == val.dim:
23                 self[i] = val
24
25 class Dimension(dict):
26     def __init__(self, atype, name=None):
27         self.type = atype
28         if (name):
29             self.name = name
30         else:
31             self.name = atype
32
33     def __iter__(self):
34         keys = self.keys()
35         keys.sort()
36         for k in keys:
37             yield self[k]
38
39     def addValue(self, *values):
40         for value in values:
41             if value not in self:
42                 self[value] = DimValue(self, value)
43     def htmlLabel(self, v):
44         return v
45     def __str__(self):
46         return self.name
47     def __repr__(self):
48         return self.type
49
50 class DimensionKern(Dimension):
51     def __init__(self):
52         Dimension.__init__(self, 'gwkern', 'GW kernel')
53     def htmlLabel(self, v):
54         i=v.find(":")
55         if i>0: kver=v[:i]
56         else: kver=v
57         return v+"<br><a href='config-%s'>config</a>"%(urllib.quote(kver))
58     def versions(self):
59         for v in self.values:
60             i=v.find(":")
61             if i>0: kver=v[:i]
62             else: kver=v
63             yield kver
64
65 class DimensionHostKern(Dimension):
66     def __init__(self):
67         Dimension.__init__(self, 'hostkern', 'Host kernel')
68     def htmlLabel(self, v):
69         if v.find("host-") == 0:
70             v = v[5:]
71         # TODO: remove host- prefix
72         i = v.find(":")
73         if i>0: kver = v[:i]
74         else: kver = v
75         return v+"<br><a href='config-%s'>config</a>"%(urllib.quote(kver))
76     def versions(self):
77         for v in self.values:
78             i=v.find(":")
79             if i>0: kver=v[:i]
80             else: kver=v
81             yield kver
82
83 class DimensionTest(Dimension):
84     def __init__(self):
85         Dimension.__init__(self, 'test', 'Test')
86     def htmlLabel(self, v):
87         return v+"<br><a href='%s.sh.html'>source</a>"%(urllib.quote(v))
88
89 class DimensionTraffic(Dimension):
90     def __init__(self):
91         Dimension.__init__(self, 'traf', 'Traffic')
92     def htmlLabel(self, v):
93         return v
94
95 class Test:
96     @classmethod
97     def isOnPath(cls, path):
98         f = os.path.join(path, '.results')
99         return os.path.isfile(f)
100     def __init__(self, path):
101         self.path = path
102     def printThumbLink(self, file):
103         thumb = self.path+'/thumb'
104         for img in dircache.listdir(thumb):
105             print >>file, "<a href='%s/%s'><img src='%s/thumb/%s'></a>" % \
106                   (urllib.quote(self.path), img, urllib.quote(self.path), img)
107
108 def iterDimValues(dimensions):
109     idx = [0 for i in xrange(len(dimensions))]
110     done=False
111     while not done:
112         values=DimValues()
113         for i in xrange(len(dimensions)):
114             values.append(dimensions[i].values()[idx[i]])
115         yield values
116         done=True
117         for i in xrange(len(dimensions)):
118             idx[i] += 1
119             if idx[i] < len(dimensions[i]):
120                 done=False
121                 break
122             idx[i] = 0
123
124 class Tests(dict):
125     """Represents all tests organized along several dimensions"""
126     def __init__(self, rootpath, *dimensions):
127         dict.__init__(self)
128         self.dimensions = dimensions
129         if (rootpath):
130             self.populate(rootpath)
131     def getTest(self, key):
132         realkey=[]
133         for d in self.dimensions:
134             for i in key:
135                 if i.dim == d:
136                     realkey.append(i.value)
137         if len(realkey) != len(self.dimensions):
138             raise KeyError("The coordinates in key do not match dimensions")
139         return self[tuple(realkey)]
140
141     def addTest(self, test, coordinates):
142         if len(coordinates) != len(self.dimensions):
143             raise KeyError("The number coordinates do not match the number of dimensions: " + str(coordinates))
144         self[tuple(coordinates)] = test
145         for i in xrange(len(coordinates)):
146             self.dimensions[i].addValue(coordinates[i])
147
148     def populate(self, rootpath):
149         for root, dirs, files in os.walk(rootpath):
150             if (root.find(rootpath) == 0):
151                 coordinates = root[len(rootpath):]
152             else:
153                 coordinates = rootpath
154             if Test.isOnPath(root):
155                 self.addTest(Test(root), coordinates.split("/"))
156     def iterDimensionPairs(self):
157         for i in xrange(len(self.dimensions)):
158             for j in xrange(i+1, len(self.dimensions)):
159                 yield (self.dimensions[i], self.dimensions[j])
160                 yield (self.dimensions[j], self.dimensions[i])
161     def iterRemainingDimensions(self, dimensionPair):
162         for d in self.dimensions:
163             if d not in dimensionPair:
164                 yield d
165     def generateHtml(self):
166         for pair in self.iterDimensionPairs():
167             remDims = [d for d in self.iterRemainingDimensions(pair)]
168             for vals in iterDimValues(remDims):
169                 page = Page(pair, remDims, vals, self)
170                 page.generate()
171         try:
172             os.remove("index.html")
173         except OSError: pass
174         os.symlink(page.getName(), "index.html")
175
176         #os.system("source-highlight -d --output-dir=. ../*.sh")
177
178 class Page:
179     def __init__(self, dimPair, dimOther, valsOther, tests):
180         self.dimy, self.dimx = dimPair
181         self.dimOther = dimOther
182         self.valsOther = valsOther
183         self.tests = tests
184     def getName(self, dimy=None, dimx=None, valsOther=None):
185         return "%s-vs-%s-for-%s.html"%(dimx or self.dimy.type,
186                                        dimy or self.dimx.type,
187                                        "-".join([v.value for v in valsOther or self.valsOther]))
188     def generate(self):
189         html = open(self.getName(), "w")
190         title = "CAN gateway timing analysis" 
191         print >> html, """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
192 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
193 <head>
194 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
195 <title>%s</title>
196 <style>
197 img { border: 0; }
198 table { border-collapse: collapse; }
199 th, td { border: 1px solid lightgray; padding: 4px;}
200 </style>
201 </head>
202 <body>
203 <h1>%s</h1>"""  % (title, title)
204         for d in self.dimOther:
205             print >>html, "%s: " % d
206             links = []
207             for v in d.values():
208                 if v in self.valsOther:
209                     links.append(str(v))
210                 else:
211                     vv = DimValues(self.valsOther)
212                     vv.replace(v)
213                     links.append("<a href='%s'>%s</a>"%(urllib.quote(self.getName(valsOther=vv)), str(v)))
214             print >>html, " | ".join(links)
215             print >>html, "<br>"
216             try:
217                 print >>html, d.htmlPreamble()
218             except Exception:
219                 pass
220
221         print >>html, "<table><thead><tr><td> </td>"
222         for x in self.dimx:
223             print >>html, "<th>%s</th>" % x.htmlLabel()
224         print >>html, "</tr></thead>"
225         for y in self.dimy:
226             print >>html, "<tr><th>%s</th>" % y.htmlLabel()
227
228             for x in self.dimx:
229                 print >>html, "<td>"
230                 idx = [x,y]
231                 idx.extend(self.valsOther)
232                 try:
233                     test = tests.getTest(idx)
234                     try:
235                         test.printThumbLink(html)
236                     except OSError:
237                         print >>html, "No thumbnail :-("
238                 except KeyError:
239                     print >>html, "N/A"
240                 print >>html, "</td>"
241             print >>html, "</tr>"
242         print >> html, """
243 </table>
244 <div style="font-size: small; color: gray; margin-top: 1em;">Authors: Michal Sojka, Pavel Píša, Copyright © 2010 Czech Technical University in Prague</div>
245 </body>
246 """
247
248
249 if __name__ == "__main__":
250     os.chdir(sys.argv[1])
251     os.system("rm *.html")
252     tests = Tests("./", DimensionHostKern(), DimensionKern(), DimensionTraffic(), DimensionTest())
253     tests.generateHtml()
254     sys.exit(0)