summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEudyptula <eitan@mosenkis.net>2009-07-17 12:27:02 -0400
committerEudyptula <eitan@mosenkis.net>2009-07-17 12:27:02 -0400
commit0ffa58ac3b7688b4849d082abf0378b78f3cb618 (patch)
treec3db8303aea79953f9065a1532f2f3b916772751
parentAdded predefined package sets; separated gentoo-specific setup into gentoo_se... (diff)
downloadingenue-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.css10
-rw-r--r--frontend/modules/gentoo/step3.php20
-rw-r--r--frontend/pages/downloadimage.php10
-rw-r--r--frontend/pages/welcome.php33
-rw-r--r--shared/classes/0sql_row_obj.php6
-rw-r--r--shared/classes/build.php13
-rw-r--r--shared/classes/download.php29
-rw-r--r--shared/classes/gentoo_package.php2
-rw-r--r--todo7
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> &bull; <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> &bull; <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> &bull; <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();
diff --git a/todo b/todo
index 821c195..6bc708c 100644
--- a/todo
+++ b/todo
@@ -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