From f6117a4ec05f269feb66a09bb7cdac723318dc2f Mon Sep 17 00:00:00 2001 From: df Date: Mon, 2 Nov 2020 15:14:23 +0000 Subject: [PATCH 01/34] Make 127.0.0.1 the default host for `system dlnahelper` In all the cases where `system dlnahelper` is called, no host/IP part is specified, and those cases are creating a URL that only needs to be accessible from the same machine, where the loopback address should be the default. Should fix eg https://hummy.tv/forum/threads/detectads-not-always-succesful.9936/post-147241. --- webif/lib/system.class | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/lib/system.class b/webif/lib/system.class index 8fbc763..e41bf7e 100644 --- a/webif/lib/system.class +++ b/webif/lib/system.class @@ -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 From da32aa0a72ba9a72309a42948464a8664d5b489a Mon Sep 17 00:00:00 2001 From: df Date: Mon, 9 Nov 2020 13:53:03 +0000 Subject: [PATCH 02/34] Set maximum width for File column Add title attribute to display possibly truncated File as tooltip. Will this work well for mobile/touchscreen use? --- webif/html/diag/queue/script.js | 3 ++- webif/html/diag/queue/style.css | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/webif/html/diag/queue/script.js b/webif/html/diag/queue/script.js index ad6a213..93c83b0 100644 --- a/webif/html/diag/queue/script.js +++ b/webif/html/diag/queue/script.js @@ -40,7 +40,8 @@ function load() $('').append($('', { 'class': 'file', href: '#', - html: v.file + html: v.file, + title: v.file })).appendTo($row); $('', { html: v.action + ' ' + v.args }) .appendTo($row); diff --git a/webif/html/diag/queue/style.css b/webif/html/diag/queue/style.css index a9e1b15..df2ed7b 100644 --- a/webif/html/diag/queue/style.css +++ b/webif/html/diag/queue/style.css @@ -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 { From d05f841bb40148890faf31f50c92cf3180dae09d Mon Sep 17 00:00:00 2001 From: df Date: Thu, 31 Dec 2020 15:18:03 +0000 Subject: [PATCH 03/34] Reduce (or apply) maximum lengths for title and synopsis, allowing for character set prefix byte --- webif/html/browse/assets.jim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/webif/html/browse/assets.jim b/webif/html/browse/assets.jim index d08b4f4..8735f9a 100755 --- a/webif/html/browse/assets.jim +++ b/webif/html/browse/assets.jim @@ -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 { @@ -131,7 +133,7 @@ puts { @@ -144,7 +146,7 @@ puts { From 98ef6a876f6f7613b08510147f89eb8420fbc1e8 Mon Sep 17 00:00:00 2001 From: df Date: Thu, 31 Dec 2020 15:22:42 +0000 Subject: [PATCH 04/34] Add missing $ for certain variable references Missing $s invalidated attempts to check the length of title, synopsis, guidance. --- webif/lib/ts.class | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webif/lib/ts.class b/webif/lib/ts.class index b998d93..83de168 100644 --- a/webif/lib/ts.class +++ b/webif/lib/ts.class @@ -296,21 +296,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] > 48} { return } if {$newguidance eq ""} { exec /mod/bin/hmt "-guidance" $file From cf407f9a809a587db068b9ade8b02d8fc7b38379 Mon Sep 17 00:00:00 2001 From: df Date: Mon, 22 Feb 2021 19:31:20 +0000 Subject: [PATCH 05/34] Correct the maximum length enforced for guidance text (74 vs 48) --- webif/lib/ts.class | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/lib/ts.class b/webif/lib/ts.class index 6f516bd..1c5cf12 100644 --- a/webif/lib/ts.class +++ b/webif/lib/ts.class @@ -310,7 +310,7 @@ ts method setsynopsis {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 From f7c37e83ae70e87a031ddb65296881dd45ef7ff2 Mon Sep 17 00:00:00 2001 From: df Date: Wed, 11 Nov 2020 12:19:32 +0000 Subject: [PATCH 06/34] Allow minimum width for cut plan Also * add ID for estimated time row * make the
@@ -29,7 +30,8 @@ puts [join [lmap i [$ts bookmarks 1] { clock format $i -format "%T" }] ", "] -puts " " +# set minimum width as positioned contents doesn't resize its cell +puts " " puts "
" @@ -64,8 +66,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 +80,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 +117,7 @@ puts [join [lmap i $newbookmarks { puts " )" puts " -Time: +Time: Cropping will take around [clock format $esttime -format "%T"] @@ -130,9 +132,9 @@ puts " -Save new bookmarks? + -
From 73d25247f094e9833c17468633820e235e48913f Mon Sep 17 00:00:00 2001 From: df Date: Wed, 11 Nov 2020 13:04:34 +0000 Subject: [PATCH 07/34] Check that bookmark save succeeded If not, enable the old "Save new bookmarks" button. Also * add icons for buttons * simplify invert URL handling. --- webif/html/browse/crop/crop.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/webif/html/browse/crop/crop.js b/webif/html/browse/crop/crop.js index a400e0b..dfaed43 100755 --- a/webif/html/browse/crop/crop.js +++ b/webif/html/browse/crop/crop.js @@ -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'); }); }); From 47495e7b8dc59c309bad108d862605f76c943b55 Mon Sep 17 00:00:00 2001 From: df Date: Tue, 23 Feb 2021 00:13:08 +0000 Subject: [PATCH 08/34] Avoid negative CSS widths --- webif/html/browse/crop/crop.jim | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/webif/html/browse/crop/crop.jim b/webif/html/browse/crop/crop.jim index 1c3fe09..f717956 100755 --- a/webif/html/browse/crop/crop.jim +++ b/webif/html/browse/crop/crop.jim @@ -37,6 +37,10 @@ puts "
" proc div {type left right} { set width $($right - $left) + if {$width < 0} { + # negative values are invalid for CSS width + set width 0 + } puts "
$type
" } From 4ae8ea85f7e85d0926093a6d635f26d060a7c641 Mon Sep 17 00:00:00 2001 From: df Date: Tue, 23 Feb 2021 00:16:04 +0000 Subject: [PATCH 09/34] Ensure cut plan segments are aligned left --- webif/html/browse/crop/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webif/html/browse/crop/style.css b/webif/html/browse/crop/style.css index f0e4546..74e82d4 100644 --- a/webif/html/browse/crop/style.css +++ b/webif/html/browse/crop/style.css @@ -11,3 +11,8 @@ div.sliderlabel line-height: 40px; } +#cutplan { + /* ensure cut plan segments are aligned left */ + padding-left: 0; +} + From dac3ea8698b18ac0f5683eea267c509ae011c2b1 Mon Sep 17 00:00:00 2001 From: df Date: Wed, 4 Nov 2020 14:16:09 +0000 Subject: [PATCH 10/34] Remove unnecessary exec Jim supports the pwd command since at least https://github.com/msteveb/jimtcl/commit/6461e8bf6ddf82ee974b4c63458915490d74a5ce, so no need to exec it. --- webif/html/dedup/dedup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/html/dedup/dedup b/webif/html/dedup/dedup index 550a05a..a878785 100755 --- a/webif/html/dedup/dedup +++ b/webif/html/dedup/dedup @@ -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 "/"} { From f5180dc14466e95489eee084e5f8f81e0bdc8814 Mon Sep 17 00:00:00 2001 From: df Date: Sun, 21 Feb 2021 07:24:50 +0000 Subject: [PATCH 11/34] Improve listing of directories with special characters, especially spaces. --- webif/html/browse/index.jim | 5 +- webif/html/browse/script.js | 9 +++- webif/lib/utils | 95 +++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 5 deletions(-) diff --git a/webif/html/browse/index.jim b/webif/html/browse/index.jim index 9c27973..2c8266d 100755 --- a/webif/html/browse/index.jim +++ b/webif/html/browse/index.jim @@ -69,7 +69,7 @@ proc directory {file bfile tbfile} { puts "
" - puts "$bfile + puts "[string map {" "  } $bfile] " lassign [dir iconset $file] icons attrs @@ -106,13 +106,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]] diff --git a/webif/html/browse/script.js b/webif/html/browse/script.js index 28ad4b1..cec02bb 100755 --- a/webif/html/browse/script.js +++ b/webif/html/browse/script.js @@ -111,8 +111,13 @@ function epginfo_callback(data, status, xhr) function insert_folder_size(folder, size) { - folder = folder.replace(/ /g, ''); - folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1'); + // folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1'); + // ID of size element is ID + RFC4648 s5 encoding of folder name + folder = "ID" + + btoa(escape(folder)) + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=/g, ''); //console.log("Folder: (%s) = (%s)", folder, size); if (size.search(/\d$/) == -1) size += 'iB'; diff --git a/webif/lib/utils b/webif/lib/utils index 53eaf04..e9b794b 100644 --- a/webif/lib/utils +++ b/webif/lib/utils @@ -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 + From 32ac3c84214666f40ed45dd4b14fbe379640281e Mon Sep 17 00:00:00 2001 From: df Date: Sun, 21 Feb 2021 12:33:55 +0000 Subject: [PATCH 12/34] Fix quoting of replacement text, avoiding "unmatched ]" --- webif/lib/utils | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webif/lib/utils b/webif/lib/utils index e9b794b..7eb71e4 100644 --- a/webif/lib/utils +++ b/webif/lib/utils @@ -103,13 +103,13 @@ proc ::js::_unescape {str} { proc ::js::escape {str} { return [subst -nobackslashes -novariables \ [regsub -all -- {[^A-Za-z0-9@*_+-./]+} $str \ - {[::js::_escape "&"]}]] + {[::js::_escape {&}]}]] } proc ::js::unescape {str} { return [subst -nobackslashes -novariables \ [regsub -all -- {%(u[[:xdigit:]]{2})?[[:xdigit:]]{2}} $str \ - {[::js::_unescape "&"]}]] + {[::js::_unescape {&}]}]] } alias jsescape ::js::escape From 8975cbd71df048f2a4a99fdf1586ced0277428f1 Mon Sep 17 00:00:00 2001 From: df Date: Sun, 21 Feb 2021 19:40:07 +0000 Subject: [PATCH 13/34] Also use non-breaking spaces in file name display --- webif/html/browse/index.jim | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/webif/html/browse/index.jim b/webif/html/browse/index.jim index 2c8266d..6351ab5 100755 --- a/webif/html/browse/index.jim +++ b/webif/html/browse/index.jim @@ -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 "
" set img "/images/711_1_09_Media_Folder.png" @@ -69,7 +73,7 @@ proc directory {file bfile tbfile} { puts "" - puts "[string map {" "  } $bfile] + puts "[nbsp $bfile] " lassign [dir iconset $file] icons attrs @@ -173,7 +177,7 @@ proc entry {file} {{i 0}} { - $bfile + [nbsp $bfile] " From 2642b190b0ed9bab40c72279410fc54b15884ace Mon Sep 17 00:00:00 2001 From: df Date: Thu, 18 Feb 2021 13:06:49 +0000 Subject: [PATCH 14/34] Fix typo and < vs <= in `dbfetch -trange` option: avoids missing channels in EPG. --- webif/lib/epg.class | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/lib/epg.class b/webif/lib/epg.class index 5c9420f..a32f40e 100644 --- a/webif/lib/epg.class +++ b/webif/lib/epg.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 { From 8bdb1233e81d27056a10e6e8e47f3160cbda6450 Mon Sep 17 00:00:00 2001 From: df Date: Thu, 18 Feb 2021 13:57:33 +0000 Subject: [PATCH 15/34] Display raw programme times, not clipped to the display period. --- webif/html/xepg/index.jim | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/webif/html/xepg/index.jim b/webif/html/xepg/index.jim index a136046..fef0fd5 100755 --- a/webif/html/xepg/index.jim +++ b/webif/html/xepg/index.jim @@ -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]] ([\ - clock format $es -format "%H:%M"] - [\ - clock format $ee -format "%H:%M"])" - if {$showing} { append txt " ($perc%)" } - append txt "" - - 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 "
+ style=\"width: [expr $px - 4]px;\" title=\"[join $txt]\"> " - puts $txt + puts [format "%s %s" {*}$txt] puts "" puts "
" } From 0060e47db5f5e5bf45cee45b57f64b95c2bc17f2 Mon Sep 17 00:00:00 2001 From: df Date: Thu, 18 Feb 2021 18:42:07 +0000 Subject: [PATCH 16/34] Remove unwanted padding before programme divs in EPG to avoid cumulative positioning error. --- webif/html/xepg/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/html/xepg/style.css b/webif/html/xepg/style.css index a6b1721..51df33b 100644 --- a/webif/html/xepg/style.css +++ b/webif/html/xepg/style.css @@ -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; From f16399ec2fbecf17c1660588305e2847c873a0f6 Mon Sep 17 00:00:00 2001 From: df Date: Mon, 14 Dec 2020 14:06:48 +0000 Subject: [PATCH 17/34] exists -proc -> exists -command `exists -command` subsumes `exists -proc` This test is generally checking whether the command exists, rather than some proc that is overriding it. Currently `class` is a proc but this may not always be so. --- webif/lib/browse.class | 2 +- webif/lib/clipboard.class | 2 +- webif/lib/epg.class | 4 ++-- webif/lib/pkg.class | 2 +- webif/lib/queue.class | 4 ++-- webif/lib/rsv.class | 6 +++--- webif/lib/settings.class | 4 ++-- webif/lib/svc.class | 4 ++-- webif/lib/system.class | 6 +++--- webif/lib/ts.class | 6 +++--- webif/lib/tvdb.class | 4 ++-- webif/lib/xml.class | 2 +- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/webif/lib/browse.class b/webif/lib/browse.class index 31ae38b..cffe0d2 100644 --- a/webif/lib/browse.class +++ b/webif/lib/browse.class @@ -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 {} diff --git a/webif/lib/clipboard.class b/webif/lib/clipboard.class index 4cf6340..5dc3f51 100644 --- a/webif/lib/clipboard.class +++ b/webif/lib/clipboard.class @@ -1,5 +1,5 @@ -if {![exists -proc class]} { package require oo } +if {![exists -command class]} { package require oo } class clipboard { path "/tmp/webif.cb" diff --git a/webif/lib/epg.class b/webif/lib/epg.class index a32f40e..db05d26 100644 --- a/webif/lib/epg.class +++ b/webif/lib/epg.class @@ -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 diff --git a/webif/lib/pkg.class b/webif/lib/pkg.class index edd5e98..0cee525 100755 --- a/webif/lib/pkg.class +++ b/webif/lib/pkg.class @@ -1,5 +1,5 @@ -if {![exists -proc class]} { package require oo } +if {![exists -command class]} { package require oo } class pkg { name "" diff --git a/webif/lib/queue.class b/webif/lib/queue.class index 4f8011a..b9811cf 100644 --- a/webif/lib/queue.class +++ b/webif/lib/queue.class @@ -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 diff --git a/webif/lib/rsv.class b/webif/lib/rsv.class index f920c44..b18090b 100644 --- a/webif/lib/rsv.class +++ b/webif/lib/rsv.class @@ -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 diff --git a/webif/lib/settings.class b/webif/lib/settings.class index f5edda2..0fd81e6 100644 --- a/webif/lib/settings.class +++ b/webif/lib/settings.class @@ -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] diff --git a/webif/lib/svc.class b/webif/lib/svc.class index d2d146a..509043b 100755 --- a/webif/lib/svc.class +++ b/webif/lib/svc.class @@ -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 { diff --git a/webif/lib/system.class b/webif/lib/system.class index 8fbc763..f492306 100644 --- a/webif/lib/system.class +++ b/webif/lib/system.class @@ -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 {} diff --git a/webif/lib/ts.class b/webif/lib/ts.class index b9b6ee2..7aba2c1 100644 --- a/webif/lib/ts.class +++ b/webif/lib/ts.class @@ -1,7 +1,7 @@ -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 } source /mod/webif/lib/setup require system.class tvdb.class classdump diff --git a/webif/lib/tvdb.class b/webif/lib/tvdb.class index 2abc580..c81cd52 100644 --- a/webif/lib/tvdb.class +++ b/webif/lib/tvdb.class @@ -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 diff --git a/webif/lib/xml.class b/webif/lib/xml.class index 7cde513..8c3025e 100644 --- a/webif/lib/xml.class +++ b/webif/lib/xml.class @@ -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 "" From 7834dae075b029b8ac804efa2252cf2dc8ed22c2 Mon Sep 17 00:00:00 2001 From: df Date: Tue, 9 Feb 2021 15:10:05 +0000 Subject: [PATCH 18/34] Error protect database access; re-create corrupt queue DB. --- webif/lib/queue.class | 198 ++++++++++++++++++++++++++---------------- 1 file changed, 122 insertions(+), 76 deletions(-) diff --git a/webif/lib/queue.class b/webif/lib/queue.class index b9811cf..59715a0 100644 --- a/webif/lib/queue.class +++ b/webif/lib/queue.class @@ -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}} { From 6f45884f94d2b374eb23e12bc854226dc11ad450 Mon Sep 17 00:00:00 2001 From: df Date: Mon, 19 Oct 2020 12:25:50 +0000 Subject: [PATCH 19/34] Add test for matching key for DLNA; fallback to direct; fail if no key matches --- webif/lib/auto/plugin/decrypt/queue.hook | 29 +++++------- webif/lib/ts.class | 59 +++++++++++++++++++++++- 2 files changed, 69 insertions(+), 19 deletions(-) diff --git a/webif/lib/auto/plugin/decrypt/queue.hook b/webif/lib/auto/plugin/decrypt/queue.hook index bc4e6cc..05c74b7 100644 --- a/webif/lib/auto/plugin/decrypt/queue.hook +++ b/webif/lib/auto/plugin/decrypt/queue.hook @@ -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]} { diff --git a/webif/lib/ts.class b/webif/lib/ts.class index 6023ec1..ad11c99 100644 --- a/webif/lib/ts.class +++ b/webif/lib/ts.class @@ -2,6 +2,8 @@ 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 @@ -537,7 +539,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 @@ -773,7 +775,7 @@ ts method episode_name {} { incr flag } if {$flag} { $self storeepisode } - + return $tvdb_data(name) } @@ -838,3 +840,56 @@ 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 + } + } 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 + } + } 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 +} + From bc2e6c1a85ed6a37dbecef7a9d7aab3862be0eaa Mon Sep 17 00:00:00 2001 From: MymsMan Date: Wed, 20 Jan 2021 16:11:59 +0000 Subject: [PATCH 20/34] Restrict matching epsiodes search to same channel --- webif/lib/rsv.class | 1 + 1 file changed, 1 insertion(+) diff --git a/webif/lib/rsv.class b/webif/lib/rsv.class index b18090b..46feca8 100644 --- a/webif/lib/rsv.class +++ b/webif/lib/rsv.class @@ -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 From 4820ade1f530b825bb5736caa5fff5acf2683dc0 Mon Sep 17 00:00:00 2001 From: HummyPkg Date: Wed, 24 Feb 2021 13:21:19 +0000 Subject: [PATCH 21/34] Fix problems pointed out by tclCheck and frink --- webif/html/browse/index.jim | 2 +- webif/html/xepg/index.jim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webif/html/browse/index.jim b/webif/html/browse/index.jim index 6351ab5..be17858 100755 --- a/webif/html/browse/index.jim +++ b/webif/html/browse/index.jim @@ -365,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 "" set tag "" set ket "a" diff --git a/webif/html/xepg/index.jim b/webif/html/xepg/index.jim index fef0fd5..0e1e373 100755 --- a/webif/html/xepg/index.jim +++ b/webif/html/xepg/index.jim @@ -270,7 +270,7 @@ foreach e $records { set txt [list [cgi_quote_html [$e get name]] "([\ clock format $es -format "%H:%M"] - [\ clock format $ee -format "%H:%M"])[\ - expr {$showing? " ($perc%)": ""}]"] + expr {$showing ? " ($perc%)" : ""}]"] if {$es < $stt} { set es $stt } if {$ee > $ett} { set ee $ett } From 1c868ae2019609b1a1f1156a8e06283e5c20d2dd Mon Sep 17 00:00:00 2001 From: df Date: Tue, 10 Nov 2020 14:04:20 +0000 Subject: [PATCH 22/34] Add thumbnail viewer to Manage Bookmarks --- webif/html/browse/bookmarks/index.jim | 34 +++++- webif/html/browse/bookmarks/script.js | 144 ++++++++++++++++++++++---- 2 files changed, 158 insertions(+), 20 deletions(-) diff --git a/webif/html/browse/bookmarks/index.jim b/webif/html/browse/bookmarks/index.jim index b12c937..f81650d 100755 --- a/webif/html/browse/bookmarks/index.jim +++ b/webif/html/browse/bookmarks/index.jim @@ -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 "