Advertisement
Guest User

Untitled

a guest
Sep 9th, 2011
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TCL 71.46 KB | None | 0 0
  1. #-----------------------------------------------------------------------------#
  2. # incith:google                                                        v1.8.8g#
  3. #                                                                             #
  4. # performs various methods of Google searches                                 #
  5. # tested on:                                                                  #
  6. #   eggdrop v1.6.17 GNU/LINUX with Tcl 8.4                                    #
  7. #   windrop v1.6.17 CYGWIN_NT with Tcl 8.4                                    #
  8. #                                                                             #
  9. # NEWS:                                                                       #
  10. #  As of v1.6, I (madwoota) have taken over the development of incith:google. #
  11. #  If you have any feature req's, bugs, ideas, etc, please dont hesitate to   #
  12. #  send them to me. My contact details have replaced incith's, but if you     #
  13. #  wish to approach him directly about anything, I can point you in the right #
  14. #  direction.                                                                 #
  15. #                                                                             #
  16. #  See the Egghelp forum for inciths handover and all the latest info:        #
  17. #    http://forum.egghelp.org/viewtopic.php?t=10175                           #
  18. #                                                                             #
  19. # Basic usage guide:                                                          #
  20. #   .chanset #channel +google                                                 #
  21. #   !google <define:|spell:> <search terms> <1+1> <1 cm in ft> <patent ##>    #
  22. #      <weather city|zip> <??? airport> <city,state/zip>                      #
  23. #   !images <search terms>                                                    #
  24. #   !groups <search terms>                                                    #
  25. #   !local <what> near <where>                                                #
  26. #   !books <search terms>                                                     #
  27. #   !video <search terms>                                                     #
  28. #   !fight <word(s) one> vs <word(s) two>                                     #
  29. #                                                                             #
  30. # ChangeLog:                                                                  #
  31. #  1.0: first public release                                                  #
  32. #  1.1: improved bolding of search terms, compatible with chopped descriptions#
  33. #       supports 'define: <word>' lookups                                     #
  34. #       supports calculator. !google (4+3) * 2 - 1                            #
  35. #         - converts, too. !google 1 lb in ounces                             #
  36. #       image lookups coded, !images <search>                                 #
  37. #       'spell: word1 word2' function added - don't rely on this, it's not a  #
  38. #         dictionary, just corrects common typos.                             #
  39. #       flood protection added                                                #
  40. #  1.2: will wrap long lines (yay, a worthy solution!)                        #
  41. #       allowed setting of the seperator instead of a ' | ' by default. If you#
  42. #         set this to "\n" then you will get each result on a seperate line   #
  43. #         instead of one line                                                 #
  44. #       will display 'did you mean' if no results                             #
  45. #       [PDF] links will be parsed/included now                               #
  46. #       fixed a bug when no data was returned from google such is the case    #
  47. #         when you search for """"""""""""""""""                              #
  48. #  1.3: can return results in multiple languages now                          #
  49. #       fixed quotes being displayed around links                             #
  50. #       private messages support added (for /msg !google)                     #
  51. #       video.google.com seems impossible, Google Video Viewer                #
  52. #         is required to view videos, etc                                     #
  53. #  1.4: bit of a different output, easier to click links now                  #
  54. #       local lookups coded, use !local <what> near <where>                   #
  55. #       seems google does currency the same way my exchange                   #
  56. #         script does (!g 1 usd in cad)                                       #
  57. #       "patent ##" will return the patent link if it exists                  #
  58. #       bugfix in private messages                                            #
  59. #       sorry to all whom grabbed a borked copy on egghelp :-(                #
  60. #  1.5: fix for !local returning html on 'Unverified listing's                #
  61. #       "madwoota" has supplied some nice code updates for us!                #
  62. #         - "answer" matches, eg: !g population of japan                      #
  63. #           - !g <upc code>                                                   #
  64. #         - google groups (!gg), google news (!gn)                            #
  65. #         - movie: review lookups                                             #
  66. #         - area code lookups (!g 780)                                        #
  67. #         - books.google lookups (!gb !books)                                 #
  68. #       reworked binds to fix horrible bug allowing !g !gi !gp                #
  69. #       case insensitive binds (!gi, !GI, !gI, !Gi, etc)                      #
  70. #   .1: fix for double triggers/bad binds                                     #
  71. #   .2: fix involving "can't read link" error                                 #
  72. #madwoota:                                                                    #
  73. #  1.6: fixed google search returning no results                              #
  74. #       fixed descriptions getting cut short on 'answers'                     #
  75. #       fixed bug where some urls were returned invalid                       #
  76. #       fixed google local searches returning no results                      #
  77. #       fixed google books searches returning invalid links                   #
  78. #       changed 'did you means' to get returned first as well                 #
  79. #       added google weather: !g weather <city|zip>                           #
  80. #         - note: US weather only (blame google!)                             #
  81. #       added travel info, eg: !g sfo airport | !g united 134                 #
  82. #       added config option to send output via /notice                        #
  83. #       added initial attempt at parsing google video (!gv)                   #
  84. #  1.7: added option to force all replies as private (req)                    #
  85. #       fixed google groups returning no results                              #
  86. #       fixed define: errors on no results                                    #
  87. #       fixed google books errors on no results/typos                         #
  88. #       fixed movie review errors on no results/typos                         #
  89. #       fixed some characters not usable as command_chars on                  #
  90. #         one of regular eggdrop or windrop+cygwin                            #
  91. #       fixed occasional weird response for travel info                       #
  92. #       updated requirements to http package 2.4                              #
  93. #       loads of other internal changes                                       #
  94. #   .1: fixed search parameters not being parsed correctly                    #
  95. #         - resulted in some bogus "no results" replies.                      #
  96. #   .2: fixed main google search returning rubbish results                    #
  97. #         - google changed their source again                                 #
  98. #       changed all methods of parsing the search results to                  #
  99. #         *hopefully* cope better with any source changes                     #
  100. #       changed output queue to stop the bot from flooding                    #
  101. #   .3: fixed some urls being returned with spaces in them                    #
  102. #         - makes them unusable in most irc clients                           #
  103. #       fixed google groups occasionally returning junk due to                #
  104. #         changes in 1.7.2 (will revisit this later)                          #
  105. #  1.8: added option to turn on "safe" searches                               #
  106. #       added channel user level filtering option (+v/+o only)                #
  107. #       added google fight! !gf or !fight <blah> vs <blah>                    #
  108. #        - inspired by www.googlefight.com                                    #
  109. #       added ability to do any custom mode to descs & links                  #
  110. #        - i'll just apologise now for this one :)                            #
  111. #       removed variable underline_links (superseded by above)                #
  112. #       removed use of 'tcl_endOfWord' to stop windrop breaking               #
  113. #       fixed excess %20's appearing in some results                          #
  114. #       fixed "translate this" only returns ? (i think)                       #
  115. #       stopped local from returning ad spam on first result                  #
  116. #   .1: added tied result check to google fight                               #
  117. #       fixed groups parsing that broke                                       #
  118. #       fixed local parsing that broke                                        #
  119. #       fixed "answer" matches parsing that broke                             #
  120. #   .2: fixed a chance of a "define:" + a "Did you mean:" not                 #
  121. #        returning a result as expected                                       #
  122. #   .3: added function to strip all &#???; unicode from desc results          #
  123. #        - simply replaces &#256; to &#99999; with a "?"                      #
  124. #   .4: fixed tracking rubbish after links on define: lookups                 #
  125. #       fixed local lookups ... again                                         #
  126. #       fixed spell: from returning "0"                                       #
  127. #       added option to disable either weblink or google link on "!g define:" #
  128. #       added stock quotes (try !g intc or !g amd)                            #
  129. #   .5: fixed main google results broke ! Google changed <p> -> <div> :)      #
  130. #       fixed weather                                                         #
  131. #       fixed area code map results (eg: !g 90210 or !g beverly hills, ca)    #
  132. #       added new setting to default to NOT return secondary results          #
  133. #   .6: fixed spell: (apparently, but i dont remember doing it :)             #
  134. #       fixed the class=1 bug which also happened to fix some results not     #
  135. #         being returned due to Google's inconsistent html formatting (sorta) #
  136. #   .6a:an update to a 'temp fix' which will actually work                    #
  137. #       note: http.tcl has now no longer included in this package.            #
  138. #   .6b:fixed !g weather results                                              #
  139. #   .7: added a url encoder/decoder to ensure sane requests are sent          #
  140. #   .7a:removed the login cruft from google                                   #
  141. #       fixed googlefights on funky characters                                #
  142. #   .7b:removed more cruft from google (thanks incith)                        #
  143. #   .7c:fixed something i broke in one of the above fixes... gotta love it.   #
  144. #   .8: fixed up whatever i could find that was broken (nearly everything :)  #
  145. #       added a new option to only return one line on some 'answer' matches   #
  146. #     a:removed some formatting cruft from calc results                       #
  147. #     c:fixed google video and some minor presentation rarities               #
  148. #     d:cleaned up <em></em> appearing in results                             #
  149. #     e:updated something                                                     #
  150. #     f:fixed google. fyi, try !g whois blah.com :)                           #
  151. #     g:fixed images that i broke while fixing google (sorry)                 #
  152. #                                                                             #
  153. # TODO:                                                                       #
  154. #   Make define: return up to $search_results definitions from single source  #
  155. #   Localisation options - determine country limit on input?                  #
  156. #   Google music Album/Albums/Songs search                                    #
  157. #   - http://www.google.com/musica?aid=53YC6821hBO                            #
  158. #   - http://www.google.com/musicsearch?q=sublime                             #
  159. #   Code base clean up !                                                      #
  160. #                                                                             #
  161. # Suggestions/Thanks/Bugs, e-mail at bottom of header.                        #
  162. #                                                                             #
  163. # LICENSE:                                                                    #
  164. #   This code comes with ABSOLUTELY NO WARRANTY.                              #
  165. #                                                                             #
  166. #   This program is free software; you can redistribute it                    #
  167. #   and/or modify it under the terms of the GNU General Public                #
  168. #   License as published by the Free Software Foundation;                     #
  169. #   either version 2 of the License, or (at your option) any                  #
  170. #   later version.                                                            #
  171. #                                                                             #
  172. #   This program is distributed in the hope that it will be                   #
  173. #   useful, but WITHOUT ANY WARRANTY; without even the implied                #
  174. #   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR                   #
  175. #   PURPOSE.  See the GNU General Public License for more                     #
  176. #   details. (http://www.gnu.org/copyleft/library.txt)                        #
  177. #                                                                             #
  178. # Copyright (C) 2005, Jordan                                                  #
  179. # Currently maintained by madwoota                                            #
  180. # google(at)woota(dot)net                                                     #
  181. #-----------------------------------------------------------------------------#
  182. package require http 2.4
  183. setudef flag google
  184.  
  185. # 0 will typically disable an option, otherwise a value 1 or
  186. # above will enable it.
  187. #
  188. namespace eval incith {
  189.   namespace eval google {
  190.     # set this to the command character you want to use for the binds
  191.     variable command_char "!"
  192.  
  193.     # set these to your preferred binds ("one two" - space delimited!)
  194.     variable google_binds "g google"
  195.     variable image_binds "gi image images"
  196.     variable weather_binds "w weather"
  197.     variable local_binds "gl local"
  198.     variable group_binds "gg group groups"
  199.     variable news_binds "gn news"
  200.     variable books_binds "gb books"
  201.     variable video_binds "gv video"
  202.     variable fight_binds "gf fight googlefight"
  203.  
  204.     # To restrict input queries to Ops (+o), Halfops (+h) or Voiced (+v) users on
  205.     #  any +google channel, use this setting.
  206.     # Set the variable to one of the following to achieve the desired filtering:
  207.     # At least Op - 3
  208.     # At least Halfop - 2  (will also allow ops)
  209.     # At least Voice - 1   (will also allow halfops and ops)
  210.     # Everyone - 0         (no filtering)
  211.     #
  212.     # Note: this does NOT apply to private messages, use the below setting for them.
  213.     #
  214.     variable chan_user_level 0
  215.  
  216.     # if you want to allow users to search via private /msg, enable this
  217.     variable private_messages 1
  218.  
  219.     # as per emailed & forum requests, use the next two variables together
  220.     # to determine the output type like so:
  221.     #  notice_reply 1 & force_private 1 = private notice reply only (this is as requested)
  222.     #  notice_reply 0 & force_private 1 = private msg reply only
  223.     #  notice_reply 1 & force_private 0 = regular channel OR private NOTICE
  224.     #  notice_reply 0 & force_private 0 = regular channel OR private MSG (default)
  225.  
  226.     # set to 1 to enable a /notice reply instead, 0 for normal text
  227.     variable notice_reply 0
  228.     # set to 1 to force all replies to be private
  229.     variable force_private 0
  230.  
  231.  
  232.     # set this to the language you want results in! use 2 letter form.
  233.     #   "all" is the default/standard google.com search.
  234.     #   See http://www.google.com/advanced_search for a list.  You have to use
  235.     #   the 'Language' dropdown box, perform a search, and find a line in the URL
  236.     #   that looks like "&lr=lang_en" (for English). "en" is your language code.
  237.     # Popular Ones: it (italian), da (danish), de (german), es (spanish), fr (french)
  238.     # please note, this does not 'translate', it searches Google in a
  239.     #   language of choice, which means you can still get English results.
  240.     variable language "all"
  241.  
  242.     # set this to "on" to let google filter "adult content" from any of your search results
  243.     #  "off" means results will not be filtered at all
  244.     #  note: this is only applicable to !google, !images and !groups
  245.     variable safe_search "off"
  246.  
  247.     # number of search results/image links to return, 'define:' is always 1 as some defs are huge
  248.     variable search_results 4
  249.     variable image_results 4
  250.     variable local_results 4
  251.     variable group_results 4
  252.     variable news_results 4
  253.     variable books_results 4
  254.     variable video_results 4
  255.  
  256.         # set this to 1 to only return a single result on these 'special' matches in google:
  257.         #  time in <blah>, weather in <blah>, population of <blah>, <blah> airport
  258.     variable break_on_special 1
  259.  
  260.     # set this to 0 to turn google fight off (it is a tad slow after all ...)
  261.     variable google_fight 1
  262.  
  263.     # what to use to seperate results, set this to "\n" and it will output each result
  264.     #  on a line of its own. the seperator will be removed from the end of the last result.
  265.     variable seperator " || "
  266.  
  267.     # ** this is not an optional setting, if a string is too long to send, it won't be sent! **
  268.     # It should be set to the max amount of characters that will be received in a public
  269.     #   message by your IRC server.  If you find you aren't receiving results, try lowering this.
  270.     variable split_length 443
  271.  
  272.     # trimmed length of returned descriptions, only for standard searches.
  273.     variable description_length 150
  274.  
  275.     # set these to 0 to turn off either the source web link or google.com define: link for a define:<blah> search
  276.     variable define_weblinks 1
  277.     variable define_googlelinks 1
  278.    
  279.     # set this to 1 to enable returning sub/secondary results from the same site from google as per forum req
  280.     variable subresults 1
  281.  
  282.     # replace search terms appearing in the description as bolded words?
  283.     # - does not bold entire description, just the matching search words
  284.     # - this is ignored if desc_modes contains the Bold mode below
  285.     variable bold_descriptions 1
  286.  
  287.     # Use these two settings to set colours, bold, reverse, underline etc on either descriptions or links
  288.     # The following modes apply and you can use any combination of them: (NO SPACES!)
  289.     #
  290.     #  Bold = \002
  291.     #  Underline = \037
  292.     #  Reverse = \026
  293.     #  Colours:                 #RGB/Html code:
  294.     #   White = \0030           #FFFFFF
  295.     #   Black = \0031           #000000
  296.     #   Blue = \0032            #00007F
  297.     #   Green = \0033           #008F00
  298.     #   Light Red = \0034       #FF0000
  299.     #   Brown = \0035           #7F0000
  300.     #   Purple = \0036          #9F009F
  301.     #   Orange = \0037          #FF7F00
  302.     #   Yellow = \0038          #F0FF00
  303.     #   Light Green = \0039     #00F700
  304.     #   Cyan = \00310           #008F8F
  305.     #   Light Cyan = \00311     #00F7FF
  306.     #   Light Blue = \00312     #0000FF
  307.     #   Pink = \00313           #FF00FF
  308.     #   Grey = \00314           #7F7F7F
  309.     #   Light Grey = \00315     #CFCFCF
  310.     #
  311.     # This example will do Bold, Underline and Light Blue: "\002\037\00312"
  312.     # Note: This will affect *ALL* descs or links. Dont forget to use the \ too !
  313.     # Also note, abusing this this heavily increases the number of characters per line,
  314.     #  so your output lines will increase somewhat.
  315.     variable desc_modes ""
  316.     variable link_modes "\00312"
  317.  
  318.     # number of minute(s) to ignore flooders, 0 to disable flood protection
  319.     variable ignore 1
  320.  
  321.     # how many requests in how many seconds is considered flooding?
  322.     # by default, this allows 3 queries in 10 seconds, the 4th being ignored
  323.     #   and ignoring the flooder for 'variable ignore' minutes
  324.     variable flood 4:10
  325.   }
  326. }
  327. # end of configuration, script begins
  328.  
  329. namespace eval incith {
  330.   namespace eval google {
  331.     variable version "incith:google-1.8.8g"
  332.   }
  333. }
  334.  
  335. # bind the public binds
  336. bind pubm -|- "*" incith::google::public_message
  337.  
  338. # bind the private message binds, if wanted
  339. if {$incith::google::private_messages >= 1} {
  340.   bind msgm -|- "*" incith::google::private_message
  341. }
  342.  
  343. namespace eval incith {
  344.   namespace eval google {
  345.     # GOOGLE
  346.     # performs a search on google.
  347.     #
  348.     proc google {input} {
  349.       # local variable initialization
  350.       set results 0 ; set calc 0 ; set break 0 ; set spell 0 ; set output "" ; set did_you_mean 0
  351.  
  352.       # can't be moved to fetch_html since $spell isn't global
  353.       if {[string match -nocase "spell:*" $input] == 1} {
  354.         set spell 1
  355.       }
  356.  
  357.       # if we don't want any search results, stop now.
  358.       if {$incith::google::search_results <= 0} {
  359.         return
  360.       }
  361.  
  362.       # fetch the html
  363.       set html [fetch_html $input 1]
  364.  
  365.       #debugging output
  366.       #set fopen [open /temp/google_temp.html w]
  367.       #puts $fopen $html
  368.       #close $fopen
  369.  
  370.       # parse the html
  371.       while {$results < $incith::google::search_results} {
  372.         # the regexp grabs the data and stores them into their variables, while
  373.         # the regsub removes the data, for the next loop to grab something new.
  374.  
  375.         # check if there was an alternate spelling first
  376.         if {[string match "*Did you mean:*" $html] == 1} {
  377.           regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - desc
  378.           regsub -all -- {Did.+?you.+?mean:.*?<a.*?href=.*?>(.+?)</a>} $html {} html
  379.           #Just neatens the bolding up a bit (if required)
  380.           regsub -all -- "\002" $desc {} desc
  381.           if {$incith::google::bold_descriptions > 0 && [string match "\002" $incith::google::desc_modes] != 1} {
  382.             set desc "Did you mean: \002${desc}\002 ?"
  383.           } else {
  384.             set desc "Did you mean: ${desc}?"
  385.           }
  386.           set did_you_mean 1
  387.           set link ""
  388.         # top match / "answer" match
  389.         # currency exchange
  390.         } elseif {[string match "*<option value=USD*" $html] == 1} {
  391.           regexp -- {<h3 class=r>(.+?)</.*?<a href=\".+?q=(.+?)\&} $html - desc link
  392.           puts "$link"
  393.           #regsub -nocase {(/url\?q=/)} $link {"http://www.google.com"} link
  394.           set link "http://www.google.com/finance?q=$link"
  395.           puts "$link"
  396.           if {$incith::google::break_on_special >= 1} { set break 1 }
  397.          #!g population of london
  398.        } elseif {[string match "*q=population*Population*According to*" $html] == 1} {
  399.          regexp -- {<ol><li class=g><h3 class=r>(.*?)</h3>.*?<li class=g><h3 class=\"r\"><a href=\"(.*?)\"} $html - desc link
  400.           if {$incith::google::break_on_special >= 1} { set break 1 }
  401.           #!g population on japan - or google public data
  402.         } elseif {[string match "*www.google.com/publicdata*" $html] == 1} {
  403.          regexp -- {<h3 class=r><a href=\"(.*?)\">(.*?)</a>.*?<em.*?>(.*?)<} $html - link desc desc2
  404.           set desc "$desc - $desc2"
  405.           if {$incith::google::break_on_special >= 1} { set break 1 }  
  406.           #!g capitol of finland
  407.         } elseif {[string match "*According to*" $html] == 1} {
  408.           regexp -- {<h3.*?>(.*?)</h3>.*?<h3.*?>.*?<a href=\"(.*?)\"} $html - desc link
  409.          if {$incith::google::break_on_special >= 1} { set break 1 }
  410.          #area codes
  411.          #!g area code 616
  412.        } elseif {[string match "*/images/map_icon2.gif*" $html] == 1} {
  413.          regexp -- {<div class=e>.*?<td.*?valign=top.*?>(.*?)<.+?href=\x22(.+?)\x22.*?</div>} $html - desc link
  414.          regsub -- {<div class=e>.*?</div>} $html {} html
  415.          if {[info exists link] == 1} {
  416.             set link [urldecode $link]
  417.             if {[string match "/url?q=http*" $link] == 1} {
  418.                 regexp -- {/url\?q=(.+?q=.+?)&} $link - link
  419.                         }
  420.          }
  421.          if {$incith::google::break_on_special >= 1} { set break 1 }
  422.        # travel info
  423.          #!g lax airport
  424.        } elseif {[string match "*/images/airplane.gif*" $html] ==1} {
  425.          regexp -- {<div class=[ge]>.*?<a href="(.+?)".*?>(.+?)</a>.*?</div>} $html - link desc
  426.          regsub -- {<div class=[ge]>.*?images/airplane.gif.*?</div>} $html - html
  427.        # weather!
  428.          #!g weather 90210
  429.        } elseif {[string match "*/onebox/weather*" $html] == 1} {
  430. #          regexp -- {<div class=e>.*?<div style=.*?>(.*?)</div>.*?<td><div.*?><div.*?>(.+?)</div><div.*?>(.+?)<.*?>(.+?)<.*?>(.+?)</div>.*?</table>} $html - w1 w2 w3 w4 w5
  431.          regexp -- {<table.*?class=obcontainer>.*?<h3 class=r>(.+?)</h3>.*?<table.*?<td.*?rowspan=2>(.+?)<td.*?<tr.*?<tr.*?<td.*?>(.+?)<td.*?<tr.*?><td.*?>(.+?)<td.*?<tr.*?><td.*?>(.+?)<td} $html - w1 w2 w3 w4 w5
  432.          #regsub -- {<div class=r>.*?</table} $html {} html
  433.           putlog " w1=$w1\n w2=$w2\n w3=$w3\n w4=$w4\n w5=$w5\n"
  434.           regexp -- {([0-9]+)} $w2 {} far
  435.           set cel "%.1f"
  436.           set cel [format $cel [expr {0.5556 * ($far-32)}]]
  437.           ##set cel [expr {round(0.5556 * ($far-32))}]
  438.          set desc "$w1\: $w2/$cel°C; Current: $w3; $w4; $w5"
  439.           #set desc "$w1\: $w2, $w3, $w4, $w5"
  440.          regsub -all -- {&deg;} $desc {°} desc
  441.          set link ""
  442.          regsub -all -- {weather} $input {} input
  443.          if {$incith::google::break_on_special >= 1} { set break 1 }
  444.        # time:
  445.          #!g time in melbourne
  446.        } elseif {[string match "*class=obcontainer*" $html] == 1} {
  447.          regexp -- {<table.+?class=obcontainer>.+?<td style="font-size:medium">(.*?)<} $html - desc
  448.          regsub -- {<table.+?class=obcontainer>.+?<td style="font-size:medium">(.*?)<} $html {} html
  449.          set link ""
  450.          if {$incith::google::break_on_special >= 1} { set break 1 }
  451.        # define:
  452.        #!g define:toast define:hyperthreading
  453.        } elseif {[string match "define:*" $input] == 1} {
  454.          #regexp -- {(<li>.+?)<a href.*(http.+?)(&usg=.+?\x22>|&sig=.+?\x22>|\x22>)} $html - d1 link
  455.           regexp -- {(<div class=s><div>.+?)<div class=gl><a href=\"/url\?q=(.+?)\&} $html - d1 link
  456.          #Setup an internal loop to find multiple bullet points (multiple definitions)
  457.          # but still only from the first group to avoid multiple same answers
  458.          while {$results < $incith::google::search_results && $break != 1 && [info exists d1]} {
  459.            regexp -- {<div>(.*?)<} $d1 - d2
  460.            if {[regexp -inline {<div>.*?<div>} $d1] != ""} {
  461.              regsub -- {<div>.+?<div>} $d1 {<div>} d1
  462.            } else {
  463.              set break 1
  464.            }
  465.                     if {[info exists desc] == 1} {
  466.                         set desc ${desc}${incith::google::seperator}${d2}
  467.                       } else {
  468.                       set desc $d2
  469.                       }
  470.            incr results
  471.          }
  472.          regsub -all -- {\+} $input {%2B} define_input
  473.          regsub -all -- { } $define_input {+} define_input
  474.          if !${incith::google::define_weblinks} {
  475.                 if ${incith::google::define_googlelinks} {
  476.                     set link "http://www.google.com/search?hl=${incith::google::language}&q=${define_input}"
  477.                 } else {
  478.                     set link ""
  479.                 }
  480.          } elseif {[info exists link] == 1 && ${incith::google::define_weblinks}} {
  481.               regsub -all " " $link "%20" link
  482.                 if ${incith::google::define_googlelinks} {
  483.                     append link " ( http://www.google.com/search?hl=${incith::google::language}&q=${define_input} )"
  484.                 }
  485.          }
  486.             set break 1
  487.        # movie:
  488.        } elseif {[string match "movie:*" $input] == 1} {
  489.          regexp -- {<td valign=top><a href=\x22/movies/reviews\?cid=(.+?)&fq(?:.+?)\x22>(.+?)</a>} $html - cid desc
  490.          regsub -- {<td valign=top><a href=\x22/movies/reviews\?cid=(.+?)</a>} $html {} html
  491.          if {[info exists cid] == 1 } { set link "http://www.google.com/movies/reviews?cid=${cid}" }
  492.        # domain whois
  493.        } elseif {[string match "*/images/whois.gif*" $html] == 1} {
  494.          regexp -- { class=\x22g(?: |>).*?<a href=".+?".*?>(.+?)<.*?<td valign=top><div.*?>(.*?)<.*?/div>} $html - d1 d2
  495.          regsub -- { class=\x22g(?: |>).*?<a href=".+?".*?>(.+?)<.*?<td valign=top><div.*?>(.*?)<.*?/div>} $html {} html
  496.          set desc "$d1, $d2"
  497.          set link ""
  498.        #finance / stock quotes
  499.        } elseif {[string match "*<div class=e><div><a href=?/url?q=http://finance.google.com/finance*" $html] == 1} {
  500.             # this has to be one of the worst regexps ever written !
  501.          regexp -- {<div class=e>.*?<a href=\x22.+?\x22>(.+?)</a>(.*?)<.*?<td colspan=3 nowrap>(.+?)</td>.*?Mkt Cap:.*?<td.*?>(.+?)</td>} $html - tick name price mktcap
  502.          regsub -- {<div class=e>.*?<a href=\x22.+?\x22>(.+?)</a>(.*?)<.*?<td colspan=3 nowrap>(.+?)</td>.*?Mkt Cap:.*?<td.*?>(.+?)</td>} $html {} html
  503.          if {[info exists tick] == 1 && [info exists name] == 1 && [info exists name] == 1} {
  504.            set desc "$tick: $name = $$price"
  505.             set link "http://finance.google.com/finance?q=$tick"
  506.                         regsub -all -- "\002" $link {} link
  507.             if {[info exists mktcap] == 1} { append desc " Mkt Cap: $mktcap" }
  508.             unset tick ; unset name ; unset price ; unset mktcap
  509.          }
  510.        # patents
  511.        # no longer supported by google in regular search - have to use http://google.com/patents/
  512.        #} elseif {[regexp {^patent\s+(\d+)\s*$} $input]} {
  513.        #  regexp -- {<a href="(http://patft.uspto.gov/.+?)">} $html - desc
  514.        #  regsub -- {<a href="(http://patft.uspto.gov/.+?)">} $html {} html
  515.        #  set break 1
  516.        #  set link ""
  517.        # spell: checker
  518.        } elseif {$spell == 1} {
  519.          set desc "No alternate spellings found."
  520.          set link ""
  521.        # calculator
  522.        } elseif {[string match "*onebox/calculator*" $html] == 1} {
  523.           #http://www.google.com/images/icons/onebox/calculator-40.gif
  524.          # remove bold codes from the html, not necessary here.
  525.          #regsub -all -- "\002" $html {} html
  526.          regexp -- {<td style=\"vertical-align:top\" >(.*?)</h2>} $html {} desc
  527.           puts "$desc"
  528.           #regsub -- {<h2 class=r.*?</h2>} $html {} html
  529.          set link " "
  530.          set calc 1
  531.        # regular search
  532.        } else {
  533.               #as per forum request. ps: yay regsub!
  534.             if !${incith::google::subresults} {
  535.                 regsub -all -- { class=g style=\x22margin-left:.*?\x22.*?</div>} $html {} html
  536.             }
  537.                    
  538.                     #fix to remove <img> spam from descriptions (usually from a picture next to the result).
  539.                     #get the div
  540.          regexp -- { class=g>(.+?)</div>} $html - div
  541.          #test the $desc for "<img"
  542.          if {[info exists div] == 1} {
  543.               regexp -- {<a.*?href=.*?>(.+?)</a>} $div - test
  544.               if {[string range $test 0 3] == "<img"} {
  545.                 #if found, remove that whole <a href /> (We will use the next one)
  546.                 regsub -- {<a.*?href=.*?</a>} $div {} div
  547.               }
  548.  
  549.               #proceed as normal
  550.               regexp -- {<a.*?href=\x22(.+?)\x22.*?>(.+?)</a>} $div - link desc
  551.               regsub -- { class=g>.*?</div>} $html {} html
  552.    
  553.               #trim the description
  554.               if {[info exists desc] == 1 && $incith::google::description_length > 0} {
  555.                 set desc [string range $desc 0 [expr $incith::google::description_length - 1]]
  556.               }
  557.          }
  558.        }
  559.  
  560.        if {[info exists desc] == 0} {
  561.          if {$output == ""} {
  562.            set output "Sorry, no search results were found."
  563.          }
  564.          return $output
  565.        }
  566.  
  567.                 #Clean up the url result to remove google cruft (tracking, etc)
  568.        if {[info exists link] == 1} {
  569.          if {[string match "*/url\?sa=U*" $link] == 1} {
  570.            regexp -- {/url.+?sa=U.+?q=(.*)&e=} $link - link
  571.          } elseif {[string match "*/url\?sa=X*" $link] == 1} {
  572.            regexp -- {/url.+?sa=X.+?q=(.*)\x22} $link - link
  573.          } elseif {[string match "*/url\?q=*&sa=*" $link] == 1 || [string match "*/url\?q=*&revid=*" $link] == 1 } {
  574.            regexp -- {/url\?q=(.+?)(?:&sa=|&revid=)} $link - link            
  575.          } elseif {[string match "/search\?q=*&revid=*&sa=*" $link] == 1} {
  576.            regexp -- {/search\?q=(.+?)&revid=.*?&sa=} $link - link
  577.            set link "http://www.google.com/search\?q=$link"
  578.          } elseif {[string match *.pdf $link] == 1} {
  579.            set desc "\[PDF\] $desc"
  580.          }
  581.        }
  582.  
  583.        # Make sure we dont have an ugly %00 style url (an encoded url also wont work on buggy webservers)
  584.        # this is a duplicate if check for debugging purposes only - trust me, you wont miss the cpu time.
  585.        if {[string match "*\%\[2-7\]\[0-9a-fA-F\]*" $link] == 1} {
  586.          set link [urldecode $link]
  587.        }
  588.  
  589.        # this removes trailing spaces from the description, and converts %20's to spaces
  590.        # \017 is ^O, read by clients as 'stop bold/colors/underline'
  591.        set desc [string trim $desc]
  592.        regsub -all "%20" $desc " " desc
  593.        regsub -all "<br>" $desc " " desc
  594.  
  595.        if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
  596.        if {$results == 0 && [string match "* -- Current local *" $desc] == 1 && [string match "http://www.google.com*" $link] == 1 } { set spell 1 }
  597.  
  598.        # add the search result
  599.        if {$calc == 0 && $spell == 0} {
  600.          if {$link != ""} {
  601.            if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
  602.            if {[string match "define:*" $input] != 1} {
  603.              regsub -all " " [string trim $link] "%20" link
  604.            }
  605.            regsub -all "(?:\x93|\x94|&quot;|\x22)" $link {} link
  606.            append output "${desc}\017 \@ ${link}\017${incith::google::seperator}"
  607.          } else {
  608.            append output "${desc}\017 ${incith::google::seperator}"
  609.          }
  610.        } else {
  611.          append output "${desc}\017"
  612.        }
  613.  
  614.        # Check the various results where we only need one result.
  615.        if {$spell == 1 || $calc == 1 || $break == 1} {
  616.          break
  617.        }
  618.  
  619.        # increase the results, clear the variables for the next loop
  620.        unset link ; unset desc ; set spell 0 ; set calc 0 ; set break 0
  621.        if {[info exists did_you_mean] == 1} { unset did_you_mean }
  622.        incr results
  623.      }
  624.  
  625.      # make sure we have something to send
  626.      if {[info exists output] == 0} {
  627.        set reply "Sorry, no search results were found."
  628.        if {[info exists did_you_mean] == 1} {
  629.          append reply " Did you mean: ${did_you_mean}?"
  630.        }
  631.        return $reply
  632.      }
  633.      return $output
  634.    }
  635.  
  636.    # IMAGES
  637.    # fetches a list of links to images from images.google.
  638.    #
  639.    proc images {input} {
  640.      ; set results 0 ; set output ""
  641.  
  642.      # if we don't want any search results, stop now.
  643.      if {$incith::google::image_results <= 0} {
  644.        return
  645.      }
  646.  
  647.      # fetch the html
  648.      set html [fetch_html $input 2]
  649.  
  650.      # check for 'did you mean?' first
  651.      regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - did_you_mean
  652.      if {[info exists did_you_mean] == 1} {
  653.        append output "Did you mean: $did_you_mean ?"
  654.        incr results
  655.      }
  656.  
  657.      # parse the html
  658.      while {$results < $incith::google::image_results} {
  659.        regexp -- {<a.+?href=\"/imgres\?imgurl=(.+?)&imgrefurl} $html {} link
  660.        regsub -- {<a.+?href=\"/imgres\?imgurl=(.+?)&imgrefurl} $html {} html
  661.  
  662.        # if there's no link, return or stop looping, depending
  663.        if {![info exists link]} {
  664.          if {$results == 0} {
  665.            set reply "Sorry, no search results were found."
  666.            return $reply
  667.          } else {
  668.            break
  669.          }
  670.        }
  671.  
  672.        # prevent duplicate results is mostly useless here, but will at least
  673.        #   ensure that we don't get the exact same picture.
  674.        if {[string match "*$link*" $output] == 1} {
  675.          break
  676.        }
  677.        if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
  678.  
  679.        # add the search result
  680.        # \017 is ^O, read by clients as 'reset color' (stop bold/etc)
  681.        if {[string length $output] > 0} {
  682.             append output "${incith::google::seperator}${link}\017"
  683.        } else {
  684.                     append output "${link}\017"
  685.                 }
  686.  
  687.        # increase the results, clear the variables for the next loop just in case
  688.        unset link
  689.        incr results
  690.      }
  691.  
  692.      # make sure we have something to send
  693.      if {[info exists output] == 0} {
  694.        set reply "Sorry, no search results were found."
  695.        return $reply
  696.      }
  697.      return $output
  698.    }
  699.  
  700.    # LOCAL
  701.    # fetches a list of address & phone numbers from local.google.
  702.    #
  703.    proc local {input} {
  704.      ; set results 0 ; set output ""
  705.  
  706.      # if we don't want any search results, stop now.
  707.      if {$incith::google::local_results <= 0} {
  708.        return
  709.      }
  710.  
  711.      # fetch the html
  712.      set html [fetch_html $input 3]
  713.  
  714.      # check for 'did you mean?' first
  715.      regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - did_you_mean
  716.      if {[info exists did_you_mean] == 1} {
  717.        append output "Did you mean: $did_you_mean ?"
  718.        incr results
  719.      }
  720.  
  721.      # parse the html
  722.      while {$results < $incith::google::local_results} {
  723.  
  724.         regexp -- {<div class="bn">.*?<a href=.*?>(.+?)</a>.*?</div>.*?<div class="al adr">(.*?)</div>} $html - name addr
  725.        regsub -- {<div class="bn">.*?</div>.*?<div class="al adr">.*?</div>} $html {} html
  726.  
  727.        # if there's no link, return or stop looping, depending
  728.        if {[info exists name] == 0} {
  729.          if {$results == 0} {
  730.            set reply "Sorry, no search results were found."
  731.            return $reply
  732.          } else {
  733.            break
  734.          }
  735.        }
  736.  
  737.                 if {[string match "*<nobr*" $addr] == 1} { regsub -- {<nobr.*?>(.*?)</nobr>} $addr {\1} addr }
  738.        if {$incith::google::desc_modes != ""} { set name "$incith::google::desc_modes$name" }
  739.        if {$incith::google::link_modes != ""} { set link "$incith::google::link_modes${addr}\017." }
  740.        if {[info exists link] == 0} { set link "${addr}." }
  741.        
  742.        
  743.        # add the search result
  744.        # \017 is ^O, read by clients as 'reset color' (stop bold/etc)
  745.        if {[string length $output] > 0} {
  746.             append output "${incith::google::seperator}${name}\017 \@ ${link}\017"
  747.        } else {
  748.             append output "${name}\017 \@ ${link}\017"
  749.                 }
  750.        # increase the results, clear the variables for the next loop just in case
  751.        unset name ; unset link
  752.        incr results
  753.      }
  754.  
  755.      # make sure we have something to send
  756.      if {[info exists output] == 0} {
  757.        set reply "Sorry, no search results were found."
  758.        return $reply
  759.      }
  760.      return $output
  761.    }
  762.  
  763.    # GROUPS
  764.    # fetches a list of threads from groups.google.
  765.    #
  766.    proc groups {input} {
  767.      set results 0 ; set output ""
  768.  
  769.      # if we don't want any search results, stop now.
  770.      if {$incith::google::group_results <= 0} {
  771.        return
  772.      }
  773.  
  774.      # fetch the html
  775.      set html [fetch_html $input 4]
  776.  
  777.      # check for 'did you mean?' first
  778.      regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - did_you_mean
  779.      if {[info exists did_you_mean] == 1} {
  780.        append output "Did you mean: $did_you_mean ?"
  781.        incr results
  782.      }
  783.      
  784.      #Remove the "groups matching" if it exists (its really quite useless)
  785.      if {[string match "*/groups/img/groups-onebox.gif*" $html] == 1} {
  786.        regsub -- {<table.*?groups-onebox.gif.*?</table>} $html {} html
  787.      }
  788.  
  789.      # parse the html
  790.      while {$results < $incith::google::group_results} {
  791.           #as per forum request. ps: yay regsub!
  792.             if !${incith::google::subresults} {
  793.                 regsub -all -- {<blockquote style=".*?">.*?</blockquote>} $html {} html
  794.             }
  795.  
  796.        regexp -- {<a.*?href=\x22/group/(.*?)/browse_thread/thread/(.+?)/.*?>(.+?)</a>.*?</table>} $html {} group thread desc
  797.        regsub -- {<a.*?href=\x22/group/.*?</table>} $html {} html
  798.  
  799.        #if theres no desc, return or stop looping, depending
  800.        if {[info exists desc] == 0} {
  801.          if {$results == 0} {
  802.            set reply "Sorry, no search results were found."
  803.            return $reply
  804.          } else {
  805.            break
  806.          }
  807.        }
  808.  
  809.        if {[info exists desc] == 1 && $incith::google::description_length > 0} {
  810.          set desc [string range $desc 0 [expr $incith::google::description_length - 1]]
  811.        }
  812.  
  813.        # make the link valid because we only got a partial href result, not a full url
  814.        set link "http://groups.google.com/group/${group}/browse_thread/thread/${thread}"
  815.  
  816.        if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
  817.        if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
  818.  
  819.        # add the search result
  820.        if {[string length $output] > 0} {
  821.             append output "${incith::google::seperator}${desc}\017 \@ ${link}\017"
  822.        } else {
  823.             append output "${desc}\017 \@ ${link}\017"
  824.                 }
  825.  
  826.        # increase the results, clear the variables for the next loop just in case
  827.        unset link; unset desc
  828.        incr results
  829.      }
  830.  
  831.      # make sure we have something to send
  832.      if {[info exists output] == 0} {
  833.        set reply "Sorry, no search results were found."
  834.        return $reply
  835.      }
  836.      return $output
  837.    }
  838.  
  839.    # NEWS
  840.    # fetches the news from news.google.
  841.    #
  842.    proc news {input} {
  843.      ; set results 0 ; set output ""
  844.  
  845.      # if we don't want any search results, stop now.
  846.      if {$incith::google::news_results <= 0} {
  847.        return
  848.      }
  849.  
  850.      # fetch the html
  851.      set html [fetch_html $input 5]
  852.  
  853.      # check for 'did you mean?' first
  854.      regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - did_you_mean
  855.      if {[info exists did_you_mean] == 1} {
  856.        append output "Did you mean: $did_you_mean ?"
  857.        incr results
  858.      }
  859.  
  860.      # parse the html
  861.      while {$results < $incith::google::news_results} {
  862.        # somewhat extenuated regexp due to allowing that there *might* be
  863.        # an image next to the story
  864.        regexp -nocase -- {<h3.*?class=r>.*?<a href=\"(.*?)\".*?>(.*?)</a>.*?</h3>} $html - link desc
  865.        regsub -nocase -- {<h3.*?class=r>.*?</h3>} $html {} html
  866.  
  867.        # if there's no desc, return or stop looping, depending
  868.        if {[info exists desc] == 0} {
  869.          if {$results == 0} {
  870.            set reply "Sorry, no search results were found."
  871.            return $reply
  872.          } else {
  873.            break
  874.          }
  875.        }
  876.  
  877.        if {[info exists desc] == 1 && $incith::google::description_length > 0} {
  878.          set desc [string range $desc 0 [expr $incith::google::description_length - 1]]
  879.        }
  880.  
  881.        # prevent duplicate results is mostly useless here, but will at least
  882.        #   ensure that we don't get the exact same article.
  883.        if {[string match "*$link*" $output] == 1} {
  884.          break
  885.        }
  886.  
  887.        if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
  888.        if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
  889.  
  890.        # add the search result
  891.        if {[string length $output] > 0} {
  892.          append output "${incith::google::seperator}${desc}\017 \@ ${link}\017"
  893.        } else {
  894.             append output "${desc}\017 \@ ${link}\017"
  895.                 }
  896.  
  897.        # increase the results, clear the variables for the next loop just in case
  898.        unset link; unset desc
  899.        incr results
  900.      }
  901.  
  902.      # make sure we have something to send
  903.      if {[info exists output] == 0} {
  904.        set reply "Sorry, no search results were found."
  905.        return $reply
  906.      }
  907.      return $output
  908.    }
  909.  
  910.    # BOOKS
  911.    # fetches book titles from books.google.
  912.    #
  913.    proc books {input} {
  914.      ; set results 0 ; set output ""
  915.  
  916.      # if we don't want any search results, stop now.
  917.      if {$incith::google::books_results <= 0} {
  918.        return
  919.      }
  920.  
  921.      # fetch the html
  922.      set html [fetch_html $input 6]
  923.  
  924.      # check for 'did you mean?' first
  925.      regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - did_you_mean
  926.      if {[info exists did_you_mean] == 1} {
  927.        append output "Did you mean: $did_you_mean ?"
  928.        incr results
  929.      }
  930.  
  931.      #parse the html
  932.      while {$results < $incith::google::books_results} {
  933.        regexp -- {<div class=resbdy.*?<a.*?href=\x22(.+?)&dq=.*?>(.+?)</a>.*?</div>} $html {} link desc
  934.        regsub -- {<div class=resbdy.*?</div>} $html {} html
  935.  
  936.        # if there's no desc, return or stop looping, depending
  937.        if {[info exists desc] == 0} {
  938.          if {$results == 0} {
  939.            set reply "Sorry, no search results were found."
  940.            return $reply
  941.          } else {
  942.            break
  943.          }
  944.        }
  945.  
  946.        # prevent duplicate results is mostly useless here, but will at least
  947.        #   ensure that we don't get the exact same article.
  948.        if {[string match "*$link*" $output] == 1} {
  949.          break
  950.        }
  951.  
  952.        if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
  953.        if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
  954.  
  955.        # add the search result
  956.        if {[string length $output] > 0} {
  957.          append output "${incith::google::seperator}${desc}\017 \@ ${link}\017"
  958.        } else {
  959.             append output "${desc}\017 \@ ${link}\017"
  960.                 }
  961.  
  962.        # increase the results, clear the variables for the next loop just in case
  963.        unset link; unset desc
  964.        incr results
  965.      }
  966.  
  967.      # make sure we have something to send
  968.      if {[info exists output] == 0} {
  969.        set reply "Sorry, no search results were found."
  970.        return $reply
  971.      }
  972.      return $output
  973.    }
  974.  
  975.    # VIDEO
  976.    # fetches links to video with search data in it (video.google.com)
  977.    #
  978.    proc video {input} {
  979.      ; set results 0 ; set output ""
  980.  
  981.      # if we don't want any search results, stop now.
  982.      if {$incith::google::video_results <= 0} {
  983.        return
  984.      }
  985.  
  986.      # fetch the html
  987.      set html [fetch_html $input 7]
  988.  
  989.      # check for 'did you mean?' first
  990.      regexp -nocase -- {Did you mean:.*?<a.*?href=.*?>(.+?)</a>} $html - did_you_mean
  991.      if {[info exists did_you_mean] == 1} {
  992.        append output "Did you mean: $did_you_mean ?"
  993.        incr results
  994.      }
  995.  
  996.      # parse the html
  997.      while {$results < $incith::google::video_results} {
  998.        regexp -nocase -- {<h3.*?class=r>.*?<a href=\"(.*?)\".*?>(.*?)</a>.*?</h3>} $html - link desc
  999.        regsub -nocase -- {<h3.*?class=r>.*?</h3>} $html {} html
  1000.  
  1001.        # if there's no desc, return or stop looping, depending
  1002.        if {[info exists desc] == 0} {
  1003.          if {$results == 0} {
  1004.            set reply "Sorry, no search results were found."
  1005.            return $reply
  1006.          } else {
  1007.            break
  1008.          }
  1009.        }
  1010.        #if {[info exists desc]} {
  1011.        #  set link "http://video.google.com/videoplay?docid=$link"
  1012.        #}
  1013.        set desc [string trim $desc]
  1014.        set link [string trim $link]
  1015.        if {[string match "*\%\[2-7\]\[0-9a-fA-F\]*" $link] == 1} {
  1016.          set link [urldecode $link]
  1017.        }
  1018.  
  1019.        # prevent duplicate results is mostly useless here, but will at least
  1020.        #   ensure that we don't get the exact same article.
  1021.        if {[string match "*$link*" $output] == 1} {
  1022.         break
  1023.        }
  1024.  
  1025.        if {[info exists desc] == 1 && $incith::google::desc_modes != ""} { set desc "$incith::google::desc_modes[string trim $desc]" }
  1026.        if {[info exists link] == 1 && $incith::google::link_modes != ""} { set link "$incith::google::link_modes[string trim $link]" }
  1027.  
  1028.        # add the search result
  1029.        if {[string length $output] > 0} {
  1030.          append output "${incith::google::seperator}${desc}\017 \@ ${link}\017"
  1031.        } else {
  1032.             append output "${desc}\017 \@ ${link}\017"
  1033.         }
  1034.  
  1035.        # increase the results, clear the variables for the next loop just in case
  1036.        unset link; unset desc
  1037.        incr results
  1038.      }
  1039.  
  1040.      # make sure we have something to send
  1041.      if {[info exists output] == 0} {
  1042.        set reply "Sorry, no search results were found."
  1043.        return $reply
  1044.      }
  1045.      return $output
  1046.    }
  1047.  
  1048.    # FIGHT
  1049.    # google fight !
  1050.    #
  1051.    proc fight {input} {
  1052.      set output ""; set winner 0
  1053.  
  1054.      # if google fight is disabled, stop now.
  1055.      if {$incith::google::google_fight <= 0} {
  1056.        return
  1057.      }
  1058.      
  1059.      regexp -nocase -- {^(.+?) vs (.+?)$} $input - word1 word2
  1060.  
  1061.      # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1062.      set word1 [incith::google::urlencode $word1]
  1063.      set word2 [incith::google::urlencode $word2]
  1064.  
  1065.      # fetch the first result
  1066.      set html [fetch_html $word1 8]
  1067.      # parse the html
  1068.      regexp -- {About.+?([,0-9]{1,}).+?results} $html - match1
  1069.  
  1070.      # fetch the second result
  1071.      set html [fetch_html $word2 8]
  1072.      # parse the html
  1073.      regexp -- {About.+?([,0-9]{1,}).+?results} $html - match2
  1074.  
  1075.      if {![info exists match1]} {
  1076.        set match1 "0"
  1077.        set match1expr "0"
  1078.      } else {
  1079.        regsub -all {,} $match1 {} match1expr
  1080.      }
  1081.  
  1082.      if {![info exists match2]} {
  1083.        set match2 "0"
  1084.        set match2expr "0"
  1085.      } else {
  1086.        regsub -all {,} $match2 {} match2expr
  1087.      }
  1088.  
  1089.      if {[expr $match2expr < $match1expr]} {
  1090.        set winner 1
  1091.      } elseif {[expr $match2expr > $match1expr]} {
  1092.        set winner 2
  1093.      } elseif {[expr $match2expr == $match1expr]} {
  1094.        set winner 3
  1095.      }
  1096.  
  1097.      # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1098.      set word1 [incith::google::urldecode $word1]
  1099.      set word2 [incith::google::urldecode $word2]
  1100.      regsub -all "%20" $word1 " " word1
  1101.      regsub -all "%20" $word2 " " word2
  1102.      
  1103.      if {$incith::google::bold_descriptions > 0 && $incith::google::desc_modes == ""} {
  1104.        set word1 "\002$word1\017"; set word2 "\002$word2\017"
  1105.        set match1 "\002 $match1\017"; set match2 "\002 $match2\017"
  1106.      } elseif {$incith::google::desc_modes != ""} {
  1107.        set word1 "$incith::google::desc_modes$word1\017"; set word2 "$incith::google::desc_modes$word2\017"
  1108.        set match1 "$incith::google::desc_modes $match1\017"; set match2 "$incith::google::desc_modes $match2\017"
  1109.      } else {
  1110.        set match1 " $match1"; set match2 " $match2"
  1111.      }
  1112.  
  1113.      if {$winner == 1} {
  1114.        set output "By results on Google: $word1 beats $word2 by$match1 to$match2!"
  1115.      } elseif {$winner == 2} {
  1116.        set output "By results on Google: $word2 beats $word1 by$match2 to$match1!"
  1117.      } elseif {$winner == 3} {
  1118.        set output "By results on Google: $word1 ties with $word2 on$match1!"
  1119.      } else {
  1120.        set output "Could not determine the winner."
  1121.      }
  1122.  
  1123.      # make sure we have something to send
  1124.      if {[info exists output] == 0} {
  1125.        set reply "Sorry, no search results were found."
  1126.        return $reply
  1127.      }
  1128.      return $output
  1129.    }
  1130.  
  1131.    # FETCH_HTML
  1132.    # fetches html for the various *.google.com sites
  1133.    #
  1134.    proc fetch_html {input switch} {
  1135.      # for local
  1136.      regexp -nocase -- {^(.+?) near (.+?)$} $input - search location
  1137.      # for the rest
  1138.  
  1139.      # GOOGLE
  1140.      if {$switch == 1} {
  1141.        # we don't want 'define:+<search>', so we'll just remove the space if there is one.
  1142.        regsub -nocase -- {^define:\s*} $input {define:} input
  1143.  
  1144.        # spell after define so 'spell: define: foo' doesn't turn into a define lookup
  1145.        if {[string match -nocase "spell:*" $input] == 1} {
  1146.          regsub -nocase -- {^spell:\s*} $input {} input
  1147.        }
  1148.  
  1149.        regsub -all -- {\x22} $input {%22} input
  1150.        regsub -all -- {\+} $input {%2B} input
  1151.        regsub -all -- {\s} $input {+} input
  1152.  
  1153.        if {[string match "movie:*" $input] == 1} {
  1154.          set query "http://www.google.com/movies?hl=en&q=${input}&safe=${incith::google::safe_search}&btnG=Search&lr=lang_${incith::google::language}"
  1155.        } else {
  1156.          set query "http://www.google.com/search?hl=en&q=${input}&safe=${incith::google::safe_search}&btnG=Search&lr=lang_${incith::google::language}"
  1157.        }
  1158.      # IMAGES
  1159.      } elseif {$switch == 2} {
  1160.        set query "http://images.google.com/images?hl=en&q=${input}&safe=${incith::google::safe_search}&btnG=Search+Images"
  1161.      # LOCAL
  1162.      } elseif {$switch == 3} {
  1163.        # a + joins words together in the search, so we change +'s to there search-form value
  1164.        regsub -all -- {\+} $search {%2B} search
  1165.        regsub -all -- {\+} $location {%2B} location
  1166.        # change spaces to +'s for a properly formatted search string.
  1167.        regsub -all -- { } $search {+} search
  1168.        regsub -all -- { } $location {+} location
  1169.        set query "http://local.google.com/local?hl=en&q=${search}&near=${location}&view=text"
  1170.      } elseif {$switch == 4} {
  1171.        set query "http://groups.google.com/groups?hl=en&q=${input}&safe=${incith::google::safe_search}"
  1172.      } elseif {$switch == 5} {
  1173.         set query "http://www.google.com/search?q=${input}&tbs=nws:1"
  1174.        #set query "http://news.google.com/news?hl=en&q=${input}&ned=tus"
  1175.      } elseif {$switch == 6} {
  1176.        regsub -all -- { } $input {+} input
  1177.        set query "http://books.google.com/books?q=${input}&as_brr=0"
  1178.      } elseif {$switch == 7} {
  1179.        set query "http://www.google.com/search?q=${input}&tbs=vid:1"
  1180.      } elseif {$switch == 8} {
  1181.        set query "http://www.google.com/search?hl=&q=${input}&safe=off&btnG=Search&lr=lang_all&num=1"
  1182.      }
  1183.  
  1184.      # beware, changing the useragent will result in differently formatted html from Google.
  1185.      #set ua "Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.4.4"
  1186.       set ua "Presto/2.9.168"
  1187.       #set ua "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.6.30 Version/10.62"
  1188.      set http [::http::config -useragent $ua]
  1189.      set http [::http::geturl "$query" -timeout [expr 1000 * 10]]
  1190.      set html [::http::data $http]
  1191.  
  1192.      # generic pre-parsing
  1193.      regsub -all "\n" $html " " html
  1194.      regsub -all "(?:\x91|\x92|&#39;)" $html "\x27" html
  1195.       regsub -all "(?:\x93|\x94|&quot;)" $html "\x22" html
  1196.       regsub -all "&amp;" $html {\&} html
  1197.       regsub -all -nocase {<h2.+?>} $html "" html
  1198.       regsub -all -nocase {<font.+?>} $html "" html
  1199.       regsub -all -nocase {<sup>(.+?)</sup>} $html {\1} html
  1200.       regsub -all -nocase {<font.+?>} $html "" html
  1201.       regsub -all -nocase {</font>} $html "" html
  1202.       regsub -all -nocase {<span.+?>} $html "" html
  1203.       regsub -all -nocase {</span>} $html "" html
  1204.       regsub -all -nocase {<input.+?>} $html "" html
  1205.       regsub -all -nocase {(?:<i>|</i>)} $html "" html
  1206.       regsub -all -nocase {(?:<em>|</em>)} $html "" html
  1207.      
  1208.       #' this is the "---" line in "population of Japan" searches
  1209.       regsub -all "&#8212;" $html "--" html
  1210.       regsub -all "&times;" $html {*} html
  1211.       regsub -all "&nbsp;" $html { } html
  1212.       regsub -all -nocase "&#215;" $html "x" html
  1213.       regsub -all -nocase "&lt;" $html "<" html
  1214.       regsub -all -nocase "&gt;" $html ">" html
  1215.  
  1216.       # regsub to junk the remaining unicode chars since irc cant handle them properly anyway
  1217.       # this will only match &#256; to &#99999;
  1218.       regsub -all -- {&#(25(\[6-9\])?|2(\[6-9\])?[\d]|(\[3-9\])?[\d]{2}|[\d]{4,5});} $html "" html
  1219.      
  1220.       #
  1221.       # regexps that should remain seperate go here
  1222.       # google specific regexps
  1223.       if {$switch == 1} {
  1224.         # regexp the rest of the html for a much easier result to parse
  1225.         regsub -all -nocase {<b>\[PDF\]</b>\s*} $html "" html
  1226.        
  1227.         regsub -all -- "<p class=g>" $html "<div class=g>" html
  1228.         regsub -all -- {<p class=g style="margin-left:} $html {<div class=g style="margin-left:} html
  1229.  
  1230.         # because we dont want to sign in
  1231.         #regsub -- {<a href=".*?/accounts/Login.*?">Sign in</a>} $html {} html
  1232.         # or go to google.com..
  1233.         #regsub -all -- {<a id=logo .*?</a>} $html {} html
  1234.         # or freaking look at the definition!  gah!  stop adding new stuff google!
  1235.         #regsub -all -- {<a href="/url.+?http://www\.answers\.com/.+?" title="Look up definition.+?">.+?</a>} $html {} html
  1236.  
  1237.       } elseif {$switch == 2} {
  1238.         # these %2520 codes, I have no idea. But they're supposed to be %20's
  1239.         regsub -all {%2520} $html {%20} html
  1240.       } elseif {$switch == 3} {
  1241.         regsub -all -nocase { - <nobr>Unverified listing</nobr>} $html "" html
  1242.       } elseif {$switch == 4} {
  1243.       } elseif {$switch == 5} {
  1244.       } elseif {$switch == 6} {
  1245.       } elseif {$switch == 7} {
  1246.       } elseif {$switch == 8} {
  1247.       }
  1248.       # no point having it so many times
  1249.       if {$incith::google::bold_descriptions > 0 && [string match "\002" $incith::google::desc_modes] != 1} {
  1250.         regsub -all -nocase {(?:<b>|</b>)} $html "\002" html
  1251.       } else {
  1252.         regsub -all -nocase {(<b>|</b>)} $html {} html
  1253.       }
  1254.  
  1255.       return $html
  1256.     }
  1257.  
  1258.     # PUBLIC_MESSAGE
  1259.     # decides what to do with binds that get triggered
  1260.     #
  1261.     proc public_message {nick uhand hand chan input} {
  1262.       if {[lsearch -exact [channel info $chan] +google] == -1} {
  1263.         if {$incith::google::chan_user_level == 3} {
  1264.           if {[isop $nick $chan] == 0} {
  1265.             return
  1266.           }
  1267.         } elseif {$incith::google::chan_user_level == 2} {
  1268.           if {[ishalfop $nick $chan] == 0 && [isop $nick $chan] == 0} {
  1269.             return
  1270.           }
  1271.         } elseif {$incith::google::chan_user_level == 1} {
  1272.           if {[isvoice $nick $chan] == 0 && [ishalfop $nick $chan] == 0 && [isop $nick $chan] == 0} {
  1273.             return
  1274.           }
  1275.         }
  1276.         send_output "$input" "$chan" "$nick" "$uhand"
  1277.       }
  1278.     }
  1279.  
  1280.     # PRIVATE_MESSAGE
  1281.     # decides what to do with binds that get triggered
  1282.     #
  1283.     proc private_message {nick uhand hand input} {
  1284.       if {$incith::google::private_messages >= 1} {
  1285.         send_output $input $nick $nick $uhand
  1286.       }
  1287.     }
  1288.  
  1289.     # SEND_OUTPUT
  1290.     # no point having two copies of this in public/private_message{}
  1291.     #
  1292.     proc send_output {input where nick uhand} {
  1293.       if {[encoding system] != "identity" && [lsearch [encoding names] "ascii"]} {
  1294.         set command_char [encoding convertfrom ascii ${incith::google::command_char}]
  1295.         set input [encoding convertfrom ascii $input]
  1296.       } elseif {[encoding system] == "identity"} {
  1297.         set command_char [encoding convertfrom identity ${incith::google::command_char}]
  1298.         set input [encoding convertfrom identity $input]
  1299.       } else {
  1300.         set command_char ${incith::google::command_char}
  1301.       }
  1302.  
  1303.       #Specifically retrieve only ONE (ascii) character, then check that matches the command_char first
  1304.       set trigger_char [string index $input 0]
  1305.       if {[encoding system] == "identity"} {
  1306.         set trigger_char [encoding convertfrom identity $trigger_char]
  1307.       }
  1308.  
  1309.       #Sanity check 1 - If no match, stop right here. No need to match every (first word) of
  1310.       # every line of channel data against every bind if the command_char doesnt even match.
  1311.       if {$trigger_char != $command_char} {
  1312.         return
  1313.       }
  1314.  
  1315.       set trigger [string range [lindex $input 0] 1 end]
  1316.       #Sanity check 2 - Stop if theres nothing to search for (quiet)
  1317.       set search [string trim [string range $input [string wordend $input 1] end]]
  1318.       if {$search == ""} { return }
  1319.  
  1320.       # flood protection check
  1321.       if {[flood $nick $uhand]} {
  1322.         return
  1323.       }
  1324.      
  1325.       if {$incith::google::force_private == 1} { set where $nick }
  1326.  
  1327.       # check for !google
  1328.       foreach bind [split $incith::google::google_binds " "] {
  1329.         if {[string match -nocase $bind $trigger] == 1} {
  1330.           # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1331.           set search [incith::google::urlencode $search]
  1332.  
  1333.           # call google
  1334.           foreach line [incith::google::parse_output [google $search]] {
  1335.             put_output $where $line
  1336.           }
  1337.           break
  1338.         }
  1339.       }
  1340.      
  1341.       #check for !w !weather
  1342.       foreach bind [split $incith::google::weather_binds " "] {
  1343.         if {[string match -nocase $bind $trigger] == 1} {
  1344.           # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1345.           #set search [incith::google::urlencode $search]
  1346.           set search "weather $search"
  1347.           # call google (will automatically pick up weather now)
  1348.           foreach line [incith::google::parse_output [google $search]] {
  1349.             put_output $where $line
  1350.           }
  1351.           break
  1352.         }
  1353.       }
  1354.  
  1355.       # check for !images
  1356.       foreach bind [split $incith::google::image_binds " "] {
  1357.         if {[string match -nocase $bind $trigger] == 1} {
  1358.           # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1359.           set search [incith::google::urlencode $search]
  1360.           # call images
  1361.           foreach line [incith::google::parse_output [images $search]] {
  1362.             put_output $where $line
  1363.           }
  1364.           break
  1365.         }
  1366.       }
  1367.       # check for !local
  1368.       foreach bind [split $incith::google::local_binds " "] {
  1369.         if {[string match -nocase $bind $trigger] == 1} {
  1370.           # local requires splitting of the search
  1371.           regexp -nocase -- {^(.+?) near (.+?)$} $search - what location
  1372.  
  1373.           if {![info exists what] || ![info exists location]} {
  1374.             put_output $where "Local searches should be the format of 'pizza near footown, bar'"
  1375.             return
  1376.           }
  1377.  
  1378.           foreach line [incith::google::parse_output [local $search]] {
  1379.             put_output $where $line
  1380.           }
  1381.           break
  1382.         }
  1383.       }
  1384.       # check for !groups
  1385.       foreach bind [split $incith::google::group_binds " "] {
  1386.         if {[string match -nocase $bind $trigger] == 1} {
  1387.           # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1388.           set search [incith::google::urlencode $search]
  1389.           # call groups
  1390.           foreach line [incith::google::parse_output [groups $search]] {
  1391.             put_output $where $line
  1392.           }
  1393.           break
  1394.         }
  1395.       }
  1396.       # check for !news
  1397.       foreach bind [split $incith::google::news_binds " "] {
  1398.         if {[string match -nocase $bind $trigger] == 1} {
  1399.           # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1400.           set search [incith::google::urlencode $search]
  1401.           # call news
  1402.           foreach line [incith::google::parse_output [news $search]] {
  1403.             put_output $where $line
  1404.           }
  1405.           break
  1406.         }
  1407.       }
  1408.       # check for !books
  1409.       foreach bind [split $incith::google::books_binds " "] {
  1410.         if {[string match -nocase $bind $trigger] == 1} {
  1411.           # call books
  1412.           foreach line [incith::google::parse_output [books $search]] {
  1413.             put_output $where $line
  1414.           }
  1415.           break
  1416.         }
  1417.       }
  1418.       # check for !video
  1419.       foreach bind [split $incith::google::video_binds " "] {
  1420.         if {[string match -nocase $bind $trigger] == 1} {
  1421.           # This fixes up the issues with 'reserved' url characters: "$&+,/:=@?" by converting them to %xx
  1422.           set search [incith::google::urlencode $search]
  1423.           # call video
  1424.           foreach line [incith::google::parse_output [video $search]] {
  1425.             put_output $where $line
  1426.           }
  1427.           break
  1428.         }
  1429.       }
  1430.       # check for !fight
  1431.       foreach bind [split $incith::google::fight_binds " "] {
  1432.         if {[string match -nocase $bind $trigger] == 1} {
  1433.           # fight requires splitting of the search
  1434.           regexp -nocase -- {^(.+?) vs (.+?)$} $search - word1 word2
  1435.           if {![info exists word1] || ![info exists word2]} {
  1436.             put_output $where "Google fights should be the format of 'random vs predictable'"
  1437.             return
  1438.           }
  1439.  
  1440.           # call fight
  1441.           foreach line [incith::google::parse_output [fight $search]] {
  1442.             put_output $where $line
  1443.           }
  1444.           break
  1445.         }
  1446.       }
  1447.     }
  1448.  
  1449.     # PUT_OUTPUT
  1450.     # actually sends the output to the server
  1451.     proc put_output {where line} {
  1452.       if {$incith::google::notice_reply == 1} {
  1453.         putserv "NOTICE $where :$line"
  1454.       } else {
  1455.         putserv "PRIVMSG $where :$line"
  1456.       }
  1457.     }
  1458.  
  1459.  
  1460.     # PARSE_OUTPUT
  1461.     # prepares output for sending to a channel/user, calls line_wrap
  1462.     #
  1463.     proc parse_output {input} {
  1464.       set parsed_output [set parsed_current {}]
  1465.       if {[string match "\n" $incith::google::seperator] == 1} {
  1466.         regsub {\n\s*$} $input "" input
  1467.         foreach newline [split $input "\n"] {
  1468.           foreach line [incith::google::line_wrap $newline] {
  1469.             lappend parsed_output $line
  1470.           }
  1471.         }
  1472.       } else {
  1473.         regsub "(?:${incith::google::seperator}|\\|)\\s*$" $input {} input
  1474.         foreach line [incith::google::line_wrap $input] {
  1475.           lappend parsed_output $line
  1476.         }
  1477.       }
  1478.       return $parsed_output
  1479.     }
  1480.  
  1481.     # LINE_WRAP
  1482.     # takes a long line in, and chops it before the specified length
  1483.     # http://forum.egghelp.org/viewtopic.php?t=6690
  1484.     #
  1485.     proc line_wrap {str {splitChr { }}} {
  1486.       set out [set cur {}]
  1487.       set i 0
  1488.       set len $incith::google::split_length
  1489.       #regsub -all "\002" $str "<ZQ" str
  1490.       #regsub -all "\037" $str "<ZX" str
  1491.       foreach word [split [set str][set str ""] $splitChr] {
  1492.         if {[incr i [string len $word]] > $len} {
  1493.           #regsub -all "<ZQ" $cur "\002" cur
  1494.           #regsub -all "<ZX" $cur "\037" cur
  1495.           lappend out [join $cur $splitChr]
  1496.           set cur [list $word]
  1497.           set i [string len $word]
  1498.         } else {
  1499.           lappend cur $word
  1500.         }
  1501.         incr i
  1502.       }
  1503.       #regsub -all "<ZQ" $cur "\002" cur
  1504.       #regsub -all "<ZX" $cur "\037" cur
  1505.       lappend out [join $cur $splitChr]
  1506.     }
  1507.  
  1508.     # FLOOD_INIT
  1509.     # modified from bseen
  1510.     #
  1511.     variable flood_data
  1512.     variable flood_array
  1513.     proc flood_init {} {
  1514.       if {$incith::google::ignore < 1} {
  1515.         return 0
  1516.       }
  1517.       if {![string match *:* $incith::google::flood]} {
  1518.         putlog "$incith::google::version: variable flood not set correctly."
  1519.         return 1
  1520.       }
  1521.       set incith::google::flood_data(flood_num) [lindex [split $incith::google::flood :] 0]
  1522.       set incith::google::flood_data(flood_time) [lindex [split $incith::google::flood :] 1]
  1523.       set i [expr $incith::google::flood_data(flood_num) - 1]
  1524.       while {$i >= 0} {
  1525.         set incith::google::flood_array($i) 0
  1526.         incr i -1
  1527.       }
  1528.     }
  1529.     ; flood_init
  1530.  
  1531.     # FLOOD
  1532.     # updates and returns a users flood status
  1533.     #
  1534.     proc flood {nick uhand} {
  1535.       if {$incith::google::ignore < 1} {
  1536.         return 0
  1537.       }
  1538.       if {$incith::google::flood_data(flood_num) == 0} {
  1539.         return 0
  1540.       }
  1541.       set i [expr ${incith::google::flood_data(flood_num)} - 1]
  1542.       while {$i >= 1} {
  1543.         set incith::google::flood_array($i) $incith::google::flood_array([expr $i - 1])
  1544.         incr i -1
  1545.       }
  1546.       set incith::google::flood_array(0) [unixtime]
  1547.       if {[expr [unixtime] - $incith::google::flood_array([expr ${incith::google::flood_data(flood_num)} - 1])] <= ${incith::google::flood_data(flood_time)}} {
  1548.         putlog "$incith::google::version: flood detected from ${nick}."
  1549.         newignore [join [maskhost *!*[string trimleft $uhand ~]]] $incith::google::version flooding $incith::google::ignore
  1550.         return 1
  1551.       } else {
  1552.         return 0
  1553.       }
  1554.     }
  1555.  
  1556.     # URL Decode
  1557.     # Decodes all of the %00 strings in a url and returns it
  1558.     #
  1559.     proc urldecode {url} {
  1560.       if {[string match "*\%\[2-7\]\[0-9a-fA-F\]*" $url] == 1} {
  1561.         #regsub -all "%20" $url " " url
  1562.         regsub -all "%22" $url "\x22" url
  1563.         regsub -all "%23" $url "#" url
  1564.         regsub -all "%25" $url "%" url
  1565.         regsub -all "%26" $url {\&} url
  1566.         regsub -all "%2B" $url "+" url
  1567.         regsub -all "%2F" $url {/} url
  1568.         regsub -all "%3A" $url ":" url
  1569.         regsub -all "%3C" $url "<" url
  1570.         regsub -all "%3D" $url "=" url
  1571.         regsub -all "%3E" $url ">" url
  1572.         regsub -all "%3F" $url "?" url
  1573.         regsub -all "%5B" $url "\[" url
  1574.         regsub -all "%5C" $url "\\" url
  1575.         regsub -all "%5D" $url "]" url
  1576.         regsub -all "%5E" $url "^" url
  1577.         regsub -all "%60" $url "`" url
  1578.         regsub -all "%7B" $url "{" url
  1579.         regsub -all "%7C" $url "|" url
  1580.         regsub -all "%7D" $url "}" url
  1581.         regsub -all "%7E" $url "~" url
  1582.       }
  1583.       return $url
  1584.     }
  1585.  
  1586.     # URL Encode
  1587.     # Encodes all non alphanumerics to %00 strings in the input and returns it
  1588.     #
  1589.     proc urlencode {url} {
  1590.       set url [string trim $url]
  1591.       # % goes first ... obviously :)
  1592.       regsub -all -- {\%} $url {%25} url
  1593.       regsub -all -- { } $url {%20} url
  1594.       regsub -all -- {\&} $url {%26} url
  1595.       #regsub -all -- {\!} $url {%21} url
  1596.       regsub -all -- {\@} $url {%40} url
  1597.       regsub -all -- {\#} $url {%23} url
  1598.       regsub -all -- {\$} $url {%24} url
  1599.       regsub -all -- {\^} $url {%5E} url
  1600.       #regsub -all -- {\*} $url {%2A} url
  1601.       #regsub -all -- {\(} $url {%28} url
  1602.       #regsub -all -- {\)} $url {%29} url
  1603.       regsub -all -- {\+} $url {%2B} url
  1604.       regsub -all -- {\=} $url {%3D} url
  1605.       regsub -all -- {\\} $url {%5C} url
  1606.       regsub -all -- {\/} $url {%2F} url
  1607.       regsub -all -- {\|} $url {%7C} url
  1608.       regsub -all -- {\[} $url {%5B} url
  1609.       regsub -all -- {\]} $url {%5D} url
  1610.       regsub -all -- {\{} $url {%7B} url
  1611.       regsub -all -- {\}} $url {%7D} url
  1612.       #regsub -all -- {\.} $url {%2E} url
  1613.       regsub -all -- {\,} $url {%2C} url
  1614.       #regsub -all -- {\-} $url {%2D} url
  1615.       #regsub -all -- {\_} $url {%5F} url
  1616.       #regsub -all -- {\'} $url {%27} url
  1617.      
  1618.       #Need : to make define:, movie: etc work
  1619.       #regsub -all -- {\:} $url {%3A} url
  1620.      
  1621.       regsub -all -- {\;} $url {%3B} url
  1622.       regsub -all -- {\?} $url {%3F} url
  1623.       regsub -all -- {\"} $url {%22} url
  1624.      regsub -all -- {\<} $url {%3C} url
  1625.      regsub -all -- {\>} $url {%3E} url
  1626.      regsub -all -- {\~} $url {%7E} url
  1627.      regsub -all -- {\`} $url {%60} url
  1628.            
  1629.      return $url
  1630.    }
  1631.  }
  1632. }
  1633.  
  1634. putlog " - $incith::google::version loaded."
  1635.  
  1636. # EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement