]>
Commit | Line | Data |
---|---|---|
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 | ||
22 | import os | |
23 | import sys | |
24 | import time | |
25 | ||
26 | sys.path.append(".") | |
27 | ||
28 | from builder import Builder, getAllBuilders | |
29 | from constants import * | |
30 | ||
31 | def 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 | ||
46 | class Site: | |
47 | def __init__(self, config): | |
48 | self.builders = None | |
49 | self.config = config | |
50 | print "Content-type: text/html" | |
51 | ||
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; | |
77 | height: 100px; | |
78 | text-align: center; | |
79 | background: #E0E0E0; | |
80 | border: 1px solid #999; | |
81 | padding-top: 10px; | |
82 | } | |
83 | #content { | |
84 | padding-top: 10px; | |
85 | width: 800px; | |
86 | } | |
87 | div.box { | |
88 | padding: 5px; | |
89 | margin: 10px 0 10px 0; | |
90 | height: 80px; | |
91 | border: 1px solid; | |
92 | } | |
93 | div.infobox { | |
94 | float: right; | |
95 | width: 240px; | |
96 | } | |
97 | p { | |
98 | margin: 2px; | |
99 | } | |
100 | p.boxheader { | |
101 | font-weight: bold; | |
102 | } | |
103 | p.online { | |
104 | color: green; | |
105 | } | |
106 | p.offline { | |
107 | color: red; | |
108 | } | |
109 | p.package { | |
110 | font: bold; | |
111 | font-size: 150%%; | |
112 | } | |
113 | img.right { | |
114 | float: right; | |
115 | } | |
116 | p.desc { | |
117 | text-decoration: bold; | |
118 | } | |
119 | a:link { | |
120 | color: black; text-decoration: none; | |
121 | } | |
122 | a:visited { | |
123 | color: black; text-decoration: none; | |
124 | } | |
125 | </style> | |
126 | <meta http-equiv="refresh" content="90; URL=%(script)s" /> | |
127 | </head> | |
128 | <body> | |
129 | <div id="header"> | |
130 | <h1>IPFire Builder</h1>""" % self.config | |
131 | if self.builders: | |
132 | print """\ | |
133 | <p> | |
134 | """, | |
135 | for builder in self.builders: | |
136 | print builder, | |
137 | print """ | |
138 | </p>""" | |
139 | for i in self.config["nightly_url"]: | |
140 | print """\ | |
141 | <p><a href="%s" target="_blank">%s</a></p>""" % (i, i,) | |
142 | print """\ | |
143 | </div>""" | |
144 | ||
145 | self.content() | |
146 | ||
147 | print "\t\t</body>\n</html>" | |
148 | ||
149 | def content(self): | |
150 | if self.builders: | |
151 | count = 0 | |
152 | print """\ | |
153 | <div id="content">""" | |
154 | for builder in self.builders: | |
155 | builder(count) | |
156 | count += 1 | |
157 | print """\ | |
158 | </div>""" | |
159 | ||
160 | class Box: | |
161 | def __init__(self, builder): | |
162 | self.builder = builder | |
163 | ||
164 | def __call__(self, count): | |
165 | print """\ | |
166 | <a name="%s"></a> | |
167 | <div class="box" style="%s">"""\ | |
168 | % (self.builder.hostname(), state2style[self.builder.state()],) | |
169 | print """\ | |
170 | <div class="infobox">""" | |
171 | self.distccinfo() | |
172 | self.package() | |
173 | self.time() | |
174 | print """\ | |
175 | </div>""" | |
176 | self.header() | |
177 | self.stateinfo() | |
178 | self.durations() | |
179 | print """\ | |
180 | </div>""" | |
181 | ||
182 | def __str__(self): | |
183 | return """<a href="#%(hostname)s">%(hostname)s</a>""" % { "hostname" : self.builder.hostname(), } | |
184 | ||
185 | def header(self): | |
186 | print """\ | |
187 | <p class="boxheader"> | |
188 | %(hostname)s <span>[%(uuid)s]</span> | |
189 | </p> | |
190 | <!-- <img class="right" src="/images/%(state)s.png" /> -->""" \ | |
191 | % { "hostname" : self.builder.hostname(), | |
192 | "state" : self.builder.state(), | |
193 | "uuid" : self.builder.uuid, } | |
194 | ||
195 | def package(self): | |
196 | if self.builder.state() in [ "compiling", "error", ]: | |
197 | print """\ | |
198 | <p class="package">%s</p>"""\ | |
199 | % self.builder.package() | |
200 | ||
201 | def time(self): | |
202 | print """\ | |
203 | <p>%s</p>""" \ | |
204 | % time.ctime(float(self.builder.state.time())) | |
205 | ||
206 | def stateinfo(self): | |
207 | if self.builder.state() in [ "compiling", "error", "idle", ]: | |
208 | print """\ | |
209 | <p class="desc">%s</p>""" \ | |
210 | % statedesc[self.builder.state()] | |
211 | ||
212 | def durations(self): | |
213 | print """\ | |
214 | <p>Average Build Duration: %s</p>""" \ | |
215 | % format_time(self.builder.duration.get_avg()) | |
216 | if self.builder.state() == "compiling": | |
217 | print """\ | |
218 | <p>ETA: %s</p>""" \ | |
219 | % self.builder.duration.get_eta(self.builder.state.time()) | |
220 | ||
221 | def distccinfo(self): | |
222 | state = self.builder.distcc.ping() | |
fda98c60 MT |
223 | port = self.builder.distcc() |
224 | if port == "0": | |
225 | state = False | |
226 | port = "disabled" | |
2b60fce9 MT |
227 | print """\ |
228 | <p class="%s">Distcc: %s</p>""" \ | |
fda98c60 | 229 | % (ping2class[state], port,) |
2b60fce9 MT |
230 | |
231 | site = Site(config) | |
232 | ||
233 | boxes = [] | |
234 | for builder in getAllBuilders(): | |
235 | boxes.append(Box(builder)) | |
236 | ||
237 | site(boxes) |