# Shows a single channel as a grid for a week # # (C) Copyright 2003 by Christopher R. Wingert # All rights reserved # # Based heavily on schedule.itcl by David Lowe and logos.itcl by Jake B. # # 06/04/2003 - v0.0.1 [Alpha] - Initial public release (C.Wingert) # # 10/08/2004 - v0.0.2 [Patch] - Got v2.5.5/v3.0 working # 10/08/2004 - v0.0.3 [Patch] - Now handles errors in guide data # 10/01/2005 - v0.0.4 [Patch] - Shorten description string (memory overflow) # 27/01/2005 - v0.0.5 [Patch] - Clean up a lot of the code (+fixed a tz issue?) # 14/02/2005 - v0.0.6 [Patch] - Attempts made to free up more memory # 15/02/2005 - v0.0.7 [Patch] - Restricted retrieved data to one week # 22/02/2005 - v0.0.8 [Patch] - Added ability to view ToDo schedule (ala schedule.itcl) # 23/02/2005 - v0.0.9 [Patch] - Code cleanup (UI alterations + DualTuner ToDo support) # 24/02/2005 - v0.1.0 [Patch] - Better support for Dual Tuners # 25/02/2005 - v0.1.1 [Patch] - User defined grid resolution # 26/02/2005 - v0.1.2 [Patch] - Mainly cosmetic alterations # 01/03/2005 - v0.1.3 [Patch] - Enable a filter for the channels to display # 02/03/2005 - v0.1.4 [Patch] - Marks shows that are going to be recorded # 03/03/2005 - v0.1.5 [Patch] - The week can now start on any day (defaults to yesterday) # 04/03/2005 - v0.1.6 [Patch] - Marks timeslots with recordings on other channels # 07/03/2005 - v0.1.7 [Patch] - Marks recordings on two other channels for dualtuners # # When you use this tool, you do, you do so at your own risk. # No warranties, expressed or implied... etc. # set global_channelgrid_version "v0.1.7r5" set global_channelgrid_link "http://www.tivocommunity.com/tivo-vb/showthread.php?p=2669018&&#post2669018" proc action_channelgrid {chan path env} { global db global tzoffset global source_dir global channeltablestation ######################################################################### # # CUSTOM USER SETTINGS # ######################################################################### # # Base schedule start time defaults # ======================================================================= # Some users may want to start their daily schedule at different times. # For example some users may want it to start at the traditional 12:00am, # but other may want it to start at 12:00pm, so that shows that start # after midnight will still appear to be on the same calendar day. This # is helpful if you time shift programs, but still want to visually # represent a show on a given day. # # For example Without A Trace and ER are both Thursday shows, and are on # at 10:00pm. If you have your tivo scheduled to tape Without A Trace # at 10:00pm (Eastern) and ER at 1:00am (Pacific) they will still show # on the schedule as a Thursday show, instead of ER showing up on Friday. # # Due to some confusions in the initial release, I have set the default # to follow the traditional calendar start time, of 12:00AM or 0 hundred # hours. # # To set the start time to your own preference set the HOUR_START # parameter to a hour in military format. So 12 PM, will 12, 7 PM will # be 19. # set HOUR_START 0 # # Show Episode Descriptions # ====================================================================== # Leave this set to false if you do not want the episode descriptions # to display in the schedule. This will greatly reduce the risk that # this module will cause a reboot due to high memory utilisation. # # Change this value to "hover" if you wish to have the description # available when you hover over the episode. Change the value to # "true" if you wish to have the description displayed within # the grid. set SHOW_DESCRIPTION "false" # # Grid Resolution # ====================================================================== # If you wish to have the grid build faster then you can set this to # use half hour slots (1800). set GRID 900 # # Channel Filter # ====================================================================== # The following can be left blank ("") so that all channels are # displayed. It can also be set at to "fav" so that only the # favourites are displayed, or it can be set to a list of the # required channel numbers (eg "101 132 145"). set CHANNEL_FILTER "fav" # START_DAY # ====================================================================== # The following can be set to Monday-Sunday, today or yesterday. # This will adjust "thisMonday" so that the grid can be made to # start on a different day of the week. set START_DAY "yesterday" # MARK_RECORDINGS # ====================================================================== # The following can be set to 1 to mark the timeslots that are # going to be recorded with a red border. If set to 2 it will # also mark timeslots that contain recordings on other channels # with a yellow border. If set to 3 then it will mark timeslots # that contain two recordings (via a dual tuner) on different # channesl with a solid yellow border. # If set to 0 then this feature will be turned off - this can # speed up the grid creation by 8 seconds. set MARK_RECORDINGS 3 # # ######################################################################### ######################################################################### # # Internal Array descriptions # # foo(timeslot) # fsid's holds information on the show scheduled to start in this slot # {SKIP} identifies that this slot is a continuation of the previous one # # bar(timeslot) # 1 There is a recording for this channel in this timeslot # 2 There is a recording for a differnet channel in this timeslot # 3 There are two other recordings for a different channel # 0 This timeslot has no EPG, but is a continuation of a recording # ######################################################################### # Load any settings found in the configuration file if {[file exists $source_dir/modules/channelgrid.cfg]} { catch {source $source_dir/modules/channelgrid.cfg} } # # # START CODE # # set GRiD [expr $GRID/2] set startWeek "" set whichChannel "" eval $env # If no channel was specified, then display a list of choices if { $whichChannel == "" } { cg_show_stations $chan $CHANNEL_FILTER return } # Start a timer so that we will know how long it took to render the page set startTimer [clock seconds] puts $chan [html_start "Channel Grid"] # Column start values set startColumn [expr $HOUR_START * 3600] set startTime [expr $startColumn] set endTime [expr $startTime + 86400] # Monday signifies the "start" of the week, but is # configurable so may not actually be on a Monday :) if {$startWeek != ""} { set thisMonday $startWeek } else { set currentTimeDate [expr [clock scan "12:00 AM"] - $tzoffset] set dateNum [clock format $currentTimeDate -format "%u"] # Make offset equal to the number of days since the last START_DAY. # "thisMonday" is now used to identify the first day of the grid. set offset [clock format [expr [clock scan "12:00 AM $START_DAY"] - $tzoffset] -format "%u"] set offset [expr $dateNum - $offset] if {$offset < 0} {set offset [expr $offset + 7]} set thisMonday [expr $currentTimeDate - (($offset) * 86400)] } set prevMonday [clock scan "-7 day" -base $thisMonday] set nextMonday [clock scan "7 day" -base $thisMonday] # # Get the Schedule # set thisMondayDate [expr $thisMonday/86400] set nextMondayDate [expr $nextMonday/86400] if { $whichChannel != 0 } { set data $channeltablestation($whichChannel) set num [lindex $data 0] set sign [lindex $data 2] set name [lindex $data 3] set asciiChannel "$num - $sign ($name)" puts $chan "" puts $chan "Getting Schedule Data..." set scheduleList {} ForeachMfsFileTrans fsid name type "/Schedule" "$whichChannel:" 15 { if ![catch {set stationday [db $db openid $fsid]}] { set showings [dbobj $stationday get Showing] foreach showing $showings { if ![catch {set date [dbobj $showing get Date]}] { if { $date >= $thisMondayDate && $date < $nextMondayDate } { set showingfsid "[dbobj $showing fsid]/[dbobj $showing subobjid]" set programfsid [dbobj $showing gettarget Program] set duration [dbobj $showing get Duration] set time [dbobj $showing get Time] # Round time to closest 15 minutes set time [expr (($time+$GRiD)/$GRID)*$GRID] # Round Duration to closest 15 minutes (minimum 15 minutes) if { $duration > $GRiD } { set duration [expr (($duration+$GRiD)/$GRID)*$GRID] } else { set duration $GRID } lappend scheduleList [list $showingfsid $programfsid $time $date $duration] } } } unset showings } else { # Signal that an error was found in the EPG puts -nonewline $chan "!" } } puts $chan "Done.
" set entries [llength $scheduleList] puts $chan "Getting Program Data (for $entries entries)..." set programList {} set entriesPerRound 50 set rounds [expr $entries / $entriesPerRound] for { set x 0 } { $x <= $rounds } { incr x } { set y [ expr $x * $entriesPerRound ] set last [ expr ( $x + 1 ) * $entriesPerRound ] if { $last > $entries } { set last $entries } RetryTransaction { for { } { $y < $last } { incr y } { set sl [lindex $scheduleList $y] # Attempt to free up some memory on the fly? set scheduleList [lreplace $scheduleList $y $y {}] set constprogramfsid [lindex $sl 1] set programfsid [lindex [split $constprogramfsid {/}] 0] if ![catch {set program [db $db openid $programfsid]}] { set seriesfsid "" catch {set seriesfsid [dbobj $program gettarget Series]} set title "" catch {set title [strim [dbobj $program get Title]]} set eptitle "" catch {set eptitle [strim [dbobj $program get EpisodeTitle]]} if {$SHOW_DESCRIPTION != "false"} { set description "" catch [set description [strim [dbobj $program get Description]]] set origairdate "" catch [set origairdate [dbobj $program get OriginalAirDate]] if { $origairdate != "" } { set origairdatesecs [expr $origairdate * 86400 - $tzoffset] if {$::lang == "en"} { set daystr [nth [clock format $origairdatesecs -format "%e"]] set airdatestr [clock format $origairdatesecs -format "%a $daystr %b %Y"] } else { set airdatestr [clock format $origairdatesecs -format "%1m/%1d/%Y"] } } else { set airdatestr "" } set description "$airdatestr $description" } else { set description "" } lappend sl $title $eptitle $description $seriesfsid lappend programList $sl } else { # Signal that an error was found in the EPG puts -nonewline $chan "!" } } } } catch {unset sl} unset scheduleList puts $chan "Done.
" set legend 0 puts $chan "Building Grid Entries..." foreach program $programList { set showingfsid [lindex $program 0] set time [lindex $program 2] set date [lindex $program 3] set duration [lindex $program 4] set title [lindex $program 5] set eptitle [lindex $program 6] set description [lindex $program 7] set constseriesfsid [lindex $program 8] set seriesfsid [lindex [split $constseriesfsid {/}] 0] set programKey [expr $date * 86400 + $time] # Check to see if there is already an entry for this timeslot if ![catch {set programList $foo($programKey)}] { set getShowingfsid [lindex $programList 4] if { $getShowingfsid != {} } { # Mark the old entry with a * to signal collision, as this # recording is in the same slot, and link to this recording set getShowName [htmlEncode $title] regsub -all {\"} $getShowName {\"} getShowName set attrs "title=\"$getShowName\"" set title [lindex $programList 0] set title "$title[html_link "/showing/$showingfsid" "*" {STYLE="text-decoration:none;color:red"} $attrs]" set eptitle [lindex $programList 1] set description [lindex $programList 2] set seriesfsid [lindex $programList 3] set showingfsid [lindex $programList 4] set duration $GRID set legend 1 } } set programList {} lappend programList $title $eptitle $description $seriesfsid $showingfsid set foo($programKey) $programList # Find the number of 15 minute slots set slots [expr ($duration+$GRiD)/$GRID] for {set slotCount 1} {$slotCount<$slots} {incr slotCount} { set programKey [expr $programKey + $GRID] set programList {} lappend programList {SKIP} set foo($programKey) $programList } } puts $chan "Done.
" if {$MARK_RECORDINGS != 0} { puts $chan "Mark Recordings..." ForeachMfsFileTrans fsid name type "/Recording/Active" "4" 15 { set rec [db $db openid $fsid] set showing [dbobj $rec get Showing] set date [dbobj $showing get Date] set station [dbobj $showing get Station] set stationfsid [dbobj $station fsid] if { $date >= $thisMondayDate && $date < $nextMondayDate } { set time [dbobj $showing get Time] set duration [dbobj $showing get Duration] # Round time to closest 15 minutes set time [expr (($time+$GRiD)/$GRID)*$GRID] # Find the number of 15 minute slots set slots [expr ($duration+$GRiD)/$GRID] if {$slots == 0} {set slots 1} set programKey [expr $date * 86400 + $time] if {$whichChannel == $stationfsid} { # Mark the timeslot as having a recording on this channel(1). # Will be displayed with a red outline. for {set slotCount 1} {$slotCount<=$slots} {incr slotCount} { set bar($programKey) 1 set programKey [expr $programKey + $GRID] } set legend [expr $legend | 2] } else { if {$MARK_RECORDINGS > 1} { # Mark the timeslot as having a recording on a different # channel(2), but only if it has not already been marked as # having a recording (on this channel). Will be displayed # with a yellow outline. for {set slotCount 1} {$slotCount<=$slots} {incr slotCount} { set marked 0 catch {set marked $bar($programKey)} if {$marked != 1} { if {$marked == 2 && $MARK_RECORDINGS > 2} { # There is already a recording on another channel # so this must be a dual-tuner unit. set bar($programKey) 3 set legend [expr $legend | 8] } else { set bar($programKey) 2 set legend [expr $legend | 4] } } set programKey [expr $programKey + $GRID] } } } } } puts $chan "Done.
" } puts $chan "
" # If we have marked any shows/timeslots then display an appropriate # legend with information on the markings. if {$legend != 0} { puts $chan "
" if {[expr $legend & 1]} { puts $chan "" } if {[expr $legend & 2]} { puts $chan "" } if {[expr $legend & 4]} { puts $chan "" } if {[expr $legend & 8]} { puts $chan "" } puts $chan "
*identifies additional shows in this timeslot
 identifies a recording within this timeslot
 marks a recording (on another channel) within this timeslot
 marks two recording (on another channels) within this timeslot
" } } else { set asciiChannel "ToDo Schedule" # # Display a schedule of the shows to be recorded this week # puts $chan "" puts $chan "Building Schedule..." set legend 0 ForeachMfsFileTrans fsid name type "/Recording/Active" "4" 15 { set rec [db $db openid $fsid] set manual 0 if {$::version3} { set recbeh [dbobj $rec get RecordingBehavior] set presbeh [dbobj $recbeh get PresentationBehavior] set progbeh [dbobj $recbeh get ProgramGuideBehavior] if { $presbeh == 10 || $presbeh == 9 } { set manual 1 } if { $progbeh == 3 || $progbeh == 8 } { set manual 1 } } else { set seltype [dbobj $rec get SelectionType] if { $seltype == 10 || $seltype == 5 } { set manual 1 } } set showing [dbobj $rec get Showing] set showingfsid [dbobj $rec gettarget Showing] set station [dbobj $showing get Station] set stationfsid [dbobj $station fsid] set program [dbobj $showing get Program] set title [strim [dbobj $program get Title]] set date [dbobj $showing get Date] set time [dbobj $showing get Time] set duration [dbobj $showing get Duration] if {$SHOW_DESCRIPTION != "false"} { set description [strim [dbobj $program get Description]] } else { set description "" } if { $manual } { if { $title == "" } { set title "Manual Recording" } set series "" set seriesfsid $showingfsid set episodic 1 } else { set series [dbobj $program get Series] set seriesfsid [dbobj $series fsid] set episodic [defaultval 1 [dbobj $series get Episodic]] } if { $episodic == 1 } { set eptitle [strim [dbobj $program get EpisodeTitle]] } else { set eptitle "" } # Round time to closest 15 minutes set time [expr (($time+$GRiD)/$GRID)*$GRID] set programKey [expr $date * 86400 + $time] # Check to see if there is already an entry if ![catch {set programList $foo($programKey)}] { set getShowingfsid [lindex $programList 4] if { $getShowingfsid == {} } { # Mark the new entry with a + to signal overlap, as this # recording is starting before the other has completed. set title "$title+" set legend [expr $legend | 1] } else { # Mark the old entry with a * to signal collision, as this # recording is starting at the same time, and link to this # recording set getShowName [htmlEncode $title] regsub -all {\"} $getShowName {\"} getShowName set attrs "title=\"$getShowName\"" set title [lindex $programList 0] set title "$title[html_link "/showing/$showingfsid" "*" {STYLE="text-decoration:none;color:red"} $attrs]" set eptitle [lindex $programList 1] set description [lindex $programList 2] set seriesfsid [lindex $programList 3] set showingfsid [lindex $programList 4] set duration $GRID set legend [expr $legend | 2] } } set programList {} lappend programList $title $eptitle $description $seriesfsid $showingfsid set foo($programKey) $programList # Find the number of 15 minute slots set slots [expr ($duration+$GRiD)/$GRID] for {set slotCount 1} {$slotCount<$slots} {incr slotCount} { set programKey [expr $programKey + $GRID] set programList {} lappend programList {SKIP} set foo($programKey) $programList } } puts $chan "Done.
" puts $chan "
" if {$legend != 0} { puts $chan "
" if {[expr $legend & 2]} { puts $chan "" } if {[expr $legend & 1]} { puts $chan "" } puts $chan "
*identifies more than one recording in this timeslot
+identifies this recording overlaps the previous one
" } # Turn this off... it is not required and will speed up the creation of the grid set MARK_RECORDINGS 0 } set startDate $thisMonday set endDate [expr $thisMonday + (86400 * 6)] set startDateDesc [clock format $startDate -format "%B %d, %Y"] set endDateDesc [clock format $endDate -format "%B %d, %Y"] set week [clock format $thisMonday -format "%V"] # # Start rendering the results # puts $chan "
" puts $chan "" puts $chan "" puts $chan " " puts $chan "" puts $chan "" puts $chan " " puts $chan "" puts $chan "" puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan "" set col(1) 0 set col(2) 0 set col(3) 0 set col(4) 0 set col(5) 0 set col(6) 0 set col(7) 0 set totalColumns 0 for {set x $startTime} {$x < $endTime} {incr x $GRID} { puts $chan {} set columnStamp [clock format $startColumn -format "%l:%M%p"] set columnCount 0 set rowsRemaining [expr ($endTime - $x) / $GRID] puts $chan " " for {set y $startDate} {$y <= $endDate} {incr y 86400} { set index [expr $x + $y] set columnCount [expr $columnCount + 1] set getValue "" if ![catch {set getValue $foo($index)}] { set getShowName [lindex $getValue 0] if { $getShowName != {SKIP} } { set getEpTitle [lindex $getValue 1] set getDescription [lindex $getValue 2] set getSeriesfsid [lindex $getValue 3] set getShowingfsid [lindex $getValue 4] set col($columnCount) 1 set rowSpan 1 set tempindex $index set marked 0 if ${MARK_RECORDINGS} {catch {set marked $bar($tempindex)}} set done 0 while { $done == 0 } { set tempindex [expr $tempindex + $GRID] if ![catch {set getVal $foo($tempindex)}] { set name [lindex $getVal 0] if { $name != {SKIP} } { set done 1 } else { set rowSpan [expr $rowSpan + 1] if {$MARK_RECORDINGS && $marked != 1} { # We want a recording on this channel (marked=1), to # override a recording on a different one (marked=2/3) catch {set marked $bar($tempindex)} } } } else { set done 1 } } if {$rowSpan > $rowsRemaining} {set rowSpan $rowsRemaining} if {$marked == 0} { puts $chan "" } else { if { $col($columnCount) == 0 } { # These are cells at the start of the day marked as SKIP. # Flag the cell as empty will allow us to check it for # any recordings that started the previous day. set getValue "" } } } if {$getValue == ""} { if {$MARK_RECORDINGS} { if {[catch {set marked $bar($index)}] != 0} { # Cell is empty and no recordings are schedule within it puts $chan " " } else { # Must be a recording that either started the previous day # (eg we are at the start of a column and getShowName=SKIP), # or a manual recording that occurs during a slot with no # EPG information. # Need to find how many rows to span... these are the ones # marked to be recorded, but have either no information or # are marked with SKIP. if {$marked > 0} { set rowSpan 1 set tempindex $index set done 0 while { $done == 0 } { set tempindex [expr $tempindex + $GRID] set getValue {SKIP} catch {set getValue $foo($tempindex)} set getShowName [lindex $getValue 0] if {[info exists bar($tempindex)] && $getShowName == {SKIP}} { # Check we have not gone onto the next day, and that the "type" # of recording is the same as that we started with (ie 1/2/3). if {$rowSpan < $rowsRemaining && $bar($tempindex) == $marked} { set rowSpan [expr $rowSpan + 1] set bar($tempindex) 0 } } else { set done 1 } } if {$marked == 1} { puts $chan " " } else { if {$marked == 2} { puts $chan " " } else { puts $chan " " } } } } } else { puts $chan " " } } set totalColumns [expr $totalColumns + 1] } puts $chan {} # update time stamp for row set startColumn [expr $startColumn + $GRID] } puts $chan "" puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan " " puts $chan "" puts $chan {
$asciiChannel
[html_link "/channelgrid?startWeek=$prevMonday&whichChannel=$whichChannel" "<<<"]   Week $week: $startDateDesc - $endDateDesc   [html_link "/channelgrid?startWeek=$nextMonday&whichChannel=$whichChannel" ">>>"]
 [clock format [expr [clock scan "0 day" -base $thisMonday]] -format "%A
%d %b
"]
[clock format [expr [clock scan "1 day" -base $thisMonday]] -format "%A
%d %b
"]
[clock format [expr [clock scan "2 day" -base $thisMonday]] -format "%A
%d %b
"]
[clock format [expr [clock scan "3 day" -base $thisMonday]] -format "%A
%d %b
"]
[clock format [expr [clock scan "4 day" -base $thisMonday]] -format "%A
%d %b
"]
[clock format [expr [clock scan "5 day" -base $thisMonday]] -format "%A
%d %b
"]
[clock format [expr [clock scan "6 day" -base $thisMonday]] -format "%A
%d %b
"]
$columnStamp" } else { if {$marked == 1} { puts $chan "" } else { if {$marked == 2} { puts $chan "" } else { puts $chan "" } } } if {$SHOW_DESCRIPTION == "hover"} { set getDescription [htmlEncode $getDescription] regsub -all {\"} $getDescription {\"} getDescription set attrs "title=\"$getDescription\"" set getDescription "" } else { set attrs "" } puts $chan " [html_link "/showing/$getShowingfsid" $getShowName {STYLE="font-size:11pt"} $attrs]" if {$getEpTitle != ""} { puts $chan "
[html_link "/showing/$getShowingfsid" $getEpTitle {STYLE="font-size:10pt"} $attrs]" } if {$getDescription != ""} { puts $chan "
[html_link "/showing/$getShowingfsid" $getDescription {STYLE="font-size:9pt"}]" } puts $chan "
     
 [clock format [expr [clock scan "0 day" -base $thisMonday]] -format "%A"][clock format [expr [clock scan "1 day" -base $thisMonday]] -format "%A"][clock format [expr [clock scan "2 day" -base $thisMonday]] -format "%A"][clock format [expr [clock scan "3 day" -base $thisMonday]] -format "%A"][clock format [expr [clock scan "4 day" -base $thisMonday]] -format "%A"][clock format [expr [clock scan "5 day" -base $thisMonday]] -format "%A"][clock format [expr [clock scan "6 day" -base $thisMonday]] -format "%A"]
} if { $whichChannel != 0 } { puts $chan "[html_link "/channelgrid?whichChannel=0" "View a grid of the Recording Schedule"]
" } puts $chan "Page took " puts $chan [expr [clock seconds] - $startTimer] puts $chan "seconds to render
" puts $chan [html_end] catch {unset foo} catch {unset bar} } proc cg_show_stations {chan filter} { global tzoffset global channeltablenum global channeltablestation puts $chan [html_start "Channel Grid - Select Channel"] puts $chan "Show Channels: " puts $chan "[html_link "/channelgrid?CHANNEL_FILTER=" "all"] " puts $chan "[html_link "/channelgrid?CHANNEL_FILTER=fav" "favs"] " puts $chan [html_link "/channelgrid" "filter"] puts $chan "" puts $chan [html_table_start "" "" ""] puts $chan "No.Get GridName" puts $chan "*[html_link "/channelgrid?whichChannel=0" "ToDo List"]Recording Schedule" puts $chan "   " foreach num [lsort -real [array names channeltablenum]] { if {[regexp {^[0-9]} $filter] && [lsearch -exact $filter $num] < 0} { continue } set sta $channeltablenum($num) set data $channeltablestation($sta) set favourite [lindex $data 1] if {[regexp -nocase "fav" $filter] && $favourite == 0} { continue } set sign [lindex $data 2] set name [lindex $data 3] set changelink [html_link "/channelgrid?whichChannel=$sta" "$sign"] puts $chan "$num$changelink[strim $name]" } puts $chan [html_table_end] puts $chan "channelgrid.itcl module version" puts $chan [html_link $::global_channelgrid_link $::global_channelgrid_version] puts $chan "(tzoffset $tzoffset)
" puts $chan [html_end] } register_module "channelgrid" "Channel Grid" "Weekly Grid of Shows"