diff --git a/CONTROL/control b/CONTROL/control
index 7e180ba..e5e8bf4 100644
--- a/CONTROL/control
+++ b/CONTROL/control
@@ -1,9 +1,9 @@
Package: sweeper
Priority: optional
Section: misc
-Version: 1.0.13
+Version: 1.0.14
Architecture: mipsel
Maintainer: af123@hummypkg.org.uk
-Depends: webif(>=1.0.14-2)
+Depends: webif(>=1.0.14-3)
Description: Automatically manage single recording files. [Web Interface. Multi-folder support.]
Tags: http://hummy.tv/forum/threads/3843/
diff --git a/webif/plugin/sweeper/auto.hook b/webif/plugin/sweeper/auto.hook
index e9c8fbc..63d38f9 100644
--- a/webif/plugin/sweeper/auto.hook
+++ b/webif/plugin/sweeper/auto.hook
@@ -57,7 +57,7 @@ proc ::sweeper::strcontains {ref val} {
}
######################################################################
-# Rule clauses
+# Rule criteria
proc ::sweeper::flag {ts flag} {
return [$ts flag $flag]
@@ -124,15 +124,23 @@ proc ::sweeper::genre {ts genre} {
proc ::sweeper::lock {ts g} {
if {$g} {
- log "Locked recording." 0
- $ts lock
+ if {![$ts flag Locked]} {
+ log "Locked recording." 0
+ $ts lock
+ }
} else {
- log "Unlocked recording." 0
- $ts unlock
+ if {[$ts flag Locked]} {
+ log "Unlocked recording." 0
+ $ts unlock
+ }
}
return 1
}
+proc ::sweeper::folder_fflag {ts flag} {
+ return [file exists "[file dirname [$ts get file]]/.$flag"]
+}
+
######################################################################
proc ::sweeper::action {ts cmds} {
@@ -172,6 +180,20 @@ proc ::sweeper::action {ts cmds} {
}
return 1
}
+ lock {
+ if {![$ts flag Locked]} {
+ log "Locked [$ts get file]" 0
+ $ts lock
+ }
+ return 0
+ }
+ unlock {
+ if {[$ts flag Locked]} {
+ log "Unlocked [$ts get file]" 0
+ $ts unlock
+ }
+ return 0
+ }
default {
log "Unknown action '$cmd'" 0
}
@@ -195,6 +217,32 @@ proc ::sweeper::find {root target orig} {
return ""
}
+proc ::sweeper::folder_apply {dir callback} {
+ log "Applying action to recordings in $dir" 2
+ foreach e [readdir -nocomplain $dir] {
+ if {![string match {*.ts} $e]} continue
+ set entry "$dir/$e"
+
+ log "+ folder_apply 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
+ }
+ $callback $ts
+ }
+}
+
proc ::sweeper:folder_merge {src dst} {
if {$src eq $dst} return
log "Moving recordings from $src to $dst" 0
@@ -287,6 +335,24 @@ proc ::sweeper::folder_action {ts cmds} {
::sweeper:folder_merge $folder $target
return 1
}
+ lock {
+ ::sweeper::folder_apply $folder [lambda {ts} {
+ if {![$ts flag Locked]} {
+ log "Locked [$ts get file]" 0
+ $ts lock
+ }
+ }]
+ return 0
+ }
+ unlock {
+ ::sweeper::folder_apply $folder [lambda {ts} {
+ if {[$ts flag Locked]} {
+ log "Unlocked [$ts get file]" 0
+ $ts unlock
+ }
+ }]
+ return 0
+ }
default {
log "Unknown action '$cmd'" 0
}
@@ -384,7 +450,9 @@ proc ::sweeper::apply {dir cf} {
if {[string match {\[*} $e]} continue
if {$e eq $dustbin} continue
- log "+ Sweeper processing folder $entry" 2
+ log "" 2
+ log "==== folder $entry ====" 2
+ log "" 2
if {![file exists "$entry/.series"]} {
log "Not series folder." 2
diff --git a/webif/plugin/sweeper/config.jim b/webif/plugin/sweeper/config.jim
index 469515d..784407f 100755
--- a/webif/plugin/sweeper/config.jim
+++ b/webif/plugin/sweeper/config.jim
@@ -6,9 +6,14 @@ require system.class
httpheader "text/javascript"
-puts {
-
-var showraw = true;
-
+set raw 0
+if {[file exists /mod/webif/plugin/sweeper/.raw]} {
+ set raw 1
}
+puts "
+
+var showraw = $raw;
+
+"
+
diff --git a/webif/plugin/sweeper/edit.jim b/webif/plugin/sweeper/edit.jim
index e9081e5..061fed0 100755
--- a/webif/plugin/sweeper/edit.jim
+++ b/webif/plugin/sweeper/edit.jim
@@ -39,6 +39,14 @@ puts {
+
+Add pre-defined ruleset:
+
+ --- Select ruleset ---
+
+ Add to rules
+
+
+
+
+
+
+
@@ -119,6 +146,13 @@ puts {
+
+
+There are no rules currently defined for this folder.
+
+You can add some example rules by using the Add pre-defined ruleset
+option at the bottom of the screen.
+
}
footer
diff --git a/webif/plugin/sweeper/img/arrow.png b/webif/plugin/sweeper/img/arrow.png
new file mode 100644
index 0000000..1e027b1
Binary files /dev/null and b/webif/plugin/sweeper/img/arrow.png differ
diff --git a/webif/plugin/sweeper/img/disable.png b/webif/plugin/sweeper/img/disable.png
new file mode 100644
index 0000000..26fbe85
Binary files /dev/null and b/webif/plugin/sweeper/img/disable.png differ
diff --git a/webif/plugin/sweeper/img/redstripes.gif b/webif/plugin/sweeper/img/redstripes.gif
new file mode 100644
index 0000000..cac008c
Binary files /dev/null and b/webif/plugin/sweeper/img/redstripes.gif differ
diff --git a/webif/plugin/sweeper/rules_json.jim b/webif/plugin/sweeper/rules_json.jim
index c827c7c..ff2d486 100755
--- a/webif/plugin/sweeper/rules_json.jim
+++ b/webif/plugin/sweeper/rules_json.jim
@@ -48,6 +48,12 @@ proc quot {str} {
proc rule {id rule} {
global clausedescr lcomment
+ set enabled 1
+ if {[lindex $rule 0] eq "##"} {
+ set enabled 0
+ set rule [lrange $rule 1 end]
+ }
+
if {$lcomment eq ""} { set lcomment "Unnamed rule" }
if {[lindex $rule 0] eq "folder"} {
set type "folder"
@@ -61,14 +67,17 @@ proc rule {id rule} {
add_json " \"raw\": \"[quot $rule]\",\n"
add_json " \"name\": \"[quot $lcomment]\",\n"
add_json " \"type\": \"$type\",\n"
+ add_json " \"enabled\": \"$enabled\",\n"
add_json " \"criteria\": \[\n"
set lcomment ""
set c 0
+ set lockfound -1
while {[llength $rule] > 1} {
set rule [lassign $rule cmd arg]
if {$cmd eq "action"} break
+ if {$cmd eq "lock"} { set lockfound $arg }
if {$c} { add_json ",\n" }
incr c
@@ -78,7 +87,17 @@ proc rule {id rule} {
add_json " }"
}
add_json "\n"
- if {$cmd ne "action"} { set arg "continue" }
+ if {$cmd ne "action"} {
+ if {$lockfound != -1} {
+ if {$lockfound == "1"} {
+ set arg "lock"
+ } else {
+ set arg "unlock"
+ }
+ } else {
+ set arg "continue"
+ }
+ }
lassign $arg cmd arg
if {$cmd eq "preserve"} { set cmd 'stop' }
add_json " ],\n"
@@ -95,8 +114,8 @@ foreach rule $rules {
if {[string index $rule 0] eq "#"} {
if {[string index $rule 1] ne "#"} {
comment $n [string range $rule 1 end]
+ continue
}
- continue
}
if {[llength $rule] < 2} continue
incr n
diff --git a/webif/plugin/sweeper/save.jim b/webif/plugin/sweeper/save.jim
index 86a8249..dd23042 100755
--- a/webif/plugin/sweeper/save.jim
+++ b/webif/plugin/sweeper/save.jim
@@ -6,6 +6,21 @@ require system.class
httpheader
+set act [cgi_get act "save"]
+
+switch $act {
+ raw {
+ set val [cgi_get val 0]
+ if {$val} {
+ file touch /mod/webif/plugin/sweeper/.raw
+ } else {
+ file delete -force /mod/webif/plugin/sweeper/.raw
+ }
+ puts "Done."
+ exit;
+ }
+}
+
set dir [cgi_get dir ""]
set root [system mediaroot]
diff --git a/webif/plugin/sweeper/schema.js b/webif/plugin/sweeper/schema.js
index 32e3e45..cd91d9b 100644
--- a/webif/plugin/sweeper/schema.js
+++ b/webif/plugin/sweeper/schema.js
@@ -1,56 +1,67 @@
var schema = {
criterion: {
lcn: {
+ 'class': 'all',
type: 'int',
desc: 'Logical Channel Number',
def: "0"
},
duration: {
+ 'class': 'all',
type: 'int',
desc: 'Recording duration (in minutes)',
def: "0"
},
schedduration: {
+ 'class': 'all',
type: 'int',
desc: 'Scheduled duration (in minutes)',
def: "0"
},
size: {
+ 'class': 'all',
type: 'int',
desc: 'Recording size (in bytes)',
def: "0"
},
hour: {
+ 'class': 'all',
type: 'int',
desc: 'Hour in which the recording started',
def: "0"
},
age: {
+ 'class': 'all',
type: 'int',
desc: 'Age (in hours)',
def: "0"
},
wage: {
+ 'class': 'all',
type: 'int',
desc: 'Time since last watched, or recorded (in hours)',
def: "0"
},
title: {
+ 'class': 'all',
type: 'substr',
desc: 'Recording Title contains',
def: 'Enter text here...'
},
synopsis: {
+ 'class': 'all',
type: 'substr',
desc: 'Synopsis contains',
def: 'Enter text here...'
},
guidance: {
+ 'class': 'all',
type: 'substr',
desc: 'Guidance Text contains',
def: 'Enter text here...'
},
genre: {
+ 'class': 'all',
type: 'select',
desc: 'Recording Genre',
select: {
@@ -67,6 +78,7 @@ var schema = {
def: 'Unclassified'
},
definition: {
+ 'class': 'all',
type: 'select',
desc: 'Recording Definition',
select: {
@@ -76,6 +88,7 @@ var schema = {
def: 'SD'
},
flag: {
+ 'class': 'all',
type: 'select',
desc: 'Recording Flagged as',
select: {
@@ -90,13 +103,21 @@ var schema = {
def: 'New'
},
lock: {
+ 'class': 'all',
type: 'select',
desc: 'Change Recording Lock',
select: {
1: 'Lock Recording',
0: 'Unlock Recording'
},
- def: 1
+ def: 1,
+ deprecated: true
+ },
+ fflag: {
+ 'class': 'folder',
+ type: 'string',
+ desc: 'Folder flagged as',
+ def: 'noflatten'
}
},
action: {
@@ -104,50 +125,224 @@ var schema = {
'class': 'all',
argtype: 'none',
desc: 'Continue on to next rule',
- showcont: false
+ continues: true
},
stop: {
'class': 'all',
argtype: 'none',
desc: 'Do nothing and stop processing rules',
- showcont: false
+ continues: false
},
move: {
'class': 'all',
argtype: 'folder',
desc: 'Move recording to folder...',
- showcont: true
+ continues: false
+ },
+ lock: {
+ 'class': 'all',
+ argtype: 'none',
+ desc: 'Lock recordings',
+ continues: true
+ },
+ unlock: {
+ 'class': 'all',
+ argtype: 'none',
+ desc: 'Unlock recordings',
+ continues: true
},
movecreate: {
'class': 'all',
argtype: 'folder',
desc: 'Move recording to folder (creating if necessary)',
- showcont: true
+ continues: false
},
fileunder: {
'class': 'folder',
argtype: 'folder',
desc: 'Merge into first folder of same name found under...',
- showcont: true
+ continues: false
},
fileundercreate: {
'class': 'folder',
argtype: 'folder',
desc: 'Merge into or create folder of ' +
'same name found under...',
- showcont: true
+ continues: false
}
}
};
-var select_criteria = {};
+var macros = {
+ seriesfiler: {
+ desc: 'Series-Filer',
+ rules: [
+ {
+ "raw": "action {fileunder ""}",
+ "name": "Emulate Seriesfiler",
+ "type": "folder",
+ "enabled": "1",
+ "criteria": [],
+ "action": {
+ "cmd": "fileunder",
+ "arg": ""
+ }
+ }
+ ]
+ },
+ example: {
+ desc: 'Example rules',
+ rules: [
+ {
+ "raw": "lcn {>= 70} lcn {<= 79} duration {>= 90} action {move Children/Films}",
+ "name": "Move any Children's films (by length)",
+ "type": "file",
+ "enabled": "0",
+ "criteria": [
+ {
+ "cmd": "lcn",
+ "arg": ">= 70"
+ },
+ {
+ "cmd": "lcn",
+ "arg": "<= 79"
+ },
+ {
+ "cmd": "duration",
+ "arg": ">= 90"
+ }
+ ],
+ "action": {
+ "cmd": "move",
+ "arg": "Children/Films"
+ }
+ },
+ {
+ "raw": "lcn {>= 70} lcn {<= 79} genre Film action {move Children/Films}",
+ "name": "Move any Children's films (by genre)",
+ "type": "file",
+ "enabled": "0",
+ "criteria": [
+ {
+ "cmd": "lcn",
+ "arg": ">= 70"
+ },
+ {
+ "cmd": "lcn",
+ "arg": "<= 79"
+ },
+ {
+ "cmd": "genre",
+ "arg": "Film"
+ }
+ ],
+ "action": {
+ "cmd": "move",
+ "arg": "Children/Films"
+ }
+ },
+ {
+ "raw": "lcn {>= 70} lcn {<= 79} action {move Children/Miscellaneous}",
+ "name": "Move anything else recorded from a children's channel",
+ "type": "file",
+ "enabled": "0",
+ "criteria": [
+ {
+ "cmd": "lcn",
+ "arg": ">= 70"
+ },
+ {
+ "cmd": "lcn",
+ "arg": "<= 79"
+ }
+ ],
+ "action": {
+ "cmd": "move",
+ "arg": "Children/Miscellaneous"
+ }
+ },
+ {
+ "raw": "lcn {>= 70} lcn {<= 79} action {fileundercreate Children}",
+ "name": "Move any series recordings from a Children's channel (folder rule)",
+ "type": "folder",
+ "enabled": "0",
+ "criteria": [
+ {
+ "cmd": "lcn",
+ "arg": ">= 70"
+ },
+ {
+ "cmd": "lcn",
+ "arg": "<= 79"
+ }
+ ],
+ "action": {
+ "cmd": "fileundercreate",
+ "arg": "Children"
+ }
+ },
+ {
+ "raw": "title {Formula 1} action {move F1}",
+ "name": "Move any one-off Formula 1 recordings into the F1 folder",
+ "type": "file",
+ "enabled": "0",
+ "criteria": [
+ {
+ "cmd": "title",
+ "arg": "Formula 1"
+ }
+ ],
+ "action": {
+ "cmd": "move",
+ "arg": "F1"
+ }
+ },
+ {
+ "raw": "age {> 120} action {movecreate Misc}",
+ "name": "Move any one-off recordings into a folder called Misc after a while",
+ "type": "file",
+ "enabled": "0",
+ "criteria": [
+ {
+ "cmd": "age",
+ "arg": "> 120"
+ }
+ ],
+ "action": {
+ "cmd": "movecreate",
+ "arg": "Misc"
+ }
+ }
+]
+ }
+
+};
+
+var select_file_criteria = {};
+var select_folder_criteria = {};
$.each(schema.criterion, function(k, v) {
- select_criteria[k] = v.desc;
+ if (v.deprecated)
+ return;
+ switch (v['class'])
+ {
+ case 'file':
+ select_file_criteria[k] = v.desc;
+ break;
+ case 'folder':
+ select_folder_criteria[k] = v.desc;
+ break;
+ case 'all':
+ select_file_criteria[k] = v.desc;
+ select_folder_criteria[k] = v.desc;
+ break;
+ }
});
var select_file_actions = {};
var select_folder_actions = {};
$.each(schema.action, function(k, v) {
+ if (v.deprecated)
+ return;
switch (v['class'])
{
case 'file':
diff --git a/webif/plugin/sweeper/script.js b/webif/plugin/sweeper/script.js
index 97a7d72..f86037d 100644
--- a/webif/plugin/sweeper/script.js
+++ b/webif/plugin/sweeper/script.js
@@ -6,7 +6,7 @@ function quot(str)
if (!str)
return '""';
- if (str.indexOf(" ") == -1)
+ if (str.indexOf(" ") == -1 && str.indexOf('"') == -1)
return str;
return '{' + str + '}';
}
@@ -15,6 +15,11 @@ function fixupdown()
{
$('#ruleset a.uprule').enable().filter(':first').disable();
$('#ruleset a.downrule').enable().filter(':last').disable();
+
+ $('#ruleset a.uprule img').attr('src', '/img/nav/up.png')
+ .first().attr('src', '/img/nav/up-grey.png');
+ $('#ruleset a.downrule img').attr('src', '/img/nav/down.png')
+ .last().attr('src', '/img/nav/down-grey.png');
}
function changed(c)
@@ -23,12 +28,12 @@ function changed(c)
return;
if (c)
{
- $('#b_save,#b_revert').enable();
+ $('#b_save,#b_revert').button('enable');
$('#pendingnote').show();
}
else
{
- $('#b_save,#b_revert').disable();
+ $('#b_save,#b_revert').button('disable');
$('#pendingnote').hide();
}
changed.last = c;
@@ -52,6 +57,9 @@ var setters = {
substr: function(cmd, a) {
return a;
},
+ 'string': function(cmd, a) {
+ return a;
+ },
select: function(cmd, a) {
return schema.criterion[cmd].select[a];
}
@@ -70,6 +78,9 @@ var getters = {
substr: function(cmd, a) {
return a;
},
+ 'string': function(cmd, a) {
+ return a;
+ },
select: function(cmd, a) {
var c = schema.criterion[cmd].select;
for (key in c)
@@ -83,11 +94,13 @@ function ruleconf(rule)
{
var s = '';
- if ($(rule).attr('type') == 'folder')
+ if (rule.hasClass('ruledisabled'))
+ s += '## ';
+ if (rule.attr('type') == 'folder')
s += 'folder ';
- $(rule).find('tr.clause').each(function(i) {
- cmd = $(this).find('th').attr('cmd');
+ rule.find('tr.clause').each(function(i) {
+ cmd = $(this).find('th.cmd').attr('cmd');
c = schema.criterion[cmd];
val = $.trim($(this).find('td.val').text());
if (getters[c.type])
@@ -96,12 +109,17 @@ function ruleconf(rule)
s += cmd + ' ' + quot(val) + ' ';
});
- act = $(rule).find('tr.action th').attr('cmd');
- arg = $.trim($(rule).find('tr.action td.val').text());
+ act = rule.find('tr.action th.cmd').attr('cmd');
+ arg = $.trim(rule.find('tr.action td.val').text());
if (schema.action[act].argtype == 'folder' && arg == mroot)
arg = '';
if (act != 'continue')
- s += 'action {' + act + ' ' + quot(arg) + '}';
+ {
+ if (schema.action[act].argtype == 'none')
+ s += 'action ' + act;
+ else
+ s += 'action {' + act + ' ' + quot(arg) + '}';
+ }
return s;
}
@@ -120,12 +138,22 @@ function conffile()
function rulerefresh(rule)
{
+ if (!showraw)
+ rule.find('.raw').hide();
rule.find('.raw').html(ruleconf(rule));
- rule.find('tr.clause td.title').text('And:').first().text('If:');
+ rule.find('tr.clause th.title').text('And:').first().text('If:');
if (rule.find('tr.clause').length < 1)
- rule.find('tr.action td.title').text('Always:');
+ {
+ rule.find('tr.action th.title').text('Always:');
+ rule.find('tr.otherwise').hide();
+ rule.find('div.criteria,div.arrow').hide();
+ }
else
- rule.find('tr.action td.title').text('Then:');
+ {
+ rule.find('tr.action th.title').text('Then:');
+ rule.find('tr.otherwise').show();
+ rule.find('div.criteria,div.arrow').show();
+ }
}
function criterion(data)
@@ -133,8 +161,9 @@ function criterion(data)
var c = schema.criterion[data.cmd];
var s;
- s = 'And: ' +
- '' + c.desc + ' ';
+ s = ' And: ' +
+ '' +
+ c.desc + ' ';
if (setters[c.type])
s += setters[c.type](data.cmd, data.arg);
@@ -160,16 +189,26 @@ function action(data)
data.arg = mroot;
s = ' ' +
- 'Then: ' +
- '' + c.desc + ' ' +
+ 'Then: ' +
+ '' + c.desc + ' ' +
'' + data.arg + ' ' +
'' +
' ' +
' ';
- if (c.showcont)
- s += 'Else: ' +
- 'Continue on to next rule. ';
+ if (data.cmd != 'continue')
+ {
+ if (c.continues)
+ s += 'And: ' +
+ 'Continue to next rule. ';
+ else if (data.cmd != 'stop')
+ s += 'And: ' +
+ 'Stop processing rules. ';
+
+ s += ' ' +
+ 'Otherwise: ' +
+ 'Continue to next rule. ';
+ }
return s;
}
@@ -196,16 +235,25 @@ function addrule(id, data)
var $c = rule.find('table.criteria');
$.each(data.criteria, function(key, val) {
+ if (val.cmd == 'lock' && (
+ data.action.cmd == 'lock' || data.action.cmd == 'unlock'))
+ return;
$c.find('tbody').append(criterion(val));
});
- $c.find('td.title:first').text('If:');
+ $c.find('th.title:first').text('If:');
rule.find('table.action tbody').append(action(data.action));
+ if (data.enabled == 0)
+ {
+ rule.addClass('ruledisabled');
+ rule.find('span.disabledtext').removeClass('hidden');
+ }
+
$('#ruleset').append(rule);
- rule.find('button.addcriterion')
- .button({icons: { primary: "ui-icon-plus"}});
+// rule.find('button.addcriterion')
+// .button({icons: { primary: "ui-icon-plus"}});
rulerefresh(rule);
@@ -241,6 +289,8 @@ function edit_text(obj, title, text, callback)
}
}
});
+ if (text == 'Enter text here...')
+ $('#edit_text_field').focus().select();
}
function edit_int(obj, title, op, val, callback)
@@ -310,10 +360,10 @@ function edit_select(obj, title, options, val, callback)
function edit_clause(obj)
{
- var cmd = $(obj).find('th').attr('cmd');
+ var cmd = $(obj).find('th.cmd').attr('cmd');
var target = $(obj).find('td.val');
var val = $.trim($(target).text());
- var title = $(obj).find('th').html();
+ var title = $(obj).find('th.cmd').html();
if (!schema.criterion[cmd])
{
alert('Unhandled command (' + cmd + ')');
@@ -364,7 +414,7 @@ function loadrules(dir)
if (!data.length)
{
$('#ruleset').attr('empty', true)
- .html('No rules defined for this folder. ');
+ .html($('#empty_rulebase').html());
return;
}
$.each(data, function(key, val) {
@@ -412,18 +462,18 @@ $('#b_add').button({icons: {primary: "ui-icon-plus"}})
}
});
$('#newrule_type_file').prop('checked', true);
- $('#newrule_comment').focus().val('').val('Unnamed rule');
+ $('#newrule_comment').focus().val('').val('Unnamed rule').select();
});
-$('#b_save').button({icons: {primary: "ui-icon-disk"}})
- .on('click', function(e) {
+$('#b_save').button({icons: {primary: "ui-icon-disk"}});
+$('#buttons')
+ .on('click', '#b_save', function(e) {
e.preventDefault();
$(this).dojConfirmAction({
question: 'Save changes?',
yesAnswer: 'Yes',
cancelAnswer: 'No'
}, function(el) {
- $('.jcaquestion').fadeOut(300);
$.post('save.jim', {
dir: $('span.dir').text(),
data: conffile()
@@ -435,15 +485,15 @@ $('#b_save').button({icons: {primary: "ui-icon-disk"}})
});
});
-$('#b_revert').button({icons: {primary: "ui-icon-arrowrefresh-1-w"}})
- .on('click', function(e) {
+$('#b_revert').button({icons: {primary: "ui-icon-arrowrefresh-1-w"}});
+$('#buttons')
+ .on('click', '#b_revert', function(e) {
e.preventDefault();
$(this).dojConfirmAction({
question: 'Discard changes?',
yesAnswer: 'Yes',
cancelAnswer: 'No'
}, function(el) {
- $('.jcaquestion').fadeOut(300);
loadrules($('span.dir').text());
changed(0);
});
@@ -470,6 +520,32 @@ $('#b_show').button({icons: {primary: "ui-icon-clipboard"}})
$('#b_raw').button({icons: {primary: "ui-icon-gear"}})
.on('click', function(e) {
$('#ruleset div.raw').toggle('slow');
+ showraw = !showraw;
+ $.get('save.jim?act=raw&val=' + (showraw ? 1 : 0));
+});
+
+$('#b_macro').button({disabled: true, icons: {primary: "ui-icon-plus"}});
+$('#macros').on('click', '#b_macro', function(e) {
+ e.preventDefault();
+ var set = $('#macroselect').val();
+ if (!set) return;
+ var desc = macros[set].desc;
+ $(this).dojConfirmAction({
+ question: 'Add ' + desc + '?',
+ yesAnswer: 'Yes',
+ cancelAnswer: 'No'
+ }, function(el) {
+ $('.jcaquestion').remove();
+ $.each(macros[set].rules, function(k, v) {
+ addrule(last_ruleid + 1, v).hide().addClass('hl');
+ });
+ $('.hl').slideDown('slow', function() {
+ $(this).removeClass('hl');
+ });
+ fixupdown();
+ changed(1);
+ $('#macroselect').val(0);
+ });
});
changed(0);
@@ -479,11 +555,17 @@ $('#ruleset')
e.preventDefault();
edit_clause($(this).closest('tr.clause'));
})
- .on('click', 'button.addcriterion', function(e) {
+ .on('click', 'a.addcriterion', function(e) {
e.preventDefault();
var rule = $(this).closest('div.rule');
- edit_select(rule, 'Select new criterion',
- select_criteria, '', function(rule, val) {
+ var type = rule.attr('type');
+
+ if (type == 'folder')
+ options = select_folder_criteria;
+ else
+ options = select_file_criteria;
+ edit_select(rule, 'Add new condition',
+ options, '', function(rule, val) {
var id = rule.attr('id');
rule.find('table.criteria tbody')
.append(criterion({
@@ -537,6 +619,35 @@ $('#ruleset')
});
});
})
+ .on('click', 'a.cprule', function(e) {
+ e.preventDefault();
+ $(this).dojConfirmAction({
+ question: 'Duplicate rule?',
+ yesAnswer: 'Yes',
+ cancelAnswer: 'No'
+ }, function(el) {
+ $('.jcaquestion').remove();
+ var rule = $(el).closest('div.rule');
+ rule.clone()
+ .attr('id', 'rule_' + ++last_ruleid)
+ .addClass('hl').hide()
+ .insertAfter(rule)
+ .slideDown('slow', function() {
+ $(this).removeClass('hl');
+ changed(1);
+ })
+ .find('span.comment').append(' (copy)');
+ });
+ })
+ .on('click', 'a.enadisrule', function(e) {
+ e.preventDefault();
+ var rule = $(this).closest('div.rule')
+ .toggleClass('ruledisabled');
+ rule.find('span.disabledtext').toggleClass('hidden',
+ !rule.hasClass('ruledisabled'));
+ rulerefresh(rule);
+ changed(1);
+ })
.on('click', 'a.editaction', function(e) {
e.preventDefault();
@@ -555,7 +666,7 @@ $('#ruleset')
);
});
- var cmd = rule.find('tr.action th').attr('cmd');
+ var cmd = rule.find('tr.action th.cmd').attr('cmd');
var arg = rule.find('tr.action td.val').html();
if (schema.action[cmd].argtype == 'none')
@@ -596,11 +707,10 @@ $('#ruleset')
.on('click', 'a.delclause', function(e) {
e.preventDefault();
$(this).dojConfirmAction({
- question: 'Delete criterion?',
+ question: 'Delete condition?',
yesAnswer: 'Yes',
cancelAnswer: 'No'
}, function(el) {
- $('.jcaquestion').fadeOut(300);
var rule = $(el).closest('div.rule');
$(el).closest('tr.clause').fadeOut('slow', function() {
$(this).remove();
@@ -616,19 +726,33 @@ $('#ruleset')
yesAnswer: 'Yes',
cancelAnswer: 'No'
}, function(el) {
- $('.jcaquestion').fadeOut(300);
- $(el).closest('div.rule').slideUp('slow', function() {
+ $(el).closest('div.rule')
+ .addClass('hl')
+ .slideUp('slow', function() {
$(this).remove();
changed(1);
fixupdown();
if ($('div.rule').length < 1)
$('#ruleset').attr('empty', true)
- .html('No rules defined for this ' +
- 'folder. ');
+ .html($('#empty_rulebase').html());
});
});
});
+ // Set up macros
+ $.each(macros, function(key, val) {
+ $('#macroselect').append(
+ $(' ').attr('value', key).text(val.desc)
+ );
+ });
+
+ $('#macroselect').on('change', function(el) {
+ if ($(this).val() == "0")
+ $('#b_macro').button('disable');
+ else
+ $('#b_macro').button('enable');
+ });
+
loadrules($('span.dir').text());
});
diff --git a/webif/plugin/sweeper/style.css b/webif/plugin/sweeper/style.css
index 4d46b47..ffbc131 100644
--- a/webif/plugin/sweeper/style.css
+++ b/webif/plugin/sweeper/style.css
@@ -1,4 +1,9 @@
+a
+{
+ outline: 0;
+}
+
span.ruleicon img
{
height: 21px;
@@ -20,15 +25,30 @@ img
background: yellow;
}
+.ruledisabled
+{
+ background: #663436 url(img/redstripes.gif) repeat;
+}
+
div.action
{
- padding-left: 1em;
float: left;
}
+a.addcriterion
+{
+ padding: 4px 2px 0 0;
+ float: left;
+ clear: left;
+}
+
div.criteria
{
- clear: left;
+ float: left;
+}
+
+div.arrow
+{
float: left;
}
@@ -47,11 +67,9 @@ div#buttons
padding-top: 1em;
}
-td.title,th.title
+div#macros
{
- line-height: 1em;
- text-align: left !important;
- background: #eee !important;
+ padding-top: 1em;
}
div.rule
@@ -86,3 +104,47 @@ span.legendright
background: transparent;
}
+table
+{
+ border: 0;
+}
+
+table th
+{
+ background: #ccff99;
+ font-weight: bold;
+ text-align: right;
+ color: black;
+ xpadding: 0.5em;
+}
+
+table td
+{
+ background: #ffffcc;
+ color: black;
+}
+
+td.title,th.title
+{
+ line-height: 1em;
+ background: #eee !important;
+ font-style: italic;
+}
+
+td.title
+{
+ text-align: left !important;
+}
+
+th.title
+{
+ font-weight: normal;
+ text-align: right !important;
+}
+
+tr.blank td
+{
+ background: transparent;
+ line-height: 7px;
+}
+