diff --git a/checkin_notes b/checkin_notes index 4e933d2dff..067d3ca2f0 100644 --- a/checkin_notes +++ b/checkin_notes @@ -1335,3 +1335,7 @@ David Feb 12 2008 lib/ common_defs.h util.C,h + +David Feb 12 2008 + lib/ + str_util.h diff --git a/doc/links.php b/doc/links.php index 713a4a9811..f7b3a9e806 100644 --- a/doc/links.php +++ b/doc/links.php @@ -296,6 +296,7 @@ language("Slovak", array( site("http://www.boinc.sk/", "www.boinc.sk") )); language("Spanish", array( + site("http://foro.noticias3d.com/vbulletin/showthread.php?t=192297", "Noticias3D"), site("http://elmajo.blogspot.com", "Computación Distribuida"), site("http://efren-canarias.blogcindario.com/", "El Pais De La Computacion"), site("http://www.canalboinc.org/modules/news/", "Canal BOINC"), diff --git a/doc/logo.php b/doc/logo.php index 9847e9ca67..9e71702f25 100644 --- a/doc/logo.php +++ b/doc/logo.php @@ -43,7 +43,7 @@ The colors are based on U.C. Berkeley's blue-and-gold colors.
  • Adobe Illustrator (.ai)
  • Vector graphics (.cdr)
  • Adobe PDF (.cdr) -
  • Scalable Vector Graphics (.svg) +
  • Scalable Vector Graphics (.svg)
  • 1280x535, transparent background (.png)
  • Windows meta-file (.wmf)
  • Favicon (GIFF) diff --git a/html/inc/bolt_db.inc b/html/inc/bolt_db.inc index 12f682f805..859d2f5ac9 100644 --- a/html/inc/bolt_db.inc +++ b/html/inc/bolt_db.inc @@ -70,7 +70,7 @@ class BoltDb extends DbConn { class BoltUser { static $cache; static function lookup_userid($id) { - $db = BoincDb::get(); + $db = BoltDb::get(); return $db->lookup('bolt_user', 'BoltUser', "user_id=$id"); } static function insert($clause) { diff --git a/html/inc/bossa_db.inc b/html/inc/bossa_db.inc index 207dc2c12e..108eebe93c 100644 --- a/html/inc/bossa_db.inc +++ b/html/inc/bossa_db.inc @@ -3,6 +3,10 @@ require_once("../inc/db_conn.inc"); require_once("../inc/util.inc"); +define ('VALIDATE_STATE_INIT', 0); +define ('VALIDATE_STATE_VALID', 1); +define ('VALIDATE_STATE_INVALID', 2); + class BossaDb extends DbConn { public static $instance; @@ -28,15 +32,47 @@ class BossaDb extends DbConn { } } +class BossaUser { + static $cache; + static function lookup_userid($id) { + $db = BossaDb::get(); + return $db->lookup('bossa_user', 'BossaUser', "user_id=$id"); + } + static function insert($clause) { + $db = BossaDb::get(); + return $db->insert('bossa_user', $clause); + } + static function lookup(&$user) { + if (!$user) return; + if (isset($user->bossa)) return; + if (isset(self::$cache[$user->id])) { + $bossa = self::$cache[$user->id]; + } else { + $bossa = self::lookup_userid($user->id); + if (!$bossa) { + self::insert("(user_id) values ($user->id)"); + $bossa = self::lookup_userid($user->id); + } + self::$cache[$user->id] = $bossa; + } + $user->bossa = $bossa; + } + function update($clause) { + $db = BossaDb::get(); + $clause = "$clause where user_id=$this->user_id"; + return $db->update_aux('bossa_user', $clause); + } +} + class BossaApp { function insert($clause) { $db = BossaDb::get(); return $db->insert('bossa_app', $clause); } - static function lookup_name($name) { + static function lookup_short_name($name) { $db = BossaDb::get(); - return $db->lookup('bossa_app', 'BossaApp', "name='$name'"); + return $db->lookup('bossa_app', 'BossaApp', "short_name='$name'"); } static function lookup_id($id) { @@ -54,7 +90,7 @@ class BossaJob { function insert() { $db = BossaDb::get(); $now = time(); - $query = "insert into DBNAME.bossa_job (create_time, name, app_id, info, batch, time_estimate, time_limit, nneeded) values ($now, '$this->name', $this->app_id, '$this->info', $this->batch, $this->time_estimate, $this->time_limit, $this->nneeded)"; + $query = "insert into DBNAME.bossa_job (create_time, name, app_id, info, batch, time_estimate, time_limit, conf_needed) values ($now, '$this->name', $this->app_id, '$this->info', $this->batch, $this->time_estimate, $this->time_limit, $this->conf_needed)"; $result = $db->do_query($query); if (!$result) { echo "$query\n"; @@ -114,7 +150,7 @@ class BossaJobInst { // // TODO: put the following in a transaction $db = BossaDb::get(); - $query = "select bossa_job.* from DBNAME.bossa_job left join DBNAME.bossa_job_inst on bossa_job_inst.job_id = bossa_job.id where bossa_job.nneeded>0 and bossa_job_inst.user_id is null limit 1"; + $query = "select bossa_job.* from DBNAME.bossa_job left join DBNAME.bossa_job_inst on bossa_job_inst.job_id = bossa_job.id where bossa_job.conf_needed>0 and bossa_job_inst.user_id is null limit 1"; $result = $db->do_query($query); if (!$result) return null; $job = mysql_fetch_object($result, 'BossaJob'); @@ -130,7 +166,8 @@ class BossaJobInst { return null; } - $job->update("nneeded=nneeded-1"); + // TODO: replace "1" + $job->update("conf_needed=conf_needed-1"); return $ji; } diff --git a/html/inc/bossa_example.inc b/html/inc/bossa_example.inc index 05c4385639..4a829ac5a3 100644 --- a/html/inc/bossa_example.inc +++ b/html/inc/bossa_example.inc @@ -31,7 +31,7 @@ function ellipse_handle($bj, $c) { $res->cy /= count($c); } - $info = json_decode[$bj->info); + $info = json_decode($bj->info); $info->result = $res; $i = json_encode($info); $bj->update("info='$i'"); diff --git a/html/ops/bossa_ops.php b/html/ops/bossa_admin.php similarity index 65% rename from html/ops/bossa_ops.php rename to html/ops/bossa_admin.php index b992f3c635..76a104fb09 100644 --- a/html/ops/bossa_ops.php +++ b/html/ops/bossa_admin.php @@ -13,17 +13,19 @@ function show_bapp($app) { "; if ($app->hidden) { - show_button("bossa_ops.php?action=unhide&app_id=$app->id", "Unhide", "Unhide this app"); + show_button("bossa_admin.php?action=unhide&app_id=$app->id", "Unhide", "Unhide this app"); } else { - show_button("bossa_ops.php?action=hide&app_id=$app->id", "Hide", "Hide this app"); + show_button("bossa_admin.php?action=hide&app_id=$app->id", "Hide", "Hide this app"); + echo "
    "; + show_button($app->short_name."_workgen.php?njobs=10", "Create jobs", "Create 10 new jobs"); } } function show_apps() { $apps = BossaApp::enum(); start_table(); - row1("Existing apps", 4); - table_header("Name/description", "Display script", "Backend script", ""); + row1("Existing apps", 2); + table_header("Name/description", ""); foreach ($apps as $app) { show_bapp($app); } @@ -32,7 +34,7 @@ function show_apps() { function add_app_form() { echo " -
    + "; start_table(); row1("Add app"); @@ -50,7 +52,7 @@ function add_app_form() { function user_settings() { global $user; $flags = $user->bossa->flags; - echo ""; + echo ""; start_table(); row1("User settings"); $x = ($flags&BOLT_FLAGS_SHOW_ALL)?"checked":""; @@ -72,20 +74,45 @@ function show_all() { admin_page_tail(); } +function show_jobs($app_id) { + $app = BossaApp::lookup_id($app_id); + echo "

    Jobs for $app->user_friendly_name

    "; + $jobs = BossaJob::enum("app_id=$app_id"); + foreach ($jobs as $job) { + echo "
    \n";
    +        print_r($job);
    +        echo "
    \n"; + echo " + id>Show instances +
    + "; + } +} + +function show_insts($job_id) { + echo "

    Job instances

    "; + $jis = BossaJobInst::enum("job_id=$job_id"); + foreach ($jis as $ji) { + echo "
    \n";
    +        print_r($ji);
    +        echo "

    \n"; + } +} + + $user = get_logged_in_user(); $submit = get_str('submit', true); if ($submit == 'Create app') { $name = BossaDb::escape_string(get_str('app_name')); + $short_name = get_str('short_name'); $description = BossaDb::escape_string(get_str('description')); - $display_script = get_str('display_script'); - $backend_script = get_str('backend_script'); $min_conf_sum = get_str('min_conf_sum'); $min_conf_frac = get_str('min_conf_frac'); $max_instances = get_str('max_instances'); $now = time(); - BossaApp::insert("(create_time, name, description, display_script, backend_script, min_conf_sum, min_conf_frac, max_instances) values ($now, '$name', '$description', '$display_script', '$backend_script', $min_conf_sum, $min_conf_frac, $max_instances)"); - Header('Location: bossa_ops.php'); + BossaApp::insert("(create_time, name, short_name, description, min_conf_sum, min_conf_frac, max_instances) values ($now, '$name', '$short_name', '$description', $min_conf_sum, $min_conf_frac, $max_instances)"); + Header('Location: bossa_admin.php'); exit(); } else if ($submit == 'Update user') { $flags = 0; @@ -93,8 +120,14 @@ if ($submit == 'Create app') { if (get_str('debug', true)) $flags |= BOLT_FLAGS_DEBUG; $user->bossa->update("flags=$flags"); $user->bossa->flags = $flags; - Header('Location: bossa_ops.php'); + Header('Location: bossa_admin.php'); exit(); +} else if ($cmd == 'show_jobs') { + $app_id = $_GET['app_id']; + show_jobs($app_id); +} else if ($cmd == 'show_insts') { + $job_id = $_GET['job_id']; + show_insts($job_id); } else { $action = get_str('action', true); if ($action) { @@ -111,7 +144,7 @@ if ($submit == 'Create app') { default: error_page("unknown action $action"); } - Header('Location: bossa_ops.php'); + Header('Location: bossa_admin.php'); exit(); } } diff --git a/html/ops/bossa_example_workgen.php b/html/ops/bossa_example_workgen.php new file mode 100644 index 0000000000..adf2f144ab --- /dev/null +++ b/html/ops/bossa_example_workgen.php @@ -0,0 +1,119 @@ +cx, $case->cy, $case->w, $case->h, rand_color($im, 50) + ); +} + +function add_rect($im) { + $cx = rand(-100, 600); + $cy = rand(-100, 400); + $w = rand(50, 100); + $h = rand(50, 100); + imagefilledrectangle($im, $cx, $cy, $cx+$w, $cy+$h, rand_color($im, 50)); +} + + +function make_image($case) { + $im = imagecreatetruecolor(600, 400); + imagefill($im, 0, 0, imagecolorallocate($im, 255, 255, 255)); + for ($i=0; $i<400; $i++) { + add_rect($im); + } + $im2 = imagecreatetruecolor(600, 400); + imagefill($im2, 0, 0, rand_color($im2, 0)); + if ($case->have_ellipse) { + add_ellipse($im2, $case); + } + imagecopymerge($im, $im2, 0, 0, 0, 0, 600, 400, 30); + return $im; +} + +function make_test_case() { + $case = null; + $case->have_ellipse = rand(0, 1); + if ($case->have_ellipse) { + $case->cx = rand(50, 550); + $case->cy = rand(50, 350); + $case->w = rand(50, 100); + $case->h = rand(50, 100); + } + return $case; +} + +function make_job($app, $batch, $i, $config) { + // create the image file; + // store it in the download directory hierarchy + // + $jobname = "job_$batch_$i"; + $filename = "$jobname.png"; + $path = dir_hier_path( + $filename, $config->download_dir, $config->uldl_dir_fanout + ); + $url = dir_hier_url( + $filename, $config->download_url, $config->uldl_dir_fanout + ); + $case = make_test_case(); + imagepng(make_image($case), $path); + $case->url = $url; + + // make a job record in the Bossa database + // + $job = new BossaJob; + $job->app_id = $app->id; + $job->batch = $batch; + $job->time_estimate = 30; + $job->time_limit = 600; + $job->name = $jobname; + $job->info = json_encode($case); + $job->conf_needed = $app->min_conf_sum; + + if (!$job->insert()) { + echo "BossaJob::insert failed: ", mysql_error(), "\n"; + exit(1); + } +} + +function make_jobs($njobs) { + $c = get_config(); + $config = null; + $config->download_dir = parse_config($c, ""); + $config->download_url = parse_config($c, ""); + $config->uldl_dir_fanout = parse_config($c, ""); + $appname = "bossa_example"; + $app = BossaApp::lookup_short_name($appname); + if (!$app) { + echo "Application $appname not found\n"; + exit(1); + } + $batch = time(); + for ($i=0; $i<$njobs; $i++) { + make_job($app, $batch, $i, $config); + } + echo "Created $njobs jobs +

    + Bossa Admin + "; +} + +$njobs = get_int('njobs', true); +if ($njobs) { + make_jobs($njobs); +} else { + header ("Content-type: image/png"); + imagepng(make_image(make_test_case())); +} + +?> diff --git a/html/ops/bossa_make_jobs_example.php b/html/ops/bossa_make_jobs_example.php deleted file mode 100644 index 7e76d27e49..0000000000 --- a/html/ops/bossa_make_jobs_example.php +++ /dev/null @@ -1,33 +0,0 @@ -app_id = $app->id; - $job->batch = 0; - $job->time_estimate = 30; - $job->time_limit = 600; - $job->nsuccess_needed = 3; - for ($i=0; $i<10; $i++) { - $job->name = "job_$i"; - $info = null; - $info->number = $i % 2; - $job->info = json_encode($info); - if (!$job->insert()) { - echo "BossaJob::insert failed: ", mysql_error(), "\n"; - exit(1); - } - } -} - -make_jobs(); -echo "All done.\n"; - -?> diff --git a/html/ops/bossa_transitioner.php b/html/ops/bossa_transitioner.php index 58dcbebad0..f7acd98b76 100644 --- a/html/ops/bossa_transitioner.php +++ b/html/ops/bossa_transitioner.php @@ -2,9 +2,7 @@ require_once("../inc/bossa_db.inc"); -var $apps; - -function lookup_app($id) { +function lookup_bapp($id) { global $apps; foreach ($apps as $app) { if ($app->id == $id) return $app; @@ -33,6 +31,7 @@ function total_confidence($instances) { if (!$i->finished_time) continue; $sum += $i->conf; } + return $sum; } // See if there's a canonical instance. @@ -55,7 +54,7 @@ function find_canonical($instances, $total_conf, &$max_conf) { return $best; } -function get_confidence(&$instances) { +function get_confidences(&$instances) { foreach ($instances as $inst) { $user = BoincUser::lookup_id($inst->user_id); BossaUser::lookup($user); @@ -68,7 +67,7 @@ function get_confidence(&$instances) { // 2) an instance has timed out // function handle_job($job) { - $app = lookup_app($job->app_id); + $app = lookup_bapp($job->app_id); if (!$app) { echo "Missing app: $job->app_id\n"; return; @@ -95,7 +94,7 @@ function handle_job($job) { // If we have enough total confidence, check for consensus // get_confidences($instances); - $total_conf = total_confidence(instances); + $total_conf = total_confidence($instances); if ($total_conf >= $app->min_conf_sum) { $inst = find_canonical($instances, $total_conf, $max_conf); } @@ -114,7 +113,7 @@ function main() { global $apps; $apps = BossaApp::enum(); foreach ($apps as $app) { - $bs = "../lib/".$app->short_name."_backend.inc"; + $bs = "../inc/".$app->short_name.".inc"; require_once($bs); } while (1) { @@ -123,4 +122,5 @@ function main() { } main(); +echo "foo"; ?> diff --git a/html/user/bossa_get_job.php b/html/user/bossa_get_job.php index b35f04f02f..7215776438 100644 --- a/html/user/bossa_get_job.php +++ b/html/user/bossa_get_job.php @@ -17,7 +17,7 @@ if (!$app) { $ji = BossaJobInst::assign($app, $user); if ($ji) { - $url = $app->display_script."?bji=$ji->id"; + $url = $app->short_name.".php?bji=$ji->id"; Header("Location: $url"); } else { page_head("No jobs available"); diff --git a/lib/str_util.h b/lib/str_util.h index e35a58b8a1..bbe24b7312 100644 --- a/lib/str_util.h +++ b/lib/str_util.h @@ -70,13 +70,9 @@ inline bool starts_with(std::string const& s, std::string const& prefix) { } inline void downcase_string(std::string& w) { - char buf[1024]; - strlcpy(buf, w.c_str(), sizeof(buf)); - size_t n = strlen(buf); - for (size_t i=0; i