forked from hummypkg/sweeper
2.0.17 - recurse rules
This commit is contained in:
parent
cafa786200
commit
1bc30bff86
@ -1,7 +1,7 @@
|
||||
Package: sweeper
|
||||
Priority: optional
|
||||
Section: misc
|
||||
Version: 2.0.16
|
||||
Version: 2.0.17
|
||||
Architecture: mipsel
|
||||
Maintainer: af123@hummypkg.org.uk
|
||||
Depends: webif(>=1.2.5-10)
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
var select_file_criteria = {};
|
||||
var select_folder_criteria = {};
|
||||
var select_global_criteria = {};
|
||||
$.each(schema.criterion, function(k, v) {
|
||||
if (v.deprecated)
|
||||
return;
|
||||
@ -13,20 +12,15 @@ $.each(schema.criterion, function(k, v) {
|
||||
case 'folder':
|
||||
select_folder_criteria[k] = v.desc;
|
||||
break;
|
||||
case 'global':
|
||||
select_global_criteria[k] = v.desc;
|
||||
break;
|
||||
case 'all':
|
||||
select_file_criteria[k] = v.desc;
|
||||
select_folder_criteria[k] = v.desc;
|
||||
select_global_criteria[k] = v.desc;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
var select_file_actions = {};
|
||||
var select_folder_actions = {};
|
||||
var select_global_actions = {};
|
||||
$.each(schema.action, function(k, v) {
|
||||
if (v.deprecated)
|
||||
return;
|
||||
@ -38,13 +32,9 @@ $.each(schema.action, function(k, v) {
|
||||
case 'folder':
|
||||
select_folder_actions[k] = v.desc;
|
||||
break;
|
||||
case 'global':
|
||||
select_global_actions[k] = v.desc;
|
||||
break;
|
||||
case 'all':
|
||||
select_file_actions[k] = v.desc;
|
||||
select_folder_actions[k] = v.desc;
|
||||
select_global_actions[k] = v.desc;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ set ::sweeper::cf "/mod/etc/sweeper.conf"
|
||||
set ::sweeper::dryrun 0
|
||||
set ::sweeper::lastruleresult 0
|
||||
set ::sweeper::stack {}
|
||||
set ::sweeper::dustbin [system dustbin 1]
|
||||
|
||||
proc ::sweeper::unknown {cmd args} {
|
||||
log "Unknown sweeper rule clause '$cmd'" 0
|
||||
@ -12,6 +13,12 @@ proc ::sweeper::unknown {cmd args} {
|
||||
######################################################################
|
||||
# Utility functions
|
||||
|
||||
proc ::sweeper::skipdir {e} {
|
||||
if {[string match {\[*} [string trimleft $e]]} { return 1 }
|
||||
if {$e eq $::sweeper::dustbin} { return 1 }
|
||||
return 0
|
||||
}
|
||||
|
||||
# Perform an integer comparison.
|
||||
proc ::sweeper::intcomp {ref val} {
|
||||
lassign $val op num
|
||||
@ -326,12 +333,10 @@ proc ::sweeper::moveset {ts dst {op rename}} {
|
||||
|
||||
# Search for a folder with name 'target' under 'root', skipping 'orig'
|
||||
proc ::sweeper::find {root target orig} {
|
||||
set dustbin [system dustbin 1]
|
||||
foreach e [readdir -nocomplain $root] {
|
||||
regsub -all -- {//} "$root/$e" "/" entry
|
||||
if {![file isdirectory $entry]} continue
|
||||
if {[string match {\[*} [string trimleft $e]]} continue
|
||||
if {$e eq $dustbin} continue
|
||||
if {[::sweeper::skipdir $e]} continue
|
||||
if {$entry eq $orig} continue
|
||||
|
||||
if {$e eq $target} { return $entry }
|
||||
@ -920,79 +925,15 @@ proc ::sweeper::runrule {ts rule folder} {
|
||||
return 0
|
||||
}
|
||||
|
||||
proc ::sweeper::apply {dir cf} {
|
||||
if {[catch {set fp [open $cf r]} msg]} {
|
||||
log "Error opening sweeper ruleset ($cf), $msg" 0
|
||||
return
|
||||
}
|
||||
|
||||
set ::sweeper::recalc {}
|
||||
|
||||
set rules [split [read $fp] "\n"]
|
||||
$fp close
|
||||
|
||||
set runfolder 0
|
||||
set nrules 0
|
||||
foreach rule $rules {
|
||||
switch -- [lindex $rule 0] {
|
||||
folder -
|
||||
global { incr runfolder }
|
||||
}
|
||||
if {[string index $rule 0] ne "#" && [llength $rule] > 1} {
|
||||
incr nrules
|
||||
}
|
||||
}
|
||||
|
||||
if {!$nrules} return
|
||||
|
||||
proc ::sweeper::apply_folder_rules {dir rules} {
|
||||
log "" 2
|
||||
log "--- SWEEP SCAN STARTING FOR $dir ($nrules) ---" 2
|
||||
log " -- FOLDER RULES --" 2
|
||||
log "" 2
|
||||
|
||||
foreach e [readdir -nocomplain $dir] {
|
||||
set entry "$dir/$e"
|
||||
if {[file isdirectory $entry]} continue
|
||||
if {![string match {*.ts} $entry]} continue
|
||||
|
||||
log "+ Sweeper processing $entry" 2
|
||||
|
||||
if {[catch {set ts [ts fetch $entry]} msg]} {
|
||||
log "Error reading TS file, $msg" 0
|
||||
continue
|
||||
}
|
||||
|
||||
if {$ts == "0"} {
|
||||
log "Invalid TS file." 2
|
||||
continue
|
||||
}
|
||||
|
||||
if {[$ts inuse]} {
|
||||
log "Recording in use." 2
|
||||
continue
|
||||
}
|
||||
|
||||
set ::sweeper::stack {}
|
||||
foreach rule $rules {
|
||||
if {[string index $rule 0] eq "#" ||
|
||||
[llength $rule] < 2} continue
|
||||
switch -- [lindex $rule 0] {
|
||||
folder continue
|
||||
global { set rule [lrange $rule 1 end] }
|
||||
}
|
||||
if {[::sweeper::runrule $ts $rule 0]} break
|
||||
}
|
||||
}
|
||||
|
||||
if {$runfolder > 0} {
|
||||
log "" 2
|
||||
log " -- FOLDER RULES --" 2
|
||||
log "" 2
|
||||
set dustbin [system dustbin 1]
|
||||
foreach e [readdir -nocomplain $dir] {
|
||||
set entry "$dir/$e"
|
||||
if {![file isdirectory $entry]} continue
|
||||
if {[string match {\[*} [string trimleft $e]]} continue
|
||||
if {$e eq $dustbin} continue
|
||||
if {[::sweeper::skipdir $e]} continue
|
||||
|
||||
log "" 2
|
||||
log "==== folder $entry ====" 2
|
||||
@ -1005,10 +946,10 @@ proc ::sweeper::apply {dir cf} {
|
||||
|
||||
set ts 0
|
||||
foreach de [lsort -command [lambda {a b} {
|
||||
upvar entry e
|
||||
return $([file mtime "$e/$b"] - [file mtime "$e/$a"])
|
||||
}] [lsearch -glob -all -inline \
|
||||
[readdir -nocomplain $entry] {*.ts}]] {
|
||||
upvar entry e
|
||||
return $([file mtime "$e/$b"] - [file mtime "$e/$a"])
|
||||
}] [lsearch -glob -all -inline \
|
||||
[readdir -nocomplain $entry] {*.ts}]] {
|
||||
set dentry "$entry/$de"
|
||||
|
||||
log " --- Considering $dentry" 2
|
||||
@ -1038,17 +979,100 @@ proc ::sweeper::apply {dir cf} {
|
||||
|
||||
set ::sweeper::stack {}
|
||||
foreach rule $rules {
|
||||
if {[string index $rule 0] eq "#" ||
|
||||
[llength $rule] < 3} continue
|
||||
switch -- [lindex $rule 0] {
|
||||
folder -
|
||||
global { set rule [lrange $rule 1 end] }
|
||||
default continue
|
||||
}
|
||||
if {[llength $rule] < 1} continue
|
||||
if {[::sweeper::runrule $ts $rule 1]} break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
proc ::sweeper::apply_rules {dir rules {depth 0}} {
|
||||
|
||||
log "" 2
|
||||
log "--- SWEEP($depth) STARTING FOR $dir ---" 2
|
||||
log "" 2
|
||||
|
||||
if {$depth > 20} {
|
||||
log "ERROR: Maximum recursion depth exceeded." 0
|
||||
return
|
||||
}
|
||||
|
||||
set moredepth 0
|
||||
set dirs {}
|
||||
foreach e [readdir -nocomplain $dir] {
|
||||
set entry "$dir/$e"
|
||||
if {[file isdirectory $entry]} {
|
||||
if {![::sweeper::skipdir $e] &&
|
||||
![file exists "$entry/.nosweep"]} {
|
||||
lappend dirs $entry
|
||||
}
|
||||
continue
|
||||
}
|
||||
if {![string match {*.ts} $entry]} continue
|
||||
|
||||
log "+ Sweeper processing $entry" 2
|
||||
|
||||
if {[catch {set ts [ts fetch $entry]} msg]} {
|
||||
log "Error reading TS file, $msg" 0
|
||||
continue
|
||||
}
|
||||
|
||||
if {$ts == "0"} {
|
||||
log "Invalid TS file." 2
|
||||
continue
|
||||
}
|
||||
|
||||
if {[$ts inuse]} {
|
||||
log "Recording in use." 2
|
||||
continue
|
||||
}
|
||||
|
||||
set ::sweeper::stack {}
|
||||
foreach rule $rules {
|
||||
if {[llength $rule] < 3} continue
|
||||
set rule [lassign $rule level]
|
||||
if {$level < $depth} continue
|
||||
if {$level > $depth} { incr moredepth }
|
||||
if {[::sweeper::runrule $ts $rule 0]} break
|
||||
}
|
||||
}
|
||||
|
||||
# No rules require greater recursion
|
||||
if {!$moredepth} return
|
||||
|
||||
foreach dir $dirs {
|
||||
::sweeper::apply_rules $dir $rules $($depth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
proc ::sweeper::apply {dir cf} {
|
||||
if {[catch {set fp [open $cf r]} msg]} {
|
||||
log "Error opening sweeper ruleset ($cf), $msg" 0
|
||||
return
|
||||
}
|
||||
|
||||
set ::sweeper::recalc {}
|
||||
|
||||
set _rules [split [read $fp] "\n"]
|
||||
$fp close
|
||||
|
||||
set rules {}
|
||||
set folder_rules {}
|
||||
foreach rule $_rules {
|
||||
if {[string index $rule 0] eq "#"} continue
|
||||
switch -- [lindex $rule 0] {
|
||||
folder { lappend folder_rules [lrange $rule 1 end] }
|
||||
global { lset rule 0 1; lappend rules $rule }
|
||||
recurse { lappend rules [lrange $rule 1 end] }
|
||||
default { lappend rules [linsert $rule 0 0] }
|
||||
}
|
||||
}
|
||||
|
||||
if {[llength $rules]} {
|
||||
::sweeper::apply_rules $dir $rules
|
||||
}
|
||||
|
||||
if {[llength $folder_rules]} {
|
||||
::sweeper::apply_folder_rules $dir $folder_rules
|
||||
}
|
||||
|
||||
foreach dir $::sweeper::recalc {
|
||||
|
@ -58,10 +58,10 @@ Add pre-defined ruleset:
|
||||
<fieldset class=rule>
|
||||
<legend class=comment>
|
||||
<span class=commentleft>
|
||||
<span class="ruleicon folder global hidden">
|
||||
<span class="ruleicon folder recurse hidden">
|
||||
<img src=/images/711_1_09_Media_Folder.png>
|
||||
</span>
|
||||
<span class="ruleicon file global hidden">
|
||||
<span class="ruleicon file recurse hidden">
|
||||
<img src=/img/Video_TS_New.png>
|
||||
</span>
|
||||
<span class=comment>Unnamed rule</span>
|
||||
@ -98,9 +98,9 @@ Add pre-defined ruleset:
|
||||
<div class="foldercomment hidden">
|
||||
For each sub-folder, inspect a recording within and:
|
||||
</div>
|
||||
<div class="globalcomment hidden">
|
||||
For each recording and sub-folder, inspect a recording
|
||||
within and:
|
||||
<div class="recursecomment hidden">
|
||||
For each recording and recordings within folders
|
||||
(<span class=depth></span> deep<a class=editdepth href=#><img src=/img/context/edit.png></a>):
|
||||
</div>
|
||||
<a href=# class=addcriterion>
|
||||
<img src=img/plus.png
|
||||
@ -151,6 +151,11 @@ For pattern matching, the following special sequences may appear in the pattern:
|
||||
size=5 maxlength=6 />
|
||||
</div>
|
||||
|
||||
<div class=hidden id=edit_plainint title="Edit int">
|
||||
<input name=edit_plainint_field id=edit_plainint_field type=number
|
||||
size=5 maxlength=6 />
|
||||
</div>
|
||||
|
||||
<div class=hidden id=edit_select title="Edit select">
|
||||
<select name=edit_select_field id=edit_select_field>
|
||||
</select>
|
||||
@ -203,11 +208,17 @@ For pattern matching, the following special sequences may appear in the pattern:
|
||||
value='file' checked />Process Files
|
||||
<input name=newrule_type id=newrule_type_folder type=radio
|
||||
value='folder' />Process Folders
|
||||
<input name=newrule_type id=newrule_type_global type=radio
|
||||
value='global' />Process Files & Folders
|
||||
<input name=newrule_type id=newrule_type_recurse type=radio
|
||||
value='recurse' />Process Files and Files within Folders
|
||||
<br>
|
||||
Description:
|
||||
<input name=newrule_comment id=newrule_comment size=80 maxlength=255 />
|
||||
<div id=newrule_depth_box class=hidden>
|
||||
Recursion Depth:
|
||||
<input name=newrule_depth id=newrule_depth type=number size=5
|
||||
maxlength=5 />
|
||||
<span class=footnote>(How many levels deep into the folder structure to look)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=hidden id=newcondition title="Add New Condition">
|
||||
|
@ -15,8 +15,10 @@ set root [system mediaroot]
|
||||
if {$dir eq "" || $dir eq $root} {
|
||||
set dir $root
|
||||
set cf "/mod/etc/sweeper.conf"
|
||||
} else {
|
||||
} elseif {[file isdirectory $dir]} {
|
||||
set cf "$dir/.sweeper"
|
||||
} else {
|
||||
set cf $dir
|
||||
}
|
||||
|
||||
httpheader "application/json"
|
||||
@ -99,14 +101,22 @@ proc rule {id rule} {
|
||||
switch -- [lindex $rule 0] {
|
||||
folder {
|
||||
set type "folder"
|
||||
set depth 0
|
||||
set rule [lrange $rule 1 end]
|
||||
}
|
||||
global {
|
||||
set type "global"
|
||||
set type "recurse"
|
||||
set depth 1
|
||||
set rule [lrange $rule 1 end]
|
||||
}
|
||||
recurse {
|
||||
set type "recurse"
|
||||
set depth [lindex $rule 1]
|
||||
set rule [lrange $rule 2 end]
|
||||
}
|
||||
default {
|
||||
set type "file"
|
||||
set depth 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,6 +125,7 @@ proc rule {id rule} {
|
||||
add_json " \"raw\": \"[quot $rule]\",\n"
|
||||
add_json " \"name\": \"[quot $lcomment]\",\n"
|
||||
add_json " \"type\": \"$type\",\n"
|
||||
add_json " \"depth\": \"$depth\",\n"
|
||||
add_json " \"enabled\": \"$enabled\",\n"
|
||||
add_json " \"criteria\": \[\n"
|
||||
|
||||
|
@ -146,10 +146,11 @@ function ruleconf(rule)
|
||||
|
||||
if (rule.hasClass('ruledisabled'))
|
||||
s += '## ';
|
||||
|
||||
if (rule.attr('type') == 'folder')
|
||||
s += 'folder ';
|
||||
else if (rule.attr('type') == 'global')
|
||||
s += 'global ';
|
||||
else if (rule.attr('depth') > 0)
|
||||
s += 'recurse ' + rule.attr('depth') + ' ';
|
||||
|
||||
s += clauseconf(rule);
|
||||
|
||||
@ -203,6 +204,10 @@ function rulerefresh(rule)
|
||||
rule.find('tr.action th.title').text('Then:');
|
||||
rule.find('tr.otherwise,div.criteria,div.arrow').show();
|
||||
}
|
||||
|
||||
if (rule.attr('type') == 'recurse')
|
||||
rule.find('.recursecomment .depth').text(rule.attr('depth') +
|
||||
' level' + (rule.attr('depth') == 1 ? '' : 's'));
|
||||
}
|
||||
|
||||
function critdesc(cmd, negate)
|
||||
@ -335,12 +340,22 @@ function addrule(id, data)
|
||||
.addClass('rule')
|
||||
.removeClass('hidden');
|
||||
|
||||
if (!data.depth)
|
||||
data.depth = 0;
|
||||
if (data.type == 'global')
|
||||
{
|
||||
data.type = 'recurse';
|
||||
data.depth = 1;
|
||||
}
|
||||
|
||||
rule.find('span.comment').html(data.name);
|
||||
switch (data.type)
|
||||
{
|
||||
case 'global':
|
||||
rule.find('.commentleft > span.global').show();
|
||||
rule.find('.globalcomment').show();
|
||||
case 'recurse':
|
||||
rule.find('.commentleft > span.recurse').show();
|
||||
rule.find('.recursecomment').show()
|
||||
.find('.depth').text(data.depth + ' level' +
|
||||
(data.depth == 1 ? '' : 's'));
|
||||
break;
|
||||
case 'folder':
|
||||
rule.find('.commentleft > span.folder').show();
|
||||
@ -351,6 +366,7 @@ function addrule(id, data)
|
||||
break;
|
||||
}
|
||||
rule.attr('type', data.type);
|
||||
rule.attr('depth', data.depth);
|
||||
|
||||
var $c = rule.find('table.criteria');
|
||||
$.each(data.criteria, function(key, val) {
|
||||
@ -451,6 +467,39 @@ function edit_int(obj, title, op, val, callback)
|
||||
});
|
||||
}
|
||||
|
||||
function edit_plainint(obj, title, val, callback)
|
||||
{
|
||||
$('#edit_plainint_field').val(val);
|
||||
$('#edit_plainint').dialog({
|
||||
title: title,
|
||||
height: 'auto', width: 'auto',
|
||||
draggable: true, resizable: false,
|
||||
autoOpen: true,
|
||||
position: {
|
||||
my: 'bottom left',
|
||||
at: 'top right',
|
||||
of: obj,
|
||||
collision: 'fit'
|
||||
},
|
||||
buttons: {
|
||||
"Save": function() {
|
||||
var val = $.trim($('#edit_plainint_field')
|
||||
.val());
|
||||
if (!val)
|
||||
alert("Bad value");
|
||||
else
|
||||
{
|
||||
callback(obj, val);
|
||||
$(this).dialog('close');
|
||||
}
|
||||
},
|
||||
"Close": function() {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function edit_select(obj, title, options, val, callback)
|
||||
{
|
||||
$('#edit_select_field').empty();
|
||||
@ -718,6 +767,7 @@ $('#b_add').button({icons: {primary: "ui-icon-plus"}})
|
||||
name: $('#newrule_comment').val(),
|
||||
type: $('input[name=newrule_type]' +
|
||||
':checked').val(),
|
||||
depth: $('#newrule_depth').val(),
|
||||
criteria: [],
|
||||
action: {
|
||||
cmd: 'continue',
|
||||
@ -733,9 +783,18 @@ $('#b_add').button({icons: {primary: "ui-icon-plus"}})
|
||||
}
|
||||
});
|
||||
$('#newrule_type_file').prop('checked', true);
|
||||
$('#newrule_depth').val(1);
|
||||
$('#newrule_depth_box').hide();
|
||||
$('#newrule_comment').focus().val('').val('Unnamed rule').select();
|
||||
});
|
||||
|
||||
$('input[name=newrule_type]').on('change', function() {
|
||||
if ($('input[name=newrule_type]:checked').val() == 'recurse')
|
||||
$('#newrule_depth_box').show();
|
||||
else
|
||||
$('#newrule_depth_box').hide();
|
||||
});
|
||||
|
||||
$('#b_edit').button({icons: {primary: "ui-icon-script"}});
|
||||
$('#buttons')
|
||||
.on('click', '#b_edit', function(e) {
|
||||
@ -894,9 +953,6 @@ function addcriterion(rule, target)
|
||||
case 'folder':
|
||||
options = select_folder_criteria;
|
||||
break;
|
||||
case 'global':
|
||||
options = select_global_criteria;
|
||||
break;
|
||||
default:
|
||||
options = select_file_criteria;
|
||||
break;
|
||||
@ -965,6 +1021,22 @@ $('#ruleset')
|
||||
changed(1);
|
||||
});
|
||||
})
|
||||
.on('click', 'a.editdepth', function(e) {
|
||||
e.preventDefault();
|
||||
var rule = $(this).closest('div.rule');
|
||||
edit_plainint($(this), 'Edit recursion depth',
|
||||
rule.attr('depth'),
|
||||
function(obj, val) {
|
||||
if (val > 0 && val < 16)
|
||||
{
|
||||
rule.attr('depth', val);
|
||||
if (val > 1)
|
||||
rule.attr('type', 'recurse');
|
||||
rulerefresh(rule);
|
||||
changed(1);
|
||||
}
|
||||
});
|
||||
})
|
||||
.on('click', 'a.uprule', function(e) {
|
||||
e.preventDefault();
|
||||
if ($(this).hasClass('ui-state-disabled'))
|
||||
@ -1039,9 +1111,6 @@ $('#ruleset')
|
||||
case 'folder':
|
||||
options = select_folder_actions;
|
||||
break;
|
||||
case 'global':
|
||||
options = select_global_actions;
|
||||
break;
|
||||
default:
|
||||
options = select_file_actions;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user