forked from hummypkg/webif
Revert e79e85af81
This commit is contained in:
parent
c5c4091cf6
commit
0d7ba4744f
|
@ -215,8 +215,8 @@ proc entry {file} {{i 0}} {
|
|||
|
||||
# Indexed
|
||||
set dlna 0
|
||||
if {$::dlnaok && $::model eq "HDR" &&
|
||||
[llength [system dlnaurl $file]]} {
|
||||
if {$::dlnaok && $::model eq "HDR" && [llength [
|
||||
system dlnaurl [file normalize $file]]]} {
|
||||
icon "/img/dlna.png" "Indexed by DLNA Server"
|
||||
set dlna 1
|
||||
}
|
||||
|
|
|
@ -316,10 +316,6 @@ proc {system dlnadb} {} {
|
|||
|
||||
proc {system _dlnaurl} {file urlbase} {
|
||||
set mime "video/mp2t"
|
||||
set nfile $file
|
||||
if {![catch {set nfile [file normalize $file]}]} {
|
||||
set file $nfile
|
||||
}
|
||||
if {[catch {set db [sqlite3.open [system dlnadb]]}]} {
|
||||
return {}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,921 @@
|
|||
|
||||
source /mod/webif/lib/setup
|
||||
|
||||
package require xconv
|
||||
|
||||
if {![exists -command class]} { package require oo }
|
||||
if {![exists -command sqlite3.open]} { package require sqlite3 }
|
||||
if {![exists -command binary]} { package require binary }
|
||||
|
||||
class system {}
|
||||
|
||||
proc {system model} {} {{model ""}} {
|
||||
if {$model ne ""} { return $model }
|
||||
if {[catch {set fp [open /etc/model r]}]} {
|
||||
set model {HD[R]}
|
||||
} else {
|
||||
set model [string trim [read $fp]]
|
||||
close $fp
|
||||
}
|
||||
return $model
|
||||
}
|
||||
|
||||
proc {system hostname} {} {
|
||||
if {[catch {set hostname [string trim [exec hostname]]}]} {
|
||||
set hostname "humax"
|
||||
}
|
||||
return $hostname
|
||||
}
|
||||
|
||||
proc {system ip} {} {
|
||||
if {[catch {set fp [open /etc/hosts r]}]} {
|
||||
set ip "127.0.0.1"
|
||||
} else {
|
||||
set ipl [lindex [split [$fp read] "\n"] 1]
|
||||
regsub -- {[[:space:]].*} $ipl "" ip
|
||||
$fp close
|
||||
}
|
||||
return $ip
|
||||
}
|
||||
|
||||
proc {system modversion} {{short 0}} {{modver ""}} {
|
||||
if {$modver eq ""} {
|
||||
if {[catch {set fp [open /etc/modversion r]}]} {
|
||||
set modver "102"
|
||||
} else {
|
||||
set modver [string trim [read $fp]]
|
||||
close $fp
|
||||
}
|
||||
}
|
||||
if {$short} { return $modver }
|
||||
lassign [split $modver ""] a b c
|
||||
return [format "%d.%d%d" $a $b $c]
|
||||
}
|
||||
|
||||
proc {system modbuild} {} {{modbuild ""}} {
|
||||
if {$modbuild ne ""} { return $modbuild }
|
||||
if {[catch {set modbuild [string trim [file read /etc/modbuild]]}]} {
|
||||
set modbuild 0
|
||||
}
|
||||
return $modbuild
|
||||
}
|
||||
|
||||
proc {system lastbootreason} {{descr 1}} {{lbr -1}} {
|
||||
if {$lbr == -1} {
|
||||
set lbr 0
|
||||
if {[file readable /tmp/.lbr]} {
|
||||
set lbr [file read /tmp/.lbr]
|
||||
}
|
||||
}
|
||||
if {!$descr} { return $lbr }
|
||||
switch $lbr {
|
||||
1 { return "Front panel button" }
|
||||
2 { return "Remote control handset" }
|
||||
3 { return "Scheduled event" }
|
||||
4 { return "Power cycle" }
|
||||
}
|
||||
return "Unknown ($lbr)"
|
||||
}
|
||||
|
||||
proc {system idletime} {} {
|
||||
if {[file exists "/tmp/.lastir"]} {
|
||||
return $([clock seconds] - [file mtime "/tmp/.lastir"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
proc {system fhtcpversion} {} {{ver ""}} {
|
||||
if {$ver ne ""} { return $ver }
|
||||
set file "/etc/fhtcpversion"
|
||||
if {![file exists $file]} { set file "/root/fhtcpversion" }
|
||||
if {[catch {set fp [open $file r]}]} {
|
||||
set ver "?.??.??"
|
||||
} else {
|
||||
set ver [string trim [read $fp]]
|
||||
close $fp
|
||||
}
|
||||
return $ver
|
||||
}
|
||||
|
||||
# :c0400 System ID
|
||||
# 4:c8400 read 1128 bytes
|
||||
# 3:c8c00 MAC address
|
||||
# 2:c9000
|
||||
# 1:cb400 DTCP key material
|
||||
# 0:cb800 Serial Number
|
||||
# 5:cbc00
|
||||
|
||||
proc {system systemid} {} {{id ""}} {
|
||||
if {$id ne ""} { return $id }
|
||||
set fd [open /dev/mtd3 r]
|
||||
|
||||
$fd seek 0xc0400
|
||||
set bytes [$fd read 4]
|
||||
$fd close
|
||||
binary scan $bytes H* hex
|
||||
set id [format "%s.%s" [string range $hex 0 3] [string range $hex 4 end]]
|
||||
return $id
|
||||
}
|
||||
|
||||
proc {system macaddr} {} {{mac ""}} {
|
||||
if {$mac ne ""} { return $mac }
|
||||
set fd [open /dev/mtd3 r]
|
||||
|
||||
$fd seek 0xc8c00
|
||||
set bytes [$fd read 6]
|
||||
$fd close
|
||||
set tmac ""
|
||||
foreach b [split $bytes ""] {
|
||||
binary scan $b H* hex
|
||||
if {$tmac ne ""} { append tmac : }
|
||||
append tmac $hex
|
||||
}
|
||||
return [set mac $tmac]
|
||||
}
|
||||
|
||||
proc {system serialno} {} {{serial ""}} {
|
||||
if {$serial ne ""} { return $serial }
|
||||
set fd [open /dev/mtd3 r]
|
||||
|
||||
$fd seek 0xcb800
|
||||
set bytes [$fd read 14]
|
||||
$fd close
|
||||
set serial "[string range $bytes 0 1] [string range $bytes 2 8] [
|
||||
string range $bytes 9 end]"
|
||||
return $serial
|
||||
}
|
||||
proc {system keybytestostring} {key_bytes} {
|
||||
binary scan $key_bytes H* key_str
|
||||
if {[string length $key_str] == 32} {
|
||||
return $key_str
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
proc {system encryptionkey} {} {{key ""}} {
|
||||
if {$key ne ""} { return $key }
|
||||
set fd [open /dev/mtd3 r]
|
||||
$fd seek 0xc8c00
|
||||
set bytes [$fd read 6]
|
||||
$fd seek 0xcb800
|
||||
append bytes [$fd read 10]
|
||||
$fd close
|
||||
return [system keybytestostring $bytes]
|
||||
}
|
||||
|
||||
proc {system customencryptionkey} {{key ""}} {{keyfile "/mod/boot/cryptokey"}} {
|
||||
|
||||
set ck_fd {}
|
||||
try {
|
||||
if {$key eq ""} {
|
||||
set ck_fd [open $keyfile r]
|
||||
set ck_bytes [$ck_fd read 16]
|
||||
return [system keybytestostring $ck_bytes]
|
||||
} elseif {[string equal -nocase $key [system encryptionkey]]} {
|
||||
file delete -force $keyfile
|
||||
return $key
|
||||
} else {
|
||||
set ck_bytes [binary format H* $key]
|
||||
set test [system keybytestostring $ck_bytes]
|
||||
if {![string equal -nocase $test $key]} {
|
||||
throw 1 "Invalid custom key"
|
||||
}
|
||||
if {[file exists $keyfile]} {
|
||||
# attempt not to truncate on update until written
|
||||
set access r+
|
||||
} else {
|
||||
set access w
|
||||
}
|
||||
set ck_fd [open $keyfile $access]
|
||||
$ck_fd seek 0
|
||||
$ck_fd puts -nonewline $ck_bytes
|
||||
$ck_fd close
|
||||
set ck_fd {}
|
||||
return $key
|
||||
}
|
||||
} on error {msg opts} {
|
||||
return {}
|
||||
} finally {
|
||||
if {$ck_fd ne {}} {
|
||||
$ck_fd close
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc {system loaderver} {} {{ver ""}} {
|
||||
if {$ver ne ""} { return $ver }
|
||||
set fd [open /dev/mtd3 r]
|
||||
$fd seek 0x20006
|
||||
set bytes [$fd read 2]
|
||||
$fd close
|
||||
set ver [switch $bytes {
|
||||
"\x04\x5f" { format "a7.30" }
|
||||
"\xec\xe5" { format "a7.31" }
|
||||
"\x59\x9d" { format "a7.33" }
|
||||
"\x72\x5c" { format "a7.34" }
|
||||
"\xe5\xe3" { format "L7.26" }
|
||||
"\x8f\x7c" { format "L7.27" }
|
||||
default {
|
||||
binary scan $bytes H* hex
|
||||
format "Unknown - $hex"
|
||||
}
|
||||
}]
|
||||
return $ver
|
||||
}
|
||||
|
||||
proc {system kernelver} {} {{ver ""}} {
|
||||
if {$ver ne ""} { return $ver }
|
||||
#1 SMP Sun Mar 25 18:30:38 KST 2012
|
||||
set rver [string range [exec uname -v] 11 end]
|
||||
set ver [switch $rver {
|
||||
# HDR
|
||||
"Sep 16 20:17:56 KST 2010" { format "HDR_1.01.05" }
|
||||
"Oct 11 21:11:05 KST 2010" { format "HDR_1.01.09" }
|
||||
"Jan 21 15:44:39 KST 2011" { format "HDR_1.02.07" }
|
||||
"Jun 11 00:54:19 KST 2011" { format "HDR_1.02.20" }
|
||||
"Mar 25 18:30:38 KST 2012" { format "HDR_1.02.27" }
|
||||
"May 27 00:19:34 KST 2012" { format "HDR_1.02.28" }
|
||||
"Jul 5 11:11:28 KST 2012" { format "HDR_1.02.29" }
|
||||
"Jan 12 16:49:05 KST 2013" { format "HDR_1.02.32" }
|
||||
"Mar 6 07:27:02 KST 2013" { format "HDR_1.03.06(a)" }
|
||||
"May 8 14:32:30 KST 2013" { format "HDR_1.03.06(b)" }
|
||||
"Dec 10 14:36:54 KST 2013" { format "HDR_1.03.11" }
|
||||
"Feb 7 14:15:02 KST 2014" { format "HDR_1.03.12" }
|
||||
"May 19 22:39:27 BST 2014" { format "HDR_CFW_3.00" }
|
||||
"Feb 19 20:58:57 GMT 2015" { format "HDR_CFW_3.03" }
|
||||
"Mar 11 23:34:27 GMT 2016" { format "HDR_CFW_3.10" }
|
||||
"Mar 11 23:37:22 GMT 2016" { format "HDR_CFW_3.10d" }
|
||||
"Jan 9 04:46:49 GMT 2017" { format "HDR_CFW_3.11" }
|
||||
"Jan 9 04:50:13 GMT 2017" { format "HDR_CFW_3.11d" }
|
||||
"Mar 23 19:36:14 GMT 2017" { format "HDR_CFW_3.12" }
|
||||
"Mar 23 19:39:44 GMT 2017" { format "HDR_CFW_3.12d" }
|
||||
"Apr 18 22:42:30 BST 2017" { format "HDR_CFW_3.13" }
|
||||
"Apr 18 22:45:34 BST 2017" { format "HDR_CFW_3.13d" }
|
||||
"Mar 29 13:48:27 BST 2020" { format "HDR_CFW_3.14" }
|
||||
"Mar 29 13:52:16 BST 2020" { format "HDR_CFW_3.14d" }
|
||||
|
||||
# HD
|
||||
"Oct 11 21:14:31 KST 2010" { format "HD_1.01.12" }
|
||||
"May 17 14:16:20 KST 2011" { format "HD_1.02.18" }
|
||||
"Jun 11 00:54:19 KST 2011" { format "HD_1.02.20" }
|
||||
"Mar 25 07:09:19 KST 2012" { format "HD_1.02.27" }
|
||||
"May 27 00:19:40 KST 2012" { format "HD_1.02.28" }
|
||||
"Jul 5 19:41:17 KST 2012" { format "HD_1.02.29" }
|
||||
"Oct 13 12:48:09 KST 2012" { format "HD_1.02.31" }
|
||||
"Dec 9 14:15:07 KST 2014" { format "HD_1.03.02" }
|
||||
|
||||
default { format "Unknown - $rver" }
|
||||
}]
|
||||
return $ver
|
||||
}
|
||||
|
||||
# Newer version below is over 100 times faster
|
||||
#proc {system pkgver} {{pkg webif}} {
|
||||
# return [lrange [split [exec opkg list-installed $pkg] " "] 2 end]
|
||||
#}
|
||||
|
||||
proc {system pkgver} {{pkg webif}} {
|
||||
if {[catch {set fp [open /mod/var/opkg/info/$pkg.control r]}]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
set v 0
|
||||
foreach line [split [$fp read] "\n"] {
|
||||
if {[string equal -length 9 $line "Version: "]} {
|
||||
lassign $line x v
|
||||
break
|
||||
}
|
||||
}
|
||||
$fp close
|
||||
return $v
|
||||
}
|
||||
|
||||
proc {system pkginst} {pkg} {
|
||||
return [file exists "/mod/var/opkg/info/$pkg.control"]
|
||||
}
|
||||
|
||||
proc {system mediaroot} {} {
|
||||
switch [system model] {
|
||||
HDR { return "/media/My Video" }
|
||||
HD { return "/media/drive1/Video" }
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
proc {system dlnastatus} {} {
|
||||
return [system is_listening 9000]
|
||||
}
|
||||
|
||||
proc {system dlnadb} {} {
|
||||
switch [system model] {
|
||||
HDR { return "/mnt/hd2/dms_cds.db" }
|
||||
HD { return "/media/drive1/dms_cds.db" }
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
proc {system _dlnaurl} {file urlbase} {
|
||||
set mime "video/mp2t"
|
||||
set nfile $file
|
||||
if {![catch {set nfile [file normalize $file]}]} {
|
||||
set file $nfile
|
||||
}
|
||||
if {[catch {set db [sqlite3.open [system dlnadb]]}]} {
|
||||
return {}
|
||||
}
|
||||
set muri [$db query {
|
||||
select tblresource.mimetype, contenturi
|
||||
from tblresource join tblmedia using (mediaid)
|
||||
where localurl = '%s'} $file]
|
||||
if {[llength $muri]} {
|
||||
lassign [lindex $muri 0] x maybemime x xuri
|
||||
if {$maybemime ne "video/ts"} {
|
||||
set mime $maybemime
|
||||
}
|
||||
} else {
|
||||
# Try for partially linked entry
|
||||
set muri [$db query {
|
||||
select mediaid from tblmedia
|
||||
where localurl = '%s'
|
||||
} $file]
|
||||
if {![llength $muri]} { return {} }
|
||||
lassign [lindex $muri 0] x mediaid
|
||||
set xuri "media/$mediaid.TS"
|
||||
}
|
||||
|
||||
$db close
|
||||
|
||||
set url "http://${urlbase}:9000/web/$xuri"
|
||||
|
||||
return [list $url $mime]
|
||||
}
|
||||
|
||||
proc {system dlnaurl} {file {urlbase "127.0.0.1"}} {
|
||||
if {$urlbase eq ""} { set urlbase [system ip] }
|
||||
set retries 5
|
||||
set ret {}
|
||||
while {$retries > 0 && [\
|
||||
catch {set ret [system _dlnaurl $file $urlbase]}]} {
|
||||
incr retries -1
|
||||
sleep 1
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
proc {system dlnahelper} {file {urlbase "127.0.0.1"}} {
|
||||
set dir /mnt/hd2/mod/.dlnahelper
|
||||
require lock
|
||||
|
||||
if {$file eq "-release"} {
|
||||
release_lock dlnahelper
|
||||
return {}
|
||||
}
|
||||
|
||||
if {![acquire_lock dlnahelper 2]} { return {} }
|
||||
|
||||
if {![file isdirectory $dir]} { file mkdir $dir }
|
||||
|
||||
set base [file rootname $file]
|
||||
foreach ext {hmt ts} {
|
||||
file delete "$dir/helper.$ext"
|
||||
file link -symbolic "$dir/helper.$ext" "$base.$ext"
|
||||
}
|
||||
|
||||
set ret [system dlnaurl "$dir/helper.ts" $urlbase]
|
||||
if {![llength $ret]} {
|
||||
# Manually import the helper file.
|
||||
if {![catch {set db [sqlite3.open [system dlnadb]]}]} {
|
||||
$db query {
|
||||
insert into tblmedia
|
||||
(localurl,folder,mediatype,refcount)
|
||||
values('%s','%s',0,1)
|
||||
} "$dir/helper.ts" $dir
|
||||
$db close
|
||||
set ret [system dlnaurl "$dir/helper.ts" $urlbase]
|
||||
}
|
||||
}
|
||||
if {![llength $ret]} {
|
||||
release_lock dlnahelper
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
proc {system dustbin} {{short 0}} {
|
||||
set dustbin "\[Deleted Items\]"
|
||||
if {![catch {set fd [open "/mod/boot/dustbin.name" r]}]} {
|
||||
set dustbin [lindex [split [read $fd] "\n"] 0]
|
||||
$fd close
|
||||
}
|
||||
if {$short} { return $dustbin }
|
||||
return "[system mediaroot]/$dustbin"
|
||||
}
|
||||
|
||||
proc {system dustbinsize} {} {
|
||||
set bin [system dustbin]
|
||||
set ret 0
|
||||
if {[file isdirectory $bin]} {
|
||||
if {[catch {
|
||||
lassign [exec /mod/bin/busybox/du -s $bin] ret
|
||||
}]} {
|
||||
set ret 0
|
||||
}
|
||||
}
|
||||
return $($ret * 1024)
|
||||
}
|
||||
|
||||
proc {system diskpart} {} {
|
||||
switch [system model] {
|
||||
HDR { return "/mnt/hd2" }
|
||||
HD { return "/media/drive1" }
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
proc {system diskdev} {} {
|
||||
return [lindex [lsearch -regexp -inline \
|
||||
[split [file read /proc/mounts] "\n\r"] " [system diskpart] "] 0]
|
||||
}
|
||||
|
||||
proc {system disk} {} {
|
||||
return [string range [system diskdev] 0 end-1]
|
||||
}
|
||||
|
||||
proc {system disktemp} {} {
|
||||
if {[catch {
|
||||
set smart [exec /bin/smartctl -A [system disk] | grep ^194]
|
||||
regsub -all -- {[[:space:]]+} $smart " " smart
|
||||
set temp [lindex [split $smart] 9]
|
||||
}]} {
|
||||
set temp 0
|
||||
}
|
||||
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}} {
|
||||
set part [system diskpart]
|
||||
|
||||
lassign [exec /mod/bin/busybox/stat -f -c {%S %b %f} $part] \
|
||||
bsize blocks fblocks
|
||||
|
||||
set size $($bsize * $blocks)
|
||||
set free $($bsize * $fblocks)
|
||||
set used $($size - $free)
|
||||
set perc $($used * 100 / $size)
|
||||
set fperc $(100 - $perc)
|
||||
|
||||
set tsrdir [system tsrdir]
|
||||
switch [system model] {
|
||||
HDR {
|
||||
set tsrok [file isdirectory $tsrdir]
|
||||
}
|
||||
HD {
|
||||
set tsrok [file exists "$tsrdir/0.ts"]
|
||||
}
|
||||
}
|
||||
|
||||
if {$tsrok} {
|
||||
set tsrbuf 21474836480
|
||||
if {[catch {
|
||||
lassign [exec du -ks $tsrdir] tsrused
|
||||
}]} {
|
||||
set tsrused 0
|
||||
set tsrbuf 0
|
||||
} else {
|
||||
set tsrused $($tsrused * 1024)
|
||||
}
|
||||
} else {
|
||||
set tsrbuf 0
|
||||
set tsrused 0
|
||||
}
|
||||
|
||||
if {!$raw} {
|
||||
set size [pretty_size $size]
|
||||
set free [pretty_size $free]
|
||||
set used [pretty_size $used]
|
||||
set tsrbuf [pretty_size $tsrbuf]
|
||||
set tsrused [pretty_size $tsrused]
|
||||
}
|
||||
|
||||
return [list $size $used $perc $free $fperc $tsrbuf $tsrused]
|
||||
}
|
||||
|
||||
proc {system diskfree} {} {
|
||||
lassign [exec /mod/bin/busybox/stat -f -c {%S %f} [system diskpart]] \
|
||||
bsize fblocks
|
||||
return $($bsize * $fblocks)
|
||||
}
|
||||
|
||||
proc {system busy} {} {
|
||||
# Is humaxtv doing anything important?
|
||||
if {[catch {set pid [exec /mod/bin/busybox/pgrep -n humaxtv]}]} {
|
||||
return 0
|
||||
}
|
||||
set c 0
|
||||
foreach line [split [\
|
||||
exec /mod/webif/lib/bin/lsof -X -Fn -p $pid] "\n"] {
|
||||
if {[string match {*Video*.ts} $line]} { incr c }
|
||||
}
|
||||
if {$c > 0} { return 1 }
|
||||
return 0
|
||||
}
|
||||
|
||||
proc {system inuse} {file} {
|
||||
if {![file exists $file]} { return 0 }
|
||||
set op [exec /mod/webif/lib/bin/lsof -X -Fn $file]
|
||||
switch -glob -- $op {
|
||||
"" -
|
||||
"*status error*" { return 0 }
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
proc {system dirinuse} {dir} {
|
||||
set files {}
|
||||
foreach line [split [\
|
||||
exec /mod/webif/lib/bin/lsof -X -Fn +d $dir] "\n"] {
|
||||
if {[string index $line 0] ne "n"} continue
|
||||
lappend files [file tail $line]
|
||||
}
|
||||
return $files
|
||||
}
|
||||
|
||||
proc {system reboot} {{fast 0}} {
|
||||
if {$fast} {
|
||||
exec /mod/webif/lib/bin/reboot -f
|
||||
} else {
|
||||
exec /mod/webif/lib/bin/reboot
|
||||
}
|
||||
}
|
||||
|
||||
proc {system restartpending} {{mode 1}} {
|
||||
if {$mode} {
|
||||
close [open /tmp/.restartpending w]
|
||||
} else {
|
||||
file delete /tmp/.restartpending
|
||||
}
|
||||
}
|
||||
|
||||
proc {system param} {param {type Value} {tbl MENUCONFIG}} {
|
||||
if {[catch {set db [sqlite3.open /var/lib/humaxtv/setup.db]} msg]} {
|
||||
return 0
|
||||
}
|
||||
set val 0
|
||||
set ret [$db query "
|
||||
select item$type
|
||||
from TBL_$tbl
|
||||
where itemName = '$param'
|
||||
"]
|
||||
if {[llength $ret] == 1} {
|
||||
lassign [lindex $ret 0] x val
|
||||
}
|
||||
$db close
|
||||
return $val
|
||||
}
|
||||
|
||||
proc {system padding} {} {
|
||||
return [list \
|
||||
[system param START_PADDING_TIME] \
|
||||
[system param STOP_PADDING_TIME] \
|
||||
]
|
||||
}
|
||||
|
||||
proc {system instandby} {} {
|
||||
return [system param LAST_STANDBY Value USERCONFIG]
|
||||
}
|
||||
|
||||
proc {system mkdir_p} {dir} {
|
||||
exec /mod/bin/busybox/mkdir -p $dir
|
||||
}
|
||||
|
||||
proc {system dirblockers} {dir {permitted {".*"}}} {
|
||||
set fl {}
|
||||
foreach e [readdir -nocomplain $dir] {
|
||||
if {$e in {. ..}} continue
|
||||
if {[file isdirectory "$dir/$e"]} {
|
||||
lappend fl $e
|
||||
continue
|
||||
}
|
||||
set flag 1
|
||||
foreach p $permitted {
|
||||
if {[string match -nocase $p $e]} {
|
||||
set flag 0
|
||||
break
|
||||
}
|
||||
}
|
||||
if {$flag} {
|
||||
lappend fl $e
|
||||
}
|
||||
}
|
||||
return $fl
|
||||
}
|
||||
|
||||
proc {system rmdir_if_empty} {dir {permitted {".*"}}} {
|
||||
set fl [system dirblockers $dir $permitted]
|
||||
|
||||
if {![llength $fl]} {
|
||||
file delete -force $dir
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
proc {system listening} {{mport 0}} {
|
||||
set ret {}
|
||||
foreach line [split [exec /mod/bin/busybox/netstat -lntpw] "\n"] {
|
||||
# Remove repeated spaces
|
||||
regsub -all -- {[[:space:]]+} $line " " line
|
||||
# tcp 0 0 0.0.0.0:9955 0.0.0.0:* LISTEN 169/humaxtv
|
||||
lassign [split $line " "] x x x port x type app
|
||||
if {$type ne "LISTEN"} { continue }
|
||||
lassign [split $port ":"] x port
|
||||
|
||||
if {$mport && $mport != $port} { continue }
|
||||
lappend ret [list $port [split $app "/"]]
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
proc {system is_listening} {mport} {
|
||||
return [llength [system listening $mport]]
|
||||
}
|
||||
|
||||
proc {system logtimestamp} {} {
|
||||
return [clock format [clock seconds] -format "%d/%m/%Y %H:%M:%S"]
|
||||
}
|
||||
|
||||
proc {system _log} {log msg} {
|
||||
set logfd [open $log "a+"]
|
||||
puts $logfd "[system logtimestamp] - $msg"
|
||||
$logfd close
|
||||
}
|
||||
|
||||
proc {system log} {log msg} {
|
||||
system _log "/var/log/$log.log" $msg
|
||||
}
|
||||
|
||||
proc {system plog} {log msg} {
|
||||
system _log "/mod/tmp/$log.log" $msg
|
||||
}
|
||||
|
||||
proc {system notify} {msg} {
|
||||
system plog notify $msg
|
||||
}
|
||||
|
||||
proc {system display} {hdr hd} {
|
||||
if {[system model] eq "HDR"} {
|
||||
exec /sbin/display $hdr
|
||||
} else {
|
||||
exec /sbin/display "\$$hd"
|
||||
}
|
||||
}
|
||||
|
||||
proc {system tuners} {} {
|
||||
if {[system model] eq "HDR"} {
|
||||
return 2
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
proc {system uptime} {} {
|
||||
set fd [open /proc/uptime r]
|
||||
set uptime [lindex [split [read $fd]] 0]
|
||||
$fd close
|
||||
return $uptime
|
||||
}
|
||||
|
||||
proc {system filename} {str {extra ""}} {
|
||||
# Humax TV replaces these characters.
|
||||
# "%*./:<>?\|
|
||||
set chars "\"%*\./:<>?\\\\|$extra"
|
||||
return [regsub -all -- "\[$chars]" $str "_"]
|
||||
}
|
||||
|
||||
proc {system connectivity} {{site "hpkg.tv"} {port 80} {ret "0"}} {
|
||||
set extra [lassign [exec /mod/bin/tcpping $site $port] result]
|
||||
if {$ret ne "0"} { upvar $ret err }
|
||||
switch $result {
|
||||
OK { return 1 }
|
||||
default {
|
||||
set err [list $result $extra]
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc {system nuggeted} {} {
|
||||
if {![system pkginst nugget]} { return 0 }
|
||||
if {[system nugget ping] eq "PONG"} {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
proc {system nugget} {args} {
|
||||
if {[catch {set ret [exec /mod/bin/nugget {*}$args]} msg]} {
|
||||
return ""
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
proc {system strip} {str} {
|
||||
if {[string range $str 1 2] eq "i7"} {
|
||||
# ISO6937, convert to UTF-8
|
||||
return [xconv [string range $str 3 end]]
|
||||
}
|
||||
if {[string first "\025" $str] == 0} {
|
||||
# UTF-8
|
||||
return [string range $str 1 end]
|
||||
}
|
||||
return [xconv $str]
|
||||
}
|
||||
|
||||
proc {system usbdisks} {{full 0}} {
|
||||
set disks [lmap i [glob -nocomplain \
|
||||
-directory /sys/bus/usb/drivers/usb-storage *:*] {
|
||||
file tail $i
|
||||
}]
|
||||
if {!$full} {
|
||||
return [llength $disks]
|
||||
}
|
||||
if {![llength $disks]} { return {} }
|
||||
|
||||
# Build list of device to device ID
|
||||
set map {}
|
||||
foreach block [glob -nocomplain -directory /sys/block sd?] {
|
||||
set link [file readlink $block/device]
|
||||
foreach disk $disks {
|
||||
if {[string first "/$disk/" $link] >= 0} {
|
||||
set map([file tail $block]) $disk
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $map
|
||||
}
|
||||
|
||||
proc {system usbmounts} {{full 0}} {
|
||||
if {!$full} {
|
||||
set num 0
|
||||
catch {
|
||||
set num [
|
||||
exec grep -cE {^/dev/sd[a-z][1-9] /media/[^/]+ } \
|
||||
/proc/mounts]
|
||||
}
|
||||
return $num
|
||||
}
|
||||
set ret {}
|
||||
if {[catch {
|
||||
set lines [exec grep -E {^/dev/sd[a-z][1-9] /media/[^/]+ } \
|
||||
/proc/mounts]
|
||||
}]} { return $ret }
|
||||
foreach line [split $lines "\n"] {
|
||||
lassign $line dev mp
|
||||
set rec "DEV {$dev} MP {$mp} LABEL {NO NAME} TYPE Unknown"
|
||||
|
||||
set rec(VENDOR) Unknown
|
||||
set rec(MODEL) Unknown
|
||||
|
||||
if {[regexp {/dev/(sd[a-z])} $dev x rdev]} {
|
||||
set rec(RDEV) $rdev
|
||||
if {[file readable [
|
||||
set f /sys/block/$rdev/device/vendor]]} {
|
||||
set rec(VENDOR) [string trim [file read $f]]
|
||||
}
|
||||
if {[file readable [
|
||||
set f /sys/block/$rdev/device/model]]} {
|
||||
set rec(MODEL) [string trim [file read $f]]
|
||||
}
|
||||
}
|
||||
|
||||
lassign [exec stat -f -c {%S %b %f} $mp] blocks blockc blockf
|
||||
set rec(SIZE) $($blockc * $blocks)
|
||||
set rec(USED) $(100 - $blockf * 100 / $blockc)
|
||||
|
||||
# /dev/sda1: LABEL="SAN" UUID="DBC1-1CF8" TYPE="vfat"
|
||||
catch {
|
||||
foreach field [
|
||||
split [exec /mod/sbin/blkid -c /dev/null $dev] "\n"] {
|
||||
while {[regexp { *([A-Z]+)="?([^"]+)"?(.*)} \
|
||||
$field x k v field]} {
|
||||
set rec($k) $v
|
||||
}
|
||||
}
|
||||
}
|
||||
# Test for EXFAT
|
||||
if {$rec(TYPE) eq "Unknown" && [
|
||||
file exists /mod/sbin/exfatlabel]} {
|
||||
catch {
|
||||
set label [exec /mod/sbin/exfatlabel $dev 2>/dev/null]
|
||||
if {$label ne ""} {
|
||||
set rec(TYPE) "EXFAT"
|
||||
set rec(LABEL) $label
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lappend ret $rec
|
||||
}
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
proc {system has} {comp} {
|
||||
switch $comp {
|
||||
wifi_dongle {
|
||||
if {[catch {exec /mod/bin/iwgetid}]} { return 0 }
|
||||
return 1
|
||||
}
|
||||
tvdb {
|
||||
require settings.class
|
||||
return [[settings] _nval_setting tvdb]
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# Note that {system checkop} can be called from processes other than that
|
||||
# which started the operation. Hence no visilibty into the ::system::ops
|
||||
# dictionary.
|
||||
proc {system checkop} {op} {
|
||||
if {![regexp -nocase -- {^[.a-z0-9]+$} $op]} { return 0 }
|
||||
if {[catch {set fp [open "/tmp/.bgop.$op" "a"]}]} {
|
||||
return 0
|
||||
}
|
||||
set ret 1
|
||||
if {[$fp lock]} {
|
||||
$fp unlock
|
||||
set ret 0
|
||||
}
|
||||
$fp close
|
||||
return $ret
|
||||
}
|
||||
|
||||
set ::system::ops {}
|
||||
|
||||
proc {system startop} {args op file} {
|
||||
if {![regexp -nocase -- {^[a-z0-9]+$} $op]} { return 0 }
|
||||
if {"-multiple" in $args} {
|
||||
set i 0
|
||||
append op "[pid]."
|
||||
while {[dict exists $::system::ops "$op$i"]} { incr i }
|
||||
append op $i
|
||||
} elseif {[dict exists $::system::ops $op]} {
|
||||
system endop $op
|
||||
}
|
||||
if {[catch {
|
||||
set fp [open "/tmp/.bgop.$op" "a"]
|
||||
if {[$fp lock]} {
|
||||
$fp puts "$file\n[pid]"
|
||||
$fp flush
|
||||
set ::system::ops($op) $fp
|
||||
} else {
|
||||
$fp close
|
||||
error "Could not lock op file."
|
||||
}
|
||||
}]} { return 0 }
|
||||
return $op
|
||||
}
|
||||
|
||||
proc {system endop} {op} {
|
||||
if {![regexp -nocase -- {^[.a-z0-9]+$} $op]} { return 0 }
|
||||
if {[dict exists $::system::ops $op]} {
|
||||
catch {
|
||||
set fp $::system::ops($op)
|
||||
$fp unlock
|
||||
$fp close
|
||||
}
|
||||
dict unset ::system::ops $op
|
||||
}
|
||||
if {[file exists "/tmp/.bgop.$op"]} {
|
||||
file delete "/tmp/.bgop.$op"
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
proc {system specialdir} {dir} {
|
||||
if {[string match {\[*} [string trimleft [file tail $dir]]]} {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
|
@ -339,7 +339,7 @@ ts method setgenre {newgenre} {
|
|||
}
|
||||
|
||||
ts method dlnaloc {{urlbase ""}} {
|
||||
return [system dlnaurl $file $urlbase]
|
||||
return [system dlnaurl [file normalize $file] $urlbase]
|
||||
}
|
||||
|
||||
ts method cleanbmp {} {
|
||||
|
|
|
@ -0,0 +1,899 @@
|
|||
|
||||
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
|
||||
|
||||
set tsgroup {ts nts hmt thm}
|
||||
|
||||
class ts {
|
||||
file ""
|
||||
base ""
|
||||
title ""
|
||||
synopsis ""
|
||||
definition ""
|
||||
channel_num 0
|
||||
channel_name ""
|
||||
start 0
|
||||
end 0
|
||||
flags ""
|
||||
error ""
|
||||
guidance ""
|
||||
bookmarks 0
|
||||
schedstart 0
|
||||
scheddur 0
|
||||
genre 0
|
||||
resume 0
|
||||
status ""
|
||||
series ""
|
||||
|
||||
seriescached 1
|
||||
seriesnum 0
|
||||
episodenum 0
|
||||
episodetot 0
|
||||
episodename ""
|
||||
tvdb_method ""
|
||||
tvdb_series {}
|
||||
tvdb_data {}
|
||||
}
|
||||
|
||||
ts method bfile {} {
|
||||
return [file tail [file rootname $file]]
|
||||
}
|
||||
|
||||
ts method dir {} {
|
||||
return [file dirname $file]
|
||||
}
|
||||
|
||||
ts method duration {{raw 0}} {
|
||||
set d [expr $end - $start]
|
||||
if {!$raw} { set d $($d / 60) }
|
||||
return $d
|
||||
}
|
||||
|
||||
ts method size {} {
|
||||
return [file size $file]
|
||||
}
|
||||
|
||||
ts method _parse {line} {
|
||||
set vars [split $line "\t"]
|
||||
|
||||
lassign [split $line "\t"] \
|
||||
title synopsis definition channel_num channel_name \
|
||||
start end flags_list guidance bookmarks schedstart scheddur \
|
||||
genre resume status seriesnum episodenum episodetot
|
||||
|
||||
set synopsis [xconv $synopsis]
|
||||
|
||||
set flags [split [string range $flags_list 0 end-1] ,]
|
||||
}
|
||||
|
||||
ts method lastmod {} {
|
||||
return [file mtime "[file rootname $file].hmt"]
|
||||
}
|
||||
|
||||
ts method inuse {} {
|
||||
return [system inuse $file]
|
||||
}
|
||||
|
||||
ts method bookmarks {{aslist 0}} {
|
||||
set marks [split [string trim [exec /mod/bin/hmt -bookmarks $file]]]
|
||||
if {$aslist} { return $marks }
|
||||
return [join $marks " "]
|
||||
}
|
||||
|
||||
ts method setbookmarks {marks} {
|
||||
exec /mod/bin/hmt +setbookmarks=[join $marks :] $file
|
||||
}
|
||||
|
||||
ts method storeepisode {{data {}}} {
|
||||
if {[llength $data]} {
|
||||
set d [join $data ","]
|
||||
} else {
|
||||
set d "$seriesnum,$episodenum,$episodetot"
|
||||
}
|
||||
exec /mod/bin/hmt +setseries=$d $file
|
||||
}
|
||||
|
||||
ts method clearepdata {} {
|
||||
set seriesnum 0
|
||||
set episodenum 0
|
||||
set episodetot 0
|
||||
}
|
||||
|
||||
ts method flag {f} {
|
||||
if {$f in $flags} {return 1} else {return 0}
|
||||
}
|
||||
|
||||
ts method unflag {f} {
|
||||
lremove flags $f
|
||||
}
|
||||
|
||||
ts method unlock {} {
|
||||
set cmd [list /mod/bin/hmt -lock $file]
|
||||
exec {*}$cmd
|
||||
lremove flags "Locked"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method lock {} {
|
||||
set cmd [list /mod/bin/hmt +lock $file]
|
||||
exec {*}$cmd
|
||||
ladd flags "Locked"
|
||||
return 1
|
||||
}
|
||||
|
||||
set ::ts::flagmap {
|
||||
detectads Addetection
|
||||
dedup Deduped
|
||||
encrypted ODEncrypted
|
||||
protect Encrypted
|
||||
}
|
||||
|
||||
ts method setflag {flag {dummy 0}} {
|
||||
if {!$dummy} {
|
||||
set cmd [list /mod/bin/hmt +$flag $file]
|
||||
if {[catch {exec {*}$cmd}]} {
|
||||
throw 20 "Unknown flag."
|
||||
}
|
||||
}
|
||||
if {[dict exists $::ts::flagmap $flag]} {
|
||||
ladd flags $::ts::flagmap($flag)
|
||||
} else {
|
||||
ladd flags [string totitle $flag]
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method unsetflag {flag {dummy 0}} {
|
||||
if {!$dummy} {
|
||||
set cmd [list /mod/bin/hmt -$flag $file]
|
||||
if {[catch {exec {*}$cmd}]} {
|
||||
throw 20 "Unknown flag."
|
||||
}
|
||||
}
|
||||
if {[dict exists $::ts::flagmap $flag]} {
|
||||
lremove flags $::ts::flagmap($flag)
|
||||
} else {
|
||||
lremove flags [string totitle $flag]
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method set_shrunk {} {
|
||||
set cmd [list /mod/bin/hmt +shrunk $file]
|
||||
exec {*}$cmd
|
||||
ladd flags "Shrunk"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method set_deduped {} {
|
||||
set cmd [list /mod/bin/hmt +dedup $file]
|
||||
exec {*}$cmd
|
||||
ladd flags "Deduped"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method unset_deduped {} {
|
||||
set cmd [list /mod/bin/hmt -dedup $file]
|
||||
exec {*}$cmd
|
||||
lremove flags "Deduped"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method unenc {} {
|
||||
set cmd [list /mod/bin/hmt -protect $file]
|
||||
exec {*}$cmd
|
||||
lremove flags "Encrypted"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method enc {} {
|
||||
set cmd [list /mod/bin/hmt +protect $file]
|
||||
exec {*}$cmd
|
||||
ladd flags "Encrypted"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method set_new {} {
|
||||
set cmd [list /mod/bin/hmt +new $file]
|
||||
exec {*}$cmd
|
||||
ladd flags "New"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method set_watched {} {
|
||||
set cmd [list /mod/bin/hmt -new $file]
|
||||
exec {*}$cmd
|
||||
lremove flags "New"
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method setfile {f} { set file $f }
|
||||
|
||||
proc {ts parse} {file line} {
|
||||
set e [ts new]
|
||||
$e setfile $file
|
||||
$e _parse $line
|
||||
return $e
|
||||
}
|
||||
|
||||
proc {ts exec} {file} {
|
||||
set raw 0
|
||||
set cmd [list /mod/bin/hmt]
|
||||
lappend cmd "-p"
|
||||
lappend cmd $file
|
||||
|
||||
#puts "CMD -$cmd-"
|
||||
|
||||
return [exec {*}$cmd]
|
||||
}
|
||||
|
||||
ts method fileset {} {
|
||||
global tsgroup
|
||||
|
||||
set root [file rootname $file]
|
||||
set fset {}
|
||||
foreach ext $tsgroup {
|
||||
if {[file exists "$root.$ext"]} {
|
||||
lappend fset "$root.$ext"
|
||||
}
|
||||
}
|
||||
return $fset
|
||||
}
|
||||
|
||||
proc {ts fetch_or_error} {file {checked 0}} {
|
||||
if {[catch {set ts [ts fetch $file $checked]}] || $ts == 0} {
|
||||
print "Could not load ts file $file"
|
||||
return 0
|
||||
}
|
||||
return $ts
|
||||
}
|
||||
|
||||
proc {ts fetch} {file {checked 0}} {
|
||||
# Check that this is a .ts file which has at least one sidecar
|
||||
# file (.hmt)
|
||||
if {!$checked} {
|
||||
if {[file extension $file] ne ".ts"} { return 0 }
|
||||
if {![file exists "[file rootname $file].hmt"]} { return 0 }
|
||||
}
|
||||
|
||||
if {[file extension $file] ne ".ts"} {
|
||||
set file "[file rootname $file].ts"
|
||||
}
|
||||
|
||||
return [ts parse $file [ts exec $file]]
|
||||
}
|
||||
|
||||
ts method delete {} {
|
||||
foreach f [$self fileset] {
|
||||
file tdelete $f
|
||||
puts "Removed $f<br>"
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method move {dst {touch 0} {force 0}} {
|
||||
foreach f [$self fileset] {
|
||||
set nf "$dst/[file tail $f]"
|
||||
while {[file exists $nf]} {
|
||||
set nf "$dst/_[file tail $nf]"
|
||||
}
|
||||
file rename $f $nf
|
||||
if {$touch} {
|
||||
exec /mod/bin/busybox/touch $nf
|
||||
}
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method copy {dst} {
|
||||
foreach f [$self fileset] {
|
||||
file copy $f "$dst/[file tail $f]"
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
ts method settitle {newtitle} {
|
||||
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 }
|
||||
|
||||
exec /mod/bin/hmt "+setsynopsis=${newsynopsis}" $file
|
||||
set synopsis $newsynopsis
|
||||
}
|
||||
|
||||
ts method setguidance {newguidance} {
|
||||
if {[string length $newguidance] > 74} { return }
|
||||
|
||||
if {$newguidance eq ""} {
|
||||
exec /mod/bin/hmt "-guidance" $file
|
||||
} else {
|
||||
exec /mod/bin/hmt "+setguidance=${newguidance}" $file
|
||||
}
|
||||
set guidance $newguidance
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
ts method dlnaloc {{urlbase ""}} {
|
||||
return [system dlnaurl $file $urlbase]
|
||||
}
|
||||
|
||||
ts method cleanbmp {} {
|
||||
set bfile [file rootname $file]
|
||||
foreach f [glob -nocomplain "${bfile}*.bmp"] {
|
||||
file delete $f
|
||||
}
|
||||
}
|
||||
|
||||
ts method mkbmps {{offset 0}} {
|
||||
set bfile [file rootname $file]
|
||||
if {[catch {
|
||||
exec /mod/bin/ffmpeg -loglevel fatal -ss $offset -i $file \
|
||||
-vf fps=fps=2 -frames 5 \
|
||||
-pix_fmt argb -vf vflip -s 140x78 "${bfile}%d.bmp"
|
||||
} msg]} {
|
||||
puts "ERROR: $msg"
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
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 -y $bmpfile]
|
||||
catch { exec {*}$cmd }
|
||||
if {![catch { file stat $bmpfile stbmp }]} {
|
||||
if {[dict get $stbmp size] != 0} { return 1 }
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
ts method mkthm {{offset 0}} {
|
||||
if {![$self mkbmp $offset]} { return 0 }
|
||||
set bfile [file rootname $file]
|
||||
# Trim the bitmap header from the start of the file
|
||||
if {[catch {
|
||||
exec /bin/dd if=$bfile.bmp of=$bfile.thm~ bs=54 skip=1
|
||||
} msg]} {
|
||||
puts "ERROR: $msg"
|
||||
return 0
|
||||
}
|
||||
exec /bin/echo -n " " >> $bfile.thm~
|
||||
file rename -force $bfile.thm~ $bfile.thm
|
||||
file tdelete $bfile.bmp
|
||||
$self setflag thumbnail
|
||||
return 1
|
||||
}
|
||||
|
||||
# From MontysEvilTwin
|
||||
# - https://hummy.tv/forum/threads/7787/page-2#post-106826
|
||||
# ffmpeg -i "File 1.ts" -c:a mp3 -b:a 128k "File 1.mp3"
|
||||
# ffmpeg -i "File 1.ts" -c:a copy "File 1.mp2"
|
||||
# ffmpeg -i "File 1.ts" -c:a copy "File 1.loas"
|
||||
ts method mkmp3 {{slow false} {tmp ""} {v 0} {br 128}} {
|
||||
set rfile [file rootname $file]
|
||||
|
||||
if {$slow} {
|
||||
set opts [list -c:a mp3 -b:a ${br}k]
|
||||
set ext mp3
|
||||
} else {
|
||||
set opts [list -c:a copy]
|
||||
if {$definition eq "HD"} {
|
||||
set ext loas
|
||||
} else {
|
||||
set ext mp2
|
||||
}
|
||||
}
|
||||
set cmd [list /mod/bin/ffmpeg \
|
||||
-y -benchmark -vn -v $v \
|
||||
-i $file {*}$opts \
|
||||
]
|
||||
|
||||
if {$tmp eq ""} {
|
||||
lappend cmd "${rfile}.$ext"
|
||||
} else {
|
||||
lappend cmd "$tmp.$ext"
|
||||
}
|
||||
|
||||
set output [exec {*}$cmd]
|
||||
|
||||
if {$tmp ne ""} {
|
||||
file rename "$tmp.$ext" "${rfile}.mp3"
|
||||
} elseif {$ext ne "mp3"} {
|
||||
file rename "${rfile}.$ext" "${rfile}.mp3"
|
||||
}
|
||||
|
||||
exec /mod/bin/id3v2 \
|
||||
--song $title \
|
||||
--comment $synopsis \
|
||||
--album $channel_name \
|
||||
--year "[clock format $start -format {%Y}]" \
|
||||
"${rfile}.mp3"
|
||||
|
||||
return $output
|
||||
}
|
||||
|
||||
ts method mkmpg {{tmp ""}} {
|
||||
set rfile [file rootname $file]
|
||||
|
||||
set cmd [list /mod/bin/ffmpeg \
|
||||
-y -benchmark -v 0 \
|
||||
-i $file \
|
||||
-map 0:0 -map 0:1 \
|
||||
-vcodec copy -acodec copy]
|
||||
|
||||
if {$tmp eq ""} {
|
||||
lappend cmd "${rfile}.mpg"
|
||||
} else {
|
||||
lappend cmd "$tmp.mpg"
|
||||
}
|
||||
|
||||
set output [exec {*}$cmd]
|
||||
|
||||
if {$tmp ne ""} {
|
||||
file rename "$tmp.mpg" "${rfile}.mpg"
|
||||
}
|
||||
|
||||
return $output
|
||||
}
|
||||
|
||||
proc {ts renamegroup} {from to} {
|
||||
global tsgroup
|
||||
|
||||
set dir [file dirname $from]
|
||||
set root [file rootname $from]
|
||||
|
||||
# Catch from string without a . character in it
|
||||
if {$root eq $from} { return }
|
||||
|
||||
foreach ext $tsgroup {
|
||||
set f "$root.$ext"
|
||||
if {![file exists $f]} continue
|
||||
file rename $f "${dir}/${to}.${ext}"
|
||||
}
|
||||
|
||||
exec /mod/bin/hmt "+setfilename=$to" "${dir}/${to}.hmt"
|
||||
|
||||
# set ndir [file normalize $dir]
|
||||
#
|
||||
# if {![catch {set db [sqlite3.open $::dmsfile]}]} {
|
||||
# catch {
|
||||
# set x [lindex [$db query {select mediaid from tblMedia
|
||||
# where localUrl = '%s'} [file normalize $from]] 0]
|
||||
# lassign $x key mediaid
|
||||
# if {$mediaid ne ""} {
|
||||
# $db query {update tblMedia set localUrl = '%s'
|
||||
# where mediaid = %s} "${ndir}/{$to}.ts" $mediaid
|
||||
# $db query {update tblMedia set title = '%s'
|
||||
# where mediaid = %s} "{$to}.ts" $mediaid
|
||||
# }
|
||||
# }
|
||||
# $db close
|
||||
# }
|
||||
}
|
||||
|
||||
proc {ts touchgroup} {target ref} {
|
||||
global tsgroup
|
||||
|
||||
set dir [file dirname $target]
|
||||
set root [file rootname $target]
|
||||
|
||||
# Catch from string without a . character in it
|
||||
if {$root eq $target} { return }
|
||||
|
||||
foreach ext $tsgroup {
|
||||
set f "$root.$ext"
|
||||
if {![file exists $f]} continue
|
||||
file touch $f $ref
|
||||
}
|
||||
}
|
||||
|
||||
proc {ts resetnew} {dir} {
|
||||
if {![file isdirectory $dir]} return
|
||||
if {![file exists "$dir/.series"]} {
|
||||
set fd [open "$dir/.series" "w"]
|
||||
puts -nonewline $fd [string repeat "\x0" 276]
|
||||
close $fd
|
||||
}
|
||||
|
||||
set tot 0
|
||||
set watched 0
|
||||
foreach file [readdir -nocomplain $dir] {
|
||||
if {![string match {*.ts} $file]} { continue }
|
||||
incr tot
|
||||
if {[set ts [ts fetch "$dir/$file"]] != 0} {
|
||||
if {![$ts flag "New"]} { incr watched }
|
||||
}
|
||||
}
|
||||
|
||||
if {!$tot} {
|
||||
file delete "$dir/.series"
|
||||
return
|
||||
}
|
||||
|
||||
set fd [open "$dir/.series"]
|
||||
set bytes [read $fd]
|
||||
close $fd
|
||||
set recs [unpack $bytes -uintle 0 32]
|
||||
set played [unpack $bytes -uintle 32 32]
|
||||
|
||||
#puts "Current: $played/$recs"
|
||||
#hexdump $bytes
|
||||
#puts "Calculated: $watched/$tot"
|
||||
|
||||
pack bytes $tot -intle 32 0
|
||||
pack bytes $watched -intle 32 32
|
||||
|
||||
#hexdump $bytes
|
||||
|
||||
set fd [open "$dir/.series" "w"]
|
||||
puts -nonewline $fd $bytes
|
||||
close $fd
|
||||
}
|
||||
|
||||
proc {ts iterate} {callback {verbose 0} {dir ""} {nospecial 0}} {{rootdev 0}} {
|
||||
require system.class
|
||||
if {$dir eq ""} {
|
||||
set dir [system mediaroot]
|
||||
file stat "$dir/" rootstat
|
||||
set rootdev $rootstat(dev)
|
||||
}
|
||||
|
||||
if {$verbose} { puts "Scanning directory ($dir)" }
|
||||
|
||||
if {$rootdev != 0} {
|
||||
file stat "$dir/" st
|
||||
if {$st(dev) != $rootdev} return
|
||||
}
|
||||
|
||||
if {$nospecial && [system specialdir $dir]} return
|
||||
|
||||
foreach entry [readdir -nocomplain $dir] {
|
||||
if {[file isdirectory "$dir/$entry"]} {
|
||||
ts iterate $callback $verbose "$dir/$entry" $nospecial
|
||||
continue
|
||||
}
|
||||
if {![string match {*.ts} $entry]} continue
|
||||
if {[catch {set ts [ts fetch "$dir/$entry"]}]} continue
|
||||
if {$ts == 0} continue
|
||||
$callback $ts
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Attempt to extract the series/episode names using a variety of techniques
|
||||
#
|
||||
|
||||
ts method series_name {} {
|
||||
|
||||
# For recorded series, use the folder name
|
||||
set dir [file dirname $file]
|
||||
if {[file exists "$dir/.series"]} {
|
||||
set s [file tail $dir]
|
||||
} else {
|
||||
set s $title
|
||||
}
|
||||
|
||||
foreach x {
|
||||
{^new: *}
|
||||
} {
|
||||
regsub -nocase -all -- $x $s "" s
|
||||
}
|
||||
|
||||
return $s
|
||||
}
|
||||
|
||||
set ::ts::episode_prefixes {
|
||||
{^new series\.* *}
|
||||
{^cbeebies\.* *}
|
||||
{^cbbc\.* *}
|
||||
{^t4: *}
|
||||
{^brand new series *[-:]* *}
|
||||
{^\.+}
|
||||
{ *\(Part [0-9] of [0-9]\) *}
|
||||
{, Part [0-9]}
|
||||
}
|
||||
|
||||
ts method _tvdb_resolve {seriesid} {
|
||||
# See if we can find a TVDB series for this recording.
|
||||
|
||||
set dir [file dirname $file]
|
||||
|
||||
set tvdb_series [set v [tvdb series "" $seriesid]]
|
||||
if {[$v get seriesid] == 0} { return }
|
||||
|
||||
# Got one.
|
||||
|
||||
# Easiest case - we can explicitly request the episode.
|
||||
if {$seriesnum && $episodenum} {
|
||||
if {$seriescached} {
|
||||
set tvdb_method "cached values"
|
||||
} else {
|
||||
set tvdb_method "series and episode number"
|
||||
}
|
||||
return [$v episodebynum $seriesnum $episodenum]
|
||||
}
|
||||
|
||||
# Now try to find the episode using the current episode name
|
||||
# (using series or episode number if available)
|
||||
set k [$v episodebyname $episodename $seriesnum $episodenum]
|
||||
if {[llength $k]} {
|
||||
set tvdb_method "episode name ($episodename)"
|
||||
return $k
|
||||
}
|
||||
|
||||
# More problematic but can at least narrow the list of candidates
|
||||
# using the episode or series numbers if we have them.
|
||||
|
||||
if {$episodenum} {
|
||||
set tvdb_method "episode number"
|
||||
return [$v episodebyepnum $episodenum $synopsis]
|
||||
}
|
||||
|
||||
if {$seriesnum} {
|
||||
set tvdb_method "series and synopsis"
|
||||
return [$v episodebyseries $seriesnum $synopsis]
|
||||
}
|
||||
|
||||
# Most difficult - try and match based on synopsis alone
|
||||
set tvdb_method "synopsis text"
|
||||
return [$v episodebysynopsis $synopsis]
|
||||
}
|
||||
|
||||
proc {ts serieslist} {dir} {
|
||||
set idfile "$dir/.tvdbseriesid"
|
||||
if {![file exists $idfile]} { return {} }
|
||||
return [lmap i [split [file read $idfile] "\n"] {
|
||||
string trim $i
|
||||
}]
|
||||
}
|
||||
|
||||
ts method extract_numbers {} {
|
||||
|
||||
######################################################################
|
||||
# Check for embedded Series/Episode number.
|
||||
# Thank you broadcasters for the variation!
|
||||
# Least trustworthy first.
|
||||
|
||||
# Episode 5
|
||||
regexp -nocase -- {Episode (\d+)} $synopsis x episodenum
|
||||
|
||||
# ^23/27.
|
||||
regexp -nocase -- {^\s*(\d+)/(\d+)} $synopsis x episodenum episodetot
|
||||
|
||||
# (8/8)
|
||||
regexp -nocase -- {\((\d+)/(\d+)\)} $synopsis x episodenum episodetot
|
||||
|
||||
# (Episode 5/10)
|
||||
# (Ep5/10)
|
||||
# (Ep 3 of 3)
|
||||
# (Ep3)
|
||||
regexp -nocase -- {Epi?s?o?d?e?\s*(\d+)\s*(of|/)?\s*(\d+)?} $synopsis \
|
||||
x episodenum x episodetot
|
||||
|
||||
# (S2 Ep1)
|
||||
# S.02 Ep.002
|
||||
# S01 Ep52
|
||||
# (S4 Ep 7)
|
||||
# (S1, ep 2)
|
||||
# (S8, Ep2)
|
||||
# (S4 Ep22/24)
|
||||
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
|
||||
} else {
|
||||
incr $v 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ts method episode_name {} {
|
||||
set s $synopsis
|
||||
|
||||
######################################################################
|
||||
# Attempt to determine the episode name from the synopsis
|
||||
|
||||
# Strip common prefixes
|
||||
foreach prefix $::ts::episode_prefixes {
|
||||
regsub -nocase -all -- $prefix $s "" s
|
||||
}
|
||||
|
||||
# Strip anything following a colon.
|
||||
regsub -all -- { *[:].*$} $s "" s
|
||||
|
||||
# If the resulting string is longer than 40 characters then
|
||||
# split around . and take the left hand side if appropriate.
|
||||
if {[string length $s] > 40} {
|
||||
lassign [split $s "."] v w
|
||||
set s $v
|
||||
if {[string length $s] < 6 && [string length $w] < 6} {
|
||||
append s "_$w"
|
||||
}
|
||||
}
|
||||
|
||||
# Shorten if too long.
|
||||
if {[string length $s] > 40} { set s [string range $s 0 39] }
|
||||
|
||||
set episodename $s
|
||||
|
||||
if {$episodenum == 0} {
|
||||
$self extract_numbers
|
||||
set seriescached 0
|
||||
}
|
||||
|
||||
# Now see if TVDB has anything to add
|
||||
|
||||
set fbase "[file dirname $file]/.tvdb"
|
||||
|
||||
if {![system has tvdb] || ![file exists "${fbase}seriesid"]} {
|
||||
return $s
|
||||
}
|
||||
|
||||
if {!$seriesnum && [file exists "${fbase}series"]} {
|
||||
set seriesnum [string trim [file read "${fbase}series"]]
|
||||
}
|
||||
foreach seriesid [ts serieslist [$self dir]] {
|
||||
set tvdb_data [$self _tvdb_resolve $seriesid]
|
||||
if {![dict exists $tvdb_data name]} continue
|
||||
set flag 0
|
||||
if {!$seriesnum} {
|
||||
set seriesnum $tvdb_data(series)
|
||||
incr flag
|
||||
}
|
||||
if {!$episodenum} {
|
||||
set episodenum $tvdb_data(episode)
|
||||
incr flag
|
||||
}
|
||||
if {$flag} { $self storeepisode }
|
||||
|
||||
return $tvdb_data(name)
|
||||
}
|
||||
|
||||
return $s
|
||||
}
|
||||
|
||||
ts method epstr {{format "s%se%E/%n"}} {
|
||||
set map {}
|
||||
if {$seriesnum eq 0} {
|
||||
set map(%s) "?"
|
||||
set map(%S) "??"
|
||||
} else {
|
||||
set map(%s) $seriesnum
|
||||
set map(%S) [format "%02d" $seriesnum]
|
||||
}
|
||||
if {$episodenum eq 0} {
|
||||
set map(%e) "?"
|
||||
set map(%E) "??"
|
||||
} else {
|
||||
set map(%e) $episodenum
|
||||
set map(%E) [format "%02d" $episodenum]
|
||||
}
|
||||
if {$episodetot eq 0} {
|
||||
set map(%n) "?"
|
||||
set map(%N) "??"
|
||||
} else {
|
||||
set map(%n) $episodetot
|
||||
set map(%N) [format "%02d" $episodetot]
|
||||
}
|
||||
return [string map $map $format]
|
||||
}
|
||||
|
||||
ts method tsr {} {
|
||||
set fd [open "[file rootname $file].nts"]
|
||||
set bytes [read $fd 0x20]
|
||||
close $fd
|
||||
set tsr [unpack $bytes -uintle $(8 * 0x1f) 8]
|
||||
return $tsr
|
||||
}
|
||||
|
||||
ts method genrenib {} {
|
||||
if {[catch {set v $($genre >> 4)}]} { set v 0 }
|
||||
return $v
|
||||
}
|
||||
|
||||
ts method genre_info {} {
|
||||
set g [$self genrenib]
|
||||
lassign $::epg::genrelist($g) txt img
|
||||
if {$img eq "Unclassified"} {
|
||||
set img "/images/173_3_26_G3_$img.png"
|
||||
} else {
|
||||
set img "/images/173_3_00_G3_$img.png"
|
||||
}
|
||||
return [list $txt $img]
|
||||
}
|
||||
|
||||
proc {ts genrelist} {} {
|
||||
require epg.class
|
||||
set glist {}
|
||||
foreach {k v} $::epg::genrelist {
|
||||
lappend glist $($k << 4) $v
|
||||
}
|
||||
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?
|
||||
set key [system customencryptionkey]
|
||||
if {$key ne ""} {
|
||||
ladd keys $key
|
||||
}
|
||||
|
||||
# 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
|
||||
}
|
||||
|
Loading…
Reference in New Issue