#-----------------------------------------------------------------------------#
# incith:google v1.8.5#
# #
# performs various methods of Google searches #
# tested on: #
# eggdrop v1.6.17 GNU/LINUX with Tcl 8.4 #
# windrop v1.6.17 CYGWIN_NT with Tcl 8.4 (http.tcl v2.4) #
# - http.tcl included - Linux/BSD users should NOT need this #
# #
# NEWS: #
# As of v1.6, I (madwoota) have taken over the development of incith:google. #
# If you have any feature req's, bugs, ideas, etc, please dont hesitate to #
# send them to me. My contact details have replaced incith's, but if you #
# wish to approach him directly about anything, I can point you in the right #
# direction. #
# #
# See the Egghelp forum for inciths handover and all the latest info: #
# http://forum.egghelp.org/viewtopic.php?t=10175 #
# #
# Basic usage guide: #
# .chanset #channel +google #
# !google <define:|spell:> <search terms> <1+1> <1 cm in ft> <patent ##> #
# <weather city|zip> <??? airport> <city,state/zip> #
# !images <search terms> #
# !groups <search terms> #
# !local <what> near <where> #
# !print <search terms> #
# !video <search terms> #
# !fight <word(s) one> vs <word(s) two> #
# #
# ChangeLog: #
# 1.0: first public release #
# 1.1: improved bolding of search terms, compatible with chopped descriptions#
# supports 'define: <word>' lookups #
# supports calculator. !google (4+3) * 2 - 1 #
# - converts, too. !google 1 lb in ounces #
# image lookups coded, !images <search> #
# 'spell: word1 word2' function added - don't rely on this, it's not a #
# dictionary, just corrects common typos. #
# flood protection added #
# 1.2: will wrap long lines (yay, a worthy solution!) #
# allowed setting of the seperator instead of a ' | ' by default. If you#
# set this to "\n" then you will get each result on a seperate line #
# instead of one line #
# will display 'did you mean' if no results #
# [PDF] links will be parsed/included now #
# fixed a bug when no data was returned from google such is the case #
# when you search for """""""""""""""""" #
# 1.3: can return results in multiple languages now #
# fixed quotes being displayed around links #
# private messages support added (for /msg !google) #
# video.google.com seems impossible, Google Video Viewer #
# is required to view videos, etc #
# 1.4: bit of a different output, easier to click links now #
# local lookups coded, use !local <what> near <where> #
# seems google does currency the same way my exchange #
# script does (!g 1 usd in cad) #
# "patent ##" will return the patent link if it exists #
# bugfix in private messages #
# sorry to all whom grabbed a borked copy on egghelp :-( #
# 1.5: fix for !local returning html on 'Unverified listing's #
# "madwoota" has supplied some nice code updates for us! #
# - "answer" matches, eg: !g population of japan #
# - !g <upc code> #
# - google groups (!gg), google news (!gn) #
# - movie: review lookups #
# - area code lookups (!g 780) #
# - print.google lookups (!gp !print) #
# reworked binds to fix horrible bug allowing !g !gi !gp #
# case insensitive binds (!gi, !GI, !gI, !Gi, etc) #
# .1: fix for double triggers/bad binds #
# .2: fix involving "can't read link" error #
#madwoota: #
# 1.6: fixed google search returning no results #
# fixed descriptions getting cut short on 'answers' #
# fixed bug where some urls were returned invalid #
# fixed google local searches returning no results #
# fixed google print searches returning invalid links #
# changed 'did you means' to get returned first as well #
# added google weather: !g weather <city|zip> #
# - note: US weather only (blame google!) #
# added travel info, eg: !g sfo airport | !g united 134 #
# added config option to send output via /notice #
# added initial attempt at parsing google video (!gv) #
# 1.7: added option to force all replies as private (req) #
# fixed google groups returning no results #
# fixed define: errors on no results #
# fixed google print errors on no results/typos #
# fixed movie review errors on no results/typos #
# fixed some characters not usable as command_chars on #
# one of regular eggdrop or windrop+cygwin #
# fixed occasional weird response for travel info #
# updated requirements to http package 2.4 #
# loads of other internal changes #
# .1: fixed search parameters not being parsed correctly #
# - resulted in some bogus "no results" replies. #
# .2: fixed main google search returning rubbish results #
# - google changed their source again #
# changed all methods of parsing the search results to #
# *hopefully* cope better with any source changes #
# changed output queue to stop the bot from flooding #
# .3: fixed some urls being returned with spaces in them #
# - makes them unusable in most irc clients #
# fixed google groups occasionally returning junk due to #
# changes in 1.7.2 (will revisit this later) #
# 1.8: added option to turn on "safe" searches #
# added channel user level filtering option (+v/+o only) #
# added google fight! !gf or !fight <blah> vs <blah> #
# - inspired by www.googlefight.com #
# added ability to do any custom mode to descs & links #
# - i'll just apologise now for this one :) #
# removed variable underline_links (superseded by above) #
# removed use of 'tcl_endOfWord' to stop windrop breaking #
# fixed excess %20's appearing in some results #
# fixed "translate this" only returns ? (i think) #
# stopped local from returning ad spam on first result #
# .1: added tied result check to google fight #
# fixed groups parsing that broke #
# fixed local parsing that broke #
# fixed "answer" matches parsing that broke #
# .2: fixed a chance of a "define:" + a "Did you mean:" not #
# returning a result as expected #
# .3: added function to strip all &#???; unicode from desc results #
# - simply replaces Ā to 𘚟 with a "?" #
# .4: fixed tracking rubbish after links on define: lookups #
# fixed local lookups ... again #
# fixed spell: from returning "0" #
# added option to disable either weblink or google link on "!g define:" #
# added stock quotes (try !g intc or !g amd) #
# .5: fixed main google results broke ! Google changed <p> -> <div> :) #
# fixed weather #
# fixed area code map results (eg: !g 90210 or !g beverly hills, ca) #
# added new setting to default to NOT return secondary results #
# #
# TODO: #
# Make define: return up to $search_results definitions from single source #
# Localisation options - determine country limit on input? #
# Google music Album/Albums/Songs search #
# - http://www.google.com/musica?aid=53YC6821hBO #
# - http://www.google.com/musicsearch?q=sublime #
# Code base clean up ! #
# #
# Suggestions/Thanks/Bugs, e-mail at bottom of header. #
# #
# LICENSE: #
# This code comes with ABSOLUTELY NO WARRANTY. #
# #
# 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; #
# either version 2 of the License, or (at your option) any #
# later version. #
# #
# 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. (http://www.gnu.org/copyleft/library.txt) #
# #
# Copyright (C) 2005, Jordan #
# Currently maintained by madwoota #
# google at woota.net #
#-----------------------------------------------------------------------------#
package require http 2.4
setudef flag google
# 0 will typically disable an option, otherwise a value 1 or
# above will enable it.
#
namespace eval incith {
namespace eval google {
# set this to the command character you want to use for the binds
variable command_char "!"
# set these to your preferred binds ("one two" - space delimited!)
variable google_binds "g google"
variable image_binds "gi image images"
variable local_binds "gl local"
variable group_binds "gg group groups"
variable news_binds "gn news"
variable print_binds "gp print"
variable video_binds "gv video"
variable fight_binds "gf fight googlefight"
# To restrict input queries to Ops (+o), Halfops (+h) or Voiced (+v) users on
# any +google channel, use this setting.
# Set the variable to one of the following to achieve the desired filtering:
# At least Op - 3
# At least Halfop - 2 (will also allow ops)
# At least Voice - 1 (will also allow halfops and ops)
# Everyone - 0 (no filtering)
#
# Note: this does NOT apply to private messages, use the below setting for them.
#
variable chan_user_level 0
# if you want to allow users to search via private /msg, enable this
variable private_messages 1
# as per emailed & forum requests, use the next two variables together
# to determine the output type like so:
# notice_reply 1 & force_private 1 = private notice reply only (this is as requested)
# notice_reply 0 & force_private 1 = private msg reply only
# notice_reply 1 & force_private 0 = regular channel OR private NOTICE
# notice_reply 0 & force_private 0 = regular channel OR private MSG (default)
# set to 1 to enable a /notice reply instead, 0 for normal text
variable notice_reply 0
# set to 1 to force all replies to be private
variable force_private 0
# set this to the language you want results in! use 2 letter form.
# "all" is the default/standard google.com search.
# See http://www.google.com/advanced_search for a list. You have to use
# the 'Language' dropdown box, perform a search, and find a line in the URL
# that looks like "&lr=lang_en" (for English). "en" is your language code.
# Popular Ones: it (italian), da (danish), de (german), es (spanish), fr (french)
# please note, this does not 'translate', it searches Google in a
# language of choice, which means you can still get English results.
variable language "all"
# set this to "on" to let google filter "adult content" from any of your search results
# "off" means results will not be filtered at all
# note: this is only applicable to !google, !images and !groups
variable safe_search "off"
# number of search results/image links to return, 'define:' is always 1 as some defs are huge
variable search_results 5
variable image_results 5
variable local_results 2
variable group_results 2
variable news_results 2
variable print_results 2
variable video_results 5
# set this to 0 to turn google fight off (it is a tad slow after all ...)
variable google_fight 1
# what to use to seperate results, set this to "\n" and it will output each result
# on a line of its own. the seperator will be removed from the end of the last result.
variable seperator "\n"
# ** this is not an optional setting, if a string is too long to send, it won't be sent! **
# It should be set to the max amount of characters that will be received in a public
# message by your IRC server. If you find you aren't receiving results, try lowering this.
variable split_length 443
# trimmed length of returned descriptions, only for standard searches.
variable description_length 40
# set these to 0 to turn off either the source web link or google.com define: link for a define:<blah> search
variable define_weblinks 1
variable define_googlelinks 1
# set this to 1 to enable returning sub/secondary results from the same site from google as per forum req
variable subresults 0
# replace search terms appearing in the description as bolded words?
# - does not bold entire description, just the matching search words
# - this is ignored if desc_modes contains the Bold mode below
variable bold_descriptions 1
# Use these two settings to set colours, bold, reverse, underline etc on either descriptions or links
# The following modes apply and you can use any combination of them: (NO SPACES!)
#
# Bold = \002
# Underline = \037
# Reverse = \026
# Colours: #RGB/Html code:
# White = \0030 #FFFFFF
# Black = \0031 #000000
# Blue = \0032 #00007F
# Green = \0033 #008F00
# Light Red = \0034 #FF0000
# Brown = \0035 #7F0000
# Purple = \0036 #9F009F
# Orange = \0037 #FF7F00
# Yellow = \0038 #F0FF00
# Light Green = \0039 #00F700
# Cyan = \00310 #008F8F
# Light Cyan = \00311 #00F7FF
# Light Blue = \00312 #0000FF
# Pink = \00313 #FF00FF
# Grey = \00314 #7F7F7F
# Light Grey = \00315 #CFCFCF
#
# This example will do Bold, Underline and Light Blue: "\002\037\00312"
# Note: This will affect *ALL* descs or links. Dont forget to use the \ too !
# Also note, abusing this this heavily increases the number of characters per line,
# so your output lines will increase somewhat.
variable desc_modes ""
variable link_modes ""
# number of minute(s) to ignore flooders, 0 to disable flood protection
variable ignore 1
# how many requests in how many seconds is considered flooding?
# by default, this allows 3 queries in 10 seconds, the 4th being ignored
# and ignoring the flooder for 'variable ignore' minutes
variable flood 4:10
}
}
# end of configuration, script begins
namespace eval incith {
namespace eval google {
variable version "incith:google-1.8.5"
}
}
# bind the public binds
bind pubm -|- "*" incith::google::public_message
# bind the private message binds, if wanted
if {$incith::google::private_messages >= 1} {
bind msgm -|- "*" incith::google::private_message
}
namespace eval incith {
namespace eval google {
# GOOGLE
# performs a search on google.
#
proc google {input} {
# local variable initialization
set results 0 ; set calc 0 ; set break 0 ; set spell 0 ; set output "" ; set did_you_mean 0
# can't be moved to fetch_html since $spell isn't global
if {[string match -nocase "spell:*" $input] == 1} {
set spell 1
}
# if we don't want any search results, stop now.
if {$incith::google::search_results <= 0} {
return
}
# fetch the html
set html [fetch_html $input 1]
# parse the html
while {$results < $incith::google::search_results} {
# the regexp grabs the data and stores them into their variables, while
# the regsub removes the data, for the next loop to grab something new.
# check if there was an alternate spelling first
if {[string match "*Did you mean:*" $html] == 1} {
regexp -nocase -- {Did you mean:.*?<a.+?href=.*?>(.+?)</a>} $html - desc
regsub -all -- {Did.+?you.+?mean:.*?<a href=.*?>(.+?)</a>} $html {} html
#Just neatens the bolding up a bit (if required)
regsub -all -- "\002" $desc {} desc
if {$incith::google::bold_descriptions > 0 && [string match "\002" $incith::google::desc_modes] != 1} {
set desc "Did you mean: \002${desc}\002 ?"
} else {
set desc "Did you mean: ${desc}?"
}
set did_you_mean 1
set link ""
# top match / "answer" match
} elseif {[string match "*&oi=answers*" $html] == 1} {
regexp -- {oi=answers(?:.*?)>(.+?)<br>.*?((http|ftp|https)://.*?) - <a} $html - desc link
regsub -all {oi=answers(?:.*?)>(.+?)<br>.*?((http|ftp|https)://.*?) - <a} $html {} html
#regexp -- {oi=answers(?:.+?)=(.+?)">(.+?)<br>} $html - link desc
#regsub -- {oi=answers(.+?)<br>} $html {} html
regsub -all "(</a>)" $desc "" desc
#"area codes
} elseif {[string match "*/images/map_icon2.gif*" $html] == 1} {
regexp -- {<p class=e>(?:.*?)<a.*?href=(.+?)>(.+?)</a>} $html - link desc
regsub -- {/images/map_icon2.gif} $html {} html
if {[info exists link] == 1} {
set link [urldecode $link]
if {[string match "/url?q=http*" $link] == 1} {
regexp -- {/url\?q=(.+?q=.+?)&} $link - link
}
}
# travel info
} elseif {[string match "*/images/airplane.gif*" $html] ==1} {
regexp -- {<p.+?class=e>.*?/images/airplane.gif.*?<td.+?valign=top.*?>(.*?)<a.+?href="(.+?)"(?:.*?)>(.+?)</a>} $html - d1 link d2
regsub -- {<p.+?class=e>.*?/images/airplane.gif.*?</a>} $html - html
set desc "$d1 $d2"
set break 1
# weather!
} elseif {[string match "*/images/weather/*" $html] == 1} {
regexp -- {<div.+?class=g>(.+?)<br>.*?<td.*?>(.+?)<.*?>(.+?)<.*?>(.+?)<.*?>(.+?)</td.*?</table>} $html - w1 w2 w3 w4 w5
regsub -- {<div.+?class=g>(.*?)</table} $html {} html
set desc "$w1\: $w2, $w3, $w4, $w5"
regsub -all -- {°} $desc {°} desc
set link ""
regsub -all -- {weather} $input {} input
# define:
} elseif {[string match "define:*" $input] == 1} {
regexp -- {<li>(.+?)(?=\s*<li>|<br>).*<a href.*(http.+?)(&usg=.+?">|&sig=.+?">|">)} $html - desc link
#"
regsub -- {<li>(.+?)(?=\s*<li>|<br>)} $html {} html
regsub -all -- {\+} $input {%2B} define_input
regsub -all -- { } $define_input {+} define_input
if !${incith::google::define_weblinks} {
if ${incith::google::define_googlelinks} {
set link "http://www.google.com/search?hl=${incith::google::language}&q=${define_input}"
} else {
set link ""
}
} elseif {[info exists link] == 1 && ${incith::google::define_weblinks}} {
regsub -all " " $link "%20" link
if ${incith::google::define_googlelinks} {
append link " ( http://www.google.com/search?hl=${incith::google::language}&q=${define_input} )"
}
}
set results $incith::google::search_results
# movie:
} elseif {[string match "movie:*" $input] == 1} {
regexp -- {<td valign=top><a href="/movies/reviews\?cid=(.+?)&fq(?:.+?)">(.+?)</a>} $html - cid desc
regsub -- {<td valign=top><a href="/movies/reviews\?cid=(.+?)</a>} $html {} html
if {[info exists cid] == 1 } { set link "http://www.google.com/movies/reviews?cid=${cid}" }
#" finance / stock quotes
} elseif {[string match "*<p class=e><div><a href=?/url?q=http://finance.google.com/finance%3Fq%3D*" $html] == 1} {
# this has to be one of the worst regexps ever written !
regexp -- {<p class=e><div><a href="/url\?q=http://finance.google.com/finance%3Fq%3D.*?">(.*?)</a>(.*?)<.*?<td colspan=3 nowrap>(.+?)</td>.*?Mkt Cap:.*?<td.*?>(.+?)</td>} $html - tick name price mktcap
regsub -- {<p class=e><div><a href="/url\?q=http://finance.google.com/finance%3Fq%3D.*?">(.*?)</a>(.*?)<.*?<td colspan=3 nowrap>(.+?)</td>.*?Mkt Cap:.*?<td.*?>(.+?)</td>} $html {} html
if {[info exists tick] == 1 && [info exists name] == 1 && [info exists name] == 1} {
set desc "$tick: $name = $$price"
set link "http://finance.google.com/finance?q=$tick"
regsub -all -- "\002" $link {} link
if {[info exists mktcap] == 1} { append desc " Mkt Cap: $mktcap" }
unset tick ; unset name ; unset price ; unset mktcap
set results $incith::google::search_results
}
# patents
} elseif {[regexp {^patent\s+(\d+)\s*$} $input]} {
regexp -- {<a href="(http://patft.uspto.gov/.+?)">} $html - desc
regsub -- {<a href="(http://patft.uspto.gov/.+?)">} $html {} html
set break 1
set link ""
# spell: checker
} elseif {$spell == 1} {
set desc "No alternate spellings found."
# calculator
} elseif {[string match "*<img src=/images/calc_img*" $html] == 1} {
set calc 1
# remove bold codes from the html, not necessary here.
regsub -all -- "\002" $html {} html
regexp -nocase -- {calc_img.+?nowrap>(.+?)</} $html - desc
set link "Iteration: $results"
# regular search
} else {
#as per forum request. ps: yay regsub!
if !${incith::google::subresults} {
regsub -all -- {<div class=g style="margin-left:.*?".*?</div>} $html {} html
}
regexp -- {<div.+?class=g.*?<a.+?href=(.+?)>(.+?)</a>} $html - link desc
if {[info exists link] == 1} {
if {[string match "*/url\?sa=U*" $link] == 1} {
regexp -- {/url.+?sa=U.+?q=(.*)&e=} $link - link
} elseif {[string match "*/url\?sa=X*" $link] == 1} {
regexp -- {/url.+?sa=X.+?q=(.*)"} $link - link
} elseif {[string match *.pdf $link] == 1} {
set desc "\[PDF\] $desc"
}
}
regsub -- {<div.+?class=g>.*?<a.+?href=(.+?)>(.+?)</a>} $html {} html
#" trim the description
if {[info exists desc] == 1 && $incith::google::description_length > 0} {
set desc [string range $desc 0 [expr $incith::google::description_length - 1]]
}
}
if {[info exists desc] == 0} {
if {$output == ""} {
set output "Sorry, no search results were found."
}
return $output
}
# Make sure we dont have an ugly %00 style url (an encoded url also wont work on buggy webservers)
# this is a duplicate if check for debugging purposes only - trust me, you wont miss the cpu time.
if {[string match "*\%\[2-7\]\[0-9a-fA-F\]*" $link] == 1} {
set link [urldecode $link]
}
# this removes trailing spaces from the description, and converts %20's to spaces
# \017 is ^O, read by clients as 'stop bold/colors/underline'
set desc [string trim $desc]
regsub -all "%20" $desc " " desc
regsub -all "<br>" $desc " " desc
if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
# add the search result
if {$calc == 0 && $spell == 0} {
if {$link != ""} {
if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
if {[string match "define:*" $input] != 1} {
regsub -all " " $link "%20" link
}
regsub -all "(?:\x93|\x94|"|\")" $link {} link
append output "${desc}\017 \@ ${link}\017${incith::google::seperator}"
} else {
append output "${desc}\017 ${incith::google::seperator}"
}
} else {
append output "${desc}\017"
}
# I've hard-coded it to only fetch one result for define lookups, and
# spell shouldn't ever have to loop.
if {[string match "define:*" $input] && [info exists did_you_mean] == 0} {
break
} elseif {$spell == 1 || $calc == 1 || $break == 1} {
break
}
# increase the results, clear the variables for the next loop
unset link ; unset desc ; set spell 0 ; set calc 0 ; set break 0
if {[info exists did_you_mean] == 1} { unset did_you_mean }
incr results
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# IMAGES
# fetches a list of links to images from images.google.
#
proc images {input} {
; set results 0 ; set output ""
# if we don't want any search results, stop now.
if {$incith::google::image_results <= 0} {
return
}
# fetch the html
set html [fetch_html $input 2]
# strip out 'did you mean?' first
regexp -nocase -- {Did.+?you.+?mean:.*?<a.+?href=.*?>(.+?)</a>} $html - did_you_mean
if {[info exists did_you_mean] == 1} {
regsub -all -- "\002" $did_you_mean {} did_you_mean
}
# parse the html
while {$results < $incith::google::image_results} {
regexp -- {<a.+?href=/imgres\?imgurl=(.+?)&imgrefurl} $html - link
regsub -- {<a.+?href=/imgres\?imgurl=(.+?)&imgrefurl} $html {} html
# if there's no link, return or stop looping, depending
if {![info exists link]} {
if {$results == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean} ?"
}
return $reply
} else {
break
}
}
# prevent duplicate results is mostly useless here, but will at least
# ensure that we don't get the exact same picture.
if {[string match "*$link*" $output] == 1} {
break
}
if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
# add the search result
# \017 is ^O, read by clients as 'reset color' (stop bold/etc)
append output "${link}\017${incith::google::seperator}"
# increase the results, clear the variables for the next loop just in case
unset link
incr results
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# LOCAL
# fetches a list of address & phone numbers from local.google.
#
proc local {input} {
; set results 0 ; set output ""
# if we don't want any search results, stop now.
if {$incith::google::local_results <= 0} {
return
}
# fetch the html
set html [fetch_html $input 3]
# strip out 'did you mean?' first
regexp -nocase -- {Did you mean:.*?<a href=.*?>(.+?)</a>} $html - did_you_mean
#regexp -nocase -- {Did you mean: <a href.+?>(.+?)</a>} $html - did_you_mean
if {[info exists did_you_mean] == 1} {
regsub -all -- "\002" $did_you_mean {} did_you_mean
}
# parse the html
while {$results < $incith::google::local_results} {
regexp -- {<div.*?class=\\042name\\042><a.*?href=\\042\/maps\?hl=en&q=.+?\\042>(.*?)</a>.*?<div>(.*?)</div>.*?<div>(.*?)(&|<)} $html - name addr num
regsub -- {<div.*?class=\\042name\\042><a.*?href=\\042\/maps\?hl=en&q=.+?\\042>(.*?)</a>.*?<div>(.*?)</div>.*?<div>(.*?)(&|<)} $html {} html
# if there's no link, return or stop looping, depending
if {[info exists name] == 0} {
if {$results == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
} else {
break
}
}
if {$incith::google::desc_modes != ""} { set name "$incith::google::desc_modes$name" }
if {$incith::google::link_modes != ""} { set link "$incith::google::link_modes${addr}\017. Ph: $incith::google::link_modes${num}" }
if {[info exists link] == 0} { set link "${addr}. Ph: ${num}" }
# add the search result
# \017 is ^O, read by clients as 'reset color' (stop bold/etc)
append output "${name}\017 \@ ${link}\017${incith::google::seperator}"
# increase the results, clear the variables for the next loop just in case
unset name ; unset link
incr results
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# GROUPS
# fetches a list of threads from groups.google.
#
proc groups {input} {
set results 0 ; set output ""
# if we don't want any search results, stop now.
if {$incith::google::group_results <= 0} {
return
}
# fetch the html
set html [fetch_html $input 4]
# strip out 'did you mean?' first
regexp -nocase -- {Did you mean:.*?<a href=.*?>(.+?)</a>} $html - did_you_mean
#regexp -nocase -- {Did you mean: <a href.+?>(.+?)</a>} $html - did_you_mean
if {[info exists did_you_mean] == 1} {
regsub -all -- "\002" $did_you_mean {} did_you_mean
}
# parse the html
while {$results < $incith::google::group_results} {
regexp -- {td style="width:.+?[0-9]em".+?/group/(.+?)/browse_thread/thread/(.+?)/.+?">(.+?)</a>} $html {} group thread desc
regsub -- {td style="width:.+?[0-9]em".+?/group/(.+?)/browse_thread/thread/(.+?)/.+?">(.+?)</a>} $html {} html
#"if theres no desc, return or stop looping, depending
if {[info exists desc] == 0} {
if {$results == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
} else {
break
}
}
if {[info exists desc] == 1 && $incith::google::description_length > 0} {
set desc [string range $desc 0 [expr $incith::google::description_length - 1]]
}
# make the link valid because we only got a partial href result, not a full url
set link "http://groups.google.com/group/${group}/browse_thread/thread/${thread}"
if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
# add the search result
append output "${desc}\017 \@ ${link}\017${incith::google::seperator}"
# increase the results, clear the variables for the next loop just in case
unset link; unset desc
incr results
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# NEWS
# fetches the news from news.google.
# -madwoota supplied
#
proc news {input} {
; set results 0 ; set output ""
# if we don't want any search results, stop now.
if {$incith::google::news_results <= 0} {
return
}
# fetch the html
set html [fetch_html $input 5]
# strip out 'did you mean?' first
regexp -nocase -- {Did.+?you.+?mean:.*?<a.+?href=.*?>(.+?)</a>} $html - did_you_mean
if {[info exists did_you_mean] == 1} {
regsub -all -- "\002" $did_you_mean {} did_you_mean
}
# We have to do a single regsub first to get down to the rough area in the html we need because
# its just *not* very elegant attempting doing this in a single regexp. (Read: unreliable)
regsub -- {<html>(.+?)</div>} $html {} html
# parse the html
while {$results < $incith::google::news_results} {
# somewhat extenuated regexp due to allowing that there *might* be
# an image next to the story
regexp -- {<table.*?width=75.+?<td valign=top><a.*?href="(.+?)".*?>(.+?)</a>} $html {} link desc
regsub -- {<table.*?width=75.+?<td valign=top><a.*?href="(.+?)".*?>(.+?)</a>} $html {} html
# if there's no desc, return or stop looping, depending
if {[info exists desc] == 0} {
if {$results == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
} else {
break
}
}
if {[info exists desc] == 1 && $incith::google::description_length > 0} {
set desc [string range $desc 0 [expr $incith::google::description_length - 1]]
}
# prevent duplicate results is mostly useless here, but will at least
# ensure that we don't get the exact same article.
if {[string match "*$link*" $output] == 1} {
break
}
if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
# add the search result
append output "${desc}\017 \@ ${link}\017${incith::google::seperator}"
# increase the results, clear the variables for the next loop just in case
unset link; unset desc
incr results
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# PRINT
# fetches book titles from print.google.
# -madwoota supplied
#
proc print {input} {
; set results 0 ; set output ""
# if we don't want any search results, stop now.
if {$incith::google::print_results <= 0} {
return
}
# fetch the html
set html [fetch_html $input 6]
# strip out 'did you mean?' first
regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - did_you_mean
#regexp -nocase -- {Did you mean: <a href.+?>(.+?)</a>} $html - did_you_mean
if {[info exists did_you_mean] == 1} {
regsub -all -- "\002" $did_you_mean {} did_you_mean
}
# We have to do a single regsub first to get down to the rough area in the html we need because
# its just *not* very elegant attempting doing this in a single regexp. (Read: unreliable)
regsub -- {<html>(.+?)style="padding} $html {} html
#parse the html
while {$results < $incith::google::print_results} {
regexp -- {<p class="e">.+?href="(.+?)\?.*?id=(.+?)&.*?">(.+?)</a>} $html {} link id desc
regsub -- {<p class="e">(.+?)</a>} $html {} html
# if there's no desc, return or stop looping, depending
if {[info exists desc] == 0} {
if {$results == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
} else {
break
}
}
if {[info exists id] == 1} { append link "?id=$id" }
# prevent duplicate results is mostly useless here, but will at least
# ensure that we don't get the exact same article.
if {[string match "*$link*" $output] == 1} {
break
}
if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
# add the search result
append output "${desc}\017 \@ ${link}\017${incith::google::seperator}"
# increase the results, clear the variables for the next loop just in case
unset link; unset desc; unset id
incr results
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# VIDEO
# fetches links to video with search data in it (video.google.com)
# -madwoota supplied
#
proc video {input} {
; set results 0 ; set output ""
# if we don't want any search results, stop now.
if {$incith::google::video_results <= 0} {
return
}
# fetch the html
set html [fetch_html $input 7]
# strip out 'did you mean?' first
regexp -nocase -- {Did you mean:.*?<a href=.*?>(.+?)</a>} $html - did_you_mean
#regexp -nocase -- {Did you mean: <a href.+?>(.+?)</a>} $html - did_you_mean
if {[info exists did_you_mean] == 1} {
regsub -all -- "\002" $did_you_mean {} did_you_mean
}
# We have to do a single regsub first to get down to the rough area in the html we need because
# its just *not* very elegant attempting doing this in a single regexp. (Read: unreliable)
#regsub -- {<html>(.+?)style="padding} $html {} html
# parse the html
while {$results < $incith::google::video_results} {
# somewhat extenuated regexp due to allowing that there might be an image next to the title
regexp -- {class="resulttitle"(?:.*?)a href="videoplay\?docid=(.+?)&(?:.*?)>(.+?)</a>} $html {} cid desc
regsub -- {class="resulttitle"(?:.*?)a href="videoplay\?docid=(.+?)&(?:.*?)>(.+?)</a>} $html {} html
# if there's no desc, return or stop looping, depending
if {[info exists desc] == 0} {
if {$results == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
} else {
break
}
}
# make the link valid because we were only given a partial href result, not a full url
set link "http://video.google.com/videoplay?docid=${cid}"
# prevent duplicate results is mostly useless here, but will at least
# ensure that we don't get the exact same article.
if {[string match "*$link*" $output] == 1} {
break
}
if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
# add the search result
append output "${desc}\017 \@ ${link}\017${incith::google::seperator}"
# increase the results, clear the variables for the next loop just in case
unset link; unset desc
incr results
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# FIGHT
# google fight !
#
proc fight {input} {
set output ""; set winner 0
# if google fight is disabled, stop now.
if {$incith::google::google_fight <= 0} {
return
}
regexp -nocase -- {^(.+?) vs (.+?)$} $input - word1 word2
# fetch the first result
set html [fetch_html $word1 8]
# parse the html
regexp -- {Results.+?of about.+?([,0-9]{1,}).+?for} $html - match1
# fetch the second result
set html [fetch_html $word2 8]
# parse the html
regexp -- {Results.+?of about.+?([,0-9]{1,}).+?for} $html - match2
if {![info exists match1]} {
set match1 "0"
set match1expr "0"
} else {
regsub -all {,} $match1 {} match1expr
}
if {![info exists match2]} {
set match2 "0"
set match2expr "0"
} else {
regsub -all {,} $match2 {} match2expr
}
if {[expr $match2expr < $match1expr]} {
set winner 1
} elseif {[expr $match2expr > $match1expr]} {
set winner 2
} elseif {[expr $match2expr == $match1expr]} {
set winner 3
}
if {$incith::google::bold_descriptions > 0 && $incith::google::desc_modes == ""} {
set word1 "\002$word1\017"; set word2 "\002$word2\017"
set match1 "\002 $match1\017"; set match2 "\002 $match2\017"
} elseif {$incith::google::desc_modes != ""} {
set word1 "$incith::google::desc_modes$word1\017"; set word2 "$incith::google::desc_modes$word2\017"
set match1 "$incith::google::desc_modes $match1\017"; set match2 "$incith::google::desc_modes $match2\017"
} else {
set match1 " $match1"; set match2 " $match2"
}
if {$winner == 1} {
set output "By results on Google: $word1 beats $word2 by$match1 to$match2!"
} elseif {$winner == 2} {
set output "By results on Google: $word2 beats $word1 by$match2 to$match1!"
} elseif {$winner == 3} {
set output "By results on Google: $word1 ties with $word2 on$match1!"
} else {
set output "Could not determine the winner."
}
# make sure we have something to send
if {[info exists output] == 0} {
set reply "Sorry, no search results were found."
if {[info exists did_you_mean] == 1} {
append reply " Did you mean: ${did_you_mean}?"
}
return $reply
}
return $output
}
# FETCH_HTML
# fetches html for the various *.google.com sites
#
proc fetch_html {input switch} {
# for local
regexp -nocase -- {^(.+?) near (.+?)$} $input - search location
# for the rest
regsub -all -- {\+} $input {%2B} input
regsub -all -- { } $input {+} input
# GOOGLE
if {$switch == 1} {
# we don't want 'define:+<search>', so we'll just remove the space if there is one.
regsub -nocase -- {^define:\s*} $input {define:} input
# spell after define so 'spell: define: foo' doesn't turn into a define lookup
if {[string match -nocase "spell:*" $input] == 1} {
regsub -nocase -- {^spell:\s*} $input {} input
}
if {[string match "movie:*" $input] == 1} {
set query "http://www.google.com/movies?hl=en&q=${input}&safe=${incith::google::safe_search}&btnG=Search&lr=lang_${incith::google::language}"
} else {
set query "http://www.google.com/search?hl=en&q=${input}&safe=${incith::google::safe_search}&btnG=Search&lr=lang_${incith::google::language}"
}
# IMAGES
} elseif {$switch == 2} {
set query "http://images.google.com/images?hl=en&q=${input}&safe=${incith::google::safe_search}&btnG=Search+Images"
# LOCAL
} elseif {$switch == 3} {
# a + joins words together in the search, so we change +'s to there search-form value
regsub -all -- {\+} $search {%2B} search
regsub -all -- {\+} $location {%2B} location
# change spaces to +'s for a properly formatted search string.
regsub -all -- { } $search {+} search
regsub -all -- { } $location {+} location
set query "http://local.google.com/local?hl=en&lr=&q=${search}&near=${location}&sa=X&oi=localr"
} elseif {$switch == 4} {
set query "http://groups.google.com/groups?hl=en&q=${input}&safe=${incith::google::safe_search}"
} elseif {$switch == 5} {
set query "http://news.google.com/news?hl=en&q=${input}&lr=&sa=N&tab=gn"
} elseif {$switch == 6} {
set query "http://print.google.com/print?q=${input}&btnG=Search+Print"
} elseif {$switch == 7} {
set query "http://video.google.com/videosearch?q=${input}&btnG=Search+Video"
} elseif {$switch == 8} {
set query "http://www.google.com/search?hl=&q=${input}&safe=off&btnG=Search&lr=lang_all&num=1"
}
# beware, changing the useragent will result in differently formatted html from Google.
set ua "Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.7e"
set http [::http::config -useragent $ua]
set http [::http::geturl $query -timeout [expr 1000 * 10]]
set html [::http::data $http]
# generic pre-parsing
regsub -all "\n" $html "" html
regsub -all "(?:\x91|\x92|')" $html {'} html
regsub -all "(?:\x93|\x94|")" $html {"} html
regsub -all "&" $html {\&} html
regsub -all -nocase {<sup>(.+?)</sup>} $html {^\1} html
regsub -all -nocase {<font.+?>} $html "" html
regsub -all -nocase {</font>} $html "" html
regsub -all -nocase {<span.+?>} $html "" html
regsub -all -nocase {</span>} $html "" html
regsub -all -nocase {<input.+?>} $html "" html
regsub -all -nocase {(?:<i>|</i>)} $html "" html
# this is the "---" line in "population of Japan" searches
regsub -all "—" $html "--" html
regsub -all "×" $html {*} html
regsub -all " " $html { } html
regsub -all -nocase "×" $html "x" html
regsub -all -nocase "<" $html "<" html
regsub -all -nocase ">" $html ">" html
# '
# regexps that should remain seperate go here
# google specific regexps
if {$switch == 1} {
# regexp the rest of the html for a much easier result to parse
regsub -all -nocase {<b>\[PDF\]</b>\s*} $html "" html
# regsub to junk the remaining unicode chars since irc cant handle them properly anyway
# this will only match Ā to 𘚟
regsub -all -- {&#(25(\[6-9\])?|2(\[6-9\])?[\d]|(\[3-9\])?[\d]{2}|[\d]{4,5});} $html "" html
} elseif {$switch == 2} {
# these %2520 codes, I have no idea. But they're supposed to be %20's
regsub -all {%2520} $html {%20} html
} elseif {$switch == 3} {
regsub -all -nocase { - <nobr>Unverified listing</nobr>} $html "" html
} elseif {$switch == 4} {
} elseif {$switch == 5} {
} elseif {$switch == 6} {
} elseif {$switch == 7} {
} elseif {$switch == 8} {
}
# no point having it so many times
if {$incith::google::bold_descriptions > 0 && [string match "\002" $incith::google::desc_modes] != 1} {
regsub -all -nocase {(?:<b>|</b>)} $html "\002" html
} else {
regsub -all -nocase {(<b>|</b>)} $html {} html
}
return $html
}
# PUBLIC_MESSAGE
# decides what to do with binds that get triggered
#
proc public_message {nick uhand hand chan input} {
if {[lsearch -exact [channel info $chan] +google] != -1} {
if {$incith::google::chan_user_level == 3} {
if {[isop $nick $chan] == 0} {
return
}
} elseif {$incith::google::chan_user_level == 2} {
if {[ishalfop $nick $chan] == 0 && [isop $nick $chan] == 0} {
return
}
} elseif {$incith::google::chan_user_level == 1} {
if {[isvoice $nick $chan] == 0 && [ishalfop $nick $chan] == 0 && [isop $nick $chan] == 0} {
return
}
}
send_output "$input" "$chan" "$nick" "$uhand"
}
}
# PRIVATE_MESSAGE
# decides what to do with binds that get triggered
#
proc private_message {nick uhand hand input} {
if {$incith::google::private_messages >= 1} {
send_output $input $nick $nick $uhand
}
}
# SEND_OUTPUT
# no point having two copies of this in public/private_message{}
#
proc send_output {input where nick uhand} {
if {[encoding system] != "identity" && [lsearch [encoding names] "utf-8"]} {
set command_char [encoding convertfrom utf-8 ${incith::google::command_char}]
set input [encoding convertfrom utf-8 $input]
} elseif {[encoding system] == "identity"} {
set command_char [encoding convertfrom identity ${incith::google::command_char}]
set input [encoding convertfrom identity $input]
} else {
set command_char ${incith::google::command_char}
}
#Specifically retrieve only ONE (utf-8) character, then check that matches the command_char first
set trigger_char [string index $input 0]
if {[encoding system] == "identity"} {
set trigger_char [encoding convertfrom identity $trigger_char]
}
#Sanity check 1 - If no match, stop right here. No need to match every (first word) of
# every line of channel data against every bind if the command_char doesnt even match.
if {$trigger_char != $command_char} {
return
}
set trigger [string range [lindex $input 0] 1 end]
#Sanity check 2 - Stop if theres nothing to search for (quiet)
set search [string trim [string range $input [string wordend $input 1] end]]
if {$search == ""} { return }
if {$incith::google::force_private == 1} { set where $nick }
# check for !google
foreach bind [split $incith::google::google_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# call google
foreach line [incith::google::parse_output [google $search]] {
put_output $where $line
}
break
}
}
# check for !images
foreach bind [split $incith::google::image_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# call images
foreach line [incith::google::parse_output [images $search]] {
put_output $where $line
}
break
}
}
# check for !local
foreach bind [split $incith::google::local_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# local requires splitting of the search
regexp -nocase -- {^(.+?) near (.+?)$} $search - what location
if {![info exists what] || ![info exists location]} {
put_output $where "Local searches should be the format of 'pizza near footown, bar'"
return
}
foreach line [incith::google::parse_output [local $search]] {
put_output $where $line
}
break
}
}
# check for !groups
foreach bind [split $incith::google::group_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# call groups
foreach line [incith::google::parse_output [groups $search]] {
put_output $where $line
}
break
}
}
# check for !news
foreach bind [split $incith::google::news_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# call news
foreach line [incith::google::parse_output [news $search]] {
put_output $where $line
}
break
}
}
# check for !print
foreach bind [split $incith::google::print_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# call print
foreach line [incith::google::parse_output [print $search]] {
put_output $where $line
}
break
}
}
# check for !video
foreach bind [split $incith::google::video_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# call video
foreach line [incith::google::parse_output [video $search]] {
put_output $where $line
}
break
}
}
# check for !fight
foreach bind [split $incith::google::fight_binds " "] {
if {[string match -nocase $bind $trigger] == 1} {
# flood protection check
if {[flood $nick $uhand]} {
return
}
# fight requires splitting of the search
regexp -nocase -- {^(.+?) vs (.+?)$} $search - word1 word2
if {![info exists word1] || ![info exists word2]} {
put_output $where "Google fights should be the format of 'random vs predictable'"
return
}
# call fight
foreach line [incith::google::parse_output [fight $search]] {
put_output $where $line
}
break
}
}
}
# PUT_OUTPUT
# actually sends the output to the server
proc put_output {where line} {
regsub -all "%20class=l" $line "" line
if {$incith::google::notice_reply == 1} {
putserv "NOTICE $where :$line"
} else {
putserv "PRIVMSG $where :$line"
}
}
# PARSE_OUTPUT
# prepares output for sending to a channel/user, calls line_wrap
#
proc parse_output {input} {
set parsed_output [set parsed_current {}]
if {[string match "\n" $incith::google::seperator] == 1} {
regsub {\n\s*$} $input "" input
foreach newline [split $input "\n"] {
foreach line [incith::google::line_wrap $newline] {
lappend parsed_output $line
}
}
} else {
regsub "(?:${incith::google::seperator}|\\|)\\s*$" $input {} input
foreach line [incith::google::line_wrap $input] {
lappend parsed_output $line
}
}
return $parsed_output
putlog $parsed_output
}
# LINE_WRAP
# takes a long line in, and chops it before the specified length
# http://forum.egghelp.org/viewtopic.php?t=6690
#
proc line_wrap {str {splitChr { }}} {
set out [set cur {}]
set i 0
set len $incith::google::split_length
#regsub -all "\002" $str "<ZQ" str
#regsub -all "\037" $str "<ZX" str
foreach word [split [set str][set str ""] $splitChr] {
if {[incr i [string len $word]] > $len} {
#regsub -all "<ZQ" $cur "\002" cur
#regsub -all "<ZX" $cur "\037" cur
lappend out [join $cur $splitChr]
set cur [list $word]
set i [string len $word]
} else {
lappend cur $word
}
incr i
}
#regsub -all "<ZQ" $cur "\002" cur
#regsub -all "<ZX" $cur "\037" cur
lappend out [join $cur $splitChr]
}
# FLOOD_INIT
# modified from bseen
#
variable flood_data
variable flood_array
proc flood_init {} {
if {$incith::google::ignore < 1} {
return 0
}
if {![string match *:* $incith::google::flood]} {
putlog "$incith::google::version: variable flood not set correctly."
return 1
}
set incith::google::flood_data(flood_num) [lindex [split $incith::google::flood :] 0]
set incith::google::flood_data(flood_time) [lindex [split $incith::google::flood :] 1]
set i [expr $incith::google::flood_data(flood_num) - 1]
while {$i >= 0} {
set incith::google::flood_array($i) 0
incr i -1
}
}
; flood_init
# FLOOD
# updates and returns a users flood status
#
proc flood {nick uhand} {
if {$incith::google::ignore < 1} {
return 0
}
if {$incith::google::flood_data(flood_num) == 0} {
return 0
}
set i [expr ${incith::google::flood_data(flood_num)} - 1]
while {$i >= 1} {
set incith::google::flood_array($i) $incith::google::flood_array([expr $i - 1])
incr i -1
}
set incith::google::flood_array(0) [unixtime]
if {[expr [unixtime] - $incith::google::flood_array([expr ${incith::google::flood_data(flood_num)} - 1])] <= ${incith::google::flood_data(flood_time)}} {
putlog "$incith::google::version: flood detected from ${nick}."
newignore [join [maskhost *!*[string trimleft $uhand ~]]] $incith::google::version flooding $incith::google::ignore
return 1
} else {
return 0
}
}
# URL Decode
# Decodes all of the %00 strings in a url and returns it
#
proc urldecode {url} {
if {[string match "*\%\[2-7\]\[0-9a-fA-F\]*" $url] == 1} {
#regsub -all "%20" $url " " url
regsub -all "%22" $url "\"" url
regsub -all "%23" $url "#" url
regsub -all "%25" $url "%" url
regsub -all "%26" $url {\&} url
regsub -all "%2B" $url "+" url
regsub -all "%3C" $url "<" url
regsub -all "%3D" $url "=" url
regsub -all "%3E" $url ">" url
regsub -all "%3F" $url "?" url
regsub -all "%5B" $url "\[" url
regsub -all "%5C" $url "\\" url
regsub -all "%5D" $url "]" url
regsub -all "%5E" $url "^" url
regsub -all "%60" $url "`" url
regsub -all "%7B" $url "{" url
regsub -all "%7C" $url "|" url
regsub -all "%7D" $url "}" url
regsub -all "%7E" $url "~" url
}
return $url
}
}
}
putlog " - $incith::google::version loaded."
# EOF