#
# 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"