# TivoWebPlus # # Search module by Jeff Keegan, http://www.keegan.org/jeff # # History: # First version, September 10, 2001 # September 10, 2001: Version 1.0 # # MelvinPurvis # Changed to use auto-generated genericgenre.js for dtvio case # resolves dependence on a static file that may not reflect the categories of the current tivo proc get_textindexsearch {searchstr searchby} { global guideindexdir set guidedir "/var/tmp/searchmodule/" catch { exec mkdir "$guidedir" } set searchbyfiles "Title TitleKeyword Keyword {TitleKeyword Keyword} Actor Director" set searchbyfilelist [lindex $searchbyfiles $searchby] # First, check to make sure the guide data files exist in # $guidedir, and that they're recent # If not, grab them from mfs foreach searchbyfile $searchbyfilelist { 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 } } } if {$searchby < 4} { set searchstr [string toupper $searchstr] } set fsids [list] if {$searchby == 1 || $searchby == 2 || $searchby == 3} { set returntype 0 foreach sstr $searchstr { set fsids1 [list] # Can't deal with "s here regsub -all {\"} $sstr {} sstr set len [string length $sstr] incr len -1 if {[string index $sstr $len] == "*"} { set sstr [string range $sstr 0 [expr $len-1]] } else { append sstr "\t" } foreach searchbyfile $searchbyfilelist { set retval [catch {set grepresults [exec "$::bin_dir/bsearch" "${guidedir}${searchbyfile}" $sstr]} error] if {$retval != 1} { set grepresultslineslist [split $grepresults "\n\r"] if {[llength $grepresultslineslist] > 1} { foreach line $grepresultslineslist { foreach fsid [lindex [split $line "\t"] 1] { if {[lsearch $fsids1 $fsid] == -1} { lappend fsids1 $fsid } } } } else { set line [lindex $grepresultslineslist 0] foreach fsid [lindex [split $line "\t"] 1] { if {[lsearch $fsids1 $fsid] == -1} { lappend fsids1 $fsid } } } } else { regsub -all "\"" $error "\\\"" error return "-2 $error" } } if {$fsids == ""} { set fsids $fsids1 } else { set fsids2 [list] foreach fsid $fsids { if {[lsearch $fsids1 $fsid] != -1} { lappend fsids2 $fsid } } set fsids $fsids2 } } } else { set retval [catch {set grepresults [exec "$::bin_dir/bsearch" "${guidedir}${searchbyfile}" $searchstr]} error] if {$retval == 1} { regsub -all "\"" $error "\\\"" error return "-2 $error" } if {$grepresults == "" && $searchby >= 3 && [string first "," $searchstr] == -1 && [llength $searchstr] > 1} { set slist [split $searchstr " "] set slen [llength $slist] set sstr "[lindex $slist [expr $slen - 1]], [join [lrange $slist 0 [expr $slen - 2]]]" set retval [catch {set grepresults [exec "$::bin_dir/bsearch" "${guidedir}${searchbyfile}" $sstr]}] } if {$retval == 1} { return -2 } set grepresultslineslist [split $grepresults "\n\r"] if {[llength $grepresultslineslist] > 1 && $searchby >= 3} { foreach line $grepresultslineslist { lappend fsids [lindex [split $line "\t"] 0] } set returntype 1 } else { foreach line $grepresultslineslist { lappend fsids [split $line "\t"] } set returntype 2 } } if {$fsids == ""} { return -1 } else { return "$returntype $fsids" } } proc action_search {chan path env} { global db global cache_sp_fsid cache_sp_key global anyresultsdisplayed global images global url_prefix set searchby 0 set q "" set watch 1 set showemptyhits 0 set cat 0 set scat 0 set showthumb 0 set showrating 0 set submit "" set doingexactsearch 0 # Added in 1.4 set w 0 eval $env set searchbyvals "0 1 2 3 4 5" set searchbylabels "Title {Title Keyword} {Description Keyword} {Title/Description Keyword} Actor Director" if {$submit=="Add WishList"} { action_add-wishlist $chan $path $env return } set searchbylab [strim [lindex $searchbylabels $searchby]] if {$w == 0} { puts $chan [html_start "Search"] puts $chan [html_form_start "GET" "/search" "name=\"search\""] if { $::dtivo } { puts $chan "" #puts $chan "" } elseif { $::uktivo } { puts $chan "" } else { puts $chan "" } puts $chan [html_table_start "" "Search" "COLSPAN=2"] puts $chan [tr "" [td "Search By:"] [td "" [html_form_select "searchby" $searchbyvals $searchbylabels $searchby "onChange=\"searchhelp(this.options.selectedIndex)\""]]] puts $chan [tr "" [td "Category:"] [td [html_form_select "cat" "0" "All" 0 "onChange=\"loadscat(this.options.selectedIndex)\""]]] puts $chan [tr "" [td "Sub-Category:"] [td [html_form_select "scat" "0" "{Don't specify a sub-category}" 0]]] puts $chan "" puts $chan [tr "" [td "Search For:"] [td [html_form_text 1 35 "q" $q]]] if {$watch == 0} { puts $chan [tr "" [td "COLSPAN=2" " Include Channels You Don't Watch"]] } else { puts $chan [tr "" [td "COLSPAN=2" " Include Channels You Don't Watch"]] } if {$showemptyhits == 1} { puts $chan [tr "" [td "COLSPAN=2" " Display Empty (No Upcoming Episodes) Hits"]] } else { puts $chan [tr "" [td "COLSPAN=2" " Display Empty (No Upcoming Episodes) Hits"]] } puts $chan [html_table_end] puts $chan [html_form_input "submit" "submit" "Search"] puts $chan [html_form_input "submit" "submit" "Add WishList"] puts $chan [html_form_end] } # Now output search results if this was a search action if {[expr {$q != ""} || {$cat != 0}]} { #puts $chan "Running query" regsub -nocase {^(a|the) } $q {} modq if {$searchby == 0} { regsub -all {\$} $modq {} modq regsub -all {\*} $modq {} modq } else { regsub -all {\$} $modq {S} modq } if {$searchby == 1 || $searchby == 2 || $searchby == 3} { regsub -all {[-/.]} $modq { } modq } if {$searchby == 4 || $searchby == 5} { regsub -all -- {-} $modq { } modq regsub -all {[ ]*,[ ]*} $modq {, } modq } regsub -all {[^A-Za-z0-9\*\", ]} $modq {} modq if {$searchby == 1 || $searchby == 2 || $searchby == 3} { if {[string first "\"" $modq] != -1} { if {[string first " " $q] == -1} { # Not really an "exact" search! regsub -all {\"} $modq {} modq set doingexactsearch 0 } else { if {[string last "\"" $q] != [expr [string length $q] - 1]} { puts $chan [h2 "Error, unrecognised search format.: $q"] return } else { if {[string first "\"" [string range $q 1 [expr [string length $q] - 2]]] != -1} { puts $chan [h2 "Error, unrecognised search format: $q"] return } set doingexactsearch 1 } } } else { set doingexactsearch 0 } } else { regsub -all {\"} $modq {} modq } regsub "\t$" $modq {} dispq if {[string length $dispq] == 0} { if {$cat == ""} { puts $chan [h2 "Error, empty search query"] puts $chan [html_end] return } } else { if {[string length $dispq] < 2} { puts $chan [h2 "Error, require at least 2 characters in query"] puts $chan [html_end] return } } set searchResultsTitle [htmlEncode $dispq] set searchResultsTitle "Search Results for \"$searchResultsTitle\"" if {[expr {$q == ""} && {$cat != ""}]} { #puts $chan "DOING GENRESEARCH" set fsids [get_genresearch $cat $scat] set watch 0 } else { if {$doingexactsearch == 1} { set fsids [get_exactsearch $q $searchby $chan] } else { set fsids [get_textindexsearch $modq $searchby] } } if {[lindex $fsids 0] == -1} { if {$w == 0} { puts $chan [h2 $searchResultsTitle] puts $chan [html_table_start "" "Results" ""] puts $chan [tr "" [td "Sorry, no shows matched your query"]] } else { puts $chan [tr "" [td "colspan=10" "