]> git.ipfire.org Git - ipfire.org.git/blame - build/index.py
Changed footer on build.ipfire.org.
[ipfire.org.git] / build / index.py
CommitLineData
2b60fce9
MT
1#!/usr/bin/python
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2008 Michael Tremer & Christian Schmidt #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22import os
23import sys
24import time
25
26sys.path.append(".")
27
28from builder import Builder, getAllBuilders
29from constants import *
30
31def format_time(seconds, use_hours=1):
32 if seconds is None or seconds < 0:
33 if use_hours: return '--:--:--'
34 else: return '--:--'
35 else:
36 seconds = int(seconds)
37 minutes = seconds / 60
38 seconds = seconds % 60
39 if use_hours:
40 hours = minutes / 60
41 minutes = minutes % 60
42 return '%02i:%02i:%02i' % (hours, minutes, seconds)
43 else:
44 return '%02i:%02i' % (minutes, seconds)
45
46class Site:
47 def __init__(self, config):
48 self.builders = None
49 self.config = config
50 print "Content-type: text/html"
51 print
52
53 def __call__(self, builders=None):
54 self.builders = builders
55 print """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
56 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
57 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
58 <head>
59 <title>%(title)s</title>
60 <style type="text/css">
61 * {
62 margin: auto;
63 padding: 0;
64 text-decoration: none;
65 outline: none;
66 }
67 body {
68 font-family: Verdana;
69 font-size: 90%%;
70 background-color:#f9f9f9;
71 }
72 h1 {
73 text-decoration: underline;
74 }
75 #header {
76 width: 800px;
2b60fce9
MT
77 text-align: center;
78 background: #E0E0E0;
79 border: 1px solid #999;
80 padding-top: 10px;
f3fdc4c6 81 padding-bottom: 5px;
2b60fce9
MT
82 }
83 #content {
84 padding-top: 10px;
85 width: 800px;
86 }
87 div.box {
88 padding: 5px;
89 margin: 10px 0 10px 0;
10da7ad4 90 /* height: 80px; */
2b60fce9
MT
91 border: 1px solid;
92 }
93 div.infobox {
94 float: right;
95 width: 240px;
96 }
10da7ad4
MT
97 div.log {
98 background: #e55;
99 border: 1px dotted;
100 margin-top: 12px;
101 /* visibility: hidden; */
102 }
103 div.log p {
104 font-family: Courier New;
105 }
0e744e5a
MT
106 div.footer {
107 }
108 div.footer p {
109 text-align: center;
110 font-size: 5px;
111 }
2b60fce9
MT
112 p {
113 margin: 2px;
114 }
115 p.boxheader {
116 font-weight: bold;
117 }
118 p.online {
119 color: green;
120 }
121 p.offline {
122 color: red;
123 }
124 p.package {
125 font: bold;
126 font-size: 150%%;
127 }
128 img.right {
129 float: right;
130 }
131 p.desc {
132 text-decoration: bold;
133 }
134 a:link {
135 color: black; text-decoration: none;
136 }
137 a:visited {
138 color: black; text-decoration: none;
139 }
140 </style>
141 <meta http-equiv="refresh" content="90; URL=%(script)s" />
142 </head>
143 <body>
144 <div id="header">
145 <h1>IPFire Builder</h1>""" % self.config
2b60fce9
MT
146 for i in self.config["nightly_url"]:
147 print """\
148 <p><a href="%s" target="_blank">%s</a></p>""" % (i, i,)
149 print """\
150 </div>"""
151
152 self.content()
153
154 print "\t\t</body>\n</html>"
155
156 def content(self):
157 if self.builders:
2b60fce9
MT
158 print """\
159 <div id="content">"""
160 for builder in self.builders:
f006517e 161 builder()
2b60fce9
MT
162 print """\
163 </div>"""
164
165class Box:
166 def __init__(self, builder):
f006517e
MT
167 self.builder = builder
168 self.points = POINTS_UNKNOWN
2b60fce9 169
f006517e
MT
170 def __cmp__(self, other):
171 if self.points > other.points:
172 return -1
173 elif self.points == other.points:
174 return 0
175 elif self.points < other.points:
176 return 1
177
2b60fce9
MT
178 def __str__(self):
179 return """<a href="#%(hostname)s">%(hostname)s</a>""" % { "hostname" : self.builder.hostname(), }
180
f006517e
MT
181 def open_bigbox(self):
182 print """<a name="%s"></a><div class="box" style="%s">""" \
183 % (self.builder.hostname(), state2style[self.builder.state()],)
184
185 def open_infobox(self):
186 print """<div class="infobox">"""
187
188 def close_bigbox(self):
189 print """</div>"""
190
191 close_infobox = close_bigbox
192
2b60fce9 193 def header(self):
f006517e
MT
194 print """<p class="boxheader">%(hostname)s <span>[%(uuid)s]</span></p>""" \
195 % { "hostname" : self.builder.hostname(),
196 "state" : self.builder.state(),
197 "uuid" : self.builder.uuid, }
2b60fce9
MT
198
199 def package(self):
200 if self.builder.state() in [ "compiling", "error", ]:
201 print """\
202 <p class="package">%s</p>"""\
203 % self.builder.package()
204
205 def time(self):
f006517e
MT
206 print """<p>%s</p>""" \
207 % time.ctime(float(self.builder.state.time()))
2b60fce9
MT
208
209 def stateinfo(self):
f006517e
MT
210 print """<p class="desc">%s</p>""" \
211 % statedesc[self.builder.state()]
2b60fce9
MT
212
213 def durations(self):
f006517e
MT
214 print """<p>Average Build Duration: %s</p>""" \
215 % format_time(self.builder.duration.get_avg())
2b60fce9 216 if self.builder.state() == "compiling":
f006517e 217 print """<p>ETA: %s</p>""" \
2b60fce9
MT
218 % self.builder.duration.get_eta(self.builder.state.time())
219
220 def distccinfo(self):
221 state = self.builder.distcc.ping()
fda98c60
MT
222 port = self.builder.distcc()
223 if port == "0":
224 state = False
225 port = "disabled"
f006517e 226 print """<p class="%s">Distcc: %s</p>""" \
fda98c60 227 % (ping2class[state], port,)
10da7ad4
MT
228
229 def log(self):
230 log = self.builder.log()
231 if log:
f006517e 232 print """<div class="log"><p>"""
10da7ad4 233 for i in log:
0359f8fc
MT
234 if i:
235 print "%s<br />" % (i.rstrip("\n"),)
f006517e 236 print """</p></div>"""
2b60fce9 237
0e744e5a 238 def footer(self):
7f77b1db
MT
239 print """<div class="footer"><p>cpu: %s - target: %s - jobs: %s</p></div>""" \
240 % (self.builder.cpu(), self.builder.target(), self.builder.jobs(),)
f006517e
MT
241
242class BoxCompiling(Box):
243 def __init__(self, builder):
244 Box.__init__(self, builder)
245 self.points = POINTS_COMPILING
246
247 def __call__(self):
248 self.open_bigbox()
249 self.open_infobox()
250 self.distccinfo()
251 self.package()
252 self.time()
253 self.close_infobox()
254 self.header()
255 self.stateinfo()
256 self.durations()
257 self.footer()
258 self.close_bigbox()
259
260class BoxError(Box):
261 def __init__(self, builder):
262 Box.__init__(self, builder)
263 self.points = POINTS_ERROR
264
265 def __call__(self):
266 self.open_bigbox()
267 self.open_infobox()
268 self.distccinfo()
269 self.package()
270 self.time()
271 self.close_infobox()
272 self.header()
273 self.stateinfo()
274 self.durations()
275 self.log()
276 self.footer()
277 self.close_bigbox()
278
279class BoxDistcc(Box):
280 def __init__(self, builder):
281 Box.__init__(self, builder)
282 self.points = POINTS_DISTCC
283
284 def __call__(self):
285 self.open_bigbox()
286 self.open_infobox()
287 self.distccinfo()
288 self.time()
289 self.close_infobox()
290 self.header()
291 self.stateinfo()
292 self.durations()
293 self.footer()
294 self.close_bigbox()
295
296class BoxIdle(Box):
297 def __init__(self, builder):
298 Box.__init__(self, builder)
299 self.points = POINTS_IDLE
300
301 def __call__(self):
302 self.open_bigbox()
303 self.open_infobox()
304 self.distccinfo()
305 self.time()
306 self.close_infobox()
307 self.header()
308 self.stateinfo()
309 self.durations()
310 self.footer()
311 self.close_bigbox()
0e744e5a 312
2b60fce9
MT
313site = Site(config)
314
315boxes = []
f006517e
MT
316for builder in getAllBuilders():
317 box = None
318 if builder.state() == "compiling":
319 box = BoxCompiling(builder)
320 elif builder.state() == "error":
321 box = BoxError(builder)
322 elif builder.state() == "idle":
323 box = BoxIdle(builder)
324 elif builder.state() == "distcc":
325 if builder.distcc() == "0":
326 continue
327 box = BoxDistcc(builder)
328 if box:
329 boxes.append(box)
2b60fce9 330
f006517e 331boxes.sort()
2b60fce9 332site(boxes)