# Copyright (c) 2001 Jeff Keegan (jkeegan@keegan.org) # $Id: # # Search module by Jeff Keegan, http://www.keegan.org/jeff # # History: # First version, September 10, 2001 # September 10, 2001: Version 1.0 # proc get_textindexsearch {searchstr searchby} { global source_dir global guideindexdir set guidedir "/var/tmp/searchmodule/" catch { exec mkdir "$guidedir" } set searchbyfiles "Title TitleKeyword Keyword Actor Director" set searchbyfile [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 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 < 3} { set searchstr [string toupper $searchstr] } set fsids [list] if {$searchby == 1 || $searchby == 2} { 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" } set retval [catch {set grepresults [exec "$source_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 { foreach line $grepresultslineslist { append fsids1 " " [lindex [split $line "\t"] 1] } } } 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 "$source_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 "$source_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 eval $env set searchbyvals "0 1 2 3 4" set searchbylabels "Title {Title Keyword} Keyword Actor Director" set searchbylab [strim [lindex $searchbylabels $searchby]] puts $chan [html_start "Search"] puts $chan [html_form_start "GET" "/search" "name=\"search\""] if { $::dtivo } { 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 "SubCategory"] [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_end] # Now output search results if this was a search action if {$q != ""} { 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} { regsub -all {[-/.]} $modq { } modq } if {$searchby == 3 || $searchby == 4} { regsub -all -- {-} $modq { } modq regsub -all {[ ]*,[ ]*} $modq {, } modq } regsub -all {[^A-Za-z0-9\*\", ]} $modq {} modq if {$searchby == 1 || $searchby == 2} { if {[string first "\"" $modq] != -1} { puts $chan [h2 "Sorry, \"exact matches\" are not supported"] puts $chan [html_end] return } } else { regsub -all {\"} $modq {} modq } regsub "\t$" $modq {} dispq if {[string length $dispq] == 0} { puts $chan [h2 "Error, empty search query"] puts $chan [html_end] return } 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\"" set fsids [get_textindexsearch $modq $searchby] if {[lindex $fsids 0] == -1} { puts $chan [h2 $searchResultsTitle] puts $chan [html_table_start "" "Results" ""] puts $chan [tr "" [td "Sorry, no shows matched your query"]] } elseif {[lindex $fsids 0] == -2} { puts $chan [h2 $searchResultsTitle] puts $chan [html_table_start "" "Results" ""] puts $chan [tr "" [td "An error was encountered running the search program"]] puts $chan [tr "" [td [lrange $fsids 1 end]]] } else { set anyresultsdisplayed 0 if {$searchby == 0} { update_sp_cache puts $chan [h2 $searchResultsTitle] puts $chan [html_table_start "" "Results" "COLSPAN=2"] foreach item [lrange $fsids 1 end] { set seriestitle [lindex $item 0] set fsid [lindex $item 1] set fsid [expr 0x$fsid] set genres [lindex $item 2] if {$cat != 0 && [genrematch $genres "$cat $scat"] == 0} { continue } regsub {^(.*), (A|The)$} $seriestitle {\2 \1} seriestitle set slists "" if {$showemptyhits == 0} { set slists [get_programshowings $fsid $watch] } if {$showemptyhits == 1 || $slists != ""} { set index [lsearch $cache_sp_key "$fsid|*"] if {$index > -1} { set imagestr [img "alt=\"\"" [lindex $images 11]] } else { set imagestr "" } set link "/series/$fsid" if {$watch != 1} { append link "?watch=0" } puts $chan [tr "" [td $imagestr] [td [html_link $link [htmlEncode $seriestitle]]]] set anyresultsdisplayed 1 } } if {$anyresultsdisplayed == 0} { puts $chan [tr "" [td "COLSPAN=2" "
Sorry, no shows matched your query
"]] } } elseif {$searchby >= 3 && [lindex $fsids 0] == 1} { puts $chan [h2 $searchResultsTitle] puts $chan [html_table_start "" "Results" ""] foreach name [lrange $fsids 1 end] { append name "\t" set link "/search?searchby=$searchby" if {$watch != 1} { append link "&watch=0" } if {$showemptyhits != 0} { append link "&showemptyhits=1" } if {$cat != 0} { append link "&cat=$cat" } if {$scat != 0} { append link "&scat=$scat" } append link "&q=[httpMapReply $name]" puts $chan [tr "" [td [html_link $link [htmlEncode $name]]]] set anyresultsdisplayed 1 } if {$anyresultsdisplayed == 0} { puts $chan [tr "" [td "
Sorry, no shows matched your query
"]] } } else { set anyepisodes 0 update_sp_cache if {$searchby >= 3} { set item [lindex $fsids 1] set fsids "0 [lindex $item 1]" set searchResultsTitle [htmlEncode [lindex $item 0]] set searchResultsTitle "Search Results for \"$searchResultsTitle\"" } puts $chan [h2 $searchResultsTitle] puts $chan [html_table_start "" "" ""] set serproghits [list] foreach fsid [lrange $fsids 1 end] { set fsid [expr 0x$fsid] if {[catch { RetryTransaction { set program [db $db openid $fsid] set seriestitle [strim [dbobj $program get Title]] if {$cat != 0} { set genres [dbobj $program get Genre] } set series [dbobj $program get Series] set seriesfsid 0 if { $series != "" } { set seriesfsid [dbobj $series fsid] set episodic [defaultval 1 [dbobj $series get Episodic]] } else { set episodic 1 } if {$episodic == 1} { set anyepisodes 1 } } }] == 1} { #puts $chan [tr "" [td "Error $fsid"]] } else { if {$cat != 0} { if { !$::dtivo || $cat == 1 || $cat == 5 || $cat == 8 } { if {[lsearch $genres $cat] < 0} { continue } } if {$scat != 0 && [lsearch $genres $scat] < 0} { continue } } lappend serproghits [list $seriestitle $seriesfsid $episodic $fsid] } } set serproghits [lsort -index 0 -dictionary $serproghits] set lastseriesfsid "" set lastseries "" set numrows [llength $serproghits] set efsids "" if {$anyepisodes} { puts $chan [tr "ALIGN=CENTER" [th ""] [th ""] [th "Episode"] [th "Num"] [th "Orig.Air Date"] [th "Channel"] [th "COLSPAN=2" "Date"] [th "Time"]] } else { puts $chan [tr "ALIGN=CENTER" [th ""] [th "Series"]] } for {set i 0} {$i < $numrows} {incr i} { set sph [lindex $serproghits $i] set stitle [strim [lindex $sph 0]] set sfsid [lindex $sph 1] set episodic [lindex $sph 2] if {$episodic == 1} { if {$sfsid != $lastseriesfsid} { set index [lsearch $cache_sp_key "$sfsid|*"] if {$index > -1} { set imagestr [img "" [lindex $images 11]] } else { set imagestr "" } set efsids "" set lastseriesfsid $sfsid set lastseries $stitle } lappend efsids [lindex $sph 3] if {$i == [expr $numrows - 1] || [lindex [lindex $serproghits [expr $i + 1]] 1] != $sfsid} { doShowingRow $chan $sfsid $stitle $efsids $watch $showemptyhits $imagestr } } else { set slists "" if {$showemptyhits == 0} { set slists [get_programshowings $sfsid $watch] } if {$showemptyhits == 1 || $slists != ""} { set link "/series/$sfsid" if {$watch != 1} { append link "?watch=0" } if {$anyepisodes} { puts $chan [tr "" [td ""] [td "COLSPAN=8" [html_link $link [htmlEncode $stitle]]]] } else { puts $chan [tr "" [td ""] [td [html_link $link [htmlEncode $stitle]]]] } set anyresultsdisplayed 1 } } } if {$anyresultsdisplayed == 0} { puts $chan [tr "" [td "COLSPAN=9" "
Sorry, no shows matched your query
"]] } } } puts $chan [html_table_end] } else { puts $chan "
" } puts $chan [html_end] } proc doShowingRow {chan serfsid sertitle progfsids watch showemptyhits imagestr} { global db global anyresultsdisplayed set first 1 if {$showemptyhits == 1} { set link "/series/$serfsid" if {$watch != 1} { append link "?watch=0" } puts $chan [tr "" [td $imagestr] [td "COLSPAN=8" [html_link $link "[htmlEncode $sertitle]"]]] set first 0 set anyresultsdisplayed 1 } set slists "" foreach progfsid $progfsids { append slists " " [get_programshowings $progfsid $watch] } set slists [lsort -index 0 $slists] foreach slist $slists { set seconds [lindex $slist 0] set stationfsid [lindex $slist 1] set date [expr $seconds / 86400] set time [expr $seconds % 86400] set timestr [format "%05d" $time] set stationdayfsid "" RetryTransaction { set recfsid [lindex [get_fsidbyprefix "/Recording/Active" "4:$date:$timestr:"] 0] set stationdayfsid [lindex [get_fsidbyprefix "/Schedule" "$stationfsid:$date:"] 0] set stationday [db $db openid $stationdayfsid] set showings [dbobj $stationday get Showing] foreach showing $showings { set stime [dbobj $showing get Time] if { $time == $stime } { # First, see if we've output the series title yet... ##################################################### if {$first == 1} { set link "/series/$serfsid" if {$watch != 1} { append link "?watch=0" } puts $chan [tr "" [td $imagestr] [td "COLSPAN=8" [html_link $link "[htmlEncode $sertitle]"]]] set first 0 } set lastseriesfsid $serfsid set lastseries $sertitle do_seriesrowtodo $chan $showing $recfsid 1 set anyresultsdisplayed 1 break } } } } } register_module "search" "Search" "Search for TV shows"