# Conflict resolution between two networked TiVos
# Version 0.2
# Stuart Anderton, 2003
# Big chunks 'repurposed' from various TiVoWeb modules
# Starting procedure, gets address of remote TiVo
proc action_confres {chan path env} {
puts $chan [html_start "Conflict Resolver"]
puts $chan "Attempt to schedule conflicts on a second TiVo"
puts $chan [html_table_start "" "" ""]
puts $chan [html_form_start "GET" "/findconfs"]
puts $chan [tr "" [td "The other TiVo to try to find recording space on: "] [td [html_form_text 1 35 "tivoname" "TiVo Name"]]]
puts $chan [tr "" [td "Number of days ahead to look: "] [td [html_form_text 1 35 "daysahead" "7"]]]
puts $chan [tr "" [td ""] [td [html_form_input "submit" "Save" "Next"]]]
puts $chan [html_form_end]
puts $chan [html_table_end]
puts $chan [html_end]
}
# Find unresolved conflicts and pass them to other TiVo
proc action_findconfs {chan path env} {
global db
eval $env
set conflicts {}
puts $chan [html_start "Conflict Resolver"]
puts $chan "Found the following unresolved conficts:"
puts $chan [html_table_start "" "" ""]
puts $chan [tr "" [td "Title"] [td "Channel"] [td "Date (TiVo format)"]]
ForeachMfsFile fsid name type "/Recording/History" "" {
set recdate [split $name ":"]
regsub {^(-?)0+([1-9])} [lindex $recdate 1] {\1\2} thetime
set rectime [expr [lindex $recdate 0] * 86400 + $thetime]
if {$rectime > [expr [clock seconds] + $daysahead * 86400]} {
break
}
if {$rectime > [clock seconds]} {
RetryTransaction {
set rec [db $db openid $fsid ]
set creason [dbobj $rec get CancelReason]
set showing [dbobj $rec get Showing]
set duration [dbobj $showing get Duration]
set endtime [expr $rectime + $duration]
set station [dbobj $showing get Station]
set callsign [dbobj $station get CallSign]
set program [dbobj $showing get Program]
set title [dbobj $program get Title]
set id [dbobj $program get TmsId]
set id2 [dbobj $program fsid]
}
if {$creason == 20} {
set alt [alt_showing $id $id2]
if {$alt == ""} {
puts $chan [tr "" [td $title] [td $callsign] [td "[clock format $rectime -format {%a %H:%M}] - [clock format $endtime -format %H:%M]"]]
lappend conflicts "$rectime $endtime $callsign $id $title $thetime"
}
}
}
}
puts $chan [html_table_end]
set othertivourl "http://$tivoname/otherside"
puts $chan [html_form_start "POST" $othertivourl"]
puts $chan [html_form_hidden "conflicts" $conflicts]
puts $chan [html_form_input "submit" "Save" "Pass them to the other TiVo"]
puts $chan [html_form_end]
puts $chan [html_end]
}
# runs on the "other" Tivo
proc action_otherside {chan path env} {
global db
global cir
global callsigns
eval $env
getchannelsir
puts $chan [html_start "Conflict Resolver"]
puts $chan "Availability on second TiVo:"
puts $chan [html_table_start "" "" ""]
puts $chan [tr "" [td "Programme"] [td "Time (TiVo internal clock)"] [td "Channel"] [td "Status"]]
foreach conflict $conflicts {
set rectime [lindex $conflict 0]
set endtime [lindex $conflict 1]
set callsign [lindex $conflict 2]
set id [lindex $conflict 3]
set title [lindex $conflict 4]
set rtime [lindex $conflict 5]
if {[lsearch $callsigns $callsign] == -1} {
set avail "Channel not available"
} else {
set cancellists [RecConflictsList $rectime $endtime]
set cancellist [lindex $cancellists 0]
if {$cancellist == ""} {
set stationfsid [lindex [lindex $cir [lsearch $callsigns $callsign]] 1]
set date [expr int($rectime/86400)]
RetryTransaction {
set schedlist [get_fsidbyprefix "/Schedule" "$stationfsid:$date:"]
}
set stationdayfsid [lindex $schedlist 0]
RetryTransaction {
set stationday [db $db openid $stationdayfsid]
set showings [dbobj $stationday get Showing]
set slen [llength $showings]
set match 0
set loop 0
set fsid ""
while { $loop < $slen } {
set testshowing [lindex $showings $loop]
set stime [dbobj $testshowing get Time]
if { $rtime == $stime } {
set fsid "[dbobj $testshowing fsid]/[dbobj $testshowing subobjid]"
set match 1
break
}
incr loop
}
}
if { $match == 0 } {
set avail "Slot free, error finding fsid for link"
} else {
set avail [html_link "/recoptions/$fsid" "Slot free, click to record"]
}
} else {
RetryTransaction {
set rec [db $db openid [lindex $cancellist 0]]
set showing [dbobj $rec get Showing]
set program [dbobj $showing get Program]
set existtitle [dbobj $program get Title]
}
if {[strim $existtitle] == [strim $title]} {
set avail "Recording [strim $existtitle] already"
} else {
set stationfsid [lindex [lindex $cir [lsearch $callsigns $callsign]] 1]
set date [expr int($rectime/86400)]
RetryTransaction {
set schedlist [get_fsidbyprefix "/Schedule" "$stationfsid:$date:"]
}
set stationdayfsid [lindex $schedlist 0]
RetryTransaction {
set stationday [db $db openid $stationdayfsid]
set showings [dbobj $stationday get Showing]
set slen [llength $showings]
set match 0
set loop 0
set fsid ""
while { $loop < $slen } {
set testshowing [lindex $showings $loop]
set stime [dbobj $testshowing get Time]
if { $rtime == $stime } {
set fsid "[dbobj $testshowing fsid]/[dbobj $testshowing subobjid]"
set match 1
break
}
incr loop
}
}
if { $match == 0 } {
set avail "Busy recording [strim $existtitle]"
} else {
set avail [html_link "/recoptions/$fsid" "Busy recording [strim $existtitle], click to record anyway"]
}
}
}
}
puts $chan [tr "" [td $title] [td "[clock format $rectime -format {%a %H:%M}] - [clock format $endtime -format %H:%M]"] [td $callsign] [td $avail]]
}
puts $chan [html_table_end]
puts $chan [html_end]
}
proc getchannelsir {} {
global cir
global callsigns
global channeltablestation
global channeltablenum
global db
foreach channum [lsort -integer [array names channeltablenum]] {
set stationfsid $channeltablenum($channum)
set data $channeltablestation($stationfsid)
set callsign [lindex $data 2]
lappend cir "$callsign $stationfsid"
lappend callsigns "$callsign"
}
}
register_module "confres" "Conflict Resolve" "Attempt to schedule conflicts on a networked TiVo"