mirror of https://github.com/BOINC/boinc.git
Merge pull request #5945 from BOINC/dpa_sandbox3
web: make sandbox file list sortable by name, size, or date
This commit is contained in:
commit
5eb9fa9829
|
@ -22,18 +22,19 @@
|
|||
// - each user (job submitter) has a 'sandbox' where they can store files
|
||||
// on the BOINC server, via a web interface.
|
||||
// These files are mutable; you can modify a file w/ a given name.
|
||||
// - files are stored in a dir project/sandbox/<userid>
|
||||
// - files are stored in project/sandbox/<userid>/
|
||||
// - When a file is uploaded, its size and MD5 are computed and stored
|
||||
// in an 'info file' in a parallel dir, project/sandbox/<userid>/.md5
|
||||
// in an 'info file' in a parallel dir, project/sandbox/<userid>/.md5/
|
||||
//
|
||||
// Sandbox files can be used for web-based job submissions systems
|
||||
// like BUDA and autodock on BOINC Central.
|
||||
// Typically they are used as job input files or app files,
|
||||
// in which case they are downloadable.
|
||||
// in which case they are downloadable by BOINC clients.
|
||||
// When a file is used in this way,
|
||||
// it must be copied to the download hierarchy,
|
||||
// and assigned a physical name that includes its MD5.
|
||||
// The name depends on the role of the file.
|
||||
// The name can depend on the role of the file;
|
||||
// e.g. it can include a batch ID or BUDA app name
|
||||
|
||||
require_once("../inc/util.inc");
|
||||
require_once("../inc/dir_hier.inc");
|
||||
|
@ -118,8 +119,9 @@ function sandbox_file_select(
|
|||
return $x;
|
||||
}
|
||||
|
||||
// copy file and info file from sandbox to $dir
|
||||
// Copy file and info file from sandbox to $dir
|
||||
// (which must have a subdir .md5/)
|
||||
// Used for BUDA app files.
|
||||
//
|
||||
function copy_sandbox_file($user, $fname, $dir) {
|
||||
$sbdir = sandbox_dir($user);
|
||||
|
@ -127,4 +129,46 @@ function copy_sandbox_file($user, $fname, $dir) {
|
|||
copy("$sbdir/.md5/$fname", "$dir/.md5/$fname");
|
||||
}
|
||||
|
||||
//////////// tables with sortable columns ////////////////
|
||||
|
||||
// maybe this should go in util.inc
|
||||
|
||||
$g_field = null;
|
||||
|
||||
function field_compare($a, $b) {
|
||||
global $g_field;
|
||||
if ($a->$g_field == $b->$g_field) return 0;
|
||||
return $a->$g_field > $b->$g_field;
|
||||
}
|
||||
|
||||
function column_sort(&$items, $field, $rev) {
|
||||
global $g_field;
|
||||
$g_field = $field;
|
||||
usort($items, 'field_compare');
|
||||
if ($rev) {
|
||||
$items = array_reverse($items);
|
||||
}
|
||||
}
|
||||
|
||||
// column header for a given field.
|
||||
// If it's the sort field, show up or down arrow to change order
|
||||
// Otherwise name is a link to make it the sort field
|
||||
//
|
||||
function column_sort_header($field, $title, $url, $sort_field, $sort_rev) {
|
||||
if ($field == $sort_field) {
|
||||
return sprintf(
|
||||
'%s <a href="%s&sort_field=%s&sort_rev=%d">%s</a>',
|
||||
$title,
|
||||
$url, $sort_field,
|
||||
$sort_rev?0:1,
|
||||
$sort_rev?'↑':'↓'
|
||||
);
|
||||
} else {
|
||||
return sprintf(
|
||||
'<a href="%s&sort_field=%s">%s</a>',
|
||||
$url, $field, $title
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -913,8 +913,8 @@ function current_url() {
|
|||
return $url;
|
||||
}
|
||||
|
||||
// style for a button
|
||||
// the colors for bootstrap' btn-success are almost illegible;
|
||||
// return style for a button
|
||||
// the colors for bootstrap's btn-success are almost illegible;
|
||||
// the green is too light. Use a darker green.
|
||||
//
|
||||
function button_style($color='green', $font_size=null) {
|
||||
|
@ -951,6 +951,10 @@ function button_text($url, $text, $desc=null, $class=null, $extra='') {
|
|||
);
|
||||
}
|
||||
|
||||
function button_text_small($url, $text, $desc=null) {
|
||||
return button_text($url, $text, $desc, "btn btn-xs", button_style());
|
||||
}
|
||||
|
||||
function show_button($url, $text, $desc=null, $class=null, $extra=null) {
|
||||
echo button_text($url, $text, $desc, $class, $extra);
|
||||
}
|
||||
|
@ -958,7 +962,7 @@ function show_button($url, $text, $desc=null, $class=null, $extra=null) {
|
|||
// for places with a bunch of buttons, like forum posts
|
||||
//
|
||||
function show_button_small($url, $text, $desc=null) {
|
||||
echo button_text($url, $text, $desc, "btn btn-xs", button_style());
|
||||
echo button_text_small($url, $text, $desc);
|
||||
}
|
||||
|
||||
// used for showing icons
|
||||
|
|
|
@ -318,7 +318,7 @@ function view_file() {
|
|||
$app = get_str('app');
|
||||
if (!is_valid_filename($app)) die('bad arg');
|
||||
$variant = get_str('variant');
|
||||
if (!is_valid_filename($arg)) die('bad arg');
|
||||
if (!is_valid_filename($variant)) die('bad arg');
|
||||
$fname = get_str('fname');
|
||||
if (!is_valid_filename($fname)) die('bad arg');
|
||||
echo "<pre>\n";
|
||||
|
|
|
@ -92,36 +92,67 @@ function list_files($user) {
|
|||
if ($notice) {
|
||||
echo "<p>$notice<hr>";
|
||||
}
|
||||
echo "
|
||||
<p>
|
||||
Your 'File sandbox' is where you store files to this BOINC server.
|
||||
";
|
||||
$files = array();
|
||||
echo "<p>Click a column title to sort on that attribute.<p>\n";
|
||||
$fnames = array();
|
||||
foreach (scandir($dir) as $f) {
|
||||
if ($f[0] == '.') continue;
|
||||
$files[] = $f;
|
||||
$fnames[] = $f;
|
||||
}
|
||||
if (count($files) == 0) {
|
||||
if (count($fnames) == 0) {
|
||||
echo "Your sandbox is currently empty.";
|
||||
} else {
|
||||
sort($files);
|
||||
$files = [];
|
||||
foreach ($fnames as $fname) {
|
||||
[$md5, $size] = sandbox_parse_info_file($user, $fname);
|
||||
$f = new StdClass;
|
||||
$f->name = $fname;
|
||||
$f->size = $size;
|
||||
$f->md5 = $md5;
|
||||
$f->date = filemtime("$dir/$fname");
|
||||
$files[] = $f;
|
||||
}
|
||||
$sort_field = get_str('sort_field', true);
|
||||
if (!$sort_field) $sort_field = 'name';
|
||||
$sort_rev = get_str('sort_rev', true);
|
||||
column_sort($files, $sort_field, $sort_rev);
|
||||
|
||||
start_table();
|
||||
table_header("Name<br><small>(click to view text files)</small>", "Modified", "Size (bytes)", "MD5", "Delete","Download");
|
||||
table_header(
|
||||
column_sort_header(
|
||||
'name',
|
||||
'Name',
|
||||
'sandbox.php?',
|
||||
$sort_field, $sort_rev
|
||||
).'<br><small>(click to view text files)</small>',
|
||||
column_sort_header(
|
||||
'date',
|
||||
'Modified',
|
||||
'sandbox.php?',
|
||||
$sort_field, $sort_rev
|
||||
),
|
||||
column_sort_header(
|
||||
'size',
|
||||
"Size (bytes)",
|
||||
'sandbox.php?',
|
||||
$sort_field, $sort_rev
|
||||
),
|
||||
"MD5",
|
||||
"Delete",
|
||||
"Download"
|
||||
);
|
||||
foreach ($files as $f) {
|
||||
[$md5, $size] = sandbox_parse_info_file($user, $f);
|
||||
$path = "$dir/$f";
|
||||
$ct = time_str(filemtime($path));
|
||||
$ct = time_str($f->date);
|
||||
table_row(
|
||||
"<a href=sandbox.php?action=view_file&name=$f>$f</a>",
|
||||
"<a href=sandbox.php?action=view_file&name=$f->name>$f->name</a>",
|
||||
$ct,
|
||||
$size,
|
||||
$md5,
|
||||
button_text(
|
||||
"sandbox.php?action=delete_file&name=$f",
|
||||
$f->size,
|
||||
$f->md5,
|
||||
button_text_small(
|
||||
"sandbox.php?action=delete_file&name=$f->name",
|
||||
"Delete"
|
||||
),
|
||||
button_text(
|
||||
"sandbox.php?action=download_file&name=$f",
|
||||
button_text_small(
|
||||
"sandbox.php?action=download_file&name=$f->name",
|
||||
"Download"
|
||||
)
|
||||
);
|
||||
|
|
|
@ -590,10 +590,10 @@ function handle_query_job($user) {
|
|||
<li><a href=submit.php?action=query_batch&batch_id=$wu->batch>Batch details</a>
|
||||
";
|
||||
|
||||
echo "<h2>Instances</h2>\n";
|
||||
echo "<h2>Job instances</h2>\n";
|
||||
start_table('table-striped');
|
||||
table_header(
|
||||
"ID<br><small>click for result page</small>",
|
||||
"ID<br><small>click for details and stderr</small>",
|
||||
"State",
|
||||
"Output files"
|
||||
);
|
||||
|
@ -651,9 +651,7 @@ function handle_query_job($user) {
|
|||
$x = "<in>".$wu->xml_doc."</in>";
|
||||
$x = simplexml_load_string($x);
|
||||
start_table('table-striped');
|
||||
table_header("Name<br><small>(click to view)</small>",
|
||||
"Size (bytes)", "MD5"
|
||||
);
|
||||
table_header("Name<br><small>(click to view)</small>", "Size (bytes)");
|
||||
foreach ($x->workunit->file_ref as $fr) {
|
||||
$pname = (string)$fr->file_name;
|
||||
$lname = (string)$fr->open_name;
|
||||
|
@ -661,8 +659,7 @@ function handle_query_job($user) {
|
|||
if ((string)$fi->name == $pname) {
|
||||
table_row(
|
||||
"<a href=$fi->url>$lname</a>",
|
||||
$fi->nbytes,
|
||||
$fi->md5_cksum
|
||||
$fi->nbytes
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue