# # HiGuide v0.4 beta # # Grid based guide with highlighting # # Implemented by Shane Weaver 2005 (shanew) # # MelvinPurvis # Previous change did not handle the movie year case properly (the 12/31/xxxx was actually # where xxxx is the year prior to release.) Fixed by using the movie year field. # Fixed channel number scanner to accept US digital channel notation. In TWP, that value is # the primary channel number and subchannel number separated by a period, as in a floating # point number(7.1). Sometimes, those values are displayed with a hyphen (7-1). While it # would not be difficult to perform the substitution, only the period form has been enabled. # changed usage of scary tcl upvar feature so that accesses to vars in the main proc # are automatically maintained even when sub procs are called from different levels. # corrected handling of schedule files. Since the names, as with the contents, # have time ranges based on UTC, when looking for a particular range of schedule # data UTC time ranges must be used. This showed up as a ragged end of channel rows. # corrected row spacing and channel icon display so that the rows in the channel table # align with the rows in the main table with consistency. # added features: # Date-time range in browser window title # Auto refresh at the top of the hour # Display unique background for HD presentations # Show icon for HD, CC, MPAA rating, USTV rating # moved invariant operations (like determining the number of tuners) to the outer most procs # computed UTC time start and end information so that correct schedule files can be selected. # constructed conventional representations of time date ranges for window title # handle schedule dates list more generally so that 3 dates can be handled (UTC vs local time # issues may mean that schedule files from 3 different dates must be used) # made explicit selection of the channel icon height so that consistent behavior can be # obtained with FireFox and IE in the channel table. # tweaked style font-size to .7em to maintain alignment on IE display. # added styles to support HD fg and bg appearance # added date time to header title # added auto refresh string to header # reworked logo image string to avoid scaling and maintain alignment of channel and schedule tables # added code to identify and accumulate icon image items for HD, MPAA, USTV and CC options. # used explicit pixel based height values for all images rather than a percentage of the row height # (which IE seems to interpret in a unique way) # added option display for refresh at the top of the hour, hd fg/bg, hd icon, mpaa icon, # ustv icon, cc icon # change appropriate date loops to loop through UTC date array rather than local time array # added clause to insure that a row with no programming found will not cause misalignment of rows # added optimizations to guide_get_matched_showings loop to minimize the work done per show found # and to exit # early when a show is found that begins after the time of interest # do_guide_row_showing is called from within guide_get_matched_showings to avoid having to make a # second pass over the data # do_guide_row_showing added code to determine if and what feature icons are required # added a lightning bolt to indicate a live broadcast (conditionalized by op_new) # made the definition of 'new' showing a bit broader to include any day in the current week # (accommodating a case where a show aired on ABC Family before its main airing on the broadcast # ABC network) # the first showing for a movie is given as a year only while others are given the full air date # (movies air date is typically 12/31/xxxx where xxxx is the year) proc action_higuide { chan path env } { global channeltablestation channeltablenum global logotablename logotableindex global db global guideindexdir global tzoffset global hdtvindex global global_channelgrid_version #default settings set guide(def_bg) white set guide(def_fg) black set guide(rec_bg) red set guide(rec_fg) white set guide(sug_bg) maroon set guide(sug_fg) white set guide(con_bg) grey set guide(con_fg) white set guide(fin_bg) black set guide(fin_fg) white set guide(hdv_bg) aqua set guide(hdv_fg) black set guide(op_showrec) "off" set guide(op_showcon) "off" set guide(op_showsug) "off" set guide(op_shownew) "off" set guide(op_showsp) "off" set guide(op_showfin) "off" set guide(op_showdes) "off" set guide(op_showhd) "off" set guide(op_showhdicon) "off" set guide(op_showMPAAicon) "off" set guide(op_showUSTVicon) "off" set guide(op_showCCicon) "off" set guide(op_refresh) "off" set guide(op_height) "1" set guide(op_chan) -2 set guide(op_chan_cust) "" set guide(start_hour) 0 set guide(end_hour) 24 set upvDepth 0 update_sp_cache global source_dir set filename "$source_dir/modules/higuide.cfg" set nowsecs [expr ([clock seconds] + $tzoffset)] set nowdate [expr $nowsecs - ($nowsecs % 86400)] set nowdate [expr $nowdate / 86400] set date $nowdate set submit "" # We are using arrays in our environment variables... could move # This into the httpd.itcl code, but then it would not work for # other versions of TivoWeb. regsub -all {%28} $env {(} env regsub -all {%29} $env {)} env eval $env regsub -all {[^0-9.]+} $guide(op_chan_cust) { } guide(op_chan_cust) regsub -all { +} $guide(op_chan_cust) { } guide(op_chan_cust) if {[info exists ::num_tuners]} { set num_tuners $::num_tuners } else { set num_tuners 1 } if { $submit == "Save" } { guide_save_preferences $filename $chan } elseif { $submit == "Go" } { set start_hour $guide(start_hour) set end_hour $guide(end_hour) set op_chan $guide(op_chan) guide_load_preferences $filename set guide(start_hour) $start_hour set guide(end_hour) $end_hour set guide(op_chan) $op_chan } elseif { $submit == "" } { guide_load_preferences $filename } set guide(start_hour_raw) $guide(start_hour) set guide(end_hour_raw) $guide(end_hour) if { $guide(start_hour) < 0 } { set guide(start_hour) [expr (($nowsecs - ($nowdate*86400)) / 3600) +1+$guide(start_hour) ] if { $guide(start_hour) < 0 } { set guide(start_hour) [expr $guide(start_hour) + 24] incr date -1 } } if { $guide(end_hour) < 0 } { set guide(end_hour) [expr $guide(start_hour) - $guide(end_hour_raw)] if { $guide(end_hour) > 24 } { set guide(end_hour) [expr $guide(end_hour) - 24] } } # start and end secs are both in local time set startsecs [expr ($date * 86400) + ($guide(start_hour) * 3600)] set endsecs [expr ($date * 86400) + ($guide(end_hour) * 3600)] if {$endsecs <= $startsecs} { set endsecs [expr $endsecs + 86400] } set enddate [expr $endsecs / 86400] # we need utc info for the file lookups since both the names and the contents are utc based set startsecsutc [expr $startsecs - $tzoffset] set endsecsutc [expr $endsecs - $tzoffset] set startdateutc [expr $startsecsutc / 86400] set enddateutc [expr $endsecsutc / 86400] set datesutc $startdateutc if {$startdateutc != $enddateutc} { lappend datesutc $enddateutc } set dates $date if { $enddate != $date } { lappend dates [expr $enddate] } if {[clock format $startsecs -format "%D"] != [clock format $endsecs -format "%D"]} { # if the range crosses the day, specify everything in both parts set dateTimeRange "[clock format $startsecs -format "%A %b %d %Y "][string trim [clock format $startsecs -format "%l%p"] "\t\n\{\} "]-[clock format $endsecs -format "%A %b %d %Y "][string trim [clock format $endsecs -format "%l%p"] "\t\n\{\} "]" } elseif {[clock format $startsecs -format "%A %b %d %Y %p"] != [clock format $endsecs -format "%A %b %d %Y %p"]} { # if the range crosses noon, specify AM/PM in both parts set dateTimeRange "[clock format $startsecs -format "%A %b %d %Y "][string trim [clock format $startsecs -format "%l%p"] "\t\n\{\} "]-[string trim [clock format $endsecs -format "%l%p"] "\t\n\{\} "]" } else { # don't repeat the day month year AM-PM if not necessary set dateTimeRange "[clock format $startsecs -format "%A %b %d %Y "][string trim [clock format $startsecs -format "%l"] "\t\n\{\} "]-[string trim [clock format $endsecs -format "%l%p"] "\t\n\{\} "]" } #set dateStart [clock format $startsecs -format "%1m/%1d/%Y %H:%M"] #set dateEnd [clock format $endsecs -format "%1m/%1d/%Y %H:%M"] #puts "date = $date enddate=$enddate $dateStart-$dateEnd" #set utcDateStart [clock format $startsecsutc -format "%1m/%1d/%Y %H:%M"] #set utcDateEnd [clock format $endsecsutc -format "%1m/%1d/%Y %H:%M"] #puts "startdateutc = $startdateutc enddateutc=$enddateutc $utcDateStart-$utcDateEnd" set rangesecs [expr $endsecs - $startsecs] #puts "startsecsutc=$startsecsutc endsecsutc=$endsecsutc" #puts "startsecs=$startsecs endsecs=$endsecs rangesecs=$rangesecs tzoffset=$tzoffset" ## setup earlier and later times set diffsecs [expr $endsecs - $startsecs - 3600] if { $diffsecs <= 0 } { set diffsecs 3600 } set earlier_start_hour [expr (($startsecs - $diffsecs) % 86400) / 3600 ] set earlier_end_hour [expr (($endsecs - $diffsecs) % 86400) / 3600 ] set earlier_date [expr ($startsecs - $diffsecs) / 86400] set later_start_hour [expr (($startsecs + $diffsecs) % 86400) / 3600 ] set later_end_hour [expr (($endsecs + $diffsecs) % 86400) / 3600 ] set later_date [expr ($startsecs + $diffsecs) / 86400] if { $earlier_end_hour == 0 } { set earlier_end_hour 24 } if { $later_end_hour == 0 } { set later_end_hour 24 } switch -exact $guide(op_height) { 0 { set channel_imgage_raw_height 0 set height 15} 1 { set channel_imgage_raw_height 55 set height 63 } 2 { set channel_imgage_raw_height 35 set height 42 } default { set channel_imgage_raw_height 55 set height 63 } } # set the refresh period for the page set refreshEnable 0 set refreshString "" if { $guide(op_refresh) == "on" } { set refreshEnable 1} catch {set refreshEnable [expr $guide(op_refresh)]} if {$refreshEnable > 0} { # seconds to the top of the hour set refreshSecs [expr 3600 - ([clock seconds] % 3600)] # add up to four minutes of random seconds to avoid multiple browsers pounding the server at the same time incr refreshSecs [expr int(rand()*240)] set refreshString "\n" } #put together style information set styles "" #put styles into header set header [html_start "HiGuide $dateTimeRange"] regexp {(.*)(<\/[Hh][Ee][Aa][Dd].*)} $header match header1 header2 puts $chan "$header1$refreshString$styles$header2" unset header match header1 header2 styles if { $submit == "Save" } { puts $chan "Preferences Saved!
" } set segment_size 5 set seg_size_secs [expr $segment_size * 60] set num_whole_mins [expr 24 * 60] set num_whole_secs [expr $num_whole_mins * 60] set num_seg_mins [expr $num_whole_mins / $segment_size] set num_thirty_mins [expr $num_whole_mins / 30] set segment_width 3 set start_seg [expr ($guide(start_hour)*60) / $segment_size] set end_seg [expr ($guide(end_hour)*60) / $segment_size] #set now_secs [higuide_now_secs] set now_secs $nowsecs set now_secs [expr $now_secs - ($now_secs % $seg_size_secs)] #todo information for {set i $startsecs} {$i < $endsecs} {incr i $seg_size_secs} { # set each segment to 0 (0=no recording, 1=recording) set segment_active($i) 0 } set reasons(nothing) "HELLO" # get todo set fsids "" foreach date $datesutc { ForeachMfsFile fsid name type "/Recording/Active" "4:$date:" { lappend fsids $fsid } } # get currently recording (if it exists!) foreach date $datesutc { RetryTransaction { set fsid [lindex [get_fsidbyprefix "/Recording/Active" "3:$date:"] 0] } if { $fsid != "" } { lappend fsids $fsid break } } foreach fsid $fsids { RetryTransaction { set todo_rec [db $db openid $fsid] set todo_showing [dbobj $todo_rec get Showing] set todo_program [dbobj $todo_showing get Program] set todo_title [string trim [dbobj $todo_program get Title] "\t\n\{\} "] set todo_station [dbobj $todo_showing get Station] set todo_station_name [string trim [dbobj $todo_station get Name] "\t\n\{\} "] set todo_time [dbobj $todo_showing get Time] set todo_date [dbobj $todo_showing get Date] set todo_duration [dbobj $todo_showing get Duration] set todo_seltype [dbobj $todo_rec get SelectionType] set todo_stationfsid [dbobj $todo_station fsid] set secs [expr $todo_date * 86400 + $todo_time + $tzoffset] set reasons($secs:$todo_stationfsid) $todo_seltype if { $todo_seltype != 6 } { for {set i $secs} {$i<[expr $secs + $todo_duration]} {incr i $seg_size_secs} { set segment_active($i) 1 set segment_title($i) "$todo_title ($todo_station_name)" } } } } # Get channel information and put selection into channel_sel # and get channel names/fsids to put in selection lappend chanvals -1 lappend chanlabs "All" lappend chanvals -2 lappend chanlabs "Favourites" lappend chanvals -3 lappend chanlabs "Custom" set channel_sel "" foreach channum [lsort -real [array names channeltablenum]] { set stationfsid $channeltablenum($channum) set data $channeltablestation($stationfsid) set favourite [lindex $data 1] set callsign [lindex $data 2] set channame [lindex $data 3] set logoindex [lindex $data 4] set logoname [lindex $logotablename(1) [lsearch $logotableindex(1) $logoindex]] if { $guide(op_height) != "0" && $logoname != "" } { set logostr [img "alt=\"$callsign\" STYLE=\"height:${channel_imgage_raw_height}px;\"" "$logoname-s$guide(op_height)-p$guide(op_height).png"] } else { set logostr "$callsign" } set channame [string trim $channame "\t\n\{\} "] #puts "checking channel $channum" if { $guide(op_chan) == -1 || ($guide(op_chan) == -2 && $favourite != 0) || ($guide(op_chan) == -3 && [lsearch $guide(op_chan_cust) $channum] >= 0) || ($guide(op_chan) == $stationfsid )} { set temp $stationfsid lappend temp $logostr lappend channel_sel $temp } lappend chanvals $stationfsid lappend chanlabs $channame } set hasExtraHeight 0 set show_seasonPass 0 set show_firstShowing 0 set show_ustvRatings 0 set show_mpaaRatings 0 set show_closedCaption 0 set show_highDefinition 0 if { $guide(op_height) != 0 } { set hasExtraHeight 1 if { $guide(op_shownew) == "on" } { set show_firstShowing 1 } if { $guide(op_showUSTVicon) == "on" } { set show_ustvRatings 1 } if { $guide(op_showMPAAicon) == "on" } { set show_mpaaRatings 1 } if { $guide(op_showCCicon) == "on" } { set show_closedCaption 1 } if { $guide(op_showhdicon) == "on" } { set show_highDefinition 1 } if { $guide(op_showsp) == "on" } { set show_seasonPass 1 } } ## QUICK SELECTION TABLE #puts $chan [html_form_start "POST" "/higuide" ""] #puts $chan [html_table_start "" "" ""] #set datestr [nth_sup [clock format [expr [lindex $dates 0]*86400] -format "%e"]] #set datestr [clock format [expr [lindex $dates 0]*86400] -format "%a $datestr %b"] #puts $chan [tr "" [th "COLSPAN=7" "$datestr"]] #puts $chan [tr "STYLE=font-size:11px" [td "COLSPAN=2 ALIGN=right" "Channel: "] [td "COLSPAN=4" [html_form_select "guide(op_chan)\" STYLE=\"font-size:11px" $chanvals $chanlabs $guide(op_chan)]] [td "" ""]] for {set i $nowdate} {$i<[expr $nowdate+14]} {incr i 1} { lappend dvals $i set tmp [nth [clock format [expr $i*86400] -format "%e"]] lappend dlabs [clock format [expr $i*86400] -format "%a $tmp %b"] } lappend shvals -1 lappend shlabs "Now" for {set i 0} {$i<4} {incr i 1} { lappend shvals [expr ($i+2)*-1] lappend shlabs "Now-[expr $i+1]" } for {set i 0} {$i<24} {incr i 1} { lappend ehvals [expr ($i+1)*-1] lappend ehlabs "Current+[expr $i+1]" } for {set i 0} {$i<24} {incr i 1} { lappend shvals $i lappend shlabs "[format %02d $i]:00" lappend ehvals [expr $i+1] lappend ehlabs "[format %02d [expr $i+1]]:00" } set datesrch [td "" "Date: "] append datesrch [td "" [html_form_select "date\" STYLE=\"font-size:11px" $dvals $dlabs [lindex $dates 0]]] append datesrch [td "" "From: "] append datesrch [td "" [html_form_select "guide(start_hour)\" STYLE=\"font-size:11px" $shvals $shlabs $guide(start_hour_raw)]] append datesrch [td "" "To: "] append datesrch [td "" [html_form_select "guide(end_hour)\" STYLE=\"font-size:11px" $ehvals $ehlabs $guide(end_hour_raw)]] #puts $chan [tr "STYLE=font-size:11px" "$datesrch [td "" [html_form_input "submit" "submit" "Go"]]"] #puts $chan [html_table_end] #puts $chan [html_form_end] puts $chan [html_link "/higuide?date=[expr [lindex $dates 0] - 1]&guide(start_hour)=$guide(start_hour)&guide(end_hour)=$guide(end_hour)&guide(op_chan)=$guide(op_chan)&submit=Go" "<< Previous Day"] puts $chan [html_link "/higuide?date=$earlier_date&guide(start_hour)=$earlier_start_hour&guide(end_hour)=$earlier_end_hour&guide(op_chan)=$guide(op_chan)&submit=Go" "< Earlier"] puts $chan [html_link "/higuide?date=$nowdate&guide(start_hour)=$guide(start_hour)&guide(end_hour)=$guide(end_hour)&guide(op_chan)=$guide(op_chan)&submit=Go" "Today"] puts $chan [html_link "/higuide?date=$later_date&guide(start_hour)=$later_start_hour&guide(end_hour)=$later_end_hour&guide(op_chan)=$guide(op_chan)&submit=Go" "Later >"] puts $chan [html_link "/higuide?date=[expr [lindex $dates 0] + 1]&guide(start_hour)=$guide(start_hour)&guide(end_hour)=$guide(end_hour)&guide(op_chan)=$guide(op_chan)&submit=Go" "Next Day >>"] puts $chan "
" ### START OF MAIN TABLE puts $chan [html_table_start "border=1 STYLE=\"border-collapse:collapse; padding: 0; border: 0; width:95%;\"" "" ""] puts $chan "" ### START OF CHANNEL TABLE puts $chan [html_table_start "CLASS=higuide" "" ""] puts $chan [tr "CLASS=status" [td "" " "]] puts $chan [tr "" [th "STYLE=\"text-align:center;\"" "Channel"]] foreach channel $channel_sel { if {[info exists global_channelgrid_version] == 0} { puts $chan [tr "" [td "" [lindex $channel 1]]] } else { puts $chan [tr "" [td "" [html_link "/channelgrid?whichChannel=[lindex $channel 0]" [lindex $channel 1] ""]]] } } puts $chan [html_table_end] ### END OF CHANNEL TABLE puts $chan "" puts $chan "
" ### START OF GUIDE TABLE puts $chan [html_table_start "CLASS=higuide STYLE=\"left:0;\"" "" ""] #First Row set row "" set space "" for {set i 0} {$i < $segment_width} {incr i 1} { append space " " } for {set i $startsecs} {$i < $endsecs} {incr i $seg_size_secs} { if { $i < $now_secs } { set style fin set row_text "$space" } elseif { $segment_active($i) == 1 } { set style rec set row_text "$space" unset segment_title($i) } else { set style def set row_text "$space" } append row [td "CLASS=\"$style\"" "$row_text"] } puts $chan [tr "CLASS=status" $row] #Second Row set row "" for {set i $startsecs} {$i<$endsecs} {incr i 1800} { set time [clock format $i -format "%H:%M"] append row [th "COLSPAN=6" "$time"] } puts $chan [tr "" $row] unset row #Guide Rows foreach channel $channel_sel { puts $chan [tr "VALIGN=TOP" [do_guide_row $datesutc [lindex $channel 0]]] } puts $chan [html_table_end] ### END OF GUIDE TABLE puts $chan "
" puts $chan "" puts $chan [html_table_end] ### END OF MAIN TABLE #Preferences puts $chan [html_form_start "POST" "/higuide" ""] puts $chan [html_table_start "STYLE=font-size:11px" "" ""] puts $chan [tr "" [th "COLSPAN=3" "Option" ] [th "" "Background"] [th "" "Foreground"]] set autoRefresh "" if { $guide(op_refresh) == "on" } { set autoRefresh "CHECKED" } puts $chan [tr "" [td "" [html_form_checkbox "guide(op_refresh)" $autoRefresh]] [td "COLSPAN=4" "Auto-refresh at Top of the Hour"]] set options "tmp $guide(op_showrec) $guide(op_showsug) $guide(op_showcon) $guide(op_showfin) $guide(op_showhd)" set opt_nams "tmp guide(op_showrec) guide(op_showsug) guide(op_showcon) guide(op_showfin) guide(op_showhd)" #set opt_cols {{$guide_rec} {$guide_sug} {$guide_con} {$guide_new} {$guide_fin} {$guide_hdv}} lappend opt_cols_fg $guide(def_fg) lappend opt_cols_bg $guide(def_bg) lappend opt_cols_fg $guide(rec_fg) lappend opt_cols_bg $guide(rec_bg) lappend opt_cols_fg $guide(sug_fg) lappend opt_cols_bg $guide(sug_bg) lappend opt_cols_fg $guide(con_fg) lappend opt_cols_bg $guide(con_bg) lappend opt_cols_fg $guide(fin_fg) lappend opt_cols_bg $guide(fin_bg) lappend opt_cols_fg $guide(hdv_fg) lappend opt_cols_bg $guide(hdv_bg) set opt_cols_nams "def rec sug con fin hdv" set opt_texts {{Default} {Scheduled to record} {Scheduled suggestion} {Conflicting} {Finished} {HDTV}} for {set i 0} {$i<[llength $options]} {incr i 1} { set option [lindex $options $i] set opt_nam [lindex $opt_nams $i] set opt_col_fg [lindex $opt_cols_fg $i] set opt_col_bg [lindex $opt_cols_bg $i] set opt_col_nam [lindex $opt_cols_nams $i] set opt_text [lindex $opt_texts $i] if { $option == "on" } { set option "CHECKED" } else { set option "" } set checkbox "" if { $i > 0 } { set checkbox [html_form_checkbox $opt_nam $option] } set background [html_form_text 1 20 "guide($opt_col_nam\_bg)\" STYLE=\"font-size:11px" $opt_col_bg] set foreground [html_form_text 1 20 "guide($opt_col_nam\_fg)\" STYLE=\"font-size:11px" $opt_col_fg] puts $chan [tr "" [td "" $checkbox] [td "STYLE=font-size:11px" "$opt_text"] [td "STYLE=\"background:$opt_col_bg;color:$opt_col_fg;font-size:11px\"" "Key"] [td "" "$background"] [td "" "$foreground"]] } set showdes "" if { $guide(op_showdes) == "on" } { set showdes "CHECKED" } puts $chan [tr "" [td "" [html_form_checkbox "guide(op_showdes)" $showdes]] [td "COLSPAN=4" "Full description on mouse hover"]] if {$hdtvindex >= 0} { # only show the option if the possibility exists set showhdicon "" if { $guide(op_showhdicon) == "on" } { set showhdicon "CHECKED" } puts $chan [tr "" [td "" [html_form_checkbox "guide(op_showhdicon)" $showhdicon]] [td "" "HD Presentation Icon"] [td "COLSPAN=3" "(Not displayed in very thin mode)"]] } set shownew "" if { $guide(op_shownew) == "on" } { set shownew "CHECKED" } set showsp "" if { $guide(op_showsp) == "on" } { set showsp "CHECKED" } puts $chan [tr "" [td "" [html_form_checkbox "guide(op_shownew)" $shownew]] [td "" "First Showing"][td "" [html_form_checkbox "guide(op_showsp)" $showsp]] [td "" "Season Pass"] [td "" "(Not seen in very thin mode)"]] set showMPAAicon "" if { $guide(op_showMPAAicon) == "on" } { set showMPAAicon "CHECKED" } set showUSTVicon "" if { $guide(op_showUSTVicon) == "on" } { set showUSTVicon "CHECKED" } puts $chan [tr "" [td "" [html_form_checkbox "guide(op_showMPAAicon)" $showMPAAicon]] [td "" "MPAA Rating Icon"] [td "" [html_form_checkbox "guide(op_showUSTVicon)" $showUSTVicon]] [td "" "US TV Rating Icon"] [td "" "(Not seen in very thin mode)"]] set showCCicon "" if { $guide(op_showCCicon) == "on" } { set showCCicon "CHECKED" } puts $chan [tr "" [td "" [html_form_checkbox "guide(op_showCCicon)" $showCCicon]] [td "" "Close Caption Icon"] [td "" ""] [td "" ""] [td "" "(Not seen in very thin mode)"]] set radio1 "[html_form_input radio guide(op_height) 1]Thick " set radio2 "[html_form_input radio guide(op_height) 2]Thin " set radio0 "[html_form_input radio guide(op_height) 0]Very thin" set checked "radio$guide(op_height)" regsub {>} [subst $$checked] { CHECKED>} checkedresult set $checked $checkedresult puts $chan [tr "" [td "" "" ] [td "" "Grid height"] [td "COLSPAN=3" "$radio1$radio2$radio0"]] unset radio1 radio2 radio0 checked checkedresult puts $chan [tr "" [td "" ""] [td "" "Channel: "] [td "COLSPAN=2" [html_form_select "guide(op_chan)\" STYLE=\"font-size:11px" $chanvals $chanlabs $guide(op_chan)]] [td "" ""]] puts $chan [tr "" [td "" ""] [td "" "Custom channels:"] [td "COLSPAN=3" [html_form_text 1 50 "guide(op_chan_cust)\" STYLE=\"font-size:11px" $guide(op_chan_cust)]]] #set dateline [html_table_start "STYLE=font-size:11px" "" ""] #append dateline $datesrch #append dateline [td "" [html_form_input "submit" "submit" "Submit"]] #append dateline [html_table_end] puts $chan [tr "" [td "COLSPAN=5" "[html_table_start "STYLE=font-size:11px" "" ""]$datesrch[td "" [html_form_input "submit" "submit" "Submit"]][html_table_end]"]] puts $chan [tr "" [td "COLSPAN=5 ALIGN=CENTER" [html_form_input "submit" "submit" "Save"] ]] puts $chan [html_table_end] puts $chan [html_form_end] puts $chan [html_end] } proc do_guide_row { datesutc stationfsid } { #puts "do_guide_row" global db upvar 1 upvDepth upvCaller set upvDepth [expr $upvCaller + 1] upvar $upvDepth startsecs startsecs upvar $upvDepth endsecs endsecs upvar $upvDepth seg_size_secs seg_size_secs set row "" set matched_showings "" set previous_show "" set col_used 0 # accumulate all the showings on a particular date, even if they are in multiple files foreach date $datesutc { #set itemTime [clock format [expr $date * 86400] -format "%1m/%1d/%Y"] #puts "check date ($date) $itemTime" ForeachMfsFile fsid name type "/Schedule" "$stationfsid:$date:" { set rowApp [guide_get_matched_showings $fsid $stationfsid] #puts "guide_get_matched_showings with fsid=$fsid name=$name returned $rowApp" append row $rowApp } } if {($row == " ") || ($row == "")} { # a row with no programming will cause a misalignment of the tables set row [td "COLSPAN=1" " "] } return $row } proc guide_get_matched_showings { fsid stationfsid} { global db global tzoffset upvar 1 upvDepth upvCaller set upvDepth [expr $upvCaller + 1] upvar $upvDepth startsecs startsecs upvar $upvDepth endsecs endsecs upvar $upvDepth seg_size_secs seg_size_secs upvar $upvDepth rangesecs rangesecs upvar 1 col_used col_used set rowData "" 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 time [dbobj $showing get Time] set date [dbobj $showing get Date] set secs [expr $date * 86400 + $time + $tzoffset] set itemTime [clock format $secs -format "%1m/%1d/%Y %H:%M"] #puts "itemTime=$itemTime Local" if { $secs >= $startsecs && $secs < $endsecs } { # if the starting time is in the range of interest set duration [dbobj $showing get Duration] set secsfinal [expr $secs + $duration] if {!$col_used && ($secs > $startsecs)} { # if the previous show has not been found and # we are at the beginning of the row add a dummy entry to maintain alignment set colspan [expr (($secs - $startsecs) / $seg_size_secs) - $col_used] if {$colspan < 1} {set colspan 1} incr col_used $colspan set unknown_show [td "COLSPAN=$colspan CLASS=def" ""] #puts "guide_get_matched_showings appending unknown_show ($unknown_show)" append rowData $unknown_show } # compute the colspan from an accumulator to auto-correct for rounding errors # as when two segments are rounded down set colspan [expr (($secsfinal - $startsecs) / $seg_size_secs) - $col_used] if {$colspan < 1} {set colspan 1} if { [expr $secsfinal - $startsecs] > $rangesecs } { # trim the back off the duration set colspan [expr ($rangesecs / $seg_size_secs) - $col_used] } if {!$colspan} {break} incr col_used $colspan # optimization - do these ops only when required set showingfsid [dbobj $showing fsid] set showingsubobjid [dbobj $showing subobjid] set match $showingfsid lappend match $showingsubobjid lappend match $stationfsid lappend match $time lappend match $date lappend match $secs lappend match $duration lappend match $colspan set matchData [do_guide_row_showing $showing $match] #puts "guide_get_matched_showings appending matchData ($matchData)" append rowData $matchData } elseif { $secs < $endsecs } { #the starting time is before the last time of interest #this is inefficient because it matters only for the last show processed by this clause set duration [dbobj $showing get Duration] set endshow [expr $secs + $duration] if { $endshow > $startsecs} { #the end falls in the range of interest # optimization - do these ops only when required set showingfsid [dbobj $showing fsid] set showingsubobjid [dbobj $showing subobjid] set previous_show $showingfsid lappend previous_show $showingsubobjid lappend previous_show $stationfsid lappend previous_show $time lappend previous_show $date lappend previous_show $secs lappend previous_show $duration # trim the front off the duration set secsfinal [expr $secs + $duration] set colspan [expr (($secsfinal - $startsecs) / $seg_size_secs) - $col_used] if {$colspan < 1} {set colspan 1} if { [expr $secsfinal - $startsecs] > $rangesecs } { # trim the back off the duration set colspan [expr ($rangesecs / $seg_size_secs) - $col_used] } if {!$colspan} {break} incr col_used $colspan lappend previous_show $colspan set previousShowData [do_guide_row_showing $showing $previous_show] #puts "guide_get_matched_showings appending previousShowData ($previousShowData)" append rowData $previousShowData } } else { break } } } } return $rowData } proc do_guide_row_showing { showing match } { upvar 1 upvDepth upvCaller set upvDepth [expr $upvCaller + 1] upvar $upvDepth guide guide upvar $upvDepth nowdate nowdate upvar $upvDepth nowsecs nowsecs upvar $upvDepth segment_width segment_width upvar $upvDepth seg_size_secs seg_size_secs upvar $upvDepth hasExtraHeight hasExtraHeight upvar $upvDepth show_seasonPass show_seasonPass upvar $upvDepth show_firstShowing show_firstShowing upvar $upvDepth show_ustvRatings show_ustvRatings upvar $upvDepth show_mpaaRatings show_mpaaRatings upvar $upvDepth show_closedCaption show_closedCaption upvar $upvDepth show_highDefinition show_highDefinition upvar $upvDepth num_tuners num_tuners upvar $upvDepth reasons reasons upvar $upvDepth segment_active segment_active set showingfsid [lindex $match 0] set showingsubobjid [lindex $match 1] set stationfsid [lindex $match 2] set time [lindex $match 3] set date [lindex $match 4] set secs [lindex $match 5] set duration [lindex $match 6] set colspan [lindex $match 7] global db global cache_sp_key global images global repeatindex global hdtvindex global liveindex global ccindex global tvratingnums tvratingvals tvratingimages global mpaaratingnums mpaaratingvals mpaaratingimages global showingbitvals # we are called from within a transaction, so we do not re-encapsulate here #RetryTransaction { #set showing [db $db openidconstruction $showingfsid $showingsubobjid] #set duration [dbobj $showing get Duration] set partindex [dbobj $showing get PartIndex] if {$partindex != ""} { set partcount [dbobj $showing get PartCount] } set program [dbobj $showing get Program] set oad [dbobj $program get OriginalAirDate] set series [dbobj $program get Series] set tmsid [dbobj $program get TmsId] set programfsid [dbobj $program fsid] set img_str "" set title [string trim [dbobj $program get Title] "\t\n\{\} "] set eptitle [string trim [dbobj $program get EpisodeTitle] "\t\n\{\} "] set description [string trim [dbobj $program get Description] "\t\n\{\} "] if {$repeatindex >= 0} { set genres [dbobj $program get Genre] } if { $series != "" } { set seriesfsid [dbobj $series fsid] } set tvrating "" set mpaarating "" set showingbits "" if {$hasExtraHeight} { set tmstype 1 if { [string range $tmsid 0 1] == "MV" } { set tmstype 0 } if { $tmstype == 1 } { # Is Not a Movie set isMovie 0 } else { # Is a Movie set isMovie 1 set movieYear [dbobj $program get MovieYear] } if {$show_ustvRatings} { catch {set tvrating [dbobj $program get TvRating]} } if {$show_mpaaRatings} { catch {set mpaarating [dbobj $program get MpaaRating]} } if {$show_closedCaption} { catch {set showingbits [dbobj $showing get Bits]} if { $showingbits == "" } { set showingbits 0 } } } #} if { $hasExtraHeight } { if {$show_closedCaption && ($ccindex >=0) && ([lsearch $genres $ccindex] >= 0)} { set showingbits [expr $showingbits | 1] } append img_str "
 " if { $show_seasonPass && [lsearch $cache_sp_key "$seriesfsid|$stationfsid"] > -1 } { append img_str [img "ALT=\"(SP)\" STYLE=\"height:16px;\"" [lindex $images 11]] } if { $show_firstShowing } { set datesecs [expr $date * 86400] if { $oad != "" } { set origairdatesecs [expr $oad * 86400] set showYear [clock format $origairdatesecs -format "%Y"] if {$showYear == [clock format $nowsecs -format "%Y"]} { set thisYear 1 } else { set thisYear 0 } if {$::lang == "en"} { set airdatestr [clock format $origairdatesecs -format "%e %b %Y"] } else { set airdatestr [clock format $origairdatesecs -format "%1m/%1d/%Y"] } } else { set airdatestr "" set origairdatesecs 0 if {$::dtivo} { set thisYear 0 } else { set thisYear 1 } } if {(($liveindex >=0) && ([lsearch $genres $liveindex] >= 0))} { append img_str [img "ALT=\"(Live)\" STYLE=\"height:16px;\"" "lightningbolt.png"] } elseif {(([clock format $origairdatesecs -format "%G%W"] == [clock format $datesecs -format "%G%W"]) && (($repeatindex < 0) || ([lsearch $genres $repeatindex] < 0)))} { append img_str [img "ALT=\"(New)\" STYLE=\"height:16px;\"" "NewEpisode.png"] } } if { $show_ustvRatings } { if { $tvrating != "" } { set tvratingindex [lsearch $tvratingnums $tvrating] if { $tvratingindex != -1 } { set tvratingstr [string trim [lindex $tvratingimages $tvratingindex] "\t\n\{\} "] set tvratingalt [string trim [lindex $tvratingvals $tvratingindex] "\t\n\{\} "] } else { set tvratingstr "" set tvratingalt "" } if {$tvratingstr != ""} { append img_str [img "ALT=\"($tvratingalt)\" STYLE=\"height:16px;\"" "$tvratingstr"] } } } if { $show_mpaaRatings } { if { $mpaarating != "" } { set mpaaratingindex [lsearch $mpaaratingnums $mpaarating] if { $mpaaratingindex != -1 } { set mpaaratingstr [string trim [lindex $mpaaratingimages $mpaaratingindex] "\t\n\{\} "] set mpaaratingalt [string trim [lindex $mpaaratingvals $mpaaratingindex] "\t\n\{\} "] } else { set mpaaratingstr "" set mpaaratingalt "" } if {$mpaaratingstr != ""} { append img_str [img "ALT=\"($mpaaratingalt)\" STYLE=\"height:16px;\"" "$mpaaratingstr"] } } } if { $show_closedCaption } { if {$showingbits & 1} { set ccAlt [string trim [lindex $showingbitvals 1] "\t\n\{\} "] append img_str [img "ALT=\"($ccAlt)\" STYLE=\"height:16px;\"" "cc-symbol.png"] } } if { $show_highDefinition } { if {$hdtvindex >= 0} { if {[lsearch $genres $hdtvindex] >= 0} { # is HD append img_str [img "ALT=\"(HD)\" STYLE=\"height:16px;\"" "HDTV.png"] } } } if { $show_firstShowing } { if {$airdatestr != ""} { if {!$isMovie} { # not a movie append img_str " ($airdatestr)" } else { append img_str " ($movieYear)" } } } # if { $tmsid != "" && $series != "" } { # set alt [alt_showing $tmsid $programfsid] # if { $alt != "" && [lindex $alt 1] != "$showingfsid/$showingsubobjid" } { # set alttype "Available in Now Showing" # if { [lindex $alt 0] == "todo" } { # set alttype "Alternate scheduled" # } # append img_str [img "ALT=\"(Alt)\" STYLE=\"height:16px;\" TITLE=\"$alttype [lindex $alt 1] $showingfsid/$showingsubobjid\"" "AltEpisode.png"] # } # } } set des "" if { $guide(op_showdes) == "on" } { if { $description != "" } { set des " - $description" } } if { $eptitle != "" } { set eptitle ": $eptitle" } if { $partindex != "" && $partcount != ""} { append eptitle " ($partindex/$partcount)" } #cut title if its too long set full_title $title if { [string length $title] >= [expr $colspan * $segment_width] } { set title [string range $title 0 [expr ($colspan * $segment_width)-3]] append title "..." } else { #set genrenumbers "" #foreach genre $genres { #if { $genrenumbers != "" } { #append genrenumbers ", " #} #append genrenumbers [string trim $genre "\t\n\{\} "] #} #append img_str " $genrenumbers" } #is it conflicting set conflicting 0 for {set i $secs} {$i<[expr $secs+$duration]} {incr i $seg_size_secs} { if { [info exists segment_active($i)] && $segment_active($i) == 1 } { incr conflicting if {$conflicting >= $num_tuners} {break} } } if {$conflicting < $num_tuners} {set conflicting 0} #setup styles if { $guide(op_showfin) == "on" && ($date < $nowdate || ( $date == $nowdate && [expr $secs+$duration] < $nowsecs ) ) } { set status fin } elseif { $guide(op_showrec) == "on" && [info exists reasons($secs:$stationfsid)] && $reasons($secs:$stationfsid) != 6 } { set status rec } elseif { $guide(op_showsug) == "on" && [info exists reasons($secs:$stationfsid)] && $reasons($secs:$stationfsid) == 6 } { set status sug } elseif { $guide(op_showcon) == "on" && $conflicting } { set status con } elseif { $guide(op_showhd) == "on" && ($hdtvindex >= 0) && ([lsearch $genres $hdtvindex] >= 0)} { set status hdv } else { set status def } set title [html_link "/showing/$showingfsid/$showingsubobjid" "$title" "TITLE=\"$full_title$eptitle$des\""] return [td "COLSPAN=$colspan NOWRAP CLASS=$status" "$title$img_str"] } proc guide_load_preferences { filename } { upvar 1 upvDepth upvCaller set upvDepth [expr $upvCaller + 1] upvar $upvDepth guide guide #saved settings if { [file exists $filename] } { set fileID [open $filename r] while {[gets $fileID line] >= 1} { if { [regexp {([^ ]*) *= *(.*)} $line match var val] } { set guide($var) $val } } close $fileID } } proc guide_save_preferences { filename chan } { upvar 1 upvDepth upvCaller set upvDepth [expr $upvCaller + 1] upvar $upvDepth guide guide set guide(def_fg) [string trim $guide(def_fg)] set guide(def_bg) [string trim $guide(def_bg)] set guide(rec_fg) [string trim $guide(rec_fg)] set guide(rec_bg) [string trim $guide(rec_bg)] set guide(sug_fg) [string trim $guide(sug_fg)] set guide(sug_bg) [string trim $guide(sug_bg)] set guide(con_fg) [string trim $guide(con_fg)] set guide(con_bg) [string trim $guide(con_bg)] set guide(fin_fg) [string trim $guide(fin_fg)] set guide(fin_bg) [string trim $guide(fin_bg)] set guide(hdv_fg) [string trim $guide(hdv_fg)] set guide(hdv_bg) [string trim $guide(hdv_bg)] set fileID [open $filename w] foreach pref [array names guide] { puts $fileID "$pref = $guide($pref)" } close $fileID } register_module "higuide" "HiGuide" "Grid based guide with highlighting"