forked from hummypkg/webif
423 lines
9.4 KiB
Tcl
Executable File
423 lines
9.4 KiB
Tcl
Executable File
#!/mod/bin/jimsh
|
|
|
|
package require cgi
|
|
source /mod/webif/lib/setup
|
|
require system.class epg.class rsv.class svc.class plugin
|
|
|
|
set runmode cli
|
|
if {[string match {*jim} $argv0]} { set runmode cgi }
|
|
|
|
set schedtime 1200
|
|
switch $runmode {
|
|
cgi {
|
|
set type [cgi_get type "full"]
|
|
httpheader
|
|
}
|
|
cli {
|
|
set type "full"
|
|
if {[lsearch -nocase $argv "-x"] >= 0} { set schedtime 7200 }
|
|
}
|
|
}
|
|
|
|
if {"-d" in $argv} {
|
|
proc debug {arg} { puts $arg }
|
|
} else {
|
|
proc debug {arg} {}
|
|
}
|
|
|
|
if {[catch {set pid [exec pgrep -n humaxtv]}]} {
|
|
puts "Cannot find humaxtv process."
|
|
exit
|
|
}
|
|
|
|
set exts {.ts .avi .mpg .mpeg .wmv .mkv .mp3 .mp4 .mov .hmt .m4v .m4a}
|
|
|
|
set statusops {
|
|
decrypt { "Decrypting"
|
|
"/img/decrypt.png style=\"padding: 0 0.2em 0 0.5em\""
|
|
}
|
|
mpg { "Extracting MPG"
|
|
"/img/mpg.png style=\"padding: 0 0.2em 0 0.5em\""
|
|
}
|
|
mp { "Extracting MP3"
|
|
"/img/mp3.png style=\"padding: 0 0.2em 0 0.5em\""
|
|
}
|
|
shrink { "Shrinking"
|
|
"/img/compress.png style=\"padding: 0 0.2em 0 0.5em\""
|
|
}
|
|
crop { "Cropping"
|
|
"/img/cut.png style=\"padding: 0 0.2em 0 0.5em\""
|
|
}
|
|
join { "Joining"
|
|
"/img/cut.png style=\"padding: 0 0.2em 0 0.5em\""
|
|
}
|
|
}
|
|
|
|
proc register_statusop {op name icon} {
|
|
set ::statusops($op) [list $name $icon]
|
|
}
|
|
|
|
eval_plugins status 1
|
|
|
|
proc get_data {} {
|
|
global pid exts stream tsr tsrcnt
|
|
|
|
set ret {}
|
|
if {[catch {set data \
|
|
[exec /mod/webif/lib/bin/lsof -Fnsa -p $pid]} msg]} {
|
|
debug "Error: $msg"
|
|
set ret {}
|
|
} else {
|
|
set size 0
|
|
foreach line [split $data "\n"] {
|
|
set typ [string index $line 0]
|
|
switch $typ {
|
|
a {
|
|
set access [string index $line 1]
|
|
}
|
|
s {
|
|
set size [string range $line 1 end]
|
|
}
|
|
n {
|
|
# strip initial n and trailing " (...)" if
|
|
# present
|
|
regsub -all -- {(^n)|( \([^\)]+\)$)} \
|
|
$line "" line
|
|
set file [subst -nocommands -novariables $line]
|
|
set ext [file extension $line]
|
|
# Note but skip TSR buffers
|
|
if {[file rootname $file] eq $tsr} {
|
|
if {$ext eq ".nts"} {
|
|
incr tsrcnt
|
|
}
|
|
continue
|
|
}
|
|
|
|
if {[string first Video/ $line] >= 0 ||
|
|
[string first /media/ $line] >= 0} {
|
|
if {$ext ni $exts} {
|
|
continue
|
|
}
|
|
} elseif {[string first $line /] >= 0} {
|
|
# fast skip other files
|
|
continue
|
|
} elseif {[regexp -- {[A-Za-z0-9._-]+:([0-9]+)->([A-Za-z0-9._-]+):([0-9]+)} $line _ sprt host dprt]} {
|
|
if {$sprt == 9000} {
|
|
incr stream
|
|
continue
|
|
} elseif {$dprt == 9000} {
|
|
set file [\
|
|
format "DLNA from %s" $host]
|
|
set size 0
|
|
set ext ""
|
|
} else {
|
|
continue
|
|
}
|
|
} else {
|
|
continue
|
|
}
|
|
# Handle chase play (same file open twice
|
|
# and recently written)
|
|
if {[dict exists $ret $file] &&
|
|
$ext eq ".ts"} {
|
|
set age [expr [clock seconds] \
|
|
- [file mtime $file]]
|
|
if {$age < 60} {
|
|
set access [lindex \
|
|
[dict get $ret $file] 1]
|
|
set ret($file) [list -1 $access]
|
|
}
|
|
} else {
|
|
debug "$file = $size,$access"
|
|
set ret($file) [list $size $access]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach file [dict keys $::ops] {
|
|
if {![dict exists $ret $file]} {
|
|
set sz 0
|
|
if {[file exists $file]} { set sz [file size $file] }
|
|
set ret($file) [list $sz u]
|
|
}
|
|
}
|
|
return $ret
|
|
}
|
|
|
|
proc add_output {icon mode name} {
|
|
global runmode output
|
|
|
|
if {$runmode eq "cgi"} {
|
|
if {[string first "/" $icon] == -1} {
|
|
set icon "/images/$icon"
|
|
}
|
|
lappend output [concat \
|
|
"<span class=\"va stitem\">\n" \
|
|
" <img class=va src=$icon>\n" \
|
|
" <span>$mode <i>$name</i></span>\n" \
|
|
"</span>\n" \
|
|
]
|
|
} else {
|
|
lappend output "$mode $name"
|
|
}
|
|
}
|
|
|
|
set play 0
|
|
set rec 0
|
|
set stream 0
|
|
set output {}
|
|
set ops {}
|
|
set model [system model]
|
|
set tsr [file rootname [system tsr]]
|
|
set tsrcnt 0
|
|
|
|
foreach opfile [glob -nocomplain -directory /tmp -tails -- ".bgop.*"] {
|
|
set op [string range $opfile 6 end]
|
|
lassign [split [file read "/tmp/$opfile"] "\n"] file oppid
|
|
if {$model eq "HDR"} {
|
|
set file [string map {/media/ /mnt/hd2/} $file]
|
|
}
|
|
|
|
# Check that the lock is still held
|
|
if {![system checkop $op]} {
|
|
debug "$op - $file - $oppid - process not found."
|
|
file delete "/tmp/$opfile"
|
|
} else {
|
|
set ops($file) $op
|
|
}
|
|
}
|
|
|
|
debug "OPS: $ops"
|
|
|
|
set data {}
|
|
if {$type eq "full"} {
|
|
set data [get_data]
|
|
}
|
|
if {[llength $data]} {
|
|
debug " DATA: ($data)"
|
|
if {[system nuggeted] && ![file exists /mod/.nonuggetrecs]} {
|
|
set recs [lmap i [split [system nugget recordings] "\n"] {
|
|
function "$i.ts"
|
|
}]
|
|
debug " RECS: $recs"
|
|
set rr 1
|
|
} else {
|
|
sleep 3
|
|
set ndata [get_data]
|
|
debug " NDATA: ($ndata)"
|
|
set rr 0
|
|
}
|
|
set bnames [lsort [lmap x [array names data] { file tail $x }]]
|
|
foreach file [array names data] {
|
|
set bname [file tail $file]
|
|
|
|
set name [string map {
|
|
"/mnt/hd2/My Video/" ""
|
|
"/media/drive1/Video/" ""
|
|
"/media/" ""
|
|
".ts" ""
|
|
} $file]
|
|
|
|
if {[lindex $data($file) 0] == -1} {
|
|
set mode chase
|
|
} elseif {$rr} {
|
|
if {$file in $recs} {
|
|
set mode rec
|
|
} elseif {[llength [\
|
|
lsearch -all $bnames $bname]] == 2} {
|
|
# two different files having same file.ext open
|
|
set mode copy
|
|
} else {
|
|
set mode play
|
|
}
|
|
} else {
|
|
if {![dict exists $ndata $file]} continue
|
|
if {[lindex $ndata($file) 0] > \
|
|
[lindex $data($file) 0]} {
|
|
set mode rec
|
|
} else {
|
|
set mode play
|
|
}
|
|
}
|
|
|
|
if {[dict exists $ops $file]} {
|
|
if {$mode eq "rec" || $mode eq "chase"} {
|
|
set mode "Recording"
|
|
set icon "745_1_11_Video_1REC.png"
|
|
add_output $icon $mode $name
|
|
}
|
|
set mode $ops($file)
|
|
}
|
|
|
|
regexp -- {^([^0-9]+)} $mode x mode
|
|
|
|
switch $mode {
|
|
chase {
|
|
incr rec
|
|
incr play
|
|
set mode "Chase Playing"
|
|
set icon "745_1_11_Video_3REC_Live.png"
|
|
}
|
|
rec {
|
|
incr rec
|
|
set mode "Recording"
|
|
set icon "745_1_11_Video_1REC.png"
|
|
}
|
|
play {
|
|
incr play
|
|
if {$play > $stream} {
|
|
set mode "Playing"
|
|
set icon "745_1_10_Video_2Live.png"
|
|
} else {
|
|
set mode "Streaming"
|
|
set icon "/img/dlna.png"
|
|
}
|
|
}
|
|
copy {
|
|
if {[lindex $data($file) 1] ne "r"} {
|
|
continue
|
|
}
|
|
set mode "Copying"
|
|
set icon "/img/dlna.png"
|
|
}
|
|
default {
|
|
if {[dict exists $statusops $mode]} {
|
|
lassign $statusops($mode) mode icon
|
|
} else {
|
|
set mode "Unknown"
|
|
set icon "/img/blank.gif"
|
|
}
|
|
}
|
|
}
|
|
|
|
add_output $icon $mode $name
|
|
}
|
|
}
|
|
|
|
######################################################################
|
|
# Live viewing information
|
|
|
|
if {![system instandby] && $play < 1} {
|
|
set hsvc [system param CUR_SVC Value USERCONFIG]
|
|
|
|
set ff [[rsv dbhandle] query "
|
|
select usSvcid as svcid, usLcn as lcn,
|
|
substr(szSvcName, 2) as name
|
|
from channel.TBL_SVC
|
|
where hSvc = $hsvc
|
|
limit 1
|
|
"]
|
|
|
|
if {[llength $ff] == 1} {
|
|
lassign [lindex $ff 0] x svcid x lcn x name
|
|
set epgs [epg dbfetch get \
|
|
-service $svcid \
|
|
-time [clock seconds]\
|
|
]
|
|
set prog ""
|
|
if {[llength $epgs] == 1} {
|
|
lassign $epgs epg
|
|
set prog "- [$epg get name] ("
|
|
append prog "[clock format [\
|
|
$epg get start] -format %H:%M] - "
|
|
append prog "[clock format $([$epg get start] \
|
|
+ [$epg get duration]) -format %H:%M]"
|
|
append prog ") \[[$epg percent]%\]"
|
|
}
|
|
|
|
# 0 => no TSR; >=2 => TSR
|
|
if {$tsrcnt == 0 || $tsrcnt == 2} {
|
|
set s "Watching"
|
|
} elseif {$tsrcnt == 3} {
|
|
set s "Watching (delayed)"
|
|
} else {
|
|
debug "tsrcnt=$tsrcnt"
|
|
set s "Not watching"
|
|
}
|
|
if {$runmode eq "cgi"} {
|
|
lappend output [format "
|
|
<span class=\"va stitem\">
|
|
[epg channelicon %s 30 \
|
|
{vertical-align: middle; padding: 0 4px 0 2px}]
|
|
<span>%s <i>%s: %s %s</i></span>
|
|
</span>
|
|
" $name $s $lcn $name $prog]
|
|
} else {
|
|
lappend output [format "%s %s: %s %s" \
|
|
$s $lcn $name $prog]
|
|
}
|
|
}
|
|
}
|
|
|
|
######################################################################
|
|
# In standby
|
|
|
|
if {[system instandby]} {
|
|
if {$runmode eq "cgi"} {
|
|
lappend output [concat \
|
|
"<span class=\"va stitem\">\n" \
|
|
" <img class=va width=28 style=\"padding: 0 4px\"" \
|
|
"src=/img/standby.png>\n" \
|
|
" <span>System is in standby.</span>\n" \
|
|
"</span>" \
|
|
]
|
|
} else {
|
|
lappend output "System is in standby."
|
|
}
|
|
}
|
|
|
|
######################################################################
|
|
# Upcoming recordings
|
|
|
|
set events [rsv list tbl_reservation \
|
|
" where ersvtype = 3 and nsttime - [clock seconds] < $schedtime
|
|
and nsttime > [clock seconds] "]
|
|
foreach event $events {
|
|
if {$runmode eq "cgi"} {
|
|
set icon "175_1_11_Reservation_Record.png"
|
|
lappend output [concat \
|
|
"<span class=\"va stitem\">\n" \
|
|
" <img class=va src=/images/$icon width=20>\n" \
|
|
" <span>Will record <i>[$event name]</i>" \
|
|
" on [$event channel_name] at"\
|
|
" [clock format [$event get nsttime] -format {%H:%M}]" \
|
|
" </span>\n" \
|
|
"</span>\n" \
|
|
]
|
|
} else {
|
|
lappend output [concat \
|
|
"Will record '[$event name]' " \
|
|
"on [$event channel_name] at " \
|
|
"[clock format [$event get nsttime] -format {%H:%M}]" \
|
|
]
|
|
}
|
|
}
|
|
|
|
######################################################################
|
|
# VFD
|
|
|
|
if {$runmode ne "cgi" && [file exists /mod/webif/plugin/redring/lib.jim]} {
|
|
source /mod/webif/plugin/redring/lib.jim
|
|
lappend output "VFD: [::redring::vfd]"
|
|
}
|
|
|
|
######################################################################
|
|
# Idle Time
|
|
|
|
if {$runmode ne "cgi"} {
|
|
lappend output "Idle: [clock format [system idletime] -format %T]"
|
|
}
|
|
|
|
######################################################################
|
|
# Output
|
|
|
|
if {[llength $output]} {
|
|
if {$runmode eq "cgi"} {
|
|
puts [join $output "\n<br>\n"]
|
|
} else {
|
|
puts [join $output "\n"]
|
|
}
|
|
}
|
|
|