/[soft]/build_system/web/index.php
ViewVC logotype

Annotation of /build_system/web/index.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 645 - (hide annotations) (download)
Fri Mar 11 16:32:38 2011 UTC (13 years ago) by dmorgan
File size: 10815 byte(s)
Use local favicon
1 pterjan 268 <?php
2 rda 298 /**
3     * Mageia build-system quick status report script.
4     *
5 blino 615 * @copyright Copyright (C) 2011 Mageia.Org
6 rda 298 *
7 blino 615 * @author Olivier Blin
8 rda 298 * @author Pascal Terjan
9     * @author Romain d'Alverny
10     *
11     * @license http://www.gnu.org/licenses/gpl-2.0.html GNU GPL v2
12     *
13     * This program is free software; you can redistribute it and/or modify it
14     * under the terms of the GNU General Public License aspublished by the
15     * Free Software Foundation; either version 2 of the License, or (at your
16     * option) any later version.
17     *
18     *
19     * Shows submitted packages in the past $max_modified 24 hours and their
20     * status (built & uploaded, failed build, rejected, etc.).
21     *
22     * This was written anew in Jan. 2011 because existing Mandriva build-system
23     * web report code was not clearly licensed at this very time.
24     */
25 pterjan 268
26     error_reporting(E_ALL);
27    
28 pterjan 333 /**
29     * @param array $pkg
30     *
31     * @return string
32     */
33     function pkg_gettype($pkg) {
34     if (array_key_exists("rejected", $pkg["status"]))
35     return "rejected";
36     if (array_key_exists("youri", $pkg["status"])) {
37     if (array_key_exists("src", $pkg["status"]))
38     return "youri";
39     else
40     return "uploaded";
41     }
42     if (array_key_exists("failure", $pkg["status"]))
43     return "failure";
44     if (array_key_exists("done", $pkg["status"]))
45     return "partial";
46     if (array_key_exists("build", $pkg["status"]))
47     return "building";
48     if (array_key_exists("todo", $pkg["status"]))
49     return "todo";
50     return "unknown";
51     }
52    
53     /**
54     * @param integer $num
55     *
56     * @return string
57     */
58     function plural($num) {
59     if ($num > 1)
60     return "s";
61     }
62    
63     /**
64     * Return timestamp from package key
65     * @param string $key package submission key
66     *
67     * @return integer
68     */
69    
70     function key2timestamp($key) {
71     global $tz;
72    
73     $date = DateTime::createFromFormat("YmdHis", $key+0, $tz);
74     if ($date <= 0)
75     return null;
76    
77     return $date->getTimestamp();
78     }
79    
80     function timediff($start, $end) {
81     /**
82     * Return human-readable time difference
83     *
84     * @param integer $start timestamp
85     * @param integer $end timestamp, defaults to now
86     *
87     * @return string
88     */
89     if (is_null($end)) {
90     $end = time();
91     }
92     $diff = $end - $start;
93     if ($diff<60)
94     return $diff . " second" . plural($diff);
95     $diff = round($diff/60);
96     if ($diff<60)
97     return $diff . " minute" . plural($diff);
98     $diff = round($diff/60);
99     if ($diff<24)
100     return $diff . " hour" . plural($diff);
101     $diff = round($diff/24);
102    
103     return $diff . " day" . plural($diff);
104     }
105    
106 rda 284 $g_user = isset($_GET['user']) ? htmlentities(strip_tags($_GET['user'])) : null;
107    
108 rda 283 $upload_dir = '/home/schedbot/uploads';
109 pterjan 268 $max_modified = 2;
110 rda 283 $title = '<a href="http://mageia.org/">Mageia</a> build system status';
111 rda 284 $robots = 'index,nofollow,nosnippet,noarchive';
112     if ($g_user) {
113     $title .= ' for ' . $g_user . "'s packages";
114     $robots = 'no' . $robots;
115     }
116 rda 283 $tz = new DateTimeZone('UTC');
117 rda 292 $date_gen = date('c');
118 pterjan 268
119 pterjan 269 # Temporary until initial mirror is ready
120 pterjan 270 chdir("data");
121 pterjan 472 $missing_deps = file("missing-deps.i586.txt");
122 pterjan 269 #########################################
123    
124 pterjan 268 chdir($upload_dir);
125    
126 pterjan 317 $all_files = shell_exec("find \( -name '*.rpm' -o -name '*.src.rpm.info' -o -name '*.youri' -o -name '*.lock' -o -name '*.done' \) -ctime -$max_modified -printf \"%p\t%T@\\n\"");
127 pterjan 614 $re = "!^\./(\w+)/((\w+)/(\w+)/(\w+)/(\d+)\.(\w+)\.(\w+)\.(\d+))_?(.*)(\.src\.rpm(?:\.info)?|\.youri|\.lock|\.done)\s+(\d+\.\d+)$!m";
128 rda 301 $r = preg_match_all($re,
129     $all_files,
130     $matches,
131     PREG_SET_ORDER);
132 pterjan 268
133     $pkgs = array();
134     foreach ($matches as $val) {
135 rda 283
136     if ($_GET['user'] && ($_GET['user'] != $val[7])) {
137     continue;
138 pterjan 269 }
139     $key = $val[6] . $val[7];
140 pterjan 268 if (!is_array($pkgs[$key])) {
141 rda 283
142     $pkgs[$key] = array(
143     'status' => array(),
144     'path' => $val[2],
145     'version' => $val[3],
146     'media' => $val[4],
147     'section' => $val[5],
148     'user' => $val[7],
149     'host' => $val[8],
150     'job' => $val[9]
151     );
152 pterjan 268 }
153     $status = $val[1];
154     $data = $val[10];
155 pterjan 374 if (preg_match("/@(\d+):/", $data, $revision)) {
156     $pkgs[$key]['revision'] = $revision[1];
157     }
158 rda 283 $pkgs[$key]['status'][$status] = 1;
159 pterjan 268 $ext = $val[11];
160 rda 283 if ($ext == '.src.rpm.info') {
161 pterjan 268 preg_match("!^(?:@\d+:)?(.*)!", $data, $name);
162 rda 283 $pkgs[$key]['package'] = $name[1];
163     } else if ($ext == '.src') {
164     $pkgs[$key]['status']['src'] = 1;
165     } else if ($ext == '.youri') {
166     $pkgs[$key]['status']['youri'] = 1;
167     } else if ($ext == '.lock') {
168 pterjan 268 // parse build bot from $data
169 rda 283 $pkgs[$key]['status']['build'] = 1;
170 rda 301 } else if ($ext == '.done') {
171 pterjan 313 $pkgs[$key]['buildtime']['start'] = key2timestamp($val[6]);
172 rda 301 $pkgs[$key]['buildtime']['end'] = round($val[12]);
173     $pkgs[$key]['buildtime']['diff'] = $pkgs[$key]['buildtime']['end'] - $pkgs[$key]['buildtime']['start'];
174 pterjan 268 }
175     }
176     // sort by key in reverse order to have more recent pkgs first
177     krsort($pkgs);
178 rda 283
179 pterjan 333 // count all packages statuses
180     $stats = array(
181     'uploaded' => 0,
182     'failure' => 0,
183     'todo' => 0,
184     'building' => 0,
185     'partial' => 0,
186     'built' => 0,
187     );
188     $total = count($pkgs);
189 rda 283
190 pterjan 333 // count users' packages
191     $users = array();
192 rda 283
193 pterjan 333 if ($total > 0) {
194     foreach ($pkgs as $key => $p) {
195     $pkgs[$key]['type'] = pkg_gettype($p);
196 pterjan 313
197 pterjan 333 $stats[$pkgs[$key]['type']] += 1;
198 pterjan 313
199 pterjan 333 if (!array_key_exists($p['user'], $users))
200     $users[$p['user']] = 1;
201     else
202     $users[$p['user']] += 1;
203     }
204 pterjan 313 }
205    
206 pterjan 333 // feedback labels
207     $badges = array(
208     'uploaded' => 'Congrats %s! \o/',
209     'failure' => 'Booooo! /o\\',
210     'todo' => '',
211     'building' => '',
212     'partial' => '',
213     'built' => ''
214     );
215 rda 283
216 pterjan 333 foreach ($stats as $k => $v) {
217     Header("X-BS-Queue-$k: $v");
218 rda 283 }
219 rda 301
220 pterjan 333 $w = $stats['todo'] - 10;
221     if($w < 0)
222     $w = 0;
223     $w = $w * 60;
224     Header("X-BS-Throttle: $w");
225 pterjan 268 ?>
226 rda 284 <!DOCTYPE html>
227 rda 281 <html lang="en">
228 pterjan 268 <head>
229 rda 284 <meta charset="utf-8">
230 rda 290 <title><?php echo strip_tags($title); ?></title>
231 rda 284 <meta name="robots" content="<?php echo $robots; ?>">
232 dmorgan 645 <link rel="icon" type="image/png" href="favicon.png" />
233 rda 284 <style type="text/css">
234 rda 288 .clear { clear: both; }
235 rda 281 table {
236     border-spacing: 0;
237 rda 293 font-family: Helvetica, Verdana, Arial, sans-serif; font-size: 80%;
238 rda 281 border: 1px solid #ccc;
239 rda 288 float: left;
240 rda 281 }
241     table tr { padding: 0; margin: 0; }
242     table th { padding: 0.2em 0.5em; margin: 0; border-bottom: 2px solid #ccc; border-right: 1px solid #ccc; }
243     table td { padding: 0; margin: 0; padding: 0.2em 0.5em; border-bottom: 1px solid #ccc; }
244 pterjan 269
245 rda 281 tr { background: transparent; }
246 rda 282 tr.uploaded { background: #bbffbb; }
247     tr.failure, tr.rejected { background: #ffbbbb; }
248 rda 281 tr.todo { background: white; }
249 rda 282 tr.building { background: #ffff99; }
250     tr.partial { background: #bbbbff; }
251     tr.built { background: #cceeff; }
252     tr.youri { background: #aacc66; }
253 rda 281
254     td.status-box { width: 1em; height: 1em; }
255     tr.uploaded td.status-box { background: green; }
256     tr.failure td.status-box, tr.rejected td.status-box { background: red; }
257     tr.todo td.status-box { background: white; }
258     tr.building td.status-box { background: yellow; }
259     tr.partial td.status-box { background: blue; }
260 rda 282 tr.built td.status-box { background: #00ccff; }
261 rda 281 tr.youri td.status-box { background: olive; }
262 rda 285
263     #stats { float: right; }
264 rda 293 #score { margin-bottom: 2em; font-family: Helvetica, Verdana, Arial, sans-serif; }
265     #score-box { width: 100px; height: 100px; background: #faa; }
266     #score-meter { width: 100px; background: #afa; }
267 rda 284 </style>
268 pterjan 268 </head>
269     <body>
270 rda 281 <h1><?php echo $title ?></h1>
271 pterjan 268
272 rda 281 <?php
273 rda 289 if (!is_null($g_user))
274     echo '<a href="/">&laquo;&nbsp;Back to full list</a>';
275 pterjan 268
276 pterjan 269 # Temporary until initial mirror is ready
277 rda 281 echo sprintf(
278 pterjan 472 '<p><a href="%s">%d broken dependencies</a>. <strong><a href="%s">You can help!</a></strong></p>',
279     'data/missing-deps.i586.txt', count($missing_deps),
280 rda 321 'http://www.mageia.org/wiki/doku.php?id=packaging#starting_package_import'
281 rda 281 );
282    
283 pterjan 269 #########################################
284    
285 rda 283 $s = '';
286     $tmpl = <<<T
287     <tr class="%s">
288     <td>%s</td>
289     <td><a href="?user=%s">%s</a></td>
290 misc 638 <td><a href="http://svnweb.mageia.org/packages?view=revision&revision=%d">%s</a></td>
291 rda 283 <td>%s</td>
292     <td>%s/%s</td>
293     <td class="status-box"></td>
294     T;
295 rda 285
296 rda 292 if ($total > 0) {
297     foreach ($pkgs as $key => $p) {
298     $s .= sprintf($tmpl,
299     $p['type'],
300 pterjan 314 timediff(key2timestamp($key)) . ' ago',
301 rda 292 $p['user'], $p['user'],
302 pterjan 374 $p['revision'],
303 rda 292 $p['package'],
304     $p['version'],
305     $p['media'], $p['section']
306     );
307 rda 283
308 rda 292 $typelink = '';
309     if ($p['type'] == 'failure') {
310     $typelink = '/uploads/' . $p['type'] . '/' . $p['path'];
311     } elseif ($p['type'] == 'rejected') {
312     $typelink = '/uploads/' . $p['type'] . '/' . $p['path'] . '.youri';
313     }
314    
315     $s .= '<td>';
316     $s .= ($typelink != '') ?
317     sprintf('<a href="%s">%s</a>', $typelink, $p['type']) :
318     $p['type'];
319    
320 rda 301 $s .= '</td><td>';
321     if ($p['type'] == 'uploaded')
322 pterjan 314 $s .= timediff($p['buildtime']['start'], $p['buildtime']['end']);
323 rda 292 $s .= '</td>';
324     //$s .= '<td>' . sprintf($badges[$p['type']], $p['user']) . '</td>';
325     $s .= '</tr>';
326 pterjan 268 }
327 rda 292 // Table
328     echo '<table>',
329 rda 316 '<caption>', $total, ' packages submitted in the past ', $max_modified * 24, '&nbsp;hours.</caption>',
330     '<tr><th>Submitted</th><th>User</th>
331     <th>Package</th><th>Target</th><th>Media</th>
332     <th colspan="2">Status</th><th>Build time</th></tr>',
333 rda 292 $s,
334     '</table>';
335 rda 283
336 rda 292 // Stats
337     $s = '<div id="stats">';
338     $score = round($stats['uploaded']/$total * 100);
339     $s .= sprintf('<div id="score"><h3>Score: %d/100</h3>
340     <div id="score-box"><div id="score-meter" style="height: %dpx;"></div></div></div>',
341     $score, $score);
342 rda 283
343 rda 292 $s .= '<table><caption>Stats.</caption><tr><th colspan="2">Status</th><th>Count</th><th>%</th></tr>';
344     foreach ($stats as $k => $v) {
345     $s .= sprintf('<tr class="%s"><td class="status-box"></td><td>%s</td><td>%d</td><td>%d%%</td></tr>',
346     $k, $k, $v, round($v/$total*100));
347     }
348 rda 299
349 rda 316 $s .= '</table><br /><br />';
350 rda 299
351     $s .= '<table><caption>Packagers</caption><tr><th>User</th><th>Packages</th></tr>';
352     foreach ($users as $k => $v)
353     $s .= sprintf('<tr><td><a href="/?user=%s">%s</a></td><td>%d</td></tr>',
354     $k, $k, $v);
355    
356     $s .= '</table>';
357     $s .= '</div>';
358    
359 rda 292 echo $s;
360 pterjan 268 }
361 rda 292 else
362     {
363     echo sprintf('<p>No package has been submitted in the past %d&nbsp;hours.</p>',
364     $max_modified * 24);
365 rda 285 }
366    
367 pterjan 268 ?>
368 rda 292 <div class="clear"></div>
369     <hr />
370     <p>Generated at <?php echo $date_gen; ?>.</p>
371 pterjan 268 </body>
372     </html>

  ViewVC Help
Powered by ViewVC 1.1.30