# wishlists.itcl # # Allows: deletion of WishLists # creation/deletion of ARWLs # search of upcoming programs from the WishList screen # adds WishList creation from the search screen # # Note: Search strings enclosed in double quotes are not supported by the # TiVoWeb search module. # # Based on code from TiVoWeb. # Original wishlist code written by angra. # Code extracted and converted into a standalone module and modified to also # run on 2.5.5 TiVos by LJ. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2. # See . # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # Save to tivoweb-tcl/modules as 'wishlists.itcl' and restart TiVoWeb. # # Replaces various procedures in ui.itcl and search.itcl as noted below. # # 02Jan04 18:59 v1.0 # 03Jan04 10:38 v1.1 Makes a wishlist created when SearchBy set to Title # create a Title WishList not a Keyword WishList! # Makes searching for an Actor/Director WishList a bit tidier # when multiple actors/directors match. # 04Jan04 18:36 v1.2 Doesn't allow empty WishLists to be added. # 18Feb04 20:38 v1.3 Load ukgenre.js if running on a UK TiVo. Remove extraneous # TAB characters from links and searches. # 10Apr04 11:46 v1.4 Add the ability to do exact searches. Add a link to show # all matching WishList shows. Finally nail the extra TAB # character bug ;) # new proc proc action_add-theme-sp {chan path env} { global db global seasonpassdir eval $env set fsid "0" #=================================================================== # Correct any gaps in the priorities. When you delete a SeasonPass # it creates a gap, so we need to shuffle all the trailing entries # to remove the gap, before adding the new one. This is the same # process the TiVo software follows. #=================================================================== set priority 0 ForeachMfsFileTrans fsid name type $seasonpassdir "" 20 { set sp [db $db openid $fsid] set type [defaultval 1 [dbobj $sp get Type]] set rprio [lindex [split $name "~"] 0] regsub {^0+(.+)} $rprio {\1} rprio if {$rprio != $priority} { dbobj $sp set Priority $priority } incr priority } #=================================================================== RetryTransaction { set themeob [db $db openid $id] if {[string length $themeob]> 0} { set sp [db $db create SeasonPass] dbobj $sp set Theme $themeob dbobj $sp set Type 3 dbobj $sp set MaxRecordings 5 dbobj $sp set Priority [mfs scancount $seasonpassdir] set fsid [dbobj $sp fsid] # Supress events for versions >=6 -- rbautch if {$::version < 6} { event send $TmkEvent::EVT_DATA_CHANGED $TmkDataChanged::SEASON_PASS $fsid } } } if {$fsid > 0} { action_editseasonpass $chan "/$fsid" $env } } # new proc proc action_delete-wishlist {chan path env} { global db set submit "" eval $env if {$submit != "Yes"} { puts $chan [html_start "Delete WishList"] RetryTransaction { set theme [db $db openid $id] set title [strim [dbobj $theme get Name]] } puts $chan "

Delete WishList \"$title\" - Are you certain?

" puts $chan [html_form_start "GET" "/delete-wishlist" name="foo"] puts $chan [html_form_hidden id "$id"] puts $chan [html_form_input "submit" "submit" "Yes"] puts $chan [html_form_end] puts $chan [html_end] } else { puts $chan [html_start "Delete WishList"] RetryTransaction { set theme [db $db openid $id] set type [dbobj $theme type] if {$type != "Theme"} { puts $chan [h2 "Invalid ID $fsid"] puts $chan [html_end] return } set sp [dbobj $theme get SeasonPass] if { $sp != "" } { set spfsid [dbobj $sp fsid] } dbobj $theme markasrubbish } if { $sp != "" } { DeleteSeasonPass $spfsid puts $chan "

Auto-recording Wishlist Deleted

" } else { puts $chan "

Wishlist Deleted

" } puts $chan [html_link "/ui/wishlists" "Return to WishLists"] puts $chan [html_end] } } # new proc proc get_genresearch {cat scat} { global source_dir global guideindexdir set guidedir "/var/tmp/searchmodule/" set searchbyfile "Title" catch { exec mkdir "$guidedir" } # First, check to make sure the guide data files exist in # $guidedir, and that they're recent # If not, grab them from mfs if {[catch {set fmoddate [file mtime "${guidedir}$searchbyfile"]}]} { set fmoddate "" } RetryTransaction { set fsid [lindex [mfs find "$guideindexdir/$searchbyfile"] 0] if {[catch {set moddate [mfs moddate $fsid]}]} { set moddate "" } if { $moddate > $fmoddate } { FromMfs "${guidedir}$searchbyfile" $fsid } } set f [open "${guidedir}$searchbyfile" "r"] set returntype 0 set line [gets $f] while {[string length $line] > 0} { set data [split $line] set genre [lindex $data end] set fsid [lindex $data [expr [llength $data] - 2]] set fsid [expr 0x$fsid] #puts "g=$genre" if [genrematch $genre "$cat $scat"] { set slists [get_programshowings $fsid 1] if {$slists != ""} { lappend fsids [split $line "\t"] #puts "$line added" set returntype 2 } } set line [gets $f] } #puts "done" return "$returntype $fsids" } # new proc proc action_add-wishlist {chan path env} { global db set cat "" set scat "" eval $env set prefix "" if {$cat != "0"} { RetryTransaction { set category [db $db open "/Genre/$cat"] set name [dbobj $category get Name] regsub -all {[\{\}\\]} $name {} name set prefix "$name" } } if {$scat != "0"} { RetryTransaction { set category [db $db open "/Genre/$scat"] set name [dbobj $category get Name] regsub -all {[\{\}\\]} $name {} name append prefix "/$name" } } if {[expr {$cat != 0} && {$q == ""}]} { set searchby 9 } else { if {$cat != 0} { append prefix " & " } } puts $chan [html_start "Add WishList"] if {$searchby != 9 && [string length [string trim $q]] == 0} { puts $chan "

Error: Nothing set to Wish for!


" puts $chan [html_link "/search" "Return to Search screen"] } else { set q [string toupper $q] RetryTransaction { set newtheme [db $db create Theme] dbobj $newtheme set Version 1 regsub -all {\+} $q { } q regsub "\t$" $q {} q dbobj $newtheme set Name "$prefix$q" if {$cat != ""} { dbobj $newtheme set GenreFilterPath $cat if {$scat != ""} { dbobj $newtheme add GenreFilterPath $scat } else { dbobj $newtheme add GenreFilterPath 0 } } switch $searchby { 0 - 1 { dbobj $newtheme set ThemeType 6 dbobj $newtheme set KeywordPhraseOp 2 dbobj $newtheme set KeywordPhrase $q } 2 { dbobj $newtheme set KeywordPhraseOp 2 dbobj $newtheme set KeywordPhrase $q } 3 { dbobj $newtheme set KeywordPhraseOp 2 dbobj $newtheme set KeywordPhrase $q } 4 { dbobj $newtheme set ThemeType 2 dbobj $newtheme set ActorOp 2 dbobj $newtheme set Actor $q } 5 { dbobj $newtheme set ThemeType 3 dbobj $newtheme set DirectorOp 2 dbobj $newtheme set Director $q } 9 { dbobj $newtheme set ThemeType 5 } } } puts $chan "

WishList Added


" puts $chan [html_link "/ui/wishlists" "Click to view WishLists"] } } # New in 1.4. Heavily based on get_textindexsearch from search.itcl proc get_exactsearch {searchstr searchby chan} { global db set fullsearchstr [string toupper $searchstr] set searchstr "" set activestr [string range $fullsearchstr 1 [expr [string length $fullsearchstr] - 2]] regsub -all {[^A-Z0-9 ]} $activestr {} activestr regsub {(THE|WHICH|THEN) } $activestr {} checkstr if {[string trim $checkstr] == ""} { # Oh well, we tried! set checkstr $activestr } foreach srchword $checkstr { if {[string length $srchword] > [string length $searchstr]} { set searchstr $srchword } } set returntype 0 set fsids [get_textindexsearch $searchstr 1] if {[lindex $fsids 0] == -2} { return -2 } else { set fsids [lrange $fsids 1 end] } if {$searchby == 2 || $searchby == 3} { set keywordfsids [get_textindexsearch $searchstr 2] if {[lindex $keywordfsids 0] == -2} { return -2 } else { set keywordfsids [lrange $keywordfsids 1 end] } if {$fsids == ""} { set fsids $keywordfsids } else { foreach fsid $keywordfsids { if {[lsearch $fsids $fsid] == -1} { lappend fsids $fsid } } } foreach word $activestr { set actorfsids [get_textindexsearch $word 3] if {[lindex $actorfsids 0] == -2} { return -2 } else { if {[lindex $actorfsids 0] == 1} { set mactorfsids "" foreach actor [lrange $actorfsids 1 end] { set mactorfsid [get_textindexsearch "$actor\t" 3] if {[lindex $mactorfsid 0] == 2} { append mactorfsids " [lrange [lindex [lindex [lrange $mactorfsid 1 end] 0] 1] 0 end]" } } set actorfsids $mactorfsids } else { set actorfsids [lrange [lindex [lindex [lrange $actorfsids 1 end] 0] 1] 0 end] } } if {$actorfsids != ""} { foreach fsid $actorfsids { if {[lsearch $fsids $fsid] == -1} { lappend fsids $fsid } } } set directorfsids [get_textindexsearch $word 4] if {[lindex $directorfsids 0] == -2} { return -2 } else { if {[lindex $directorfsids 0] == 1} { set mdirectorfsids "" foreach director [lrange $directorfsids 1 end] { set mdirectorfsid [get_textindexsearch "$director\t" 4] if {[lindex $mdirectorfsid 0] == 2} { append mdirectorfsids " [lindex [lindex [lindex [lrange $mdirectorfsid 1 end] 0] 1] 0]" } } set directorfsids $mdirectorfsids } else { set directorfsids [lindex [lindex [lindex [lrange $directorfsids 1 end] 0] 1] 0] } } if {$directorfsids != ""} { foreach fsid $directorfsids { if {[lsearch $fsids $fsid] == -1} { lappend fsids $fsid } } } } } if {$fsids == ""} { return -1 } # Searches: Titles; Episode Titles and if a keyword search Descriptions; Actors; Guest Stars; Directors too. # Doesn't search: Writers; Producers; Exec Producers, Hosts set fsids1 $fsids set fsids [list] foreach objfsid $fsids1 { scan $objfsid "%x" objfsidd RetryTransaction { if {[catch {db $db openid $objfsidd} showing ]} { puts "**** Couldn't find obj $objfsidd !!" } else { set title [dbobj $showing get Title] if {$title != ""} { regsub -all {[^A-Za-z0-9 ]} $title {} title if {[string first $activestr [string toupper $title]] != -1} { lappend fsids $objfsid continue } } if {$searchby == 2 || $searchby == 3} { set episodetitle [dbobj $showing get EpisodeTitle] if {$episodetitle != ""} { regsub -all {[^A-Za-z0-9 ]} $episodetitle {} episodetitle if {[string first $activestr [string toupper $episodetitle]] != -1} { lappend fsids $objfsid continue } } set description [dbobj $showing get Description] if {$description != ""} { regsub -all {[^A-Za-z0-9 ]} $description {} description if {[string first $activestr [string toupper $description]] != -1} { lappend fsids $objfsid continue } } set actordirector "[dbobj $showing get Actor] [dbobj $showing get Director] [dbobj $showing get GuestStar]" set ppls "" foreach person $actordirector { set barpos [string first "|" $person] append ppls "[string range $person [expr $barpos + 1] end] [string range $person 0 [expr $barpos - 1]]," } if {$ppls != ""} { regsub -all {[^A-Za-z0-9 ]} $ppls {} ppls if {[string first $activestr [string toupper $ppls]] != -1} { lappend fsids $objfsid continue } } } } } } set returntype 2 if {$fsids == ""} { return -1 } else { return "$returntype $fsids" } } # New in 1.4 proc action_showwishlists {chan path env} { global db global images set imagef [lindex $images 13] set imageg [lindex $images 3] set themetypes "Keyword Actor Director Advanced Category Title" puts $chan [html_start "All WishList Matches"] puts $chan [h2 "All WishList Matches"] set fsids "" ForeachMfsFileTrans fsid name type "/Theme" "" 20 { lappend fsids $fsid } foreach fsid $fsids { RetryTransaction { set theme [db $db openid $fsid] set title [strim [dbobj $theme get Name]] set ampindex [string first "&" $title] if {$ampindex != -1} { set query [string range $title [expr $ampindex + 2] end] } else { set query $title } regsub -all "\"" $query "\\\"" query set url "set \"searchby\" " set sp [dbobj $theme get SeasonPass] set type [defaultval 1 [dbobj $theme get ThemeType]] switch -exact $type { 1 {append url "\"3\";set \"q\" \"$query\";" } 2 {if { [string range $query [expr [string length $query] - 3] end] == "%09" } { append url "\"4\"; set \"q\" \"$query\";" } else { append url "\"4\";set \"q\" \"$query\t\";" } } 3 {append url "\"5\";set \"q\" \"$query\";" } 6 {append url "\"1\";set \"q\" \"$query\";" } 5 {append url "\"0\";set \"q\" \"\";" } } set genre [dbobj $theme get GenreFilterPath] set cat [defaultval 0 [lindex $genre 0]] set scat [defaultval 0 [lindex $genre 1]] append url "set \"cat\" \"$cat\";set \"scat\" \"$scat\";set \"w\" \"1\"" set title1 $title set imagestr "" if { $sp != "" } { set spfsid [dbobj $sp fsid] set imagestr [html_link "/editseasonpass/$spfsid" [img "alt=\"Edit Season Pass\"" $imagef]] } else { set imagestr [html_link "/add-theme-sp?id=$fsid" [img "alt=\"Click to convert to an auto-recording WishList\"" $imageg]] } } set themestr [lindex $themetypes [expr $type - 1]] puts $chan [html_table_start "" "" ""] if {$type == 5} { puts $chan [tr "" [th "align=right" $imagestr] [th "colspan=2 align=left" "$title1 - ($themestr)    [html_link "/delete-wishlist?id=$fsid" "Delete"]"]] } else { puts $chan [tr "" [th "colspan=3 align=right" $imagestr] [th "colspan=7 align=left" "$title1 - ($themestr)    [html_link "/delete-wishlist?id=$fsid" "Delete"]"]] } if {$type == 4} { # Sorry, no search for Advanced wishlists yet! ;) puts $chan [tr "" [td "colspan=10" "
Sorry, can't search for Advanced WishLists yet!"]] } else { set env $url action_search $chan $path $env } puts $chan [html_table_end] puts $chan "

" } puts $chan [html_end] }