forked from hummypkg/webif
Compare commits
31 Commits
df-hostipp
...
df-listdir
| Author | SHA1 | Date | |
|---|---|---|---|
| 1de256ec16 | |||
| ccf7304ce0 | |||
| 07c7613209 | |||
| 5c4d8d087e | |||
| 8f99579c58 | |||
|
|
269f844f43 | ||
|
|
488961c600 | ||
|
|
a5f0734201 | ||
| 94849c51e7 | |||
| 907d9d8dcf | |||
| 6641b6f458 | |||
| 4da3bb0209 | |||
|
|
2e471129b8 | ||
| 0ad1491634 | |||
| 8021455a94 | |||
| c995f2232e | |||
| 6dc47f2b96 | |||
| af74503b99 | |||
| 58ecd41952 | |||
| e579c8dd24 | |||
| 7c600be77e | |||
| e3f7a2b738 | |||
| a90f49b324 | |||
| 3e9ecc8a7c | |||
| 7bb66de5f2 | |||
| 9b64128c92 | |||
| 6822c833be | |||
| cefe60c722 | |||
| ee885a173c | |||
| 2d06ec7811 | |||
| 0e09258bfa |
@@ -1,7 +1,7 @@
|
||||
Package: webif
|
||||
Priority: optional
|
||||
Section: web
|
||||
Version: 1.4.8-10
|
||||
Version: 1.4.9
|
||||
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
|
||||
|
||||
@@ -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>
|
||||
"
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ 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"
|
||||
}
|
||||
if {$new ne $old} {
|
||||
if {$attr eq "guidance" ||
|
||||
[string length $new] > 0} {
|
||||
|
||||
@@ -10,6 +10,18 @@ var plugins = {
|
||||
dmenu_prepare: {}
|
||||
};
|
||||
|
||||
// pattern matches directory path prefix
|
||||
var pathre = /.*\/|\.[^.]*$/g;
|
||||
|
||||
// IDs of size, img, etc elements for folders use RFC4648 s5 encoding of folder name
|
||||
function folderID(folder) {
|
||||
return btoa(escape(folder))
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
function blockpage(msg)
|
||||
{
|
||||
if (!msg)
|
||||
@@ -111,17 +123,14 @@ function epginfo_callback(data, status, xhr)
|
||||
|
||||
function insert_folder_size(folder, size)
|
||||
{
|
||||
folder = folder.replace(/ /g, '');
|
||||
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
|
||||
//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 = folderID(folder);
|
||||
//console.log("Folder: (%s) = (%s)", folder, size);
|
||||
$(folder == "" ? '#dirsize': '#ID' + folder)
|
||||
.text(' (' + size + ')');
|
||||
}
|
||||
|
||||
function folder_size_callback(data, status, xhr)
|
||||
@@ -133,11 +142,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 +163,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 +261,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 +434,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');
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -54,6 +54,28 @@ class settings {
|
||||
rtschedule 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 ""}} {
|
||||
if {$name == ""} {
|
||||
# Get
|
||||
@@ -104,11 +126,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 +139,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 +148,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 +161,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -354,13 +354,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}} {
|
||||
@@ -696,6 +697,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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user