From 74e4fbb8a44a68b0d97d0d363cf4ea60b5346bbe Mon Sep 17 00:00:00 2001 From: Romain d'Alverny Date: Wed, 12 Sep 2012 19:55:20 +0000 Subject: replace previous index with new one --- index.php | 655 ++++++++++++++++++++------------------------------------- test_index.php | 342 ------------------------------ 2 files changed, 224 insertions(+), 773 deletions(-) delete mode 100644 test_index.php diff --git a/index.php b/index.php index 18cec0b..4c4beec 100644 --- a/index.php +++ b/index.php @@ -26,524 +26,317 @@ error_reporting(E_ALL); -/** - * @param array $pkg - * - * @return string -*/ -function pkg_gettype($pkg) { - if (array_key_exists("rejected", $pkg["status"])) - return "rejected"; - if (array_key_exists("upload", $pkg["status"])) - return "uploaded"; - if (array_key_exists("failure", $pkg["status"])) - return "failure"; - if (array_key_exists("done", $pkg["status"])) - return "partial"; - if (array_key_exists("build", $pkg["status"])) - return "building"; - if (array_key_exists("todo", $pkg["status"])) - return "todo"; - return "unknown"; -} - -/** - * @param integer $num - * - * @return string -*/ -function plural($num) { - if ($num > 1) - return "s"; -} - -/** - * Return timestamp from package key - * @param string $key package submission key - * - * @return integer -*/ - -function key2timestamp($key) { - global $tz; - - $date = DateTime::createFromFormat("YmdHis", $key+0, $tz); - if ($date <= 0) - return null; - - return $date->getTimestamp(); -} - -function timediff($start, $end) { -/** - * Return human-readable time difference - * - * @param integer $start timestamp - * @param integer $end timestamp, defaults to now - * - * @return string -*/ - if (is_null($end)) { - $end = time(); - } - $diff = $end - $start; - if ($diff<60) - return $diff . " second" . plural($diff); - $diff = round($diff/60); - if ($diff<60) - return $diff . " minute" . plural($diff); - $diff = round($diff/60); - if ($diff<24) - return $diff . " hour" . plural($diff); - $diff = round($diff/24); - - return $diff . " day" . plural($diff); +require __DIR__ . '/conf.php'; +require __DIR__ . '/lib.php'; + +// sanity checks +if (!is_dir($upload_dir)) { + $msg = "$upload_dir does not exist on this system. Please check your config."; + error_log($msg); + die($msg); } $g_user = isset($_GET['user']) ? htmlentities(strip_tags($_GET['user'])) : null; -$upload_dir = '/home/schedbot/uploads'; -$max_modified = 2; -$title = 'Mageia build system status'; -$robots = 'index,nofollow,nosnippet,noarchive'; if ($g_user) { $title .= ' for ' . $g_user . "'s packages"; $robots = 'no' . $robots; } -$tz = new DateTimeZone('UTC'); +$tz = new DateTimeZone('UTC'); $date_gen = date('c'); -chdir($upload_dir); +$matches = get_submitted_packages($upload_dir, $max_modified); -$all_files = shell_exec("find \( -name '*.rpm' -o -name '*.src.rpm.info' -o -name '*.lock' -o -name '*.done' -o -name '*.upload' \) -ctime -$max_modified -printf \"%p\t%T@\\n\""); -$re = "!^\./(\w+)/((\w+)/(\w+)/(\w+)/(\d+)\.(\w+)\.(\w+)\.(\d+))_?(.*)(\.src\.rpm(?:\.info)?|\.lock|\.done|\.upload)\s+(\d+\.\d+)$!m"; -$r = preg_match_all($re, - $all_files, +list($pkgs, $hosts, $build_count, $build_dates, $buildtime_total) = get_refined_packages_list( $matches, - PREG_SET_ORDER); - -$pkgs = array(); -$hosts = array(); - -$buildtime_total = array(); -$buid_dates = array(); - -foreach ($matches as $val) { - - if ($_GET['user'] && ($_GET['user'] != $val[7])) { - continue; - } - $key = $val[6] . $val[7]; - if (!is_array($pkgs[$key])) { - - $pkgs[$key] = array( - 'status' => array(), - 'path' => $val[2], - 'version' => $val[3], - 'media' => $val[4], - 'section' => $val[5], - 'user' => $val[7], - 'host' => $val[8], - 'job' => $val[9] - ); - } - $status = $val[1]; - $data = $val[10]; - if (preg_match("/@(\d+):/", $data, $revision)) { - $pkgs[$key]['revision'] = $revision[1]; - } - $pkgs[$key]['status'][$status] = 1; - $ext = $val[11]; - if ($ext == '.src.rpm.info') { - preg_match("!^(?:@\d+:)?(.*)!", $data, $name); - $pkgs[$key]['package'] = $name[1]; - } else if ($ext == '.src.rpm') { - $pkgs[$key]['status']['src'] = 1; - } else if ($ext == '.upload') { - $pkgs[$key]['status']['upload'] = 1; - } else if ($ext == '.lock') { - preg_match("!(.*)\.iurt\.(.*)\.\d+\.\d+!", $data, $buildhost); - if (!$hosts[$buildhost[2]]) { - $hosts[$buildhost[2]]= array(); - } - $hosts[$buildhost[2]][$buildhost[1]] = $key; - if ($pkgs[$key]['status']['build']) - array_push($pkgs[$key]['status']['build'], $buildhost[2]); - else - $pkgs[$key]['status']['build'] = array($buildhost[2]); - } else if ($ext == '.done') { - // beware! this block is called twice for a given $key - - $pkgs[$key]['buildtime']['start'] = key2timestamp($val[6]); - $pkgs[$key]['buildtime']['end'] = round($val[12]); - $pkgs[$key]['buildtime']['diff'] = $pkgs[$key]['buildtime']['end'] - $pkgs[$key]['buildtime']['start']; - - @$build_dates[date('H', $pkgs[$key]['buildtime']['start'])] += 1; - - // keep obviously dubious values out of there - // 12 hours is be an acceptable threshold given current BS global perfs - // as of April 2011 - if ($pkgs[$key]['buildtime']['diff'] < 43200) { - $buildtime_total[$key] = $pkgs[$key]['buildtime']['diff']; - } - } -} - -// filter packages if a package name was provided -if ($_GET['package']) { - foreach ($pkgs as $key => $pkg) { - preg_match("/^(.*)-[^-]*-[^-]*$/", $pkg['package'], $name); - if ($_GET['package'] != $name[1]) { - unset($pkgs[$key]); - } - } -} - -// sort by key in reverse order to have more recent pkgs first -krsort($pkgs); -ksort($build_dates); - -$build_count = count($buildtime_total); -$buildtime_total = array_sum($buildtime_total); - -// count all packages statuses -$stats = array( - 'uploaded' => 0, - 'failure' => 0, - 'todo' => 0, - 'building' => 0, - 'partial' => 0 + isset($_GET['package']) ? $_GET['package'] : null, + isset($_GET['user']) ? $_GET['user'] : null ); -$total = count($pkgs); -// count users' packages -$users = array(); - -if ($total > 0) { - foreach ($pkgs as $key => $p) { - $pkgs[$key]['type'] = pkg_gettype($p); - - $stats[$pkgs[$key]['type']] += 1; - - if (!array_key_exists($p['user'], $users)) - $users[$p['user']] = 1; - else - $users[$p['user']] += 1; - } -} - -// check if emi is running -$stat = stat("/var/lib/schedbot/tmp/upload"); -if ($stat) { - $upload_time = $stat['mtime']; -} - -// publish stats as headers - -foreach ($stats as $k => $v) { - Header("X-BS-Queue-$k: $v"); -} - -$w = $stats['todo'] - 10; -if($w < 0) - $w = 0; -$w = $w * 60; -Header("X-BS-Throttle: $w"); - -if ($_GET['last'] && $total > 0) { - reset($pkgs); - $last = current($pkgs); - Header("X-BS-Package-Status: ".$last['type']); -} +list($stats, $users, $total, $pkgs) = build_stats($pkgs); $buildtime_total = $buildtime_total / 60; -header(sprintf('X-BS-Buildtime: %d', round($buildtime_total))); -$buildtime_avg = round($buildtime_total / $build_count, 2); -header(sprintf('X-BS-Buildtime-Average: %5.2f', $buildtime_avg)); +$buildtime_avg = ($build_count == 0) ? + 0 : + round($buildtime_total / $build_count, 2); + +publish_stats_headers( + $stats, + $buildtime_total, + $buildtime_avg, + $build_count, + (isset($_GET['last']) && $total > 0) ? reset($pkgs) : null +); + ?> - + <?php echo strip_tags($title); ?> - - + + + + + - -

- + « Back to full list'; +if (!isset($_GET['package'])) { -if (!$_GET['package']) { + // TODO should be cached. + $missing_deps_count = preg_match_all("//m", file_get_contents("http://check.mageia.org/cauldron/dependencies.rss"), $matches); + $unmaintained_count = file_exists(__DIR__ . '/data/unmaintained.txt') ? count(file(__DIR__ . '/data/unmaintained.txt')) : 0; -$missing_deps_count = preg_match_all("//m", file_get_contents("http://check.mageia.org/cauldron/dependencies.rss"), $matches); -$unmaintained_count = count(file(__DIR__ . '/data/unmaintained.txt')); -if ($missing_deps_count > 0 || $unmaintained_count > 0) { - echo "

"; - if ($missing_deps_count > 0) - echo "$missing_deps_count broken dependencies. "; - if ($unmaintained_count > 0) - echo "$unmaintained_count unmaintained packages. "; - echo 'You can help!

'; -} + if ($missing_deps_count > 0 + || $unmaintained_count > 0 + ) { + if ($missing_deps_count > 0) { + $figures_list[] = sprintf('%d broken deps.', + $missing_deps_count, + 'http://check.mageia.org/cauldron/dependencies.html' + ); + } - -preg_match_all('/(\d+)/', file_get_contents("https://bugs.mageia.org/buglist.cgi?quicksearch=%40qa-bugs+-kw%3Avali"), $matches); -$qa_bugs = $matches[1][0]; -if ($qa_bugs > 0) { - echo "

"; - echo "$qa_bugs package updates to validate. "; - echo 'You can help!

'; -} + if ($unmaintained_count > 0) { + $figures_list[] = sprintf('%d unmaintained', + $unmaintained_count, + 'data/unmaintained.txt' + ); + } -if ($upload_time) { - echo sprintf('

Upload in progress for %s.

', timediff($upload_time)); -} + if (count($figures_list) > 0) + $figures_list[count($figures_list)-1] .= sprintf(' %s', + 'https://wiki.mageia.org/en/Importing_packages', + 'YES you can help!', 'pick one'); + } -$buildtime_stats = array(); + preg_match_all('/(\d+)/', file_get_contents("https://bugs.mageia.org/buglist.cgi?quicksearch=%40qa-bugs+-kw%3Avali"), $matches); + $qa_bugs = $matches[1][0]; + if ($qa_bugs > 0) { + $figures_list[] = sprintf('%d update%s to validate + %s', + $qa_bugs, + 'https://bugs.mageia.org/buglist.cgi?quicksearch=%40qa-bugs+-kw%3Avali', + plural($qa_bugs), + 'https://wiki.mageia.org/en/QA_process_for_validating_updates', + 'YES you can help!', 'see how' + ); + } -// Builds in progress -$s = ''; -$tmpl = << 0) { + $html_figures = 'Packages: ' . implode(', ', $figures_list) . '.'; + } + +?> +
+

+ +
+
+« Back to full list'; + } + + echo '
    '; + $buildtime_stats = array(); + + // Builds in progress + if (count($hosts) > 0) { + echo '
  • ', + sprintf('

    %d build%s in progress:

    ', count($hosts), plural(count($hosts))); + + $s = ''; + $tmpl = << - %s - %s - %s - %s - %s - %s/%s + %s + %s + %s %s/%s + %s %s TB; -foreach ($hosts as $machine => $b) { - foreach ($b as $arch => $key) { - $s .= sprintf($tmpl, - $machine, - $arch, - $pkgs[$key]['user'], $pkgs[$key]['user'], - $pkgs[$key]['package'], - $pkgs[$key]['version'], - $pkgs[$key]['media'], $pkgs[$key]['section']); + foreach ($hosts as $machine => $b) { + foreach ($b as $arch => $key) { + $s .= sprintf($tmpl, + $pkgs[$key]['package'], + $pkgs[$key]['user'], $pkgs[$key]['user'], + $pkgs[$key]['version'], $pkgs[$key]['media'], $pkgs[$key]['section'], + $machine, $arch); + } + } + echo '
    ', + ' + + + ', + $s, + '
    PackageUserTarget mediaMachine arch
    ', + '
    ', + '
  • '; + } else { + //echo '
  • No build in progress.

  • '; } } -echo '
    ', - '', - '', - $s, - '
    ', count($hosts), ' builds in progress.
    MachineArchUserPackageTargetMedia
    '; -echo '
    '; +$upload_time = get_upload_time(); +if (!is_null($upload_time)) { + echo sprintf('
  • Upload in progress for %s.

  • ', timediff($upload_time)); } // Build queue -$s = ''; +$s = ''; $tmpl = << - %s - %s - %s - %s - %s/%s - + %s + view changes @ r%d + %s + %s + %s + %s/%s T; if ($total > 0) { foreach ($pkgs as $key => $p) { + if (trim($p['package']) == '') { + continue; + } + $revision_link = sprintf('http://svnweb.mageia.org/packages?view=revision&revision=%d', $p['revision']); + $s .= sprintf($tmpl, $p['type'], - timediff(key2timestamp($key)) . ' ago', - $p['user'], $p['user'], - $p['revision'], + $revision_link, addslashes($p['summary']), $p['package'], + $revision_link, $p['revision'], + $p['user'], $p['user'], + timediff(key2timestamp($key)) . ' ago', $p['version'], $p['media'], $p['section'] ); - + $typelink = ''; if ($p['type'] == 'failure') { - $typelink = '/uploads/' . $p['type'] . '/' . $p['path']; + $typelink = '/uploads/' . $p['type'] . '/' . $p['path']; } elseif ($p['type'] == 'rejected') { - $typelink = '/uploads/' . $p['type'] . '/' . $p['path'] . '.youri'; + $typelink = '/uploads/' . $p['type'] . '/' . $p['path'] . '.youri'; } else { - $typelink = '/uploads/done/' . $p['path']; - if (!is_dir("..$typelink")) { - $typelink = ''; - } + $typelink = '/uploads/done/' . $p['path']; + if (!is_dir(realpath($upload_dir . '/..' . $typelink))) { + $typelink = ''; + } } $typestr = $p['type']; - if ($p['status']['build']) { + if (isset($p['status']['build'])) { $typealt = 'Building on'; - foreach ($p['status']['build'] as $h) + foreach ($p['status']['build'] as $h) { $typealt .= " $h"; + } $typestr = "$typestr"; } - $s .= ''; - $s .= ($typelink != '') ? - sprintf('%s', $typelink, $typestr) : - $typestr; + $s .= ''; - $s .= ''; + $show_time = ''; if ($p['type'] == 'uploaded') { $tdiff = timediff($p['buildtime']['start'], $p['buildtime']['end']); // use $p['buildtime']['diff']; instead? - $s .= $tdiff; + $show_time = '' . $tdiff . ''; + $tdiff = floor(($p['buildtime']['end'] - $p['buildtime']['start']) / 60)*60; @$buildtime_stats[timediff(0, $tdiff)] += 1; } - $s .= ''; - $s .= ''; - } - // Table - echo '', - '', - ' - - ', - $s, - '
    ', $total, ' packages submitted in the past ', $max_modified * 24, ' hours.
    SubmittedUserPackageTargetMediaStatusBuild time
    '; - - // Stats - $s = '
    '; - $score = round($stats['uploaded']/$total * 100); - $s .= sprintf('

    Score: %d/100

    -
    ', - $score, $score); - - $s .= ''; - foreach ($stats as $k => $v) { - $s .= sprintf('', - $k, $k, $v, round($v/$total*100)); - } - - $s .= '
    Stats.
    StatusCount%
    %s%d%d%%


    '; - - $s .= ''; - arsort($users); - foreach ($users as $k => $v) - $s .= sprintf('', - $k, $k, $v); - - $s .= '
    Packagers
    UserPackages
    %s%d


    '; - - /** - */ - function timesort($a, $b) - { - $a = explode(' ', trim($a)); - $b = explode(' ', trim($b)); - - if ($a[1] == 'hour' || $a[1] == 'hours') - $a[0] *= 3600; + $s .= ($typelink != '') + ? sprintf(' %s %s', + $typelink, $typestr, $show_time) + : sprintf(' %s %s', + $typestr, $show_time); - if ($b[1] == 'hour' || $b[1] == 'hours') - $b[0] *= 3600; - - if ($a[1] == 'minute' || $a[1] == 'minutes') - $a[0] *= 60; - - if ($b[1] == 'minute' || $b[1] == 'minutes') - $b[0] *= 60; - - if ($a[0] > $b[0]) - return 1; - elseif ($a[0] < $b[0]) - return -1; - - return 0; - } - uksort($buildtime_stats, "timesort"); - - $bts = ''; - $max = max($buildtime_stats); - foreach ($buildtime_stats as $time => $count) { - $bts .= sprintf('%s', - $time == "0 second" ? "< 1 minute" : $time, - round($count/$max*100), - $count); - - $tmp = explode(' ', $time); + $s .= ''; } + echo sprintf('
  • %d packages submitted in the past %d hours:

    ', $total, $max_modified * 24); + + // Last submitted packages + echo '', + ' + + + + + ', + '', $s, '', + '
    PackageWho whenTarget mediaStatus process time
    '; - $s .= ''; + echo ''; - $s .= sprintf(' - - ', - round($buildtime_total / 60, 2), + // Stats + $s = '
      +
    • Stats

    • +
    • +
    • '; + + $total_buildtime = round($buildtime_total / 60, 1); + $avail_capacity = 24 * $max_modified * $g_nodes_count; + $capacity_used = round($total_buildtime / $avail_capacity * 100, 1); + $s .= sprintf( + '
    Build time
    Total time%s hours
    Average%s minutes
    Builds count%s
    + + + +
    Total time%s hours (%s%% of capacity with %d nodes)
    Average%s minutes
    Builds count%s
    ', + $total_buildtime, + $capacity_used, + $g_nodes_count, $buildtime_avg, - $buildtime_cnt); - - $s .= 'DurationPack. nb.'; - $s .= $bts; - $s .= 'Does not take
    build failures
    into account.
    '; + $build_count + ); - $s .= ''; - $max = max($build_dates); - foreach ($build_dates as $time => $count) - $s .= sprintf('', - $time, - round($count / $max * 100), - $count); - $s .= '
    Build times
    %d
    '; - - $s .= '
  • '; + $s .= '
  • +
  • +
'; echo $s; + + uksort($buildtime_stats, "timesort"); + echo ''; + echo mga_bs_charts::js_init(); } else { - echo sprintf('

No package has been submitted in the past %d hours.

', + echo sprintf('
  • No package has been submitted in the past %d hours.

  • ', $max_modified * 24); } ?> + + + +

    -

    Generated at . - Code for this page is in http://svnweb.mageia.org/soft/build_system/web/.

    + +
    diff --git a/test_index.php b/test_index.php deleted file mode 100644 index 4c4beec..0000000 --- a/test_index.php +++ /dev/null @@ -1,342 +0,0 @@ - 0) ? reset($pkgs) : null -); - -?> - - - - - <?php echo strip_tags($title); ?> - - - - - - - - -/m", file_get_contents("http://check.mageia.org/cauldron/dependencies.rss"), $matches); - $unmaintained_count = file_exists(__DIR__ . '/data/unmaintained.txt') ? count(file(__DIR__ . '/data/unmaintained.txt')) : 0; - - if ($missing_deps_count > 0 - || $unmaintained_count > 0 - ) { - if ($missing_deps_count > 0) { - $figures_list[] = sprintf('%d broken deps.', - $missing_deps_count, - 'http://check.mageia.org/cauldron/dependencies.html' - ); - } - - if ($unmaintained_count > 0) { - $figures_list[] = sprintf('%d unmaintained', - $unmaintained_count, - 'data/unmaintained.txt' - ); - } - - if (count($figures_list) > 0) - $figures_list[count($figures_list)-1] .= sprintf(' %s', - 'https://wiki.mageia.org/en/Importing_packages', - 'YES you can help!', 'pick one'); - } - - preg_match_all('/(\d+)/', file_get_contents("https://bugs.mageia.org/buglist.cgi?quicksearch=%40qa-bugs+-kw%3Avali"), $matches); - $qa_bugs = $matches[1][0]; - if ($qa_bugs > 0) { - $figures_list[] = sprintf('%d update%s to validate - %s', - $qa_bugs, - 'https://bugs.mageia.org/buglist.cgi?quicksearch=%40qa-bugs+-kw%3Avali', - plural($qa_bugs), - 'https://wiki.mageia.org/en/QA_process_for_validating_updates', - 'YES you can help!', 'see how' - ); - } - - $html_figures = null; - if (count($figures_list) > 0) { - $html_figures = 'Packages: ' . implode(', ', $figures_list) . '.'; - } - -?> -
    -

    - -
    -
    -« Back to full list'; - } - - echo '
      '; - $buildtime_stats = array(); - - // Builds in progress - if (count($hosts) > 0) { - echo '
    • ', - sprintf('

      %d build%s in progress:

      ', count($hosts), plural(count($hosts))); - - $s = ''; - $tmpl = << - %s - %s - %s %s/%s - %s %s - -TB; - foreach ($hosts as $machine => $b) { - foreach ($b as $arch => $key) { - $s .= sprintf($tmpl, - $pkgs[$key]['package'], - $pkgs[$key]['user'], $pkgs[$key]['user'], - $pkgs[$key]['version'], $pkgs[$key]['media'], $pkgs[$key]['section'], - $machine, $arch); - } - } - echo '
      ', - ' - - - ', - $s, - '
      PackageUserTarget mediaMachine arch
      ', - '
      ', - '
    • '; - } else { - //echo '
    • No build in progress.

    • '; - } -} - -$upload_time = get_upload_time(); -if (!is_null($upload_time)) { - echo sprintf('
    • Upload in progress for %s.

    • ', timediff($upload_time)); -} - -// Build queue -$s = ''; -$tmpl = << - %s - view changes @ r%d - %s - %s - %s - %s/%s -T; - -if ($total > 0) { - foreach ($pkgs as $key => $p) { - if (trim($p['package']) == '') { - continue; - } - $revision_link = sprintf('http://svnweb.mageia.org/packages?view=revision&revision=%d', $p['revision']); - - $s .= sprintf($tmpl, - $p['type'], - $revision_link, - addslashes($p['summary']), - $p['package'], - $revision_link, $p['revision'], - $p['user'], $p['user'], - timediff(key2timestamp($key)) . ' ago', - $p['version'], - $p['media'], $p['section'] - ); - - $typelink = ''; - if ($p['type'] == 'failure') { - $typelink = '/uploads/' . $p['type'] . '/' . $p['path']; - } elseif ($p['type'] == 'rejected') { - $typelink = '/uploads/' . $p['type'] . '/' . $p['path'] . '.youri'; - } else { - $typelink = '/uploads/done/' . $p['path']; - if (!is_dir(realpath($upload_dir . '/..' . $typelink))) { - $typelink = ''; - } - } - $typestr = $p['type']; - if (isset($p['status']['build'])) { - $typealt = 'Building on'; - foreach ($p['status']['build'] as $h) { - $typealt .= " $h"; - } - $typestr = "$typestr"; - } - - $s .= ''; - - $show_time = ''; - if ($p['type'] == 'uploaded') { - $tdiff = timediff($p['buildtime']['start'], $p['buildtime']['end']); // use $p['buildtime']['diff']; instead? - $show_time = '' . $tdiff . ''; - - $tdiff = floor(($p['buildtime']['end'] - $p['buildtime']['start']) / 60)*60; - @$buildtime_stats[timediff(0, $tdiff)] += 1; - } - $s .= ($typelink != '') - ? sprintf(' %s %s', - $typelink, $typestr, $show_time) - : sprintf(' %s %s', - $typestr, $show_time); - - $s .= ''; - } - echo sprintf('
    • %d packages submitted in the past %d hours:

      ', $total, $max_modified * 24); - - // Last submitted packages - echo '', - ' - - - - - ', - '', $s, '', - '
      PackageWho whenTarget mediaStatus process time
      '; - - echo '
    '; - - // Stats - $s = '
      -
    • Stats

    • -
    • -
    • '; - - $total_buildtime = round($buildtime_total / 60, 1); - $avail_capacity = 24 * $max_modified * $g_nodes_count; - $capacity_used = round($total_buildtime / $avail_capacity * 100, 1); - $s .= sprintf( - ' - - - -
      Total time%s hours (%s%% of capacity with %d nodes)
      Average%s minutes
      Builds count%s
      ', - $total_buildtime, - $capacity_used, - $g_nodes_count, - $buildtime_avg, - $build_count - ); - - $s .= '
    • -
    • -
    '; - - echo $s; - - uksort($buildtime_stats, "timesort"); - echo ''; - echo mga_bs_charts::js_init(); -} -else -{ - echo sprintf('
  • No package has been submitted in the past %d hours.

  • ', - $max_modified * 24); -} - -?> - - - - -
    -
    - -
    - - -- cgit v1.2.1