1.3.5 second draft

git-svn-id: file:///root/webif/svn/pkg/webif/trunk@3479 2a923420-c742-0410-a762-8d5b09965624
This commit is contained in:
hummypkg 2017-01-06 20:28:13 +00:00
parent 0dd9641e76
commit e910472fa6
19 changed files with 200 additions and 106 deletions

View File

@ -24,7 +24,8 @@ if {![acquire_lock webif_autoscan 600 5]} {
}
if {$loglevel > 0} { system plog auto "$prefix: got lock" }
exec /mod/webif/lib/auto/scan -prelocked -logprefix "$prefix: " -singledir $dir
exec /mod/webif/lib/auto/scan -f -prelocked -logprefix "$prefix: " \
-singledir $dir
if {$loglevel > 0} { system plog auto "$prefix: done" }

View File

@ -1,14 +0,0 @@
#!/mod/bin/jimsh
package require cgi
source /mod/webif/lib/setup
require queue.class
httpheader
set slots [cgi_get slot 0]
foreach slot [split $slots ","] {
queue delete_by_id $slot
}

View File

@ -14,14 +14,16 @@ foreach q [queue all] {
"/media/" ""
".ts" ""
} [$q get file]]
set submitted [clock format [$q get submitted] -format {%c}]
set submitted [clock format [$q get submitted] \
-format {%d/%m/%Y %H:%M:%S}]
if {$flag} { puts "," } else { incr flag }
puts "{"
puts " \"qid\": [$q get id],"
puts " \"submitted\": \"$submitted\","
puts " \"file\": \"[::json::escape $name]\","
puts " \"action\": \"[$q get action]\","
puts " \"action\": \"[::json::escape [$q get action]]\","
puts " \"args\": \"[::json::escape [$q get args]]\","
puts " \"status\": \"[$q get status]\","
puts " \"log\": \"[::json::escape [$q get log]]\","
if {[$q get runtime] > 0} {

View File

@ -16,7 +16,16 @@ puts {
</h3>
<fieldset class=cleft>
<legend>Queued Tasks</legend>
<table id=queuetab class=borders cellpadding=5>
<div id=loading>
<img src=/img/loading.gif> Loading queue data...
</div>
<div id=nodata class="hidden">
There are no tasks in the queue.
</div>
<table id=queuetab class="borders hidden" cellpadding=5>
<thead>
<tr>
<th nowrap>ID</th>
@ -31,13 +40,16 @@ puts {
<tbody>
</tbody>
</table>
<button id=qdelete class=needssel>Delete Selected</button>
<button id=qresubmit class=needssel>Retry Selected</button>
<button id=selcomplete>Select Completed</button>
<button id=selall>Select All</button>
<button id=selnone>Select None</button>
<div class=buttonbar>
<button id=qdelete act=delete class="submit needssel">Delete</button>
<button id=qresubmit act=resubmit class="submit needssel">Re-submit</button>
<button id=qhold act=hold class="submit needssel">Hold</button>
<button id=selcomplete class=needsdata>Select Completed</button>
<button id=selall class=needsdata>Select All</button>
<button id=selnone class=needsdata>Select None</button>
<button id=refresh>Refresh</button>
<span id=isloading><img src=/img/loading.gif></span>
</div>
</fieldset>
}

View File

@ -1,14 +0,0 @@
#!/mod/bin/jimsh
package require cgi
source /mod/webif/lib/setup
require queue.class
httpheader
set slots [cgi_get slot 0]
foreach slot [split $slots ","] {
queue resubmit $slot
}

View File

@ -10,7 +10,7 @@ function page_refresh(msg)
function load()
{
$('#isloading').show('fast');
$('#isloading').show();
$.getJSON('fetch.jim', function(data) {
$('#queuetab > tbody').empty();
@ -22,7 +22,7 @@ function load()
v.qid + '</td>' +
'<td>' + v.submitted + '</td>' +
'<td>' + v.file + '</td>' +
'<td>' + v.action + '</td>' +
'<td>' + v.action + ' ' + v.args + '</td>' +
'<td class="status ' + v.status + '">' + v.status;
if (v.status == 'RUNNING')
s += ' &nbsp;<img class=va src=/img/loading.gif>';
@ -35,6 +35,20 @@ function load()
$('#queuetab > tbody').append(s);
});
if (data.length > 0)
{
$('#nodata').hide();
$('#queuetab').show();
$('.needsdata').enable();
}
else
{
$('#nodata').show();
$('#queuetab').hide();
$('.needssel,.needsdata').disable();
}
var resort = true;
$('#queuetab').trigger('update', [resort]);
$('input.qid:checkbox').prop('checked', false).enable();
@ -47,7 +61,7 @@ function load()
});
$('input.qid').first().trigger('change');
$('#isloading').hide('slow');
$('#loading,#isloading').hide('slow');
});
}
@ -71,63 +85,48 @@ $('#queuetab').on('change', 'input.qid', function() {
$('.needssel').disable();
}).first().trigger('change');
$('#qdelete').button({icons:{primary:"ui-icon-trash"}})
.on('click', function() {
$('#qdelete').button({icons:{primary:"ui-icon-trash"}});
$('#qresubmit').button({icons:{primary:"ui-icon-refresh"}});
$('#qhold').button({icons:{primary:"ui-icon-pause"}});
$('button.submit').on('click', function() {
var name = $(this).text();
var act = $(this).attr('act');
$(this).dojConfirmAction({
question: 'Delete selected?',
question: name + ' selected?',
yesAnswer: 'Yes',
cancelAnswer: 'No'
}, function(el) {
$.blockUI({
message: '<h1><img src=/img/loading.gif> Deleting... </h1>'
message: '<h1><img src=/img/loading.gif> Processing... </h1>'
});
var slots = $('input.qid:checked').map(function() {
return this.value;
}).get();
$.get('delete.jim', {
$.get('update.jim', {
act: act,
slot: slots.join(',')
}, function() {
page_refresh();
$.unblockUI();
load();
});
});
});
$('#qresubmit').button({icons:{primary:"ui-icon-refresh"}})
.on('click', function() {
$(this).dojConfirmAction({
question: 'Re-submit selected?',
yesAnswer: 'Yes',
cancelAnswer: 'No'
}, function(el) {
$.blockUI({
message: '<h1><img src=/img/loading.gif> Re-submitting... </h1>'
});
var slots = $('input.qid:checked').map(function() {
return this.value;
}).get();
$.get('resubmit.jim', {
slot: slots.join(',')
}, function() {
page_refresh();
});
});
});
$('#selnone').button({icons:{primary:"ui-icon-close"}})
.on('click', function() {
$('#queuetab input:checkbox').prop('checked', false).trigger('change');
});
$('#selall').button({icons:{primary:"ui-icon-check"}})
$('#selall').button({icons:{primary:"ui-icon-star"}})
.on('click', function() {
$('#queuetab input:checkbox').prop('checked', true).trigger('change');
});
$('#selcomplete').button({icons:{primary:"ui-icon-stop"}})
$('#selcomplete').button({icons:{primary:"ui-icon-check"}})
.on('click', function() {
$('#queuetab input:checkbox[status="COMPLETE"]').prop('checked', true)
.trigger('change');

View File

@ -26,3 +26,14 @@ td.status.INTERRUPTED
font-weight: bold;
}
div.buttonbar
{
padding-top: 5px;
}
div#loading, div#nodata
{
font-style: italic;
color: #ff4000;
}

View File

@ -0,0 +1,25 @@
#!/mod/bin/jimsh
package require cgi
source /mod/webif/lib/setup
require queue.class
httpheader
set slots [cgi_get slot 0]
set act [cgi_get act -]
foreach slot [split $slots ","] {
switch -- $act {
delete {
queue delete_by_id $slot
}
resubmit {
queue resubmit $slot
}
hold {
queue hold $slot
}
}
}

View File

@ -25,6 +25,7 @@ set pages {
"pkg" "/pkg/"
"diag" "/diag/diag.jim"
"settings" "/settings/settings.jim"
"queue" "/diag/queue/"
}
set pages(epg) $epglink

View File

@ -8,7 +8,8 @@ set autokeep [$settings autokeep]
if {$autokeep == 0} { set autokeep 7 }
set noautohours [$settings noautohours]
set autofreq [$settings autofreq]
if {$autofreq == 0} { set autofreq 20 }
if {$autofreq == 0} { set autofreq 10 }
set toolbarqueue [$settings toolbarqueue]
handle_int_update autolog $autolog "Auto-processing log level"
handle_int_update noautorec $noautorec "Auto-processing during recording"
@ -18,4 +19,5 @@ handle_int_update autorecperiod $autorecperiod \
handle_int_update autokeep $autokeep "Auto-processing queue period" 1 1 365
handle_int_update autofreq $autofreq "Auto-processing frequency" 1 5 60
handle_str_update noautohours $noautohours "Auto processing hours" ascii
handle_int_update toolbarqueue $toolbarqueue "Toolbar queue icon"

View File

@ -81,6 +81,8 @@ setting_number autokeep \
"How many days should completed entries stay in the queue?" $autokeep \
1 365
setting_toggle "Show queue icon in toolbar?" "toolbarqueue" $toolbarqueue
puts {
</table></fieldset></div>

View File

@ -39,6 +39,9 @@ tb "/img/spanner.png" "Services" "/go/mm_service"
tb "/img/packages.png" "Packages" "/go/mm_pkg"
tb "/images/326_1_00_Menu_Settings.png" "Settings" "/go/mm_settings"
tb "/img/diagnostics.png" "Diag" "/go/mm_diag"
if {[[settings] toolbarqueue]} {
tb "/img/queuep.png" "Queue" "/go/mm_queue"
}
eval_plugins toolbar
puts {

View File

@ -12,7 +12,7 @@ Module Scan De-queue
expire 900 -
dedup 800 -
*sweeper 700 -
*flatten 650 -
*flatten 750 -
*flatview 650 -
decrypt 600 900
shrink 400 800
@ -99,6 +99,9 @@ The following functions are available for modules to use:
The callback will be called once for each flagged directory with
the directory name passed as the sole argument.
If the callback returns the string "STOP" then the directory
scan stops.
::auto::flagscan <root> <fiag> <callback>
Starting at the directory indicated by <root>, all directories are
@ -108,11 +111,17 @@ The following functions are available for modules to use:
The callback will be called once for each flagged directory with
the directory name passed as the sole argument.
If the callback returns the string "STOP" then the directory
scan stops.
::auto::direntries <directory> <callback>
Scan the named directory and call the callback for each loadable
ts file found. The ts object is passed to the callback function.
If the callback returns the string "STOP" then the directory
scan stops.
::auto::recalcdir <directory>
Indicate that the unwatched recording count for the given directory
@ -142,6 +151,7 @@ The framework will call the following callbacks (if defined within the module):
Examples:
return "OK"
return {"OK" "Processing was successful."}
return [list "OK" "Processing was successful."]
return [list "DEFER" "File not yet decrypted."]
return [list "FAILED" "File is already decrypted."]

View File

@ -64,7 +64,7 @@ if {[system uptime] < 180} {
# Initialisation
set scanstart [clock milliseconds]
::auto::log "Auto de-queue starting"
::auto::log "Auto de-queue starting" 2
::auto::tmpdir "webif_autoq"
@ -91,7 +91,7 @@ proc ::auto::register {plugin {priority 500}} {
set fn "::${plugin}::dequeue"
set plugins($plugin) $priority
log "Registered $plugin with priority $priority"
log "Registered $plugin with priority $priority" 2
}
######################################################################
@ -111,6 +111,7 @@ queue startup [$::auto::settings autokeep]
proc ::auto::dumpq {qq} {
foreach q $qq {
set pri 0
if {[$q get action] in $::auto::plugins} {
set pri $::auto::plugins([$q get action])
}
@ -168,7 +169,7 @@ for {set qq [::auto::pending]} {[llength $qq]} {set qq [::auto::pending]} {
::auto::dsc
::auto::oktorun
$q update RUNNING "Started at [clock format [clock seconds]]"
$q update RUNNING "Started at [::auto::date]"
set ologprefix $::auto::logprefix
set ::auto::logprefix "$plugin:$::auto::logprefix"
@ -185,7 +186,7 @@ for {set qq [::auto::pending]} {[llength $qq]} {set qq [::auto::pending]} {
$q update "FAILED" "Plugin failure" 1
}
"OK" {
$q update "COMPLETE" $msg 1 $elapsed
$q update "COMPLETE" "[::auto::date] $msg" 1 $elapsed
::auto::runplugins dequeued $plugin $q $ts
}
"DEFER" { $q update "DEFER" $msg 1 $elapsed }

View File

@ -69,7 +69,7 @@ if {[system uptime] < 180} {
::auto::oktorun
if {!$::auto::force} {
set autofreq [$::auto::settings autofreq]
if {$autofreq == 0} { set autofreq 20 }
if {$autofreq == 0} { set autofreq 10 }
set timesincelast $(([clock seconds] - [$::auto::settings autolast]) / 60)
if {$timesincelast < $autofreq} {
@ -91,7 +91,7 @@ if {$::auto::earlyexit} {
# Initialisation
set scanstart [clock milliseconds]
::auto::log "Auto processing starting"
::auto::log "Auto processing starting" 2
::auto::tmpdir "webif_auto"
@ -120,7 +120,7 @@ proc ::auto::direntries {dir callback} {
if {![string match {*.ts} $entry]} continue
if {[catch {set ts [ts fetch "$dir/$entry"]}]} continue
if {$ts == 0} continue
$callback $ts
if {[$callback $ts] eq "STOP"} break
}
}
@ -177,14 +177,22 @@ proc ::auto::autoflagscan {dir attr callback {recurse 1} {force 0} {seen {}}} \
dsc
if {$force || [file exists "$dir/.auto$attr"]} {
$callback $dir
if {[$callback $dir] eq "STOP"} {
log "[string repeat " " $indent\
]Callback returned STOP." 2
incr indent -2
return "STOP"
}
}
foreach entry [readdir -nocomplain $dir] {
if {$recurse && [file isdirectory "$dir/$entry"]} {
autoflagscan "$dir/$entry" \
if {[autoflagscan "$dir/$entry" \
$attr $callback $recurse $force \
$seen
$seen] eq "STOP"} {
incr indent -2
return "STOP"
}
file stat "$dir/$entry" st
set key "$st(dev):$st(ino)"
lappend seen $key
@ -209,11 +217,19 @@ proc ::auto::flagscan {dir flag callback {seen {}}} {
}
lappend seen $key
if {[file exists "$dir/.$flag"]} { $callback $dir }
if {[file exists "$dir/.$flag"]} {
if {[$callback $dir] eq "STOP"} {
log "Callback returned STOP." 2
return "STOP"
}
}
foreach entry [readdir -nocomplain $dir] {
if {[file isdirectory "$dir/$entry"]} {
flagscan "$dir/$entry" $flag $callback $seen
if {[flagscan "$dir/$entry" $flag $callback $seen]
eq "STOP"} {
return "STOP"
}
file stat "$dir/$entry" st
set key "$st(dev):$st(ino)"
@ -232,7 +248,7 @@ proc ::auto::register {plugin {priority 500} {fn ""}} {
if {$fn eq ""} { set fn "::${plugin}::run" }
lappend plugins [list $plugin $fn $priority]
log "Registered $plugin with priority $priority ($fn)"
log "Registered $plugin with priority $priority ($fn)" 2
}
# Backwards compatibility with legacy plugins

View File

@ -3,9 +3,18 @@
source /mod/webif/lib/setup
require queue.class
if {[queue version] == 1} {
queue dbhandle -close
file delete /mod/etc/queue.db
queue dbhandle
switch -- [queue version] {
1 {
puts "Clearing queue due to version change..."
queue dbhandle -close
file delete /mod/etc/queue.db
queue dbhandle
}
2 {
puts "Queue version is up-to-date."
}
default {
puts "Unknown queue version."
}
}

View File

@ -157,3 +157,8 @@ proc ::auto::autoflagscanup {dir flag} {
return 0
}
proc ::auto::date {{s 0}} {
if {!$s} { set s [clock seconds] }
return [clock format $s -format "%d/%m/%Y %H:%M:%S"]
}

View File

@ -6,21 +6,23 @@ class queue {
id -1
file ""
action ""
args ""
start 0
status ""
log ""
runtime 0
retries 0
interrupts 0
submitted 0
}
#
# Queue status values:
# PENDING
# FAILED
# INTERRUPTED
# COMPLETE
# DEFER
# HOLD
proc {queue dbhandle} {args} {
if {"-close" in $args} {
@ -43,11 +45,13 @@ proc {queue dbhandle} {args} {
id integer primary key autoincrement,
file text,
action text,
args text,
start integer default 0,
status text default 'PENDING',
log text default '',
runtime integer,
retries integer default 0,
interrupts integer default 0,
submitted integer
);
}
@ -77,16 +81,16 @@ proc {queue startup} {{days 7}} {
update queue
set status = 'INTERRUPTED',
log = 'Job will be retried automatically.',
retries = retries + 1
where status in ('RUNNING', 'INTERRUPTED')
and retries < 5
retries = retries + 1,
interrupts = interrupts + 1
where status = 'RUNNING'
}
$db query {
update queue
set status = 'FAILED',
log = 'Too many retries.'
where status in ('RUNNING', 'INTERRUPTED')
and retries >= 5
log = 'Too many interrupts.'
where status = 'INTERRUPTED'
and interrupts >= 5
}
$db query {
update queue
@ -100,13 +104,14 @@ proc {queue startup} {{days 7}} {
} [expr [clock seconds] - 86400 * $days]
}
proc {queue fetch} {id} {
proc {queue fetch} {file action} {
set db [queue dbhandle]
foreach row [$db query {
select * from queue
where id = %s
} $id] {
where file = '%s'
and action = '%s'
} [file normalize $file] $action] {
return [queue new $row]
}
return {}
@ -120,7 +125,7 @@ proc {queue insert} {ts action} {
values(%s, '%s', '%s')
} [clock seconds] [file normalize [$ts get file]] $action
return [queue fetch [$db lastid]]
return [queue fetch [$ts get file] $action]
}
proc {queue delete} {ts {action "*"}} {
@ -129,7 +134,7 @@ proc {queue delete} {ts {action "*"}} {
set q "
delete from queue
where file = '%s'
and status in ('PENDING', 'INTERRUPTED', 'COMPLETE', 'FAILED')
and status != 'RUNNING'
"
if {$action ne "*"} {
append q " and action = '%s'"
@ -144,7 +149,7 @@ proc {queue delete_by_id} {id} {
set q "
delete from queue
where id = '%s'
and status in ('PENDING', 'INTERRUPTED', 'COMPLETE', 'FAILED')
and status != 'RUNNING'
"
$db query $q $id
@ -155,9 +160,22 @@ proc {queue resubmit} {id} {
set q "
update queue
set status = 'PENDING', retries = 0
set status = 'PENDING', interrupts = 0
where id = '%s'
and status in ('FAILED')
and status in ('FAILED', 'HOLD')
"
$db query $q $id
}
proc {queue hold} {id} {
set db [queue dbhandle]
set q "
update queue
set status = 'HOLD'
where id = '%s'
and status != 'RUNNING'
"
$db query $q $id
@ -172,7 +190,7 @@ proc {queue status} {ts} {
select group_concat(action)
from queue
where file = '%s'
and status not in ('COMPLETE', 'FAILED')
and status not in ('COMPLETE', 'FAILED', 'HOLD')
} [file normalize [$ts get file]]]
set q ""

View File

@ -43,6 +43,7 @@ class settings {
noautohours ""
autofreq 20
autolast 0
toolbarqueue 0
changechangenc 0
audiomp3 0
logsize 1048576
@ -185,6 +186,10 @@ settings method notoolbar {{val -1}} {
return [$self _nval_setting notoolbar $val]
}
settings method toolbarqueue {{val -1}} {
return [$self _nval_setting toolbarqueue $val]
}
settings method tvdb {{val -1}} {
return [$self _nval_setting tvdb $val]
}