# What's On module for TiVoWeb. # Shows an hourly snapshot of what's on. # # Based very heavily on other parts of TiVoWeb! # # LJ @ http://www.tivocommunity.com/ # # 01Dec02 18:06 v1.0 # 01Dec02 19:40 v1.1 A bit faster! - doesn't read the starting time from the db twice in do_wochandata. # - aborts loop sooner if the title is "SIGN OFF". # Use time zone when working out current date. # 02Dec02 19:34 v1.2 Find all programmes when searching close to a day change. # Include channel links. # 03Dec02 20:43 v1.3 Tidy a few things to eek out a bit more speed! # Take account of the timezone properly. # 06Dec02 18:19 v1.4 Show appropriate icon if show scheduled for recording or in Now Showing. # Make Search button in focus on first run. # 08Dec02 11:40 v1.5 Add quick links for search back/forward 24/1 hours. # Make recycle symbol a link to undelete the programme. # 08Dec02 17:30 v1.6 Adding thumbs & rating/advisories (zvonar) # 15Dec02 08:26 v1.7 Show if any programmes scheduled to be recorded during the hour. # Include option to show only programmes that start in the hour/from now onwards. # 15Dec02 22:26 v1.8 Show 'Watch' buttons for programmes now on. # 28Dec02 11:38 v1.9 Change keys sent by watch buttons to cope with already being on Live TV. # 28Dec02 16:23 v1.10 Add 'Enter' key to end of channel change. # Add column for episode description. # 29Dec02 15:32 v1.11 Add call to slotfree code. # 10Jan03 21:30 v1.12 Remove description from tooltip. # 19Jan03 10:50 v1.13 Ensure variables are set if called directly. Check wodatetz % 86400 is zero. # 19Jan03 11:08 v1.14 Allow wodatetz to be passed in either seconds or days. # 02May04 09:48 v1.15 Adds a "Top Favourites" selection - see below for instructions. # Adds a checkbox to only show new episodes (thanks for the idea Sanderton!). New # episodes are always flagged with "(New) " before the episode name. # # This version is compatible with both TiVoWeb and TiVoWebPlus - I've merged in the changes from both. # Clickable thumbs in TWP coming shortly...! # Top Favourites: # # Adds an extra selection "Top Favourites" to the "Channels to search:" box that will show matches only # from a list of channels you specify. (Since searching only "Favourite Channels" is still a bit slow ;P) # # To specify which channels are your Top Favourites: # Create a text file in /var/hack called favchan that lists the channel numbers to search. Channel numbers # can be separated by spaces or be on separate lines - any combination is ok. The order of channels is not # important, nor are duplications. # # e.g. This command from a telnet session works well: echo "103 42 102" > /var/hack/favchan # And to add more channels later: echo "68 123" >> /var/hack/favchan # # If the favchan file can't be found or is empty then the "Top Favourites" option doesn't appear # in the "Channels to search:" box. # # The favchan file is re-read every time What's On is called, so changes to favchan are immediately effective. proc action_whatson {chan path eenv} { global channeltablestation channeltablenum global logotablename logotableindex global db global guideindexdir global tzoffset global reccount global usformat if { $::lang == "us" } { set usformat 1 } else { set usformat 0 } set starting 0 set onlynew 0 set wodatetz [expr ([clock seconds] + $tzoffset) - (([clock seconds] + $tzoffset) % 86400)] set wotimetz [expr (([clock seconds] + $tzoffset - $wodatetz) / 3600 )] set favfile "/var/hack/favchan" if { [file exists $favfile] } { set favhnd [open $favfile r] while {![eof $favhnd]} { append favchan "[gets $favhnd] " } close $favhnd set favchan [string trim $favchan] set chnsel "4" } else { set favchan "" } if {$favchan == ""} { set chnsel "2" } eval $eenv puts $chan [html_start "What's On Listing"] if { $eenv == "" || ![info exists "chnvals"] } { set timevals "" set datevals "" set datelabels "" set timelabels "" set starting 1 set onlynew 0 if {$favchan == ""} { set chnvals "3 2" if { $usformat } { set chnlabels "{Favorite Channels} {Channels Watched}" } else { set chnlabels "{Favourite Channels} {Channels Watched}" } } else { set chnvals "4 3 2" if { $usformat } { set chnlabels "{Top Favorites} {Favorite Channels} {Channels Watched}" } else { set chnlabels "{Top Favourites} {Favourite Channels} {Channels Watched}" } } for {set i 0} {$i < 24} {incr i 1} { append timevals "$i " if { $usformat } { append timelabels "[if {[expr $i % 12] == 0} { format "\{12" } else { format "\{[expr $i % 12]" }]" append timelabels "[if {$i < 12} { format " am\} " } else { format " pm\} " }]" } else { append timelabels "[string range "0$i" [expr [string length "$i"] - 1] end]\:00 " } } set minday "99999" set maxday "00000" set ictr 0 ForeachMfsFile fsid name type "/Schedule" "" { scan $name "%d:%d:" schedsid schedday if {$schedday != 15000} { if {$minday > $schedday} { set minday $schedday } if {$maxday < $schedday} { set maxday $schedday } incr ictr if { $ictr > 500 } { break } } } set minseconds [expr $minday * 86400] set maxseconds [expr $maxday * 86400] for {set i $minseconds} {$i <= $maxseconds} {incr i 86400} { if { $usformat } { set timestr [clock format $i -format "%a %1m/%1d"] } else { set timestr [clock format $i -format "%a %e[switch -glob [clock format $i -format "%e"] {1? {format th} *1 {format st} *2 {format nd} *3 {format rd} default {format th} }] %b"] } append datevals "$i " append datelabels "\{$timestr\} " } } else { if { $submit == "Watch" } { if { [string length $channel] == 0 } { SendKey "livetv" } else { SendKey "guide" after 1500 SendKey "select" for {set i 0} {$i < [string length $channel]} {incr i 1} { after 200 SendKey "num[ string index $channel $i]" } after 200 SendKey "enter" } } } if { $wodatetz < 86400 } { set wodatetz [expr $wodatetz * 86400] } puts $chan [html_form_start "GET" "/whatson" "name=\"search\""] puts $chan [html_table_start "" "Search" "COLSPAN=2"] # puts $chan [tr "" [td "Channels to search:"] [td "" [html_form_select "chnsel" $chnvals $chnlabels $chnsel]]] puts $chan [tr "" [td "Channels to search:"] [td "width=50%" [html_form_select "chnsel" $chnvals $chnlabels $chnsel]]] puts $chan [tr "" [td "Date to search:"] [td "" [html_form_select "wodatetz" $datevals $datelabels $wodatetz]]] puts $chan [tr "" [td "Hour to search:"] [td "" [html_form_select "wotimetz" $timevals $timelabels $wotimetz]]] if { $usformat } { set me "" } else { set me "me" } set datewrng "" if { $wodatetz % 86400 != 0 } { set wodatetz [expr $wodatetz - ($wodatetz %86400)] set datewrng "Warning! Invalid value passed for wodatetz, using $wodatetz instead.
" } if { $wodatetz == [expr ([clock seconds] + $tzoffset) - (([clock seconds] + $tzoffset) % 86400)] \ && $wotimetz == [expr (([clock seconds] + $tzoffset - $wodatetz) / 3600 )] } { if { $starting } { puts $chan [tr "" [td "colspan=2" " Only show program$me\s that haven't started"]] } else { puts $chan [tr "" [td "colspan=2" " Only show program$me\s that haven't started"]] } set currenthour 1 } else { if { $starting } { puts $chan [tr "" [td "colspan=2" " Only show program$me\s that start in the hour"]] } else { puts $chan [tr "" [td "colspan=2" " Only show program$me\s that start in the hour"]] } set currenthour 0 } if { $onlynew } { puts $chan [tr "" [td "colspan=2" " Only show new episodes"]] } else { puts $chan [tr "" [td "colspan=2" " Only show new episodes"]] } puts $chan [html_table_end] puts $chan [html_form_input "submit" "submit" "Search"] puts $chan [html_form_end] if { $datewrng != "" } { puts $chan $datewrng } set chkdate [expr $wodatetz / 86400] if { $eenv != ""} { if { $starting && $currenthour } { set minseconds [clock seconds] set maxseconds [expr $wodatetz + ($wotimetz * 3600) - $tzoffset + 3600] } else { set minseconds [expr $wodatetz + ($wotimetz * 3600) - $tzoffset] set maxseconds [expr $minseconds + 3600] } set hr [expr $wotimetz - ($tzoffset / 3600)] if { $hr < 0 } { incr chkdate -1 } elseif { $hr > 23 } { incr chkdate 1 } puts $chan [html_table_start "" "" ""] if { $currenthour } { puts $chan [tr "ALIGN=CENTER" [th ""] [th ""] [th "Start Time"] [th "End Time"] [th ""] [th "Chan"] [th "Series"] [th "Episode"] [th "Description"]] } else { puts $chan [tr "ALIGN=CENTER" [th ""] [th "Start Time"] [th "End Time"] [th ""] [th "Chan"] [th "Series"] [th "Episode"] [th "Description"]] } set reccount 0 foreach channum [lsort -real [array names channeltablenum]] { set stationfsid $channeltablenum($channum) set data $channeltablestation($stationfsid) set favorite [lindex $data 1] if { $chnsel == "3" && $favorite == 0 } { continue } if { $chnsel == "4" && ([lsearch -exact $favchan $channum] == -1) } { continue } set callsign [lindex $data 2] if { [expr ($wotimetz - ($tzoffset / 3600) + 24) % 24] < 5 && !$starting } { incr chkdate -1 ForeachMfsFile fsid name type "/Schedule" "$stationfsid:$chkdate" { if {[catch [do_wochandata $chan $fsid $minseconds $maxseconds $channum $callsign $stationfsid $starting $currenthour $onlynew] error]} { puts "do_wochandata $fsid $minseconds $channum $callsign $stationfsid $starting $currenthour $onlynew" puts "$error" } } incr chkdate 1 } ForeachMfsFile fsid name type "/Schedule" "$stationfsid:$chkdate" { if {[catch [do_wochandata $chan $fsid $minseconds $maxseconds $channum $callsign $stationfsid $starting $currenthour $onlynew] error]} { puts "do_wochandata $fsid $minseconds $channum $callsign $stationfsid $starting $currenthour $onlynew" puts "$error" } } } if { $reccount > 0 } { puts $chan "($reccount scheduled recording[ if {$reccount > 1} { format "s" } ] found)

" } puts -nonewline $chan [html_table_end] } else { puts $chan " " } if { $chkdate > $minday } { puts -nonewline $chan "[html_link "/whatson?chnsel=$chnsel&wodatetz=[expr $wodatetz - 86400]&wotimetz=$wotimetz&starting=$starting&onlynew=$onlynew&submit=Search" "<< A day earlier"]" } if { $chkdate > $minday || $wotimetz > 0 } { if { $wotimetz == 0 } { set datem1hrtz [expr $wodatetz - 86400] set timem1hrtz 23 } else { set datem1hrtz $wodatetz set timem1hrtz [expr $wotimetz - 1] } puts -nonewline $chan " [html_link "/whatson?chnsel=$chnsel&wodatetz=$datem1hrtz&wotimetz=$timem1hrtz&starting=$starting&onlynew=$onlynew&submit=Search" "< One hour earlier"]" } puts -nonewline $chan " | " if { $chkdate < $maxday || $wotimetz < 23 } { if { $wotimetz == 23 } { set datep1hrtz [expr $wodatetz + 86400] set timep1hrtz 0 } else { set datep1hrtz $wodatetz set timep1hrtz [expr $wotimetz + 1] } puts -nonewline $chan " [html_link "/whatson?chnsel=$chnsel&wodatetz=$datep1hrtz&wotimetz=$timep1hrtz&starting=$starting&onlynew=$onlynew&submit=Search" "One hour later >"]" if { $wotimetz == 0 } { puts -nonewline $chan " [html_link "/whatson?chnsel=$chnsel&wodatetz=$datep1hrtz&wotimetz=18&starting=$starting&onlynew=$onlynew&submit=Search" "18:00"]" } } if { $chkdate < $maxday } { puts -nonewline $chan " [html_link "/whatson?chnsel=$chnsel&wodatetz=[expr $wodatetz + 86400]&wotimetz=$wotimetz&starting=$starting&onlynew=$onlynew&submit=Search" "A day later >>"]" } puts $chan [html_end] } proc do_wochandata {chan fsid startsecs endsecs channum callsign stationfsid starting currenthour onlynew} { global db global tzoffset global usformat global images global tvratingnums tvratingvals global advisorynums advisoryvals global mpaaratingnums mpaaratingvals global reccount RetryTransaction { set stationday [db $db openid $fsid] set showings [dbobj $stationday gettarget Showing] } for {set x 0} {$x < [llength $showings]} {incr x 20} { RetryTransaction { foreach showingfsid [lrange $showings $x [expr $x+19]] { regexp {([0-9]*)/(.*)} $showingfsid junk showingobjid subobjid set showing [db $db openidconstruction $showingobjid $subobjid] set date [dbobj $showing get Date] set prgtime [dbobj $showing get Time] set secs [expr $date * 86400 + $prgtime] if { $secs >= $endsecs } { continue } set finsecs [expr $secs + [dbobj $showing get Duration]] if { $finsecs <= $startsecs } { continue } if { $starting && $secs < $startsecs } { continue } set program [dbobj $showing get Program] set title [strim [dbobj $program get Title]] if { $title == "SIGN OFF" } { continue } set origairdate [dbobj $program get OriginalAirDate] if {$origairdate == $date} { set firstad "(New) " } else { if { $onlynew } { continue } else { set firstad "" } } if { $usformat } { set timestrtz [clock format [expr $secs + $tzoffset] -format "%l:%M %P"] set timeendtz [clock format [expr $finsecs + $tzoffset] -format "%l:%M %P"] } else { set timestrtz [clock format [expr $secs + $tzoffset] -format "%H:%M"] set timeendtz [clock format [expr $finsecs + $tzoffset] -format "%H:%M"] } set partindex [dbobj $showing get PartIndex] set partcount [dbobj $showing get PartCount] set series [dbobj $program get Series] set seriesfsid "" if { $series != "" } { set seriesfsid [dbobj $series fsid] set episodic [defaultval 1 [dbobj $series get Episodic]] } else { set episodic 1 } set description [strim [dbobj $program get Description]] set eptitle [strim [dbobj $program get EpisodeTitle]] if { $origairdate != "" } { set origairdatesecs [expr $origairdate * 86400] if {$::lang == "en"} { set daystr [string trim [nth [clock format $origairdatesecs -format "%e"]]] set airdatestr [clock format $origairdatesecs -format "$daystr %b %Y"] } else { set airdatestr [clock format $origairdatesecs -format "%1m/%1d/%Y"] } } else { set airdatestr "" } if { $eptitle == "" } { if { $episodic == 1 } { set eptitle "UNKNOWN" } else { set eptitle $title } } if { $partcount != "" && $partindex != "" } { append eptitle " ($partindex/$partcount)" } if { $seriesfsid != "" } { set title [html_link "/series/$seriesfsid" $title] } if { $airdatestr != "" && $description != "" } { set description "$description ($airdatestr)" } set description [htmlEncode $description] regsub -all {\"} $description {\"} description if { $description == "" } { set description " " } set imagenum -1 set today [expr [clock seconds] / 86400] if { $date >= $today } { set recfsid [lindex [get_fsidbyprefix "/Recording/Active" "4:$date:[string range "0000$prgtime" [expr [string length "$prgtime"] - 1] end]:"] 0] } else { set recfsid "" } if { $recfsid == "" && $date <= $today } { if { $prgtime == 0 } { incr date -1 set prgtime 86398 } else { incr prgtime -2 } set prgtime "[string range "0000$prgtime" [expr [string length "$prgtime"] - 1] end]" set recfsid [lindex [get_fsidbyprefix "/Recording/Active" "1:$date:$prgtime:"] 0] } if { $recfsid == "" && $date <= $today } { set recfsid [lindex [get_fsidbyprefix "/Recording/Active" "3:$date:$prgtime:"] 0] } if {$recfsid != ""} { set rec [db $db openid $recfsid] set recshowing [dbobj $rec get Showing] set recstation [dbobj $recshowing get Station] set recstationfsid [dbobj $recstation fsid] if {$recstationfsid == $stationfsid} { set state [dbobj $rec get State] if {$state == 4} { set imagenum 3 } elseif {$state == 5} { set imagenum 20 } elseif {$state == 3} { set imagenum 8 incr reccount 1 } elseif {$state == 6} { if {([info exists ::version] == 1 && $::version >= 3) || $::version3} { set recbeh [dbobj $rec get RecordingBehavior] set seltype [dbobj $recbeh get PresentationBehavior] if {$seltype == 6} { set imagenum 10 incr reccount 1 } elseif {$seltype == 2} { set imagenum 11 incr reccount 1 } elseif {$seltype == 3} { set imagenum 13 incr reccount 1 } else { set imagenum 1 incr reccount 1 } } else { set seltype [dbobj $rec get SelectionType] if {$seltype == 6} { set imagenum 10 incr reccount 1 } elseif {$seltype == 9} { set imagenum 11 incr reccount 1 } elseif {$seltype == 13} { set imagenum 13 incr reccount 1 } else { set imagenum 1 incr reccount 1 } } } else { set expdate [dbobj $rec get ExpirationDate] set expsecs [expr $expdate * 86400 + [dbobj $rec get ExpirationTime]] set nowsecs [clock seconds] if {$expdate == 24855} { set imagenum 0 } elseif {$expsecs < $nowsecs} { set imagenum 5 } elseif {$expsecs < [expr $nowsecs + 24*60*60]} { set imagenum 3 } } } } if {$imagenum >= 0} { set imagef [lindex $images $imagenum] if { $imagenum == 20 } { set imageh [html_link "/confirmdelete/3/$recfsid" "[img "align=absmiddle" $imagef]" "title=\"Click to undelete\""] } else { set imageh [img "align=absmiddle" $imagef] } } else { if { $secs > [clock seconds] } { set imageh "[slotfree $secs [expr $finsecs - $secs] $chan] " } else { set imageh " " } } set thumbs "" if { $series != "" } { set score [dbobj $series get ThumbData] if { $score != "" } { # This section in place till thumb modification code added to TWP: if { [catch {set imagenumt [get_thumbimagelj $score]}] == 0 } { if { [lindex $imagenumt 0] >= 0} { set imagef [lindex $images [lindex $imagenumt 0]] set thconf [lindex $imagenumt 1] set thumbs [html_link "/thumbs/$seriesfsid" "[img "alt=\"Confidence: $thconf\"" $imagef]"] } } else { set imagenumt [get_thumbimage $score] if { $imagenumt >= 0} { set imagef [lindex $images $imagenumt] set thumbs [img "align=absmiddle alt=\"\"" $imagef] } } } } if { $thumbs == "" } { set thumbs [html_link "/thumbs/$seriesfsid" "(none)"] } if { $currenthour } { if { $secs <= [clock seconds] && $finsecs > [clock seconds] } { set butn [html_form_start "GET" "/whatson" "style=\"margin-botton:0\" name=\"watch\""] if { $imagenum == 8 } { append butn [html_form_input "hidden" "channel" ""] } else { append butn [html_form_input "hidden" "channel" $channum] } append butn [html_form_input "submit" "submit" "Watch"] append butn [html_form_end] } else { set butn " " } puts $chan [tr "" [td "align=center valign=middle" $butn] [td "align=center" "$imageh"] [td "align=center" "$timestrtz"] [td "align=center" $timeendtz] [td "align=center" "$thumbs"] [td [html_link "/channel/$stationfsid" "$channum $callsign"]] [td "$title"] [td "$firstad[html_link "/showing/$showingfsid" $eptitle]"] [td "$description"]] } else { puts $chan [tr "" [td "align=center" "$imageh"] [td "align=center" "$timestrtz"] [td "align=center" $timeendtz] [td "align=center" "$thumbs"] [td [html_link "/channel/$stationfsid" "$channum $callsign"]] [td "$title"] [td "$firstad[html_link "/showing/$showingfsid" $eptitle]"] [td "$description"]] } } } } } ########################################## register_module "whatson" "What\'s On" "Hourly What\'s On listing"