forked from hummypkg/webif
Compare commits
73 Commits
df-bbrawpa
...
master
Author | SHA1 | Date |
---|---|---|
HummyPkg | ee4c121a54 | |
HummyPkg | 8f340c9a3b | |
af123 | 67504198ec | |
df | ba0f505e34 | |
af123 | 33e2f705c3 | |
df | a26526b047 | |
HummyPkg | 04e4fd1083 | |
af123 | 6e3b5114be | |
df | 6c40da165d | |
df | 346ed469c8 | |
HummyPkg | 029b115628 | |
HummyPkg | c7a91766af | |
HummyPkg | d00f925e58 | |
HummyPkg | fc3b28e978 | |
prpr | c4afa7ac60 | |
Bob Buxton | 3c3b0af49f | |
prpr | f206766191 | |
prpr | 67afb37f27 | |
prpr | ad150143a8 | |
df | 5d3b046c70 | |
df | 18bed926b3 | |
df | 1c868ae201 | |
HummyPkg | 4820ade1f5 | |
Bob Buxton | bc2e6c1a85 | |
df | 6f45884f94 | |
af123 | a1cf871a84 | |
df | 7834dae075 | |
af123 | 15cba14cc3 | |
af123 | 3f74654ea2 | |
df | f16399ec2f | |
df | 0060e47db5 | |
df | 8bdb1233e8 | |
df | 2642b190b0 | |
df | 8975cbd71d | |
df | 32ac3c8421 | |
df | f5180dc144 | |
df | dac3ea8698 | |
df | 4ae8ea85f7 | |
df | 47495e7b8d | |
df | 73d25247f0 | |
df | f7c37e83ae | |
df | cf407f9a80 | |
df | d98217b679 | |
HummyPkg | 269f844f43 | |
HummyPkg | 488961c600 | |
HummyPkg | a5f0734201 | |
af123 | 94849c51e7 | |
af123 | 907d9d8dcf | |
df | 6641b6f458 | |
df | 98ef6a876f | |
df | d05f841bb4 | |
df | 4da3bb0209 | |
HummyPkg | 2e471129b8 | |
df | 0ad1491634 | |
df | da32aa0a72 | |
df | f6117a4ec0 | |
af123 | 8021455a94 | |
af123 | c995f2232e | |
prpr | 6dc47f2b96 | |
prpr | af74503b99 | |
prpr | 58ecd41952 | |
df | e579c8dd24 | |
df | 7c600be77e | |
af123 | e3f7a2b738 | |
prpr | a90f49b324 | |
df | 3e9ecc8a7c | |
df | 7bb66de5f2 | |
df | 9b64128c92 | |
df | 6822c833be | |
df | cefe60c722 | |
prpr | ee885a173c | |
df | 2d06ec7811 | |
df | 0e09258bfa |
|
@ -1,7 +1,7 @@
|
|||
Package: webif
|
||||
Priority: optional
|
||||
Section: web
|
||||
Version: 1.4.8-10
|
||||
Version: 1.4.9-6
|
||||
Architecture: mipsel
|
||||
Maintainer: af123@hpkg.tv
|
||||
Depends: tcpfix,webif-channelicons(>=1.1.27),lighttpd(>=1.4.39-1),jim(>=0.79),jim-pack(>=0.79),jim-oo(>=0.77),jim-sqlite3(>=0.77),jim-cgi(>=0.7-2),jim-binary(>=0.76),service-control(>=2.3),busybox(>=1.20.2-1),lsof(>=4.87),epg(>=1.2.8),hmt(>=2.0.10),ssmtp,cron-daemon(>=1.18.3-3),at(>=3.1.18),anacron,trm(>=1.1),openssl-command,nicesplice,id3v2,file,rsvsync(>=1.1.13),webif-charts(>=1.2-1),stripts(>=1.4.2),tmenu(>=1.21-2),ffmpeg(>=2.8),id3v2,multienv(>=1.6),tcpping(>=1.1),e2fsprogs,wireless-tools(>=29-1),dbupdate,recmon(>=2.0.7),hwctl,nugget(>=0.98),sqlite3(>=3.15.1),jim-xconv,zip(>=3.0-1),wget
|
||||
|
|
|
@ -31,7 +31,7 @@ if {[$record get sched_type] < 1} {
|
|||
[system tuners]]
|
||||
if {[llength $conflicts]} {
|
||||
puts {
|
||||
<div class=warningbox style="width: 100%; margin: 0.2em"><div>
|
||||
<div class=warningbox style="width: auto; margin: 0.2em"><div>
|
||||
This event conflicts with the following items in your scheduled recording list.
|
||||
<ul>
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
package require cgi
|
||||
source /mod/webif/lib/setup
|
||||
require pkg.class system.class
|
||||
require pkg.class system.class settings.class
|
||||
|
||||
cgi_input
|
||||
#cgi_dump
|
||||
|
@ -61,6 +61,11 @@ if {$cmd eq "dependinfo"} {
|
|||
}
|
||||
|
||||
if {$cmd eq "upgrade"} { opkg update }
|
||||
|
||||
if {$cmd eq "remove" && [[settings] noautoremove] ne "1"} {
|
||||
append cmd " --autoremove"
|
||||
}
|
||||
|
||||
opkg "$cmd $cmdargs"
|
||||
|
||||
if {$cmd eq "update" || $cmd eq "upgrade"} {
|
||||
|
|
|
@ -7,7 +7,7 @@ require system.class epg.class rsv.class svc.class plugin
|
|||
set runmode cli
|
||||
if {[string match {*jim} $argv0]} { set runmode cgi }
|
||||
|
||||
set schedtime 1200
|
||||
set schedtime 1200
|
||||
switch $runmode {
|
||||
cgi {
|
||||
set type [cgi_get type "full"]
|
||||
|
@ -15,8 +15,7 @@ switch $runmode {
|
|||
}
|
||||
cli {
|
||||
set type "full"
|
||||
if {"-X" in $argv} { set schedtime 7200 }
|
||||
if {"-x" in $argv} { set schedtime 7200 }
|
||||
if {[lsearch -nocase $argv "-x"] >= 0} { set schedtime 7200 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,11 +60,11 @@ proc register_statusop {op name icon} {
|
|||
eval_plugins status 1
|
||||
|
||||
proc get_data {} {
|
||||
global pid exts
|
||||
global pid exts stream tsr tsrcnt
|
||||
|
||||
set ret {}
|
||||
if {[catch {set data \
|
||||
[exec /mod/webif/lib/bin/lsof -X -Fns -p $pid]} msg]} {
|
||||
[exec /mod/webif/lib/bin/lsof -Fnsa -p $pid]} msg]} {
|
||||
debug "Error: $msg"
|
||||
set ret {}
|
||||
} else {
|
||||
|
@ -73,35 +72,64 @@ proc get_data {} {
|
|||
foreach line [split $data "\n"] {
|
||||
set typ [string index $line 0]
|
||||
switch $typ {
|
||||
a {
|
||||
set access [string index $line 1]
|
||||
}
|
||||
s {
|
||||
set size [string range $line 1 end]
|
||||
}
|
||||
n {
|
||||
if {[string first Video/ $line] == -1 && \
|
||||
[string first /media/ $line] == -1} {
|
||||
# strip initial n and trailing " (...)" if
|
||||
# present
|
||||
regsub -all -- {(^n)|( \([^\)]+\)$)} \
|
||||
$line "" line
|
||||
set file [subst -nocommands -novariables $line]
|
||||
set ext [file extension $line]
|
||||
# Note but skip TSR buffers
|
||||
if {[file rootname $file] eq $tsr} {
|
||||
if {$ext eq ".nts"} {
|
||||
incr tsrcnt
|
||||
}
|
||||
continue
|
||||
}
|
||||
regsub -- { \([^\)]+\)$} $line "" line
|
||||
set ext [file extension $line]
|
||||
if {$ext ni $exts} continue
|
||||
set file [subst -nocommands -novariables \
|
||||
[string range $line 1 end]]
|
||||
# Skip HD-Fox TSR buffer
|
||||
if {$file eq "/media/drive1/.tsr/0.ts"} {
|
||||
|
||||
if {[string first Video/ $line] >= 0 ||
|
||||
[string first /media/ $line] >= 0} {
|
||||
if {$ext ni $exts} {
|
||||
continue
|
||||
}
|
||||
} elseif {[string first $line /] >= 0} {
|
||||
# fast skip other files
|
||||
continue
|
||||
} elseif {[regexp -- {[A-Za-z0-9._-]+:([0-9]+)->([A-Za-z0-9._-]+):([0-9]+)} $line _ sprt host dprt]} {
|
||||
if {$sprt == 9000} {
|
||||
incr stream
|
||||
continue
|
||||
} elseif {$dprt == 9000} {
|
||||
set file [\
|
||||
format "DLNA from %s" $host]
|
||||
set size 0
|
||||
set ext ""
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
# Handle chase play (same file open twice
|
||||
# and recently written)
|
||||
if {[dict exists $ret $file] && \
|
||||
if {[dict exists $ret $file] &&
|
||||
$ext eq ".ts"} {
|
||||
set age [expr [clock seconds] - \
|
||||
[file mtime $file]]
|
||||
set age [expr [clock seconds] \
|
||||
- [file mtime $file]]
|
||||
if {$age < 60} {
|
||||
set ret($file) -1
|
||||
set access [lindex \
|
||||
[dict get $ret $file] 1]
|
||||
set ret($file) [list -1 $access]
|
||||
}
|
||||
} else {
|
||||
debug "$file = $size"
|
||||
set ret($file) $size
|
||||
} else {
|
||||
debug "$file = $size,$access"
|
||||
set ret($file) [list $size $access]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,11 +137,9 @@ proc get_data {} {
|
|||
}
|
||||
foreach file [dict keys $::ops] {
|
||||
if {![dict exists $ret $file]} {
|
||||
if {[file exists $file]} {
|
||||
set ret($file) [file size $file]
|
||||
} else {
|
||||
set ret($file) 0
|
||||
}
|
||||
set sz 0
|
||||
if {[file exists $file]} { set sz [file size $file] }
|
||||
set ret($file) [list $sz u]
|
||||
}
|
||||
}
|
||||
return $ret
|
||||
|
@ -139,9 +165,12 @@ proc add_output {icon mode name} {
|
|||
|
||||
set play 0
|
||||
set rec 0
|
||||
set stream 0
|
||||
set output {}
|
||||
set ops {}
|
||||
set model [system model]
|
||||
set tsr [file rootname [system tsr]]
|
||||
set tsrcnt 0
|
||||
|
||||
foreach opfile [glob -nocomplain -directory /tmp -tails -- ".bgop.*"] {
|
||||
set op [string range $opfile 6 end]
|
||||
|
@ -179,8 +208,9 @@ if {[llength $data]} {
|
|||
debug " NDATA: ($ndata)"
|
||||
set rr 0
|
||||
}
|
||||
set bnames [lsort [lmap x [array names data] { file tail $x }]]
|
||||
foreach file [array names data] {
|
||||
set bname [file rootname [file tail $file]]
|
||||
set bname [file tail $file]
|
||||
|
||||
set name [string map {
|
||||
"/mnt/hd2/My Video/" ""
|
||||
|
@ -189,17 +219,22 @@ if {[llength $data]} {
|
|||
".ts" ""
|
||||
} $file]
|
||||
|
||||
if {$data($file) == -1} {
|
||||
if {[lindex $data($file) 0] == -1} {
|
||||
set mode chase
|
||||
} elseif {$rr} {
|
||||
if {$file in $recs} {
|
||||
set mode rec
|
||||
} elseif {[llength [\
|
||||
lsearch -all $bnames $bname]] == 2} {
|
||||
# two different files having same file.ext open
|
||||
set mode copy
|
||||
} else {
|
||||
set mode play
|
||||
}
|
||||
} else {
|
||||
if {![dict exists $ndata $file]} continue
|
||||
if {$ndata($file) > $data($file)} {
|
||||
if {[lindex $ndata($file) 0] > \
|
||||
[lindex $data($file) 0]} {
|
||||
set mode rec
|
||||
} else {
|
||||
set mode play
|
||||
|
@ -231,8 +266,20 @@ if {[llength $data]} {
|
|||
}
|
||||
play {
|
||||
incr play
|
||||
set mode "Playing"
|
||||
set icon "745_1_10_Video_2Live.png"
|
||||
if {$play > $stream} {
|
||||
set mode "Playing"
|
||||
set icon "745_1_10_Video_2Live.png"
|
||||
} else {
|
||||
set mode "Streaming"
|
||||
set icon "/img/dlna.png"
|
||||
}
|
||||
}
|
||||
copy {
|
||||
if {[lindex $data($file) 1] ne "r"} {
|
||||
continue
|
||||
}
|
||||
set mode "Copying"
|
||||
set icon "/img/dlna.png"
|
||||
}
|
||||
default {
|
||||
if {[dict exists $statusops $mode]} {
|
||||
|
@ -272,23 +319,33 @@ if {![system instandby] && $play < 1} {
|
|||
if {[llength $epgs] == 1} {
|
||||
lassign $epgs epg
|
||||
set prog "- [$epg get name] ("
|
||||
append prog "[clock format [$epg get start] -format %H:%M] - "
|
||||
append prog "[clock format $([$epg get start] + [$epg get duration]) -format %H:%M]"
|
||||
append prog "[clock format [\
|
||||
$epg get start] -format %H:%M] - "
|
||||
append prog "[clock format $([$epg get start] \
|
||||
+ [$epg get duration]) -format %H:%M]"
|
||||
append prog ") \[[$epg percent]%\]"
|
||||
}
|
||||
|
||||
if {$runmode eq "cgi"} {
|
||||
set s "
|
||||
<span class=\"va stitem\">
|
||||
[epg channelicon $name 30 \
|
||||
{vertical-align: middle; padding: 0 4px 0 2px}]
|
||||
<span>Watching <i>$lcn: $name $prog</i></span>
|
||||
"
|
||||
append s "</span>"
|
||||
lappend output $s
|
||||
# 0 => no TSR; >=2 => TSR
|
||||
if {$tsrcnt == 0 || $tsrcnt == 2} {
|
||||
set s "Watching"
|
||||
} elseif {$tsrcnt == 3} {
|
||||
set s "Watching (delayed)"
|
||||
} else {
|
||||
set s "Watching $lcn: $name $prog"
|
||||
lappend output $s
|
||||
debug "tsrcnt=$tsrcnt"
|
||||
set s "Not watching"
|
||||
}
|
||||
if {$runmode eq "cgi"} {
|
||||
lappend output [format "
|
||||
<span class=\"va stitem\">
|
||||
[epg channelicon %s 30 \
|
||||
{vertical-align: middle; padding: 0 4px 0 2px}]
|
||||
<span>%s <i>%s: %s %s</i></span>
|
||||
</span>
|
||||
" $name $s $lcn $name $prog]
|
||||
} else {
|
||||
lappend output [format "%s %s: %s %s" \
|
||||
$s $lcn $name $prog]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +371,7 @@ if {[system instandby]} {
|
|||
# Upcoming recordings
|
||||
|
||||
set events [rsv list tbl_reservation \
|
||||
" where ersvtype = 3 and nsttime - [clock seconds] < $schedtime
|
||||
" where ersvtype = 3 and nsttime - [clock seconds] < $schedtime
|
||||
and nsttime > [clock seconds] "]
|
||||
foreach event $events {
|
||||
if {$runmode eq "cgi"} {
|
||||
|
|
|
@ -103,6 +103,8 @@ if {[llength $plugins(dmenu)]} {
|
|||
}
|
||||
}
|
||||
|
||||
# the maxlength values for title and synopsis are 1 less than the maximum to
|
||||
# allow for an extra byte to indicate character encoding (see rename.jim)
|
||||
puts {
|
||||
</ul>
|
||||
|
||||
|
@ -131,20 +133,51 @@ puts {
|
|||
</th>
|
||||
<td>
|
||||
<input type=text name="rename_title" id="rename_title"
|
||||
value="" size=70 maxlength=48
|
||||
value="" size=70 maxlength=47
|
||||
class="text ui-widget-content ui-corner-all">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr style="display: none" class=tstype>
|
||||
<th>
|
||||
<label for="rename_seriesnum" style="padding-top: 0.5em">
|
||||
<b>New Series Number</b>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<span title="Series number">
|
||||
<input type=number name="rename_seriesnum" id="rename_seriesnum"
|
||||
value=0 max=255
|
||||
class="uint8_t ui-widget-content ui-corner-all">
|
||||
</span>
|
||||
<label for="rename_episodenum" style="padding-top: 0.5em">
|
||||
<b>Episode</b>
|
||||
</label>
|
||||
<span title="Episode number">
|
||||
<input type=number name="rename_episodenum"
|
||||
id="rename_episodenum" value=0 max=255
|
||||
class="uint8_t ui-widget-content ui-corner-all">
|
||||
</span>
|
||||
<label for="rename_episodetot" style="padding-top: 0.5em">
|
||||
<b>of</b>
|
||||
</label>
|
||||
<span title="Episode total">
|
||||
<input type=number name="rename_episodetot"
|
||||
id="rename_episodetot" value=0 max=255
|
||||
class="uint8_t ui-widget-content ui-corner-all">
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr style="display: none" class=tstype>
|
||||
<th>
|
||||
<label for="rename_synopsis" style="padding-top: 0.5em">
|
||||
<b>New Synopsis</b>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<td colspan=3>
|
||||
<textarea name="rename_synopsis" id="rename_synopsis"
|
||||
value="" cols=70 rows=4
|
||||
value="" cols=70 rows=4 maxlength=251
|
||||
class="text ui-widget-content ui-corner-all"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
package require cgi
|
||||
source /mod/webif/lib/setup
|
||||
require ts.class pretty_size
|
||||
require ts.class system.class pretty_size
|
||||
|
||||
jscss script.js style.css
|
||||
jqplugin touchpunch
|
||||
|
@ -15,6 +15,10 @@ set erfile [string map {' \\'} $rfile]
|
|||
|
||||
set len [$ts duration 1]
|
||||
|
||||
set start -1
|
||||
set incr 1
|
||||
set limit $(1-$start)
|
||||
|
||||
puts "
|
||||
<script type=text/javascript>
|
||||
var initbookmarks = '[$ts bookmarks]';
|
||||
|
@ -39,10 +43,38 @@ var dir = '$dir';
|
|||
<button class=left id=addbmark>Add Bookmark</button>
|
||||
<button class=left id=delbmark>Remove Bookmark</button>
|
||||
</td><td><div id=slider></div></td></tr>
|
||||
<tr><td align=right>
|
||||
<span class=left>Current: <span id=curbmk></span></span><br><br><br>
|
||||
<button id=genthumbs title=\"Generate Thumbnails\"
|
||||
class=left>Generate Thumbnails</button>
|
||||
</td><td>
|
||||
<div id=thumbs class=hidden>
|
||||
<table><tr>
|
||||
"
|
||||
set times {}
|
||||
loop v $start $limit $incr {
|
||||
lappend times $v
|
||||
puts "
|
||||
<th style=\"text-align: center\"><span class=mark>
|
||||
[format "%+d" $v]</span>s</th>
|
||||
"
|
||||
}
|
||||
puts "</tr><tr>"
|
||||
foreach v $times {
|
||||
puts "<td><img class=bmp src=/img/generating.png pos=$v></td>"
|
||||
}
|
||||
puts "
|
||||
</tr></table>
|
||||
</div></td></tr>
|
||||
</table>
|
||||
<div id=buttons>
|
||||
<button id=save>Save Bookmarks</button>
|
||||
<button id=back>Back to Media Browser</button>
|
||||
"
|
||||
if {[system pkginst nicesplice]} {
|
||||
puts "<button id=crop>Go to Crop</button>"
|
||||
}
|
||||
puts "
|
||||
</div>
|
||||
<div id=results class=\"hidden blood\"></div>
|
||||
"
|
||||
|
|
|
@ -1,11 +1,26 @@
|
|||
var curval = 0;
|
||||
var $slider;
|
||||
var values;
|
||||
|
||||
function
|
||||
toTimeStr(tval)
|
||||
{
|
||||
return new Date(null, null, null, null, null, tval)
|
||||
.toTimeString().match(/\d{2}:\d{2}:\d{2}/)[0] + ' ';
|
||||
}
|
||||
|
||||
function
|
||||
valarray(valstr)
|
||||
{
|
||||
return valstr.trim().split(/ +/);
|
||||
}
|
||||
|
||||
function
|
||||
setvals()
|
||||
{
|
||||
values = $.trim($('#bookmarks').val()).split(/ +/);
|
||||
if (!values.length || values[0] == '')
|
||||
var nvalues;
|
||||
values = valarray($('#bookmarks').val());
|
||||
if (values.length > 0 && values[0] != '')
|
||||
{
|
||||
refreshtimes();
|
||||
return;
|
||||
|
@ -20,6 +35,7 @@ setvals()
|
|||
});
|
||||
values = nvalues;
|
||||
$('#bookmarks').val(values.join(' '));
|
||||
values = valarray($('#bookmarks').val());
|
||||
sortmarks();
|
||||
refreshtimes();
|
||||
}
|
||||
|
@ -32,7 +48,6 @@ draw_slider()
|
|||
else
|
||||
$slider = $('#slider');
|
||||
setvals();
|
||||
values = $.trim($('#bookmarks').val()).split(/ +/);
|
||||
if (!values.length || values[0] == '')
|
||||
{
|
||||
$slider = null;
|
||||
|
@ -55,55 +70,95 @@ draw_slider()
|
|||
var marks = '';
|
||||
for (var i = 0; i < ui.values.length; ++i)
|
||||
marks += ui.values[i] + ' ';
|
||||
$('#bookmarks').val($.trim(marks));
|
||||
$('#bookmarks').val(marks.trim());
|
||||
setvals();
|
||||
}
|
||||
});
|
||||
refreshtimes();
|
||||
};
|
||||
|
||||
function
|
||||
regenthumbs(curbmkstr)
|
||||
{
|
||||
$('#curbmk').html(curbmkstr);
|
||||
$('#thumbs').hide();
|
||||
$('#genthumbs')
|
||||
.button('enable')
|
||||
.button('option', 'icon', 'ui-icon-zoomin');
|
||||
}
|
||||
|
||||
function
|
||||
update_slider()
|
||||
{
|
||||
setvals();
|
||||
|
||||
/* slider values are strings */
|
||||
var curvalstr = "" + curval;
|
||||
if (!values.includes(curvalstr)) {
|
||||
/* try to map current selected bmk to new bmk */
|
||||
var ovalues = $slider.slider("option", "values");
|
||||
var nn = ovalues.indexOf(curvalstr);
|
||||
if (nn < 0) {
|
||||
curval = 0;
|
||||
} else {
|
||||
if (nn >= values.length)
|
||||
nn = values.length - 1;
|
||||
curval = nn >= 0 ? values[nn] : 0;
|
||||
}
|
||||
regenthumbs(toTimeStr(curval));
|
||||
}
|
||||
$('#slider .ui-slider-handle').each(function(i) {
|
||||
if (i >= values.length)
|
||||
$(this).hide();
|
||||
else
|
||||
$(this).show();
|
||||
});
|
||||
$slider.slider("option", "values", values);
|
||||
};
|
||||
|
||||
function
|
||||
refreshtimes()
|
||||
{
|
||||
var t = '';
|
||||
values = $.trim($('#bookmarks').val()).split(/ +/);
|
||||
if (!values.length || values[0] == '')
|
||||
{
|
||||
$('#bookmarkstime').text(t);
|
||||
return;
|
||||
$.each(values, function(k, v) {
|
||||
t += toTimeStr(v);
|
||||
});
|
||||
$('#slider .ui-slider-handle').each(function(i) {
|
||||
$(this).attr('title', toTimeStr(values[i]));
|
||||
});
|
||||
}
|
||||
$.each(values, function(k, v) {
|
||||
t += new Date(null, null, null, null, null, v)
|
||||
.toTimeString().match(/\d{2}:\d{2}:\d{2}/)[0] + ' ';
|
||||
});
|
||||
$('#bookmarkstime').text(t);
|
||||
}
|
||||
|
||||
function
|
||||
sortmarks()
|
||||
{
|
||||
var a = $.trim($('#bookmarks').val()).split(/ +/);
|
||||
a.sort(function(a, b){return a-b});
|
||||
$('#bookmarks').val(a.join(" "));
|
||||
values.sort(function(a, b){return a - b});
|
||||
$('#bookmarks').val(values.join(" "));
|
||||
}
|
||||
|
||||
$(function() {
|
||||
|
||||
$('#bookmarks').val($('#bookmarks').attr('init'));
|
||||
draw_slider();
|
||||
$('#curbmk').html(toTimeStr(curval));
|
||||
|
||||
$('#addbmark').button({icons: {primary: "ui-icon-plus"}, text: false})
|
||||
.on('click', function() {
|
||||
$('#bookmarks').val('0 ' + $('#bookmarks').val());
|
||||
draw_slider();
|
||||
curval = 0;
|
||||
update_slider();
|
||||
});
|
||||
|
||||
$('#delbmark').button({icons: {primary: "ui-icon-minus"}, text: false})
|
||||
.on('click', function() {
|
||||
var cur = $('#bookmarks').val();
|
||||
cur = $.trim(cur.replace(
|
||||
new RegExp('(^| )' + curval + '( |$)', ''), ' '));
|
||||
cur = cur.replace(
|
||||
new RegExp('(^| )' + curval + '( |$)', ''), ' ').trim();
|
||||
$('#bookmarks').val(cur);
|
||||
draw_slider();
|
||||
update_slider();
|
||||
});
|
||||
|
||||
$('#save').button({icons: {primary: "ui-icon-disk"}})
|
||||
|
@ -122,11 +177,62 @@ $('#back').button({icons: {primary: "ui-icon-arrowreturnthick-1-w"}})
|
|||
window.location = '/go/browse?dir=' + encodeURIComponent(dir);
|
||||
});
|
||||
|
||||
$('#crop').button({icons: {primary: "ui-icon-arrowreturnthick-1-e"}})
|
||||
.on('click', function() {
|
||||
window.location =
|
||||
window.location.href.replace('/bookmarks/?','/crop/crop.jim?');
|
||||
});
|
||||
|
||||
$('#update').button()
|
||||
.on('click', function() {
|
||||
draw_slider();
|
||||
update_slider();
|
||||
});
|
||||
|
||||
$('#slider')
|
||||
.on('slidechange', function(evt, ui) {
|
||||
var tstr = toTimeStr(curval);
|
||||
if (tstr != $('#curbmk').html())
|
||||
regenthumbs(tstr);
|
||||
});
|
||||
|
||||
$('#genthumbs').button({icons: {primary: "ui-icon-zoomin"}, disabled: false})
|
||||
.on('click', function() {
|
||||
var start;
|
||||
var incr = -1;
|
||||
var last;
|
||||
$(this)
|
||||
.button('disable')
|
||||
.button('option', 'icon', 'ui-icon-refresh');
|
||||
$('img.bmp').each(function(i) {
|
||||
if (start === undefined) {
|
||||
start = $(this).attr('pos') | 0;
|
||||
} else {
|
||||
last = $(this).attr('pos') | 0;
|
||||
}
|
||||
incr++;
|
||||
});
|
||||
|
||||
incr = (last - start) / incr;
|
||||
|
||||
$.get('/browse/thumbnail/mkrange.jim', {
|
||||
'file': file,
|
||||
's': start+curval,
|
||||
'e': last+curval,
|
||||
'i': incr
|
||||
}, function() {
|
||||
$('#thumbs').show();
|
||||
$('img.bmp').each(function(i) {
|
||||
/* cast to "int" */
|
||||
var pos = $(this).attr('pos')|0;
|
||||
$(this).attr('src',
|
||||
'/browse/thumbnail/fetch.jim?' +
|
||||
'file=' + encodeURIComponent(file) +
|
||||
'&pos=' + (curval+pos).toFixed(1));
|
||||
});
|
||||
$('#genthumbs').button('option', 'icon', 'ui-icon-zoomin');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ set ts [ts fetch $rfile]
|
|||
set dir [file dirname $rfile]
|
||||
|
||||
set len [$ts duration 1]
|
||||
set planwidth 500
|
||||
|
||||
puts "
|
||||
<fieldset>
|
||||
|
@ -29,12 +30,17 @@ puts [join [lmap i [$ts bookmarks 1] {
|
|||
clock format $i -format "%T"
|
||||
}] ", "]
|
||||
|
||||
puts "</td></tr><tr><th> </th><td id=cutplan>"
|
||||
# set minimum width as positioned contents doesn't resize its cell
|
||||
puts "</td></tr><tr><th> </th><td id=cutplan style=\"min-width: ${planwidth}px\">"
|
||||
|
||||
puts "<div style=\"position: relative; top: -10px\">"
|
||||
|
||||
proc div {type left right} {
|
||||
set width $($right - $left)
|
||||
if {$width < 0} {
|
||||
# negative values are invalid for CSS width
|
||||
set width 0
|
||||
}
|
||||
puts "<div class=$type style=\"left: ${left}px; width: ${width}px\">
|
||||
$type</div>"
|
||||
}
|
||||
|
@ -64,8 +70,8 @@ foreach b $bookmarks {
|
|||
incr cur $l
|
||||
append newbookmarks "[expr $cur + 3] "
|
||||
|
||||
set left $($start * 500 / $len)
|
||||
set right $($end * 500 / $len)
|
||||
set left $($start * $planwidth / $len)
|
||||
set right $($end * $planwidth / $len)
|
||||
|
||||
div cut $last $($left - 1)
|
||||
div keep $left $($right - 1)
|
||||
|
@ -78,11 +84,11 @@ foreach b $bookmarks {
|
|||
if {$start > 0} {
|
||||
# Still in a keep section...
|
||||
incr keeping $($len - $start)
|
||||
set left $($start * 500 / $len)
|
||||
set left $($start * $planwidth / $len)
|
||||
div cut $last $($left - 1)
|
||||
div keep $left 500
|
||||
div keep $left $planwidth
|
||||
} else {
|
||||
div cut $last 500
|
||||
div cut $last $planwidth
|
||||
}
|
||||
|
||||
if {$cur > $keeping - 8 && $keeping - 8 > 0} {
|
||||
|
@ -115,7 +121,7 @@ puts [join [lmap i $newbookmarks {
|
|||
puts " )</td></tr>"
|
||||
|
||||
puts "
|
||||
<tr><th>Time:</th>
|
||||
<tr id=esttime><th>Time:</th>
|
||||
<td>Cropping will take around [clock format $esttime -format "%T"]</td></tr>
|
||||
</table>
|
||||
|
||||
|
@ -130,9 +136,9 @@ puts "
|
|||
<td><button id=invert invert=$invert>Invert selection</button></td>
|
||||
<td><button id=cropit>Perform crop operation</button></td>
|
||||
<td>
|
||||
Save new bookmarks?
|
||||
<label id=saveitlabel for=saveit>Save new bookmarks?</label>
|
||||
<input id=saveit type=checkbox name=saveit checked>
|
||||
<label id=saveitlabel for=saveit> </label>
|
||||
|
||||
</td>
|
||||
</tr></table>
|
||||
</div>
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
var handle = 0;
|
||||
|
||||
function escapestring(str)
|
||||
{
|
||||
str = JSON.stringify(String(str));
|
||||
str = str.substring(1, str.length - 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
$.get('progress.jim', {
|
||||
|
@ -27,7 +20,8 @@ $('[type="checkbox"]').iphoneStyle({
|
|||
|
||||
$('#progressbar').reportprogress(0);
|
||||
|
||||
$('#back').button().click(function() {
|
||||
$('#back').button({icons: {primary: "ui-icon-arrowreturnthick-1-w"}})
|
||||
.on('click', function() {
|
||||
window.location = '/go/browse?dir=' + $('#params').attr('dir');
|
||||
});
|
||||
|
||||
|
@ -44,10 +38,17 @@ $('#save').button({icons: {primary: "ui-icon-disk"}})
|
|||
.slideUp('slow');
|
||||
$('#originalbookmarks')
|
||||
.html($('#newbookmarks').clone());
|
||||
$('#esttime').hide();
|
||||
if ($('#results').html().indexOf(' successful') < 0) {
|
||||
$('#saveit').hide();
|
||||
$('#saveitlabel').hide();
|
||||
$('#save').show();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#cropit').button().click(function() {
|
||||
$('#cropit').button({icons: {primary: "ui-icon-scissors"}})
|
||||
.on('click', function() {
|
||||
$('#cropdiv').hide('slow');
|
||||
$('#progressdiv').show('slow');
|
||||
$('#back').hide();
|
||||
|
@ -56,7 +57,7 @@ $('#cropit').button().click(function() {
|
|||
.load('execute.jim', {
|
||||
'file': $('#params').attr('file'),
|
||||
'invert': $('#invert').attr('invert')
|
||||
}, function() {
|
||||
}, function() {
|
||||
clearInterval(handle);
|
||||
handle = 0;
|
||||
$('#back,#save').show();
|
||||
|
@ -73,10 +74,10 @@ $('#cropit').button().click(function() {
|
|||
});
|
||||
});
|
||||
|
||||
$('#invert').button().on('click', function() {
|
||||
window.location = 'crop.jim?file=' +
|
||||
escapestring($('#params').attr('file')) +
|
||||
'&invert=' + ($(this).attr('invert') == '1' ? '0' : '1');
|
||||
$('#invert').button({icons: {primary: "ui-icon-shuffle"}})
|
||||
.on('click', function() {
|
||||
window.location = window.location.href.replace(/&invert=[01]/,'') +
|
||||
'&invert=' + ($(this).attr('invert') == '1' ? '0' : '1');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -11,3 +11,8 @@ div.sliderlabel
|
|||
line-height: 40px;
|
||||
}
|
||||
|
||||
#cutplan {
|
||||
/* ensure cut plan segments are aligned left */
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ puts "{"
|
|||
puts "\"title\" : \"[jescape [$ts get title]]\","
|
||||
puts "\"synopsis\" : \"[jescape [$ts get synopsis]]\","
|
||||
puts "\"guidance\" : \"[jescape [$ts get guidance]]\","
|
||||
puts "\"genre\" : [jescape [$ts genrenib]]"
|
||||
puts "\"genre\" : [jescape [$ts genrenib]],"
|
||||
puts "\"seriesnum\" : [jescape [$ts get seriesnum]],"
|
||||
puts "\"episodenum\" : [jescape [$ts get episodenum]],"
|
||||
puts "\"episodetot\" : [jescape [$ts get episodetot]]"
|
||||
puts "}"
|
||||
|
||||
|
|
|
@ -58,6 +58,10 @@ proc icon {img {hover ""} {extra ""} {class "va"}} {
|
|||
puts ">"
|
||||
}
|
||||
|
||||
proc nbsp {str} {
|
||||
return [string map {" " } $str]
|
||||
}
|
||||
|
||||
proc directory {file bfile tbfile} {
|
||||
puts "<div class=\"va relative\">"
|
||||
set img "/images/711_1_09_Media_Folder.png"
|
||||
|
@ -69,7 +73,7 @@ proc directory {file bfile tbfile} {
|
|||
puts "<a class=dbf
|
||||
href=\"$::env(SCRIPT_NAME)?dir=[cgi_quote_url $file]\"
|
||||
file=\"[cgi_quote_html $file]\">"
|
||||
puts "$bfile</a><span class=filesize id=\"$tbfile\">
|
||||
puts "[nbsp $bfile]</a><span class=filesize id=\"ID$tbfile\">
|
||||
</span>"
|
||||
|
||||
lassign [dir iconset $file] icons attrs
|
||||
|
@ -106,13 +110,12 @@ proc entry {file} {{i 0}} {
|
|||
global dircount filecount dinuse
|
||||
|
||||
set bfile [file tail $file]
|
||||
regsub -all " +" $bfile "" tbfile
|
||||
if {[string index $bfile 0] == "\025"} {
|
||||
set bfile [string range $bfile 1 end]
|
||||
}
|
||||
if {[file isdirectory "$file"]} {
|
||||
incr dircount
|
||||
directory $file $bfile $tbfile
|
||||
directory $file $bfile [b64uencode [jsescape $bfile]]
|
||||
return
|
||||
}
|
||||
set ext [string tolower [file extension $file]]
|
||||
|
@ -174,7 +177,7 @@ proc entry {file} {{i 0}} {
|
|||
<input class=\"$fscl\" type=checkbox>
|
||||
<a class=bf title=\"$synopsis\"
|
||||
file=\"[cgi_quote_html $file]\" type=$type href=#>
|
||||
$bfile
|
||||
[nbsp $bfile]
|
||||
</a>
|
||||
"
|
||||
|
||||
|
@ -362,7 +365,7 @@ foreach sl $sortlist {
|
|||
|
||||
set tag " (current)"
|
||||
if {$order != $index} {
|
||||
set qs [regsub -all {&order=[[[:digit:]]+} $env(QUERY_STRING) ""]
|
||||
set qs [regsub -all {&order=[[:digit:]]+} $env(QUERY_STRING) ""]
|
||||
puts "<a href=\"$env(SCRIPT_NAME)?$qs&order=$index\" title=\"$tt\">"
|
||||
set tag ""
|
||||
set ket "a"
|
||||
|
|
|
@ -26,16 +26,59 @@ if {[file isdirectory $file]} {
|
|||
set new [string map {"\n" ""} [
|
||||
string trim [cgi_get "rename_$attr"]]]
|
||||
set old [$ts get $attr]
|
||||
if {$attr eq "title" || $attr eq "synopsis"} {
|
||||
set new "\025$new"
|
||||
} elseif {$attr eq "genre"} {
|
||||
set new [ts genre $new]
|
||||
}
|
||||
if {$new ne $old} {
|
||||
if {$attr eq "guidance" ||
|
||||
[string length $new] > 0} {
|
||||
if {$attr eq "guidance" || $new ne ""} {
|
||||
$ts set$attr $new
|
||||
}
|
||||
}
|
||||
} msg]} {
|
||||
puts "$attr: $msg"
|
||||
stderr puts "$attr: $msg"
|
||||
}
|
||||
}
|
||||
# deal with series number/ep num/ep total, which get set together
|
||||
# list the old values seen in case a later one is changed
|
||||
set epdataold {}
|
||||
# list values to be set, or {}
|
||||
set epdatanew {}
|
||||
foreach attr {seriesnum episodenum episodetot} {
|
||||
if {[catch {
|
||||
set new [string map {"\n" ""} [
|
||||
string trim [cgi_get "rename_$attr"]]]
|
||||
set old [$ts get $attr]
|
||||
if {$new ne $old} {
|
||||
switch $attr {
|
||||
seriesnum {
|
||||
set epdatanew [list $new]
|
||||
}
|
||||
episodenum -
|
||||
episodetot {
|
||||
if {$epdatanew eq {}} {
|
||||
set epdatanew $epdataold
|
||||
}
|
||||
lappend epdatanew $new
|
||||
}
|
||||
}
|
||||
} elseif {$epdatanew eq {}} {
|
||||
# nothing to be changed yet
|
||||
lappend epdataold $old
|
||||
} else {
|
||||
# fill to-be-set list with old value
|
||||
lappend epdatanew $old
|
||||
}
|
||||
} msg]} {
|
||||
stderr puts "$attr: $msg"
|
||||
}
|
||||
}
|
||||
if {$epdatanew ne {}} {
|
||||
if {[catch {$ts storeepisode $epdatanew} msg]} {
|
||||
puts "ts::storeepisode: $msg"
|
||||
}
|
||||
}
|
||||
|
||||
if {"$dir/$newfile.ts" ne "$file"} { ts renamegroup $file $newfile }
|
||||
} else {
|
||||
|
|
|
@ -10,6 +10,18 @@ var plugins = {
|
|||
dmenu_prepare: {}
|
||||
};
|
||||
|
||||
// pattern matches directory path prefix
|
||||
var pathre = /.*\/|\.[^.]*$/g;
|
||||
|
||||
// IDs of size, img elements for folders use RFC4648 s5 encoding of name
|
||||
function folderID(folder)
|
||||
{
|
||||
return btoa(escape(folder))
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=/g, '');
|
||||
}
|
||||
|
||||
function blockpage(msg)
|
||||
{
|
||||
if (!msg)
|
||||
|
@ -105,23 +117,21 @@ function epginfo_callback(data, status, xhr)
|
|||
$('#rename_synopsis').val(data.synopsis);
|
||||
$('#rename_guidance').val(data.guidance);
|
||||
$('#rename_genre').val(data.genre);
|
||||
$('#rename_seriesnum').val(data.seriesnum);
|
||||
$('#rename_episodenum').val(data.episodenum);
|
||||
$('#rename_episodetot').val(data.episodetot);
|
||||
|
||||
$('tr.tstype').show('slow');
|
||||
}
|
||||
|
||||
function insert_folder_size(folder, size)
|
||||
{
|
||||
folder = folder.replace(/ /g, '');
|
||||
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
|
||||
// folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
|
||||
size += (size.search(/\d$/) == -1 ? 'iB' : ' bytes');
|
||||
folder = folderID(folder);
|
||||
//console.log("Folder: (%s) = (%s)", folder, size);
|
||||
if (size.search(/\d$/) == -1)
|
||||
size += 'iB';
|
||||
else
|
||||
size += ' bytes';
|
||||
if (folder == "")
|
||||
$('#dirsize').text(' (' + size + ')');
|
||||
else
|
||||
$('#' + folder).text(' (' + size + ')');
|
||||
$(folder == "" ? '#dirsize' : '#ID' + folder)
|
||||
.text(' (' + size + ')');
|
||||
}
|
||||
|
||||
function folder_size_callback(data, status, xhr)
|
||||
|
@ -133,11 +143,9 @@ function folder_size_callback(data, status, xhr)
|
|||
|
||||
function set_folder_new(folder, cnt)
|
||||
{
|
||||
folder = folder.replace(/ /g, '');
|
||||
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
|
||||
//console.log("Folder: (%s) = (%s)", folder, cnt);
|
||||
left = cnt > 99 ? 11 : (cnt > 9 ? 14 : 17);
|
||||
$('#img' + folder)
|
||||
$('#img' + folderID(folder))
|
||||
.attr('src', '/img/Folder_New.png')
|
||||
.next('span.foldernum')
|
||||
.css('left', left + 'px')
|
||||
|
@ -156,10 +164,8 @@ function new_folder_callback(data, status, xhr)
|
|||
|
||||
function set_folder__(folder)
|
||||
{
|
||||
folder = folder.replace(/ /g, '');
|
||||
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
|
||||
//console.log("Folder: (%s)", folder);
|
||||
$('#img' + folder + ' ~ span.folderu').show();
|
||||
$('#img' + folderID(folder) + ' ~ span.folderu').show();
|
||||
}
|
||||
|
||||
function __folder_callback(data, status, xhr)
|
||||
|
@ -256,7 +262,7 @@ var $confirm; // Populated after DOM is loaded.
|
|||
|
||||
function confirm_action(action, callback, file, type, id)
|
||||
{
|
||||
var bfile = file.replace(/.*\/|\.[^.]*$/g, '');
|
||||
var bfile = file.replace(pathre, '');
|
||||
$confirm.dialog('option', 'buttons', {
|
||||
'Yes': function() { $(this).dialog('close');
|
||||
callback(file, type, id); },
|
||||
|
@ -429,7 +435,7 @@ var menuclick = function(action, el, pos)
|
|||
{
|
||||
var file = $(el).parent().prevAll('a.bf').last().attr('file');
|
||||
var efile = encodeURIComponent(file);
|
||||
var bfile = file.replace(/.*\/|\.[^.]*$/g, '');
|
||||
var bfile = file.replace(pathre, '');
|
||||
bfile = bfile.replace(/[\x00-\x1f]+/g, '');
|
||||
var type = $(el).attr('type');
|
||||
var id = $(el).attr('did');
|
||||
|
|
|
@ -30,3 +30,8 @@ img.qb
|
|||
color: #ff4000;
|
||||
}
|
||||
|
||||
input.uint8_t
|
||||
{
|
||||
width: 6ch;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ foreach arg $argv {
|
|||
lappend dirs $arg
|
||||
}
|
||||
}
|
||||
if {![llength $dirs]} { lappend dirs [exec pwd] }
|
||||
if {![llength $dirs]} { lappend dirs [pwd] }
|
||||
|
||||
foreach dir $dirs {
|
||||
if {[string index $dir end] eq "/"} {
|
||||
|
|
|
@ -46,12 +46,16 @@ There are no tasks in the queue.
|
|||
</tbody>
|
||||
</table>
|
||||
<div class=buttonbar>
|
||||
<button id=selcomplete class=needsdata>Select Completed</button>
|
||||
<button id=selfailed class=needsdata>Select Failed</button>
|
||||
<button id=selpending class=needsdata>Select Pending</button>
|
||||
<button id=selall class=needsdata>Select All</button>
|
||||
<button id=selnone class=needsdata>Select None</button>
|
||||
</div>
|
||||
<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 class=refresh id=refresh>Refresh</button>
|
||||
<span class=isloading><img src=/img/spin.gif></span>
|
||||
</div>
|
||||
|
|
|
@ -40,7 +40,8 @@ function load()
|
|||
$('<td>').append($('<a>', {
|
||||
'class': 'file',
|
||||
href: '#',
|
||||
html: v.file
|
||||
html: v.file,
|
||||
title: v.file
|
||||
})).appendTo($row);
|
||||
$('<td>', { html: v.action + ' ' + v.args })
|
||||
.appendTo($row);
|
||||
|
@ -162,6 +163,18 @@ $('#selall').button({icons:{primary:"ui-icon-star"}})
|
|||
$('#queuetab input:checkbox').prop('checked', true).trigger('change');
|
||||
});
|
||||
|
||||
$('#selpending').button({icons:{primary:"ui-icon-check"}})
|
||||
.on('click', function() {
|
||||
$('#queuetab input:checkbox[status="PENDING"]').prop('checked', true)
|
||||
.trigger('change');
|
||||
});
|
||||
|
||||
$('#selfailed').button({icons:{primary:"ui-icon-check"}})
|
||||
.on('click', function() {
|
||||
$('#queuetab input:checkbox[status="FAILED"]').prop('checked', true)
|
||||
.trigger('change');
|
||||
});
|
||||
|
||||
$('#selcomplete').button({icons:{primary:"ui-icon-check"}})
|
||||
.on('click', function() {
|
||||
$('#queuetab input:checkbox[status="COMPLETE"]').prop('checked', true)
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
/* constrain File column width */
|
||||
td:nth-child(3), th:nth-child(3)
|
||||
{
|
||||
max-width: 50ch;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
td.status
|
||||
{
|
||||
|
|
|
@ -9,6 +9,11 @@ lassign [system diskspace 1] size used perc free fperc tsrbuf tsrused
|
|||
set tsrreserve $($tsrbuf - $tsrused)
|
||||
# Adjust values to account for the TSR reserve
|
||||
set free $($free - $tsrreserve)
|
||||
# In case the reserve has been over-committed
|
||||
if {$free < 0} {
|
||||
# avoid displaying negative free, or used > available
|
||||
set free 0
|
||||
}
|
||||
set used $($size - $free)
|
||||
|
||||
set dbs 0
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
img/fav/favicon.ico
|
Before Width: | Height: | Size: 19 B After Width: | Height: | Size: 10 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 B After Width: | Height: | Size: 10 KiB |
|
@ -28,6 +28,7 @@ if {[cgi_get act] eq "cryptokey"} {
|
|||
|
||||
set pkgdev [$settings pkgdev]
|
||||
set rtschedule [$settings rtschedule]
|
||||
set noautoremove [$settings noautoremove]
|
||||
set logsize [$settings logsize]
|
||||
set logkeep [$settings logkeep]
|
||||
set logage [$settings logage]
|
||||
|
@ -44,6 +45,7 @@ if {![catch {set ck_fd [open "/mod/boot/cryptokey"]}]} {
|
|||
|
||||
handle_int_update pkgdev $pkgdev "Development Package Display"
|
||||
handle_int_update rtschedule $rtschedule "Real-time scheduling"
|
||||
handle_int_update noautoremove $noautoremove "Package auto-remove"
|
||||
handle_int_update logsize $logsize "Log rotation size"
|
||||
handle_int_update logkeep $logkeep "Logs to keep"
|
||||
handle_int_update logage $logage "Rotated log max age"
|
||||
|
|
|
@ -16,6 +16,9 @@ if {[system nuggeted]} {
|
|||
setting_toggle "Real-time scheduling?" "rtschedule" $rtschedule
|
||||
}
|
||||
|
||||
setting_toggle "Automatically remove unneeded dependent packages?" \
|
||||
"noautoremove" $(!$noautoremove) 1
|
||||
|
||||
puts -nonewline "
|
||||
<tr>
|
||||
<form class=auto id=logsize method=get action=$env(SCRIPT_NAME)>
|
||||
|
|
|
@ -263,6 +263,15 @@ foreach e $records {
|
|||
|
||||
if {$es < $le} continue
|
||||
|
||||
set perc [$e percent]
|
||||
set showing 0
|
||||
if {$perc > 0 && $perc < 100} { set showing 1 }
|
||||
|
||||
set txt [list [cgi_quote_html [$e get name]] "([\
|
||||
clock format $es -format "%H:%M"] - [\
|
||||
clock format $ee -format "%H:%M"])[\
|
||||
expr {$showing ? " ($perc%)" : ""}]"]
|
||||
|
||||
if {$es < $stt} { set es $stt }
|
||||
if {$ee > $ett} { set ee $ett }
|
||||
|
||||
|
@ -292,21 +301,6 @@ foreach e $records {
|
|||
set recopts 1
|
||||
if {[$e get series_crid] ne ""} { set recopts 2 }
|
||||
|
||||
set perc [$e percent]
|
||||
set showing 0
|
||||
if {$perc > 0 && $perc < 100} { set showing 1 }
|
||||
|
||||
set txt "[cgi_quote_html [$e get name]] <span>([\
|
||||
clock format $es -format "%H:%M"] - [\
|
||||
clock format $ee -format "%H:%M"])"
|
||||
if {$showing} { append txt " ($perc%)" }
|
||||
append txt "</span>"
|
||||
|
||||
set htxt "[cgi_quote_html [$e get name]] ([\
|
||||
clock format $es -format "%H:%M"] - [\
|
||||
clock format $ee -format "%H:%M"])"
|
||||
if {$showing} { append hxt " ($perc%)" }
|
||||
|
||||
set lbg $bg
|
||||
# Set backround if scheduled. 1 1-off, 2 series, 3 recorded, 4 skipped
|
||||
switch -- [$e scheduled] {
|
||||
|
@ -318,11 +312,11 @@ foreach e $records {
|
|||
}
|
||||
|
||||
puts "<div class=\"xeprog $lbg\"
|
||||
style=\"width: [expr $px - 4]px;\" title=\"$htxt\">
|
||||
style=\"width: [expr $px - 4]px;\" title=\"[join $txt]\">
|
||||
<a class=event href=# xs=[$e get service_id]
|
||||
xe=[$e get event_id] sch=[$e get sched_type]
|
||||
rec=$recopts>"
|
||||
puts $txt
|
||||
puts [format "%s <span>%s</span>" {*}$txt]
|
||||
puts "</a>"
|
||||
puts "</div>"
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ div.xeprog
|
|||
float: left;
|
||||
vertical-align: middle;
|
||||
height: 25px;
|
||||
padding: 4px 0 3px 2px;
|
||||
padding: 4px 0 3px 0px;
|
||||
margin: 3px 0 3px 2px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 10px;
|
||||
|
|
|
@ -94,6 +94,13 @@ proc ::decrypt::dequeue {q ts} {
|
|||
::auto::startclock
|
||||
log " DECRYPT: $rfile" 0
|
||||
|
||||
if {$mode eq "dlna"} {
|
||||
if {[$ts getkey $mode] eq ""} {
|
||||
::auto::log "system key doesn't match, trying direct"
|
||||
set mode direct
|
||||
}
|
||||
}
|
||||
|
||||
if {$mode eq "dlna"} {
|
||||
log " DLNA: $url" 0
|
||||
if {[catch {exec wget -O "$tmp/$bfile" $url} msg opts]} {
|
||||
|
@ -104,24 +111,12 @@ proc ::decrypt::dequeue {q ts} {
|
|||
if {$helper} { system dlnahelper -release }
|
||||
} else {
|
||||
log " Direct decryption" 0
|
||||
set keys {}
|
||||
if {![catch {set fd [open "/mod/boot/cryptokey"]}]} {
|
||||
set bytes [$fd read 16]
|
||||
$fd close
|
||||
binary scan $bytes H* key
|
||||
if {[string length $key] == 32} {
|
||||
lappend keys $key
|
||||
}
|
||||
}
|
||||
lappend keys [string range [system nugget cryptokey -key] 0 31]
|
||||
lappend keys [system encryptionkey]
|
||||
foreach key $keys {
|
||||
::auto::log "Testing key ($key)" 2
|
||||
if {[catch {
|
||||
set ret [exec /mod/bin/stripts -q/ $key $rfile]
|
||||
}]} continue
|
||||
if {$ret eq "1"} break
|
||||
|
||||
set key [$ts getkey $mode]
|
||||
if {$key eq ""} {
|
||||
return {"FAILED" "No matching key for decryption"}
|
||||
}
|
||||
|
||||
::auto::log "Using key ($key)" 2
|
||||
if {[catch {exec /mod/bin/stripts -@ $key $rfile "$tmp/[\
|
||||
file rootname $bfile]" } msg opts]} {
|
||||
|
|
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
|
||||
require system.class plugin
|
||||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -command class]} { package require oo }
|
||||
class dir {}
|
||||
class browse {}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -command class]} { package require oo }
|
||||
|
||||
class clipboard {
|
||||
path "/tmp/webif.cb"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
source /mod/webif/lib/setup
|
||||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
|
||||
require settings.class progressbar rsv.class mwildcard svc.class
|
||||
|
||||
|
@ -482,7 +482,7 @@ proc {epg dbfetch} {mode args} {
|
|||
append q "and (e.start is null or
|
||||
(e.start > $stt and e.start < $ett) or
|
||||
(e.end > $stt and e.end < $ett) or
|
||||
(e.start < $stt and e.end > $stt)
|
||||
(e.start <= $stt and e.end >= $ett)
|
||||
) "
|
||||
}
|
||||
-fav {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -command class]} { package require oo }
|
||||
|
||||
class pkg {
|
||||
name ""
|
||||
|
@ -128,7 +128,7 @@ pkg method loadraw {} {
|
|||
} else {
|
||||
set data [exec /bin/opkg info $name]
|
||||
}
|
||||
|
||||
|
||||
foreach line [split $data "\n"] {
|
||||
if {$tag ne "" && [string match { *} $line]} {
|
||||
append raw($tag) $line
|
||||
|
@ -237,7 +237,7 @@ proc {pkg fetchfile} {url} {
|
|||
#puts "Web Header: $line"
|
||||
set line [string trim [$f gets]]
|
||||
}
|
||||
|
||||
|
||||
# Save the body
|
||||
set ret [$f read]
|
||||
$f close
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
|
||||
class queue {
|
||||
id -1
|
||||
|
@ -53,77 +53,127 @@ proc {queue dbhandle} {args} {
|
|||
return $::queue::db
|
||||
}
|
||||
|
||||
if {![file exists /mod/etc/queue.db]} {
|
||||
set ::queue::db [sqlite3.open /mod/etc/queue.db]
|
||||
$::queue::db query {
|
||||
create table queue(
|
||||
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 default 0,
|
||||
last integer default 0
|
||||
);
|
||||
try {
|
||||
set db [sqlite3.open /mod/etc/queue.db]
|
||||
} on error {msg} {
|
||||
stderr puts $msg
|
||||
return 0
|
||||
}
|
||||
if {[catch {$db query { select count(*) from queue, config; }}]} {
|
||||
catch {$db {drop table queue}}
|
||||
catch {$db {drop table config}}
|
||||
try {
|
||||
$db query {
|
||||
create table queue(
|
||||
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 default 0,
|
||||
last integer default 0
|
||||
);
|
||||
}
|
||||
$db query {
|
||||
create table config(
|
||||
var text,
|
||||
val text
|
||||
);
|
||||
}
|
||||
$db query {
|
||||
insert into config values('version', 3);
|
||||
}
|
||||
$db query {
|
||||
create unique index file on queue(file, action);
|
||||
}
|
||||
} on error {msg opts} {
|
||||
stderr puts $msg
|
||||
catch {$db close}
|
||||
return 0
|
||||
}
|
||||
$::queue::db query {
|
||||
create table config(
|
||||
var text,
|
||||
val text
|
||||
);
|
||||
}
|
||||
$::queue::db query {
|
||||
insert into config values('version', 3);
|
||||
}
|
||||
$::queue::db query {
|
||||
create unique index file on queue(file, action);
|
||||
}
|
||||
} else {
|
||||
set ::queue::db [sqlite3.open /mod/etc/queue.db]
|
||||
}
|
||||
|
||||
return $::queue::db
|
||||
return [set ::queue::db $db]
|
||||
}
|
||||
|
||||
proc {queue dbquery} {query args} {
|
||||
set db [queue dbhandle]
|
||||
try {
|
||||
return [$db query $query {*}$args]
|
||||
} on error {msg opts} {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
proc {queue dbaction} {query args} {
|
||||
set db [queue dbhandle]
|
||||
try {
|
||||
$db query $query {*}$args
|
||||
return true
|
||||
} on error {msg opts} {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
proc {queue dbqueryl} {query_list {txn_mode ""}} {
|
||||
set db [queue dbhandle]
|
||||
try {
|
||||
if {$txn_mode ne ""} {
|
||||
if {$txn_mode ni { immediate exclusive }} {
|
||||
set txn_mode "deferred"
|
||||
}
|
||||
$db query "begin %s transaction" $txn_mode
|
||||
}
|
||||
foreach q $query_list {
|
||||
$db query {*}$q
|
||||
}
|
||||
if {$txn_mode ne ""} {
|
||||
$db query "commit transaction"
|
||||
}
|
||||
return true
|
||||
} on error {msg opts} {
|
||||
}
|
||||
if {$txn_mode ne ""} {
|
||||
catch { $db query "rollback transaction" }
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
proc {queue startup} {{days 7}} {
|
||||
if {$days == 0} { set days 7 }
|
||||
set db [queue dbhandle]
|
||||
$db query {
|
||||
return [queue dbqueryl { { {
|
||||
update queue
|
||||
set status = 'INTERRUPTED',
|
||||
log = 'Job will be retried automatically.',
|
||||
retries = retries + 1,
|
||||
interrupts = interrupts + 1
|
||||
where status = 'RUNNING'
|
||||
}
|
||||
$db query {
|
||||
} } { {
|
||||
update queue
|
||||
set status = 'FAILED',
|
||||
log = 'Too many interrupts.'
|
||||
where status = 'INTERRUPTED'
|
||||
and interrupts >= 5
|
||||
}
|
||||
$db query {
|
||||
} } { {
|
||||
update queue
|
||||
set status = 'PENDING'
|
||||
where status = 'DEFER'
|
||||
}
|
||||
$db query {
|
||||
} } { {
|
||||
delete from queue
|
||||
where status in ('COMPLETE', 'FAILED')
|
||||
and submitted < %s
|
||||
} [expr [clock seconds] - 86400 * $days]
|
||||
} } ]
|
||||
}
|
||||
|
||||
proc {queue fetch} {file action} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
foreach row [$db query {
|
||||
foreach row [queue dbquery {
|
||||
select * from queue
|
||||
where file = '%s'
|
||||
and action = '%s'
|
||||
|
@ -134,23 +184,23 @@ proc {queue fetch} {file action} {
|
|||
}
|
||||
|
||||
proc {queue insert} {args file action} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
set status "PENDING"
|
||||
if {"-hold" in $args} { set status "HOLD" }
|
||||
|
||||
set file [queue key $file]
|
||||
|
||||
$db query {
|
||||
if {[queue dbaction {
|
||||
insert or ignore into queue(submitted, file, action, status)
|
||||
values(%s, '%s', '%s', '%s')
|
||||
} [clock seconds] $file $action $status
|
||||
} [clock seconds] $file $action $status]} {
|
||||
|
||||
return [queue fetch $file $action]
|
||||
return [queue fetch $file $action]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
proc {queue delete} {file {action "*"}} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
set q "
|
||||
delete from queue
|
||||
|
@ -161,11 +211,10 @@ proc {queue delete} {file {action "*"}} {
|
|||
append q " and action = '%s'"
|
||||
}
|
||||
|
||||
$db query $q [queue key $file] $action
|
||||
return [queue dbaction $q [queue key $file] $action]
|
||||
}
|
||||
|
||||
proc {queue delete_by_id} {id} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
set q "
|
||||
delete from queue
|
||||
|
@ -173,11 +222,10 @@ proc {queue delete_by_id} {id} {
|
|||
and status != 'RUNNING'
|
||||
"
|
||||
|
||||
$db query $q $id
|
||||
return [queue dbaction $q $id]
|
||||
}
|
||||
|
||||
proc {queue resubmit} {id} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
set q "
|
||||
update queue
|
||||
|
@ -186,11 +234,10 @@ proc {queue resubmit} {id} {
|
|||
and status in ('FAILED', 'HOLD', 'COMPLETE')
|
||||
"
|
||||
|
||||
$db query $q $id
|
||||
return [queue dbaction $q $id]
|
||||
}
|
||||
|
||||
proc {queue hold} {id} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
set q "
|
||||
update queue
|
||||
|
@ -199,15 +246,13 @@ proc {queue hold} {id} {
|
|||
and status not in ('RUNNING', 'COMPLETE')
|
||||
"
|
||||
|
||||
$db query $q $id
|
||||
return [queue dbaction $q $id]
|
||||
}
|
||||
|
||||
proc {queue status} {file} {
|
||||
if {$file eq "0"} { return "" }
|
||||
|
||||
set db [queue dbhandle]
|
||||
|
||||
set ret [$db query {
|
||||
set ret [queue dbquery {
|
||||
select group_concat(action)
|
||||
from queue
|
||||
where file = '%s'
|
||||
|
@ -230,10 +275,9 @@ proc {queue check} {file {q "any"}} {
|
|||
}
|
||||
|
||||
proc {queue all} {} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
set ret {}
|
||||
foreach row [$db query {select * from queue order by id}] {
|
||||
foreach row [queue dbquery {select * from queue order by id}] {
|
||||
lappend ret [queue new $row]
|
||||
}
|
||||
return $ret
|
||||
|
@ -243,7 +287,7 @@ proc {queue pending} {} {
|
|||
set db [queue dbhandle]
|
||||
|
||||
set ret {}
|
||||
foreach row [$db query {
|
||||
foreach row [queue dbquery {
|
||||
select * from queue
|
||||
where status in ('PENDING', 'INTERRUPTED')
|
||||
and start < %s
|
||||
|
@ -259,23 +303,20 @@ proc {queue size} {} {
|
|||
}
|
||||
|
||||
proc {queue version} {} {
|
||||
set db [queue dbhandle]
|
||||
|
||||
set version 1
|
||||
catch {
|
||||
foreach row [$db query {
|
||||
foreach row [queue dbquery {
|
||||
select val from config
|
||||
where var = 'version'
|
||||
}] {
|
||||
lassign $row x version
|
||||
}
|
||||
lassign $row x version
|
||||
}
|
||||
return $version
|
||||
}
|
||||
|
||||
queue method update {_status {_log ""} {_retries 0} {_runtime 0}} {
|
||||
set db [queue dbhandle]
|
||||
$db query {
|
||||
|
||||
if {[queue dbaction {
|
||||
update queue
|
||||
set status = '%s',
|
||||
log = '%s',
|
||||
|
@ -283,22 +324,27 @@ queue method update {_status {_log ""} {_retries 0} {_runtime 0}} {
|
|||
runtime = %s,
|
||||
last = %s
|
||||
where id = %s
|
||||
} $_status $_log $_retries $_runtime [clock seconds] $id
|
||||
} $_status $_log $_retries $_runtime [clock seconds] $id]} {
|
||||
|
||||
set status $_status
|
||||
set log $_log
|
||||
incr retries $_retries
|
||||
set runtime $_runtime
|
||||
set status $_status
|
||||
set log $_log
|
||||
incr retries $_retries
|
||||
set runtime $_runtime
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
queue method set {var val} {
|
||||
set db [queue dbhandle]
|
||||
$db query {
|
||||
|
||||
if {[queue dbaction {
|
||||
update queue
|
||||
set %s = '%s'
|
||||
where id = %s
|
||||
} $var $val $id
|
||||
set $var $val
|
||||
} $var $val $id]} {
|
||||
set $var $val
|
||||
}
|
||||
return $var
|
||||
}
|
||||
|
||||
queue method submit {{_start 0}} {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
source /mod/webif/lib/setup
|
||||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -proc binary]} { package require binary }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command binary]} { package require binary }
|
||||
require settings.class system.class plugin svc.class
|
||||
|
||||
set binaryfields aulEventToRecordInfo
|
||||
|
@ -970,6 +970,7 @@ proc {rsv construct} {event type} {
|
|||
set now [clock seconds]
|
||||
set progs [lmap i [\
|
||||
epg dbfetch dump -scrid [$event get series_crid] \
|
||||
-service [$event get service_id] \
|
||||
-sort start] {
|
||||
if {[set ecrid [$i get event_crid]] eq ""} continue
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
|
||||
if {![file exists /mod/etc/webif.db]} {
|
||||
set ::settingsdb [sqlite3.open /mod/etc/webif.db]
|
||||
|
@ -52,6 +52,29 @@ class settings {
|
|||
logkeep 2
|
||||
logage 0
|
||||
rtschedule 0
|
||||
noautoremove 0
|
||||
}
|
||||
|
||||
proc {settings _safer_query} { queryText args } {
|
||||
global settingsdb
|
||||
|
||||
# allow 4 tries from 0.5s delay, doubling, to get access
|
||||
for {set lockCnt 4; set delay 0.5} {true} {sleep $delay; set delay $(2*$delay)} {
|
||||
try {
|
||||
return [$settingsdb query $queryText {*}$args]
|
||||
} on error {msg opts} {
|
||||
if {[string first "database is locked" $msg] >= 0} {
|
||||
if {[incr lockCnt -1] > 0} {
|
||||
continue
|
||||
} else {
|
||||
# raise error from caller
|
||||
set msg "Persistently unable to access Settings: database locked"
|
||||
incr opts(-level)
|
||||
}
|
||||
}
|
||||
return {*}$opts $msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings method hostname {{name ""}} {
|
||||
|
@ -104,11 +127,10 @@ settings method smtp_server {{server ""}} {
|
|||
}
|
||||
|
||||
settings method _nval_setting {name {val -1}} {
|
||||
global settingsdb
|
||||
|
||||
if {$val == -1} {
|
||||
# Get
|
||||
set res [$settingsdb query "
|
||||
set res [settings _safer_query "
|
||||
select nval from settings
|
||||
where name = '$name'
|
||||
"]
|
||||
|
@ -118,7 +140,7 @@ settings method _nval_setting {name {val -1}} {
|
|||
return 0
|
||||
} else {
|
||||
# Set
|
||||
$settingsdb query "
|
||||
settings _safer_query "
|
||||
replace into settings(name,nval)
|
||||
values('$name', $val)
|
||||
"
|
||||
|
@ -127,11 +149,10 @@ settings method _nval_setting {name {val -1}} {
|
|||
}
|
||||
|
||||
settings method _tval_setting {name {val -1} {def 0}} {
|
||||
global settingsdb
|
||||
|
||||
if {$val eq "-1"} {
|
||||
# Get
|
||||
set res [$settingsdb query "
|
||||
set res [settings _safer_query "
|
||||
select tval from settings
|
||||
where name = '$name'
|
||||
"]
|
||||
|
@ -141,7 +162,7 @@ settings method _tval_setting {name {val -1} {def 0}} {
|
|||
return $def
|
||||
} else {
|
||||
# Set
|
||||
$settingsdb query "
|
||||
settings _safer_query "
|
||||
replace into settings(name,tval)
|
||||
values('$name', '%s')
|
||||
" $val
|
||||
|
@ -237,6 +258,10 @@ settings method rtschedule {{val -1}} {
|
|||
return [$self _nval_setting rtschedule $val]
|
||||
}
|
||||
|
||||
settings method noautoremove {{val -1}} {
|
||||
return [$self _nval_setting noautoremove $val]
|
||||
}
|
||||
|
||||
settings method sortorder {{val -1}} {
|
||||
return [$self _nval_setting sortorder $val]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
source /mod/webif/lib/setup
|
||||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
require system.class
|
||||
|
||||
class svc {
|
||||
|
|
|
@ -3,9 +3,9 @@ source /mod/webif/lib/setup
|
|||
|
||||
package require xconv
|
||||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -proc binary]} { package require binary }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command binary]} { package require binary }
|
||||
|
||||
class system {}
|
||||
|
||||
|
@ -309,7 +309,7 @@ proc {system dlnaurl} {file {urlbase ""}} {
|
|||
return $ret
|
||||
}
|
||||
|
||||
proc {system dlnahelper} {file {urlbase ""}} {
|
||||
proc {system dlnahelper} {file {urlbase "127.0.0.1"}} {
|
||||
set dir /mnt/hd2/mod/.dlnahelper
|
||||
require lock
|
||||
|
||||
|
@ -398,6 +398,22 @@ proc {system disktemp} {} {
|
|||
return $($temp + 0)
|
||||
}
|
||||
|
||||
proc {system tsrdir} {} {
|
||||
switch [system model] {
|
||||
HDR {
|
||||
set tsrdir "/mnt/hd2/Tsr"
|
||||
}
|
||||
HD {
|
||||
set tsrdir "/media/drive1/.tsr"
|
||||
}
|
||||
}
|
||||
return $tsrdir
|
||||
}
|
||||
|
||||
proc {system tsr} {} {
|
||||
return [file join [system tsrdir] "0.ts"]
|
||||
}
|
||||
|
||||
require pretty_size
|
||||
|
||||
proc {system diskspace} {{raw 0}} {
|
||||
|
@ -412,13 +428,12 @@ proc {system diskspace} {{raw 0}} {
|
|||
set perc $($used * 100 / $size)
|
||||
set fperc $(100 - $perc)
|
||||
|
||||
set tsrdir [system tsrdir]
|
||||
switch [system model] {
|
||||
HDR {
|
||||
set tsrdir "/mnt/hd2/Tsr"
|
||||
set tsrok [file isdirectory $tsrdir]
|
||||
}
|
||||
HD {
|
||||
set tsrdir "/media/drive1/.tsr"
|
||||
set tsrok [file exists "$tsrdir/0.ts"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,11 @@ foreach {sample expected} {
|
|||
{(S8, Ep2)} {S8E2/0}
|
||||
{(S4 Ep22/24)} {S4E22/24}
|
||||
{23/27.} {S0E23/27}
|
||||
{Part 5/10} {S0E5/10}
|
||||
{Pt. 5/10} {S0E5/10}
|
||||
{Part 5 of 10} {S0E5/10}
|
||||
{Pt. 5 of10} {S0E5/10}
|
||||
{Pt5} {S0E5/0}
|
||||
} {
|
||||
set ts [ts new "synopsis {$sample}"]
|
||||
$ts episode_name
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc pack]} { package require pack }
|
||||
if {![exists -proc xconv]} { package require xconv }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command pack]} { package require pack }
|
||||
if {![exists -command xconv]} { package require xconv }
|
||||
if {![exists -command binary]} { package require binary }
|
||||
|
||||
source /mod/webif/lib/setup
|
||||
require system.class tvdb.class classdump
|
||||
|
||||
|
@ -296,21 +298,21 @@ ts method copy {dst} {
|
|||
}
|
||||
|
||||
ts method settitle {newtitle} {
|
||||
if {[string length newtitle] > 48} { return }
|
||||
if {[string length $newtitle] > 48} { return }
|
||||
|
||||
exec /mod/bin/hmt "+settitle=${newtitle}" $file
|
||||
set title $newtitle
|
||||
}
|
||||
|
||||
ts method setsynopsis {newsynopsis} {
|
||||
if {[string length newsynopsis] > 252} { return }
|
||||
if {[string length $newsynopsis] > 252} { return }
|
||||
|
||||
exec /mod/bin/hmt "+setsynopsis=${newsynopsis}" $file
|
||||
set synopsis $newsynopsis
|
||||
}
|
||||
|
||||
ts method setguidance {newguidance} {
|
||||
if {[string length newguidance] > 48} { return }
|
||||
if {[string length $newguidance] > 74} { return }
|
||||
|
||||
if {$newguidance eq ""} {
|
||||
exec /mod/bin/hmt "-guidance" $file
|
||||
|
@ -320,10 +322,18 @@ ts method setguidance {newguidance} {
|
|||
set guidance $newguidance
|
||||
}
|
||||
|
||||
ts method setgenre {newgenre} {
|
||||
if {$newgenre <= 15} {
|
||||
set newgenre $($newgenre << 4)
|
||||
proc {ts genre} {genre} {
|
||||
if {![string is integer $genre] || $genre < 0} {
|
||||
set genre 0
|
||||
}
|
||||
if {$genre <= 15} {
|
||||
set genre $($genre << 4)
|
||||
}
|
||||
return $genre
|
||||
}
|
||||
|
||||
ts method setgenre {newgenre} {
|
||||
set newgenre [ts genre $newgenre]
|
||||
exec /mod/bin/hmt "+setgenre=-${newgenre}" $file
|
||||
set genre $newgenre
|
||||
}
|
||||
|
@ -354,13 +364,14 @@ ts method mkbmps {{offset 0}} {
|
|||
|
||||
ts method mkbmp {{offset 0} {ext ""}} {
|
||||
set bfile [file rootname $file]
|
||||
set bmpfile "$bfile$ext.bmp"
|
||||
set cmd [list /mod/bin/ffmpeg -loglevel fatal -ss $offset -i $file \
|
||||
-frames 1 -pix_fmt argb -vf vflip -s 140x78 "$bfile$ext.bmp"]
|
||||
if {[catch { exec {*}$cmd } msg]} {
|
||||
puts "ERROR: $msg"
|
||||
return 0
|
||||
-frames 1 -pix_fmt argb -vf vflip -s 140x78 -y $bmpfile]
|
||||
catch { exec {*}$cmd }
|
||||
if {![catch { file stat $bmpfile stbmp }]} {
|
||||
if {[dict get $stbmp size] != 0} { return 1 }
|
||||
}
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
ts method mkthm {{offset 0}} {
|
||||
|
@ -536,7 +547,7 @@ proc {ts resetnew} {dir} {
|
|||
#hexdump $bytes
|
||||
#puts "Calculated: $watched/$tot"
|
||||
|
||||
pack bytes $tot -intle 32 0
|
||||
pack bytes $tot -intle 32 0
|
||||
pack bytes $watched -intle 32 32
|
||||
|
||||
#hexdump $bytes
|
||||
|
@ -696,6 +707,14 @@ ts method extract_numbers {} {
|
|||
regexp -nocase -- {S\.*(\d+),?\s*Ep\.?\s*(\d+)(/(\d+))?} $synopsis \
|
||||
x seriesnum episodenum x episodetot
|
||||
|
||||
# (Part 5/10)
|
||||
# (Pt. 5/10)
|
||||
# (Part 5 of 10)
|
||||
# (Pt. 5 of 10)
|
||||
# (Pt5)
|
||||
regexp -nocase -- {P(art|t\.?)\s*(\d+)\s*(of|/)?\s*(\d+)?} $synopsis \
|
||||
x x episodenum x episodetot
|
||||
|
||||
foreach v {seriesnum episodenum episodetot} {
|
||||
if {[set $v] eq ""} {
|
||||
set $v 0
|
||||
|
@ -764,7 +783,7 @@ ts method episode_name {} {
|
|||
incr flag
|
||||
}
|
||||
if {$flag} { $self storeepisode }
|
||||
|
||||
|
||||
return $tvdb_data(name)
|
||||
}
|
||||
|
||||
|
@ -806,7 +825,8 @@ ts method tsr {} {
|
|||
}
|
||||
|
||||
ts method genrenib {} {
|
||||
return $($genre >> 4)
|
||||
if {[catch {set v $($genre >> 4)}]} { set v 0 }
|
||||
return $v
|
||||
}
|
||||
|
||||
ts method genre_info {} {
|
||||
|
@ -829,3 +849,58 @@ proc {ts genrelist} {} {
|
|||
return $glist
|
||||
}
|
||||
|
||||
# return the key that will decrypt the file in the mode, or nothing
|
||||
ts method getkey {mode} {
|
||||
# mode: dlna (active key), direct
|
||||
|
||||
set rfile [file rootname $file]
|
||||
|
||||
set keys {}
|
||||
# the active key
|
||||
set key [string range [system nugget cryptokey -key] 0 31]
|
||||
if {$key ne ""} {
|
||||
lappend keys $key
|
||||
}
|
||||
if { $mode ne "dlna" } {
|
||||
# also try other keys, such as this - same as active?
|
||||
try {
|
||||
set fd [open "/mod/boot/cryptokey"]
|
||||
set bytes [$fd read 16]
|
||||
binary scan $bytes H* key
|
||||
if {[string length $key] == 32} {
|
||||
ladd keys $key
|
||||
}
|
||||
} on error {} {
|
||||
} finally {
|
||||
catch {$fd close}
|
||||
}
|
||||
|
||||
# the native key
|
||||
if {![catch {set key [system encryptionkey]}]} {
|
||||
ladd keys $key
|
||||
}
|
||||
|
||||
# support a file listing other keys in hex, one-per-line
|
||||
# eg, for recordings imported from a broken box
|
||||
try {
|
||||
set fd [open "/mod/etc/keys" r]
|
||||
foreach key [split [$fd read -nonewline] "\n"] {
|
||||
ladd keys $key
|
||||
}
|
||||
} on error {} {
|
||||
} finally {
|
||||
catch {$fd close}
|
||||
}
|
||||
}
|
||||
|
||||
foreach key $keys {
|
||||
if {[catch {
|
||||
set ret [exec /mod/bin/stripts -q/ $key $rfile]
|
||||
}]} continue
|
||||
if {$ret eq "1"} {
|
||||
return $key
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
source /mod/webif/lib/setup
|
||||
|
||||
package require cgi
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
require system.class xml.class
|
||||
|
||||
set ::tvdb::apikey 1764335F804A5A91
|
||||
|
|
|
@ -20,3 +20,98 @@ proc midnight {} {{today ""}} {
|
|||
return [clock scan "$today 00:00:00" -format "%Y %m %d %T"]
|
||||
}
|
||||
|
||||
# Base-64 according to RFC 4648
|
||||
# See https://wiki.tcl-lang.org/page/base64
|
||||
|
||||
if {![exists -command binary]} { package require binary }
|
||||
|
||||
# RFC 4648 section 4
|
||||
set ::b64::map {
|
||||
000000 A 000001 B 000010 C 000011 D 000100 E 000101 F
|
||||
000110 G 000111 H 001000 I 001001 J 001010 K 001011 L
|
||||
001100 M 001101 N 001110 O 001111 P 010000 Q 010001 R
|
||||
010010 S 010011 T 010100 U 010101 V 010110 W 010111 X
|
||||
011000 Y 011001 Z 011010 a 011011 b 011100 c 011101 d
|
||||
011110 e 011111 f 100000 g 100001 h 100010 i 100011 j
|
||||
100100 k 100101 l 100110 m 100111 n 101000 o 101001 p
|
||||
101010 q 101011 r 101100 s 101101 t 101110 u 101111 v
|
||||
110000 w 110001 x 110010 y 110011 z 110100 0 110101 1
|
||||
110110 2 110111 3 111000 4 111001 5 111010 6 111011 7
|
||||
111100 8 111101 9 111110 + 111111 /
|
||||
}
|
||||
|
||||
set ::b64::unmap [join [lmap {a b} $::b64::map {list $b $a}]]
|
||||
|
||||
proc ::b64::encode {str} {
|
||||
binary scan $str B* bits
|
||||
switch [expr {[string length $bits]%6}] {
|
||||
0 {set tail {}}
|
||||
2 {append bits 0000; set tail ==}
|
||||
4 {append bits 00; set tail =}
|
||||
}
|
||||
return [string cat [string map $::b64::map $bits] $tail]
|
||||
}
|
||||
|
||||
proc ::b64::decode {str} {
|
||||
set nstr [string trimright $str =]
|
||||
set dstr [string map $::b64::unmap $nstr]
|
||||
switch [expr [string length $str]-[string length $nstr]] {
|
||||
0 {#nothing to do}
|
||||
1 {set dstr [string range $dstr 0 {end-2}]}
|
||||
2 {set dstr [string range $dstr 0 {end-4}]}
|
||||
}
|
||||
return [binary format B* $dstr]
|
||||
}
|
||||
|
||||
# RFC 4648 section 5
|
||||
proc ::b64::url_encode {str} {
|
||||
tailcall string map {+ - / _ = ""} [::b64::encode $str]
|
||||
}
|
||||
|
||||
proc ::b64::url_decode {str} {
|
||||
tailcall ::b64::decode [string map {- + _ /} $str]
|
||||
}
|
||||
|
||||
alias b64encode ::b64::encode
|
||||
alias b64decode ::b64::decode
|
||||
alias b64uencode ::b64::url_encode
|
||||
alias b64udecode ::b64::url_decode
|
||||
|
||||
|
||||
# ECMA-262 Annex B.2.1
|
||||
proc ::js::_escape {str} {
|
||||
return [join [lmap c [split $str ""] {
|
||||
if {1 != [scan $c "%c" cc]} {
|
||||
format "%s" $c
|
||||
} elseif {$cc < 256} {
|
||||
format "%%%02X" $cc
|
||||
} else {
|
||||
format "%%u%04X" $cc
|
||||
}
|
||||
}] ""]
|
||||
}
|
||||
|
||||
proc ::js::_unescape {str} {
|
||||
if {1 == [scan $str "%%%2x" cc] ||
|
||||
1 == [scan $str "%%u%4x" cc]} {
|
||||
return [format "%c" $cc]
|
||||
} else {
|
||||
return $str
|
||||
}
|
||||
}
|
||||
|
||||
proc ::js::escape {str} {
|
||||
return [subst -nobackslashes -novariables \
|
||||
[regsub -all -- {[^A-Za-z0-9@*_+./-]+} $str \
|
||||
{[::js::_escape {&}]}]]
|
||||
}
|
||||
|
||||
proc ::js::unescape {str} {
|
||||
return [subst -nobackslashes -novariables \
|
||||
[regsub -all -- {%(u[[:xdigit:]]{2})?[[:xdigit:]]{2}} $str \
|
||||
{[::js::_unescape {&}]}]]
|
||||
}
|
||||
|
||||
alias jsescape ::js::escape
|
||||
alias jsunescape ::js::unescape
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# From https://wiki.tcl-lang.org/page/Parsing+XML
|
||||
# Keith Vetter 2004-03-01
|
||||
|
||||
if {![exists -proc class]} { package require oo }
|
||||
if {![exists -command class]} { package require oo }
|
||||
|
||||
class xml {
|
||||
xml ""
|
||||
|
|
Loading…
Reference in New Issue