diff --git a/etc/recmon.d/autotrigger b/etc/recmon.d/autotrigger index ad1102b..dc26976 100755 --- a/etc/recmon.d/autotrigger +++ b/etc/recmon.d/autotrigger @@ -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" } diff --git a/webif/html/diag/queue/delete.jim b/webif/html/diag/queue/delete.jim deleted file mode 100755 index 6b5d725..0000000 --- a/webif/html/diag/queue/delete.jim +++ /dev/null @@ -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 -} - diff --git a/webif/html/diag/queue/fetch.jim b/webif/html/diag/queue/fetch.jim index 2e557da..13ec138 100755 --- a/webif/html/diag/queue/fetch.jim +++ b/webif/html/diag/queue/fetch.jim @@ -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} { diff --git a/webif/html/diag/queue/index.jim b/webif/html/diag/queue/index.jim index 7d27f6e..03142f1 100755 --- a/webif/html/diag/queue/index.jim +++ b/webif/html/diag/queue/index.jim @@ -16,7 +16,16 @@ puts {
Queued Tasks - + +
+ Loading queue data... +
+ + + +
@@ -31,13 +40,16 @@ puts { - - - - - +
+ + + + + + +
} diff --git a/webif/html/diag/queue/resubmit.jim b/webif/html/diag/queue/resubmit.jim deleted file mode 100755 index bd74eea..0000000 --- a/webif/html/diag/queue/resubmit.jim +++ /dev/null @@ -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 -} - diff --git a/webif/html/diag/queue/script.js b/webif/html/diag/queue/script.js index 1c5d0dd..e6b2543 100644 --- a/webif/html/diag/queue/script.js +++ b/webif/html/diag/queue/script.js @@ -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 + '' + '' + v.submitted + '' + '' + v.file + '' + - '' + v.action + '' + + '' + v.action + ' ' + v.args + '' + '' + v.status; if (v.status == 'RUNNING') s += '  '; @@ -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: '

Deleting...

' + message: '

Processing...

' }); 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: '

Re-submitting...

' - }); - - 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'); diff --git a/webif/html/diag/queue/style.css b/webif/html/diag/queue/style.css index 48e37b1..da9cdce 100644 --- a/webif/html/diag/queue/style.css +++ b/webif/html/diag/queue/style.css @@ -26,3 +26,14 @@ td.status.INTERRUPTED font-weight: bold; } +div.buttonbar +{ + padding-top: 5px; +} + +div#loading, div#nodata +{ + font-style: italic; + color: #ff4000; +} + diff --git a/webif/html/diag/queue/update.jim b/webif/html/diag/queue/update.jim new file mode 100755 index 0000000..b2e0dbe --- /dev/null +++ b/webif/html/diag/queue/update.jim @@ -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 + } + } +} + diff --git a/webif/html/go b/webif/html/go index f9a8603..c8712a8 100755 --- a/webif/html/go +++ b/webif/html/go @@ -25,6 +25,7 @@ set pages { "pkg" "/pkg/" "diag" "/diag/diag.jim" "settings" "/settings/settings.jim" + "queue" "/diag/queue/" } set pages(epg) $epglink diff --git a/webif/html/settings/modules/auto/init.hook b/webif/html/settings/modules/auto/init.hook index 00620ab..5c6709b 100644 --- a/webif/html/settings/modules/auto/init.hook +++ b/webif/html/settings/modules/auto/init.hook @@ -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" diff --git a/webif/html/settings/modules/auto/settings.hook b/webif/html/settings/modules/auto/settings.hook index 30573a2..75d8f60 100755 --- a/webif/html/settings/modules/auto/settings.hook +++ b/webif/html/settings/modules/auto/settings.hook @@ -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 { diff --git a/webif/include/toolbar.jim b/webif/include/toolbar.jim index 62d0eaf..aa1a442 100755 --- a/webif/include/toolbar.jim +++ b/webif/include/toolbar.jim @@ -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 { diff --git a/webif/lib/auto/NOTES b/webif/lib/auto/NOTES index c714b4c..6f7e6c1 100644 --- a/webif/lib/auto/NOTES +++ b/webif/lib/auto/NOTES @@ -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 Starting at the directory indicated by , 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 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 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."] diff --git a/webif/lib/auto/deq b/webif/lib/auto/deq index 0120086..b4be7f9 100755 --- a/webif/lib/auto/deq +++ b/webif/lib/auto/deq @@ -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 } diff --git a/webif/lib/auto/scan b/webif/lib/auto/scan index 35719f5..ee442ad 100755 --- a/webif/lib/auto/scan +++ b/webif/lib/auto/scan @@ -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 diff --git a/webif/lib/auto/upgrade b/webif/lib/auto/upgrade index d310b06..e994133 100755 --- a/webif/lib/auto/upgrade +++ b/webif/lib/auto/upgrade @@ -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." + } } diff --git a/webif/lib/auto/util.jim b/webif/lib/auto/util.jim index 7e15015..13218d9 100644 --- a/webif/lib/auto/util.jim +++ b/webif/lib/auto/util.jim @@ -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"] +} + diff --git a/webif/lib/queue.class b/webif/lib/queue.class index 89e9ebe..8bc532c 100644 --- a/webif/lib/queue.class +++ b/webif/lib/queue.class @@ -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 "" diff --git a/webif/lib/settings.class b/webif/lib/settings.class index bad7d82..df26071 100644 --- a/webif/lib/settings.class +++ b/webif/lib/settings.class @@ -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] }