# <- SUPERGOOGLE 1.3 -> brazman@systemz.org # # --> fixed & powered by brazOo (original by brother) # supergoogle.tcl 1.2 by brother (luc@rocketmail.com) # # This tcl script is an extension to the google.tcl script by # aNa|0Gue - analogue@glop.org - http://www.glop.org # It is completely written from scratch to provide more options # and features than the original one. # # Features # * select the channels to listen on for the request # * proxy support # * request multiple hits for the search # * details like sitename and size per hit # * online help included # * debug mode # * crude flood control (for now) # * partyline google (suggested by Holieman) # * every option can be set by some simple variables # * ... # # I have included in the zip a file called http.tcl for users who # cannot get the http package installed (mainly win32 users) # This file will fully emulate all its commands and is useable for # other modules too. You also need alltools.tcl loaded before this # one. # # Just load the tcl scripts as follows in your config # source scripts/alltools.tcl # source scripts/http.tcl #only for win32 or if it complains # source scripts/supergoogle.tcl # # Revisions: # 1.0 Initial version # 1.1 Fixed a bug in detailed section # Added a handler variable and partyline searching # 1.2 Parse procedure sucked, it was slow and buggy; so # i have completely rewritten it. It should both be # faster and (hopefully) bugfree this time. # # # # Below you can set some important variables # Hostname of proxy service. Set to "" if you don't want to use this. # This one is for pandora.be members # set sgoogle_proxy "proxy.pandora.be:8080" set sgoogle_proxy "" # Only allow command on following channels # set sgoogle_channels "#chan1 #chan2 #chanX" # or for all channels set sgoogle_channels "" # maximum number of hits on a search returned by the engine set sgoogle_hits 5 # default number of hits returned set sgoogle_hits_default 1 # allow use of detailed mode? set sgoogle_detail 1 # use detailed mode only when requested? set sgoogle_detail_request 1 # reply method for a public request (on the channel) # set to 0 for a notice to the user # set to 1 for a msg to the user # set to 2 for a public msg on the channel set sgoogle_pubmethod 2 # who should i allow a google search in the partyline (use the eggdrop flags) # ie. only allow botmasters and botowners set sgoogle_pline_flags "mn" # log requests? set sgoogle_log 1 # debug the script set sgoogle_debug 0 # # do not change below here # set sgoogle_lastreq "" set sgoogle_antiflood 0 package require http if {!($sgoogle_proxy == "")} { http::config -proxyhost [lindex [split $sgoogle_proxy {:}] 0] -proxyport [lindex [split $sgoogle_proxy {:}] 1] -useragent "BrasMort Browser" } { http::config -useragent "BrasMort Browser" } bind pub - !google pub:sgoogle bind pub - !zoek pub:sgoogle bind pub - !search pub:sgoogle bind pub - !images pub:gimages bind pub - !groups pub:ggroups bind dcc $sgoogle_pline_flags google dcc:sgoogle bind dcc $sgoogle_pline_flags zoek dcc:sgoogle bind dcc $sgoogle_pline_flags search dcc:sgoogle bind dcc $sgoogle_pline_flags images dcc:gimages bind dcc $sgoogle_pline_flags groups dcc:ggroups proc sgoogle_antiflood_reset {} { global sgoogle_antiflood set sgoogle_antiflood 0 set sgoogle_lastreq "" foreach th [timers] { if {[lindex $th 1]=="sgoogle_antiflood_reset"} { killtimer [lindex $th 2] } } } proc pub:sgoogle { nick uhost handle channel arg } { global sgoogle_channels sgoogle_pubmethod global sgoogle_antiflood sgoogle_lastreq sgoogle_log if {$sgoogle_antiflood > 4} {return 0} if {[llength $arg]!=0} { if {$arg == $sgoogle_lastreq} {return 0} } set sgoogle_lastreq $arg set sgoogle_antiflood [expr $sgoogle_antiflood + 1] timer 1 sgoogle_antiflood_reset if {!($sgoogle_channels == "") && ([lsearch -exact [string tolower $sgoogle_channels] [string tolower $channel]] < 0)} {return 0} if {$sgoogle_pubmethod == 0} {set logger [sgoogle_start "google" 0 $nick $arg]} elseif {($sgoogle_pubmethod == 2) && ([string tolower $arg] != "help")} { set logger [sgoogle_start "google" 2 $channel $arg]} else {set logger [sgoogle_start "google" 1 $nick $arg]} if {$sgoogle_log == 1} {putcmdlog "\[SG\] ($channel) $nick $logger"} return 0 } proc dcc:sgoogle { handle idx arg } { global sgoogle_antiflood sgoogle_lastreq sgoogle_log if {$sgoogle_antiflood > 8} {return 0} if {$arg == $sgoogle_lastreq} {return 0} set sgoogle_lastreq $arg set sgoogle_antiflood [expr $sgoogle_antiflood + 1] timer 1 sgoogle_antiflood_reset set logger [sgoogle_start "google" 3 $idx $arg] if {$sgoogle_log == 1} {putcmdlog "\[SG\] (Pline) $handle $logger"} return 0 } proc pub:gimages { nick uhost handle channel arg } { global sgoogle_channels sgoogle_pubmethod global sgoogle_antiflood sgoogle_lastreq sgoogle_log if {$sgoogle_antiflood > 4} {return 0} if {$arg == $sgoogle_lastreq} {return 0} set sgoogle_lastreq $arg set sgoogle_antiflood [expr $sgoogle_antiflood + 1] timer 1 sgoogle_antiflood_reset if {!($sgoogle_channels == "") && ([lsearch -exact [string tolower $sgoogle_channels] [string tolower $channel]] < 0)} {return 0} if {$sgoogle_pubmethod == 0} {set logger [sgoogle_start "images" 0 $nick $arg]} elseif {($sgoogle_pubmethod == 2) && ([string tolower $arg] != "help")} { set logger [sgoogle_start "images" 2 $channel $arg]} else {set logger [sgoogle_start "images" 1 $nick $arg]} if {$sgoogle_log == 1} {putcmdlog "\[SG\] ($channel) $nick $logger"} return 0 } proc dcc:gimages { handle idx arg } { global sgoogle_antiflood sgoogle_lastreq sgoogle_log if {$sgoogle_antiflood > 8} {return 0} if {$arg == $sgoogle_lastreq} {return 0} set sgoogle_lastreq $arg set sgoogle_antiflood [expr $sgoogle_antiflood + 1] timer 1 sgoogle_antiflood_reset set logger [sgoogle_start "images" 3 $idx $arg] if {$sgoogle_log == 1} {putcmdlog "\[SG\] (Pline) $handle $logger"} return 0 } proc pub:ggroups { nick uhost handle channel arg } { global sgoogle_channels sgoogle_pubmethod global sgoogle_antiflood sgoogle_lastreq sgoogle_log if {$sgoogle_antiflood > 4} {return 0} if {$arg == $sgoogle_lastreq} {return 0} set sgoogle_lastreq $arg set sgoogle_antiflood [expr $sgoogle_antiflood + 1] timer 1 sgoogle_antiflood_reset if {!($sgoogle_channels == "") && ([lsearch -exact [string tolower $sgoogle_channels] [string tolower $channel]] < 0)} {return 0} if {$sgoogle_pubmethod == 0} {set logger [sgoogle_start "groups" 0 $nick $arg]} elseif {($sgoogle_pubmethod == 2) && ([string tolower $arg] != "help")} { set logger [sgoogle_start "groups" 2 $channel $arg]} else {set logger [sgoogle_start "groups" 1 $nick $arg]} if {$sgoogle_log == 1} {putcmdlog "\[SG\] ($channel) $nick $logger"} return 0 } proc dcc:ggroups { handle idx arg } { global sgoogle_antiflood sgoogle_lastreq sgoogle_log if {$sgoogle_antiflood > 8} {return 0} if {$arg == $sgoogle_lastreq} {return 0} set sgoogle_lastreq $arg set sgoogle_antiflood [expr $sgoogle_antiflood + 1] timer 1 sgoogle_antiflood_reset set logger [sgoogle_start "groups" 3 $idx $arg] if {$sgoogle_log == 1} {putcmdlog "\[SG\] (Pline) $handle $logger"} return 0 } proc sgoogle_start { mode public destination arg } { global sgoogle_version version sgoogle_hits sgoogle_hits_default sgoogle_debug sgoogle_detail_request sgoogle_detail lastbind regsub -all -nocase {\$\{\}\[\]} $arg {} arg set arg [string tolower $arg] if {(([llength $arg]==0) || ([string tolower $arg] == "help")) && ($mode=="google")} { set temp "" lappend temp "Help: $sgoogle_version" lappend temp "|-$lastbind \[fr|france|linux\] \[detail|simple\] " lappend temp "|  Search google for keywords. You can specify" lappend temp "|  the number of hits you want generated and" lappend temp "|  you want the results in detailed or simple" lappend temp "|  mode. Maximum number of hits is set to $sgoogle_hits" lappend temp "|-!images " lappend temp "|  Search google images for keywords." lappend temp "|-!groups \[lang=fr|de|en...\] " lappend temp "|  Search google groups for keywords." lappend temp "|-$lastbind version" lappend temp "|  check this scripts version" lappend temp "`-$lastbind help" sgoogle_sendtext $temp $public $destination return "asked for help." } if {(([llength $arg]==0) || ([string tolower $arg] == "help")) && ($mode=="images")} { set temp "" lappend temp "Help: $sgoogle_version" lappend temp "|-$lastbind \[fr|france|linux\] \[detail|simple\] " lappend temp "|  Search google for keywords. You can specify" lappend temp "|  the number of hits you want generated and" lappend temp "|  you want the results in detailed or simple" lappend temp "|  mode. Maximum number of hits is set to $sgoogle_hits" lappend temp "|-$lastbind " lappend temp "|  Search google images for keywords." lappend temp "|-!groups \[lang=fr|de|en...\] " lappend temp "|  Search google groups for keywords." lappend temp "|-$lastbind version" lappend temp "|  check this scripts version" lappend temp "`-$lastbind help" sgoogle_sendtext $temp $public $destination return "asked for help." } if {(([llength $arg]==0) || ([string tolower $arg] == "help")) && ($mode=="groups")} { set temp "" lappend temp "Help: $sgoogle_version" lappend temp "|-$lastbind \[fr|france|linux\] \[detail|simple\] " lappend temp "|  Search google for keywords. You can specify" lappend temp "|  the number of hits you want generated and" lappend temp "|  you want the results in detailed or simple" lappend temp "|  mode. Maximum number of hits is set to $sgoogle_hits" lappend temp "|-!images " lappend temp "|  Search google images for keywords." lappend temp "|-$lastbind \[lang=fr|de|en...\] " lappend temp "|  Search google groups for keywords." lappend temp "|-$lastbind version" lappend temp "|  check this scripts version" lappend temp "`-$lastbind help" sgoogle_sendtext $temp $public $destination return "asked for help." } if {$arg == "version"} { sgoogle_sendtext "{$sgoogle_version running on eggdrop [lindex $version 0].}" $public $destination return "requested the version." } if {$mode=="images"} { set zoekstring $arg set detailed 0 if {[string match {[0-9]} [lindex $zoekstring 0]] || [string match {[0-9][0-9]} [lindex $zoekstring 0]]} { set hits [lindex $zoekstring 0] set zoekstring [lrange $arg 1 end] if {$hits > $sgoogle_hits} { sgoogle_sendtext "{Too many hits requested (try $lastbind help)}" $public $destination return "tried to retrieve too many hits." } if {$hits < 1} { sgoogle_sendtext "{Number of hits must be at least 1}" $public $destination return "gave an invalid hits value." } } else { set hits $sgoogle_hits_default } set query "http://images.google.fr/images?q=" for { set index 0 } { $index<[llength $zoekstring] } { incr index } { set query "$query[lindex $zoekstring $index]" if {$index<[llength $zoekstring]-1} then { set query "$query+" } } set query "$query&num=$hits" if {$sgoogle_debug == 1} { putlog "DEBUG: Query built ($query)" putlog "DEBUG: Contacting website..." } set token [http::geturl $query] puts stderr "" upvar #0 $token state if {$sgoogle_debug == 1} {putlog "DEBUG: Got state ($state(http))"} if {[string tolower [lindex $state(http) 2]] != "ok"} { sgoogle_sendtext "{Could not find results for $zoekstring (Error: [lrange $state(http) 2 end])}" $public $destination return "requested $zoekstring but got an error: [lrange $state(http) 2 end]." } set htmldata [http::data $token] if {$sgoogle_debug == 1} {putlog "DEBUG: Got data ([string length $htmldata] bytes)"} set parsed [images_parse $htmldata] if {$parsed == 0} { if {$sgoogle_debug == 1} {putlog "DEBUG: Could not find items to parse."} sgoogle_sendtext "{Could not find results for $zoekstring}" $public $destination return "requested $zoekstring but couldn't find any results." } if {$sgoogle_debug == 1} {putlog "DEBUG: Data parsed (got [lindex $parsed 0] items)"} set sendtext [images_template $parsed $detailed $zoekstring] if {$sgoogle_debug == 1} {putlog "DEBUG: Template applied ([llength $sendtext] lines of text)"} sgoogle_sendtext $sendtext $public $destination if {$sgoogle_debug == 1} {putlog "DEBUG: Sent text to output. Done..."} return "requested $zoekstring and got [lindex $parsed 0] items ([string length $htmldata] bytes)" } if {$mode=="groups"} { set zoekstring $arg set detailed 0 if {[string match {[0-9]} [lindex $zoekstring 0]] || [string match {[0-9][0-9]} [lindex $zoekstring 0]]} { set hits [lindex $zoekstring 0] set zoekstring [lrange $arg 1 end] if {$hits > $sgoogle_hits} { sgoogle_sendtext "{Too many hits requested (try $lastbind help)}" $public $destination return "tried to retrieve too many hits." } if {$hits < 1} { sgoogle_sendtext "{Number of hits must be at least 1}" $public $destination return "gave an invalid hits value." } } else { set hits $sgoogle_hits_default } set lang 0 if {[string range $zoekstring 0 4]=="lang="} { set lang [lindex $zoekstring 0] set zoekstring [lrange $zoekstring 1 end] set lang [string range $lang 5 end] set lang "lr=lang_[string tolower $lang]" } set query "http://groups.google.fr/groups?q=" for { set index 0 } { $index<[llength $zoekstring] } { incr index } { set query "$query[lindex $zoekstring $index]" if {$index<[llength $zoekstring]-1} then { set query "$query+" } } if {$lang!=0} { set query "$query&$lang" } set query "$query&num=$hits" if {$sgoogle_debug == 1} { putlog "DEBUG: Query built ($query)" putlog "DEBUG: Contacting website..." } set token [http::geturl $query] puts stderr "" upvar #0 $token state if {$sgoogle_debug == 1} {putlog "DEBUG: Got state ($state(http))"} if {[string tolower [lindex $state(http) 2]] != "ok"} { sgoogle_sendtext "{Could not find results for $zoekstring (Error: [lrange $state(http) 2 end])}" $public $destination return "requested $zoekstring but got an error: [lrange $state(http) 2 end]." } set htmldata [http::data $token] if {$sgoogle_debug == 1} {putlog "DEBUG: Got data ([string length $htmldata] bytes)"} set parsed [groups_parse $htmldata] if {$parsed == 0} { if {$sgoogle_debug == 1} {putlog "DEBUG: Could not find items to parse."} sgoogle_sendtext "{Could not find results for $zoekstring}" $public $destination return "requested $zoekstring but couldn't find any results." } if {$sgoogle_debug == 1} {putlog "DEBUG: Data parsed (got [lindex $parsed 0] items)"} set sendtext [groups_template $parsed $detailed $zoekstring] if {$sgoogle_debug == 1} {putlog "DEBUG: Template applied ([llength $sendtext] lines of text)"} sgoogle_sendtext $sendtext $public $destination if {$sgoogle_debug == 1} {putlog "DEBUG: Sent text to output. Done..."} return "requested $zoekstring and got [lindex $parsed 0] items ([string length $htmldata] bytes)" } set maybelang [string tolower [lindex $arg 0]] if {($maybelang == "france")||($maybelang == "fr")} {set arg [lrange $arg 1 end];set google_lang "fr"} if {($maybelang == "linux")} {set arg [lrange $arg 1 end];set google_lang "linux"} if {[string tolower [lindex $arg 0]] == "detail"} { set zoekstring [lrange $arg 1 end] if {$sgoogle_detail == 1} { set detailed 1 } else { sgoogle_sendtext "{Detailed mode is DISABLED by the admin}" $public $destination } } elseif {[string tolower [lindex $arg 0]] == "simple"} { set zoekstring [lrange $arg 1 end] set detailed 0 } else { set zoekstring $arg if {$sgoogle_detail_request == 1} {set detailed 0} else {set detailed 1} } if {[string match {[0-9]} [lindex $zoekstring 0]] || [string match {[0-9][0-9]} [lindex $zoekstring 0]]} { set hits [lindex $zoekstring 0] set zoekstring [lrange $zoekstring 1 end] if {$hits > $sgoogle_hits} { sgoogle_sendtext "{Too many hits requested (try $lastbind help)}" $public $destination return "tried to retrieve too many hits." } if {$hits < 1} { sgoogle_sendtext "{Number of hits must be at least 1}" $public $destination return "gave an invalid hits value." } } else { set hits $sgoogle_hits_default set zoekstring $zoekstring } if {[info exist google_lang]} { switch -exact -- $google_lang { "fr" {set query "http://www.google.fr/search?lr=lang_fr&q="} "linux" {set query "http://www.google.com/linux?q="} } } else { set query "http://www.google.com/search?q=" } for { set index 0 } { $index<[llength $zoekstring] } { incr index } { set query "$query[lindex $zoekstring $index]" if {$index<[llength $zoekstring]-1} then { set query "$query+" } } set query "$query&num=$hits" if {$sgoogle_debug == 1} { putlog "DEBUG: Query built ($query)" putlog "DEBUG: Contacting website..." } set token [http::geturl $query] puts stderr "" upvar #0 $token state if {$sgoogle_debug == 1} {putlog "DEBUG: Got state ($state(http))"} if {[string tolower [lindex $state(http) 2]] != "ok"} { sgoogle_sendtext "{Could not find results for $zoekstring (Error: [lrange $state(http) 2 end])}" $public $destination return "requested $zoekstring but got an error: [lrange $state(http) 2 end]." } set htmldata [http::data $token] if {$sgoogle_debug == 1} {putlog "DEBUG: Got data ([string length $htmldata] bytes)"} set parsed [sgoogle_parse $htmldata] if {$parsed == 0} { if {$sgoogle_debug == 1} {putlog "DEBUG: Could not find items to parse."} sgoogle_sendtext "{Could not find results for $zoekstring}" $public $destination return "requested $zoekstring but couldn't find any results." } if {$sgoogle_debug == 1} {putlog "DEBUG: Data parsed (got [lindex $parsed 0] items)"} set sendtext [sgoogle_template $parsed $detailed $zoekstring] if {$sgoogle_debug == 1} {putlog "DEBUG: Template applied ([llength $sendtext] lines of text)"} sgoogle_sendtext $sendtext $public $destination if {$sgoogle_debug == 1} {putlog "DEBUG: Sent text to output. Done..."} return "requested $zoekstring and got [lindex $parsed 0] items ([string length $htmldata] bytes)" } proc sgoogle_parse {data} { set count 0 set outputdata "" regsub -all "\n" $data "" data regsub -all "

" $data \n data #regsub -all "" $data \n data set data [split $data \n] set pattern "href=*" foreach elem $data { if {[string match "Results *" $elem]} { regsub -all "" $elem "\n" elem set elem [lindex [split $elem \n] 0] regsub -all "" $elem "\002" elem regsub -all "" $elem "\002" elem lappend outputdata $elem } if {[string match $pattern $elem]} { set full $elem regsub -all "" $elem \n elem set elem [split $elem \n] set elem [lindex $elem 0] set full [lrange $full [expr [llength $full]-7] end] set size "N/A" foreach word $full { regexp {[0-9]+k} $word size } set result "" set infos [gere_result $elem] set title [lindex $infos 0] set url [lindex $infos 1] lappend result $title $url $size lappend outputdata $result incr count } } if {$count==0} {return 0} return "$count $outputdata" } proc gere_result { line } { set reply "" regsub -all "href=" $line "" line regsub -all ">" $line \n buf set lien [lindex $buf 0] set lienlen [string length $lien] set title [string range $line [expr $lienlen+1] end] regsub -all "" $title "" title regsub -all "" $title "" title regsub -all "" $title "" title regsub -all "" $title "" title regsub -all ">" $title ">" title regsub -all "&" $title "&" title lappend reply $title $lien return $reply } proc images_parse {data} { set count 0 set outputdata "" regsub -all "\n" $data "" data regsub -all "" data regsub -all "

" $elem "\n" elem set elem [split $elem \n] set url [lindex $elem 0] set elem $full set title [string range $elem [expr [string length $url]+1] end] regsub -all "" $title "\n" title set title [split $title \n] set title [lindex $title 0] regsub -all "" $title "" title regsub -all "" $title "" title regsub -all "" $title "" title regsub -all "" $title "" title set url "http://groups.google.fr/groups$url" regsub -all "