#!/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 \ "\n" \ " \n" \ " $mode $name\n" \ "\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 " [epg channelicon %s 30 \ {vertical-align: middle; padding: 0 4px 0 2px}] %s %s: %s %s " $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 \ "\n" \ " \n" \ " System is in standby.\n" \ "" \ ] } 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 \ "\n" \ " \n" \ " Will record [$event name]" \ " on [$event channel_name] at"\ " [clock format [$event get nsttime] -format {%H:%M}]" \ " \n" \ "\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
\n"] } else { puts [join $output "\n"] } }