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

Contents of /build_system/web/index.php

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.30