diff options
author | 2009-07-17 12:27:02 -0400 | |
---|---|---|
committer | 2009-07-17 12:27:02 -0400 | |
commit | 0ffa58ac3b7688b4849d082abf0378b78f3cb618 (patch) | |
tree | c3db8303aea79953f9065a1532f2f3b916772751 | |
parent | Added predefined package sets; separated gentoo-specific setup into gentoo_se... (diff) | |
download | ingenue-0ffa58ac3b7688b4849d082abf0378b78f3cb618.tar.gz ingenue-0ffa58ac3b7688b4849d082abf0378b78f3cb618.tar.bz2 ingenue-0ffa58ac3b7688b4849d082abf0378b78f3cb618.zip |
Fixed bugs and added new/popular builds to welcome page
-rw-r--r-- | frontend/css/build.css | 10 | ||||
-rw-r--r-- | frontend/modules/gentoo/step3.php | 20 | ||||
-rw-r--r-- | frontend/pages/downloadimage.php | 10 | ||||
-rw-r--r-- | frontend/pages/welcome.php | 33 | ||||
-rw-r--r-- | shared/classes/0sql_row_obj.php | 6 | ||||
-rw-r--r-- | shared/classes/build.php | 13 | ||||
-rw-r--r-- | shared/classes/download.php | 29 | ||||
-rw-r--r-- | shared/classes/gentoo_package.php | 2 | ||||
-rw-r--r-- | todo | 7 |
9 files changed, 107 insertions, 23 deletions
diff --git a/frontend/css/build.css b/frontend/css/build.css index 7ae7345..43ade38 100644 --- a/frontend/css/build.css +++ b/frontend/css/build.css @@ -25,6 +25,16 @@ div.build span.status.queued { div.build span.status.config { color: teal; } +div.build span.downloads { + font-weight: bold; + font-size: 90%; + text-align: right; + float: right; +} +div.build span.downloads span.time { + font-size: 90%; + font-family: monospace; +} div.build span.links { font-size: 90%; } diff --git a/frontend/modules/gentoo/step3.php b/frontend/modules/gentoo/step3.php index 89e7ec3..a4f1b30 100644 --- a/frontend/modules/gentoo/step3.php +++ b/frontend/modules/gentoo/step3.php @@ -4,17 +4,19 @@ if (in_array('timezone', $opts)) $this->select('timezone', 'timezone', 'Timezone', get_timezones()); if (in_array('dev-manager', $opts)) $this->select('dev-manager', 'dev-manager', '/dev Manager', array('udev' => 'udev', 'static-dev' => 'Static /dev')); -$profile=new sql_gentoo_profile($opts['profile']); -foreach (explode(' ', $this->get_opt('pkgsets')) as $pkgset) { - $pkgset=new sql_gentoo_pkgset($pkgset); - $pkgs=array(); - foreach (explode("\n", $pkgset->packages) as $pkg) { - if ($obj=sql_gentoo_package::from_atom($pkg, $profile)) { - $array=$obj->to_array(); - $pkgs[$pkg]="$pkg: {$array['desc']}"; +$profile=new sql_gentoo_profile($this->get_opt('profile')); +if (strlen($pkgsets=$this->get_opt('pkgsets'))) { + foreach (explode(' ', $this->get_opt('pkgsets')) as $pkgset) { + $pkgset=new sql_gentoo_pkgset($pkgset); + $pkgs=array(); + foreach (explode("\n", $pkgset->packages) as $pkg) { + if ($obj=sql_gentoo_package::from_atom($pkg, $profile)) { + $array=$obj->to_array(); + $pkgs[$pkg]="$pkg: {$array['desc']}"; + } } + $this->checkbox_array('pkgset-'.$pkgset->id, 'pkgset-'.$pkgset->id, $pkgset->name, $pkgs); } - $this->checkbox_array('pkgset-'.$pkgset->id, 'pkgset-'.$pkgset->id, $pkgset->name, $pkgs); } // TODO This shouldn't be a step at all, it should be in wizard.php to choose between bundlers // TODO This shouldn't be part of configurations, except possibly a default value. It should be for builds diff --git a/frontend/pages/downloadimage.php b/frontend/pages/downloadimage.php index 91c1161..2234a10 100644 --- a/frontend/pages/downloadimage.php +++ b/frontend/pages/downloadimage.php @@ -4,16 +4,20 @@ function init_downloadimage() { if (!isset($S['user'])) { return 'login'; } - if (!isset($request['build']) || !preg_match('/^[a-zA-Z0-9]{6}$/', $request['build'])) { + if (!(isset($request['build']) && strlen($request['build']) == 6 && ctype_alnum($request['build']))) { debug('downlaodimage', 'No build or badly formatted build requested'); return '404'; } - $r=$S['pdo']->query('SELECT * FROM `builds` WHERE `owner`='.$S['user']->id.' AND `id`="'.$request['build'].'"'); + $r=$S['pdo']->query('SELECT * FROM `builds` WHERE `id`="'.$request['build'].'"'); if ($r->rowCount() == 0) { debug('downloadimage', 'build not found or not owned by user'); return '404'; } $build=new sql_build($r->fetch(PDO::FETCH_ASSOC)); + if (!owner_or_admin($build->owner)) { + debug('downloadimage', 'Permission denied'); + return '404'; + } $files=glob(COMPLETED.'/build-'.$build->id.'.*'); if (count($files)) { if (count($files) > 1) { @@ -30,6 +34,8 @@ function init_downloadimage() { debug('downloadimage', 'image file not found'); return '404'; } + $dl=new sql_download($build->id, $S['user']->id, time()); + $dl->write(); contenttype('application/octet-stream'); header('Content-Length: '.filesize($S['file'])); header('Content-Description: File Transfer'); diff --git a/frontend/pages/welcome.php b/frontend/pages/welcome.php index d326f08..4b727e3 100644 --- a/frontend/pages/welcome.php +++ b/frontend/pages/welcome.php @@ -6,5 +6,38 @@ function init_welcome() { function body_welcome() { global $S; echo '<h2>Welcome</h2>'; + echo '<div class="box"><h3>Most Popular Downloads</h3>'; + $r=$S['pdo']->query('SELECT `build` FROM `downloads` GROUP BY `build` ORDER BY COUNT(*) DESC LIMIT 3'); + if ($r->rowCount()) { + while ($build=$r->fetch(PDO::FETCH_COLUMN)) { + $build=new sql_build($build); + echo $build->display(); + } + } else { + echo print_warning('No downloads'); + } + echo '</div>'; + echo '<div class="box"><h3>Recently Downloaded</h3>'; + $r=$S['pdo']->query('SELECT * FROM `downloads` ORDER BY `time` DESC LIMIT 3'); + if ($r->rowCount()) { + while ($download=$r->fetch(PDO::FETCH_ASSOC)) { + $download=new sql_download($download); + echo $download->get_build()->display(); + } + } else { + echo print_warning('No downloads'); + } + echo '</div>'; + echo '<div class="box"><h3>Recently Built</h3>'; + $r=$S['pdo']->query('SELECT * FROM `builds` WHERE `status`="finished/success" ORDER BY `finish` DESC LIMIT 3'); + if ($r->rowCount()) { + while ($build=$r->fetch(PDO::FETCH_ASSOC)) { + $build=new sql_build($build); + echo $build->display(); + } + } else { + echo print_warning('No finished builds'); + } + echo '</div>'; } ?> diff --git a/shared/classes/0sql_row_obj.php b/shared/classes/0sql_row_obj.php index 564da0a..a86552a 100644 --- a/shared/classes/0sql_row_obj.php +++ b/shared/classes/0sql_row_obj.php @@ -232,7 +232,11 @@ abstract class sql_row_obj { // If the name of this class changes, it must be up } $r=self::sql_query('SELECT * FROM `'.$this->table.'` WHERE '.$this->sql_id()); if ($r->rowCount() == 0) { - throw new Exception(get_class($this).' object constructed with '.func_num_args().' values '.$this->sql_id().' but no rows were found (PRIMARY KEY).'); + if (count($this->primary_key) == count($this->columns)) { + $this->values=$this->db_values; + $this->db_values=array(); + } else + throw new Exception(get_class($this).' object constructed with '.func_num_args().' values '.$this->sql_id().' but no rows were found (PRIMARY KEY).'); } else { $this->from_array($r->fetch(), true); return; diff --git a/shared/classes/build.php b/shared/classes/build.php index 8b19b41..8212d56 100644 --- a/shared/classes/build.php +++ b/shared/classes/build.php @@ -50,7 +50,7 @@ class sql_build extends conf_build_common { // Returns HTML code describing this build's status (for human consumption) function display() { global $S; - $format='D j M Y G:i:s'; + $format='D j M Y G:i:s T'; $html='<div class="build"><span class="name">'.(isset($this->name) && strlen($this->name)?htmlentities($this->name):'Unnamed Build').'</span> '; $status=explode('/', $this->status, 2); if ($status[0] == 'config') { @@ -71,7 +71,10 @@ class sql_build extends conf_build_common { } elseif ($status[0] == 'finished') { $status=explode(': ', $status[1], 2); if ($status[0] == 'success') { - $html.='<span class="status successful">[successful]</span><br/><span class="links"><a href="'.url('download/'.$this->id).'">Download image</a> • <a href="'.url('logs/'.$this->id).'">Build log</a></span>'; + $r=$S['pdo']->query('SELECT COUNT(*) as `count`, MAX(`time`) as `time` FROM `downloads` WHERE `build`="'.$this->id.'"'); + $r=$r->fetch(PDO::FETCH_ASSOC); + $d=$r['count'].' download'.($r['count'] != 1?'s':'').($r['count']?'<br/><span class="time">(last at '.date($format, $r['time']).')</span>':''); + $html.='<span class="downloads">'.$d.'</span><span class="status successful">[successful]</span><br/><span class="links"><a href="'.url('download/'.$this->id).'">Download image</a> • <a href="'.url('logs/'.$this->id).'">Build log</a></span>'; } elseif ($status[0] == 'failed') { $html.='<span class="status failed">[failed: '.htmlentities($status[1]).']</span><br/><span class="links"><a href="'.url('logs/'.$this->id.'/failure').'">View output of failed command</a> • <a href="'.url('logs/'.$this->id).'">Build log</a></span>'; } elseif ($status[0] == 'uploading') { @@ -83,11 +86,11 @@ class sql_build extends conf_build_common { throw_exception('Unrecognized build status '.$this->status); } if (isset($this->ctime)) { - $html.='<div class="time">Submitted for build at: <span class="time">'.date($format, $this->ctime).' UTC</span><br/>'; + $html.='<div class="time">Submitted for build at: <span class="time">'.date($format, $this->ctime).'</span><br/>'; if (isset($this->start)) { - $html.='Build started at: <span class="time">'.date($format, $this->start).' UTC</span><br/>'; + $html.='Build started at: <span class="time">'.date($format, $this->start).'</span><br/>'; if (isset($this->finish)) { - $html.='Build finished at: <span class="time">'.date($format, $this->finish).' UTC</span><br/>Total build time: <span class="time">'.display_time($this->finish-$this->start).'</span>'; + $html.='Build finished at: <span class="time">'.date($format, $this->finish).'</span><br/>Total build time: <span class="time">'.display_time($this->finish-$this->start).'</span>'; } else { $html.='Running for: <span class="time">'.display_time(time()-$this->start).'</span>'; } diff --git a/shared/classes/download.php b/shared/classes/download.php new file mode 100644 index 0000000..f255f1c --- /dev/null +++ b/shared/classes/download.php @@ -0,0 +1,29 @@ +<?php +class sql_download extends sql_row_obj { + protected $table='downloads', $primary_key=array('build', 'user', 'time'), $columns=array( + 'build' => array ( + 'type' => 'CHAR', + 'length' => 6, + 'not_null' => true, + 'default' => '', + 'refers_to' => 'builds.id' + ), + 'user' => array ( + 'type' => 'INT', + 'length' => 10, + 'unsigned' => true, + 'not_null' => true, + 'default' => 0, + 'refers_to' => 'users.id' + ), + 'time' => array ( + 'type' => 'INT', + 'length' => 10, + 'unsigned' => true, + 'not_null' => true, + 'default' => 0 + ) + + ); +} +?> diff --git a/shared/classes/gentoo_package.php b/shared/classes/gentoo_package.php index 4426565..41fec01 100644 --- a/shared/classes/gentoo_package.php +++ b/shared/classes/gentoo_package.php @@ -68,6 +68,7 @@ class sql_gentoo_package extends sql_row_obj { } public static function from_atom($atom, &$profile=null) { global $S; + if (strlen($atom) == 0) return null; if (strpos($atom, '/')) { list($bcat, $name)=explode('/', $atom); if ($i=strpos($bcat, '-')) { @@ -75,6 +76,7 @@ class sql_gentoo_package extends sql_row_obj { $bcat=substr($bcat, 0, strlen($bcat)-strlen($lcat)); } } else { + $bcat=$lcat=null; $name=$atom; } $c=array(); @@ -1,19 +1,14 @@ -Have backend handle builds that it finds to already be running (break in to steps and store current status) -Make package adding friendly for browsers without JS/CSS (use ul/li, not div) Write a live git ebuild -Write an AJAX-based self-updating status viewer *** Add logging besides just commands *** -Make backend do a dummy run through and queue all commands and other tasks, then execute them (for better status handling, easier debugging, etc.) Have builds and tasks not give links to logs if we're already viewing the logs Either make task status a TEXT or stop putting command name in the status (via thrown exception) - we can fetch this later anyway - just store the task id that failed (or use the last task) -Consider saving env. passed to tasks, path if we ever use it +Consider logging env. passed to tasks, path if we ever use it Add metadata back to logviewer Add a statistics page Add a profiles management page/backend utility Add cleanup functions to the frontend and backend (tasks dir in backend containing scripts that can be launched through frontend) Separate variables we got from the URL from the rest, stop using $request, instead keep super globals and strip slashes on them Add masked indicator back to step2, support ~arch installation -Completely plan out how frontend modules should function - each step needs to report if it finished successfully (required values) Allow backend to define bail-out functions to call when it dies (things like unmounting the ISO it was copying) Add STDERR (maybe STDOUT) only option to log viewer Simplify status to numeric on builds - varchar isn't necessary |