PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/willie/modules/search.py

https://github.com/Alhifar/CGRelay
Python | 213 lines | 193 code | 9 blank | 11 comment | 8 complexity | 8530b940013cb7807fff690662907abc MD5 | raw file
  1. # coding=utf8
  2. """
  3. search.py - Willie Web Search Module
  4. Copyright 2008-9, Sean B. Palmer, inamidst.com
  5. Copyright 2012, Edward Powell, embolalia.net
  6. Licensed under the Eiffel Forum License 2.
  7. http://willie.dftba.net
  8. """
  9. from __future__ import unicode_literals
  10. import re
  11. from willie import web
  12. from willie.module import commands, example
  13. import json
  14. import sys
  15. import time
  16. def google_ajax(query):
  17. """Search using AjaxSearch, and return its JSON."""
  18. uri = 'http://ajax.googleapis.com/ajax/services/search/web'
  19. args = '?v=1.0&safe=off&q=' + query
  20. bytes = web.get(uri + args)
  21. return json.loads(bytes)
  22. def google_search(query):
  23. results = google_ajax(query)
  24. try:
  25. return results['responseData']['results'][0]['unescapedUrl']
  26. except IndexError:
  27. return None
  28. except TypeError:
  29. return False
  30. def google_count(query):
  31. results = google_ajax(query)
  32. if not 'responseData' in results:
  33. return '0'
  34. if not 'cursor' in results['responseData']:
  35. return '0'
  36. if not 'estimatedResultCount' in results['responseData']['cursor']:
  37. return '0'
  38. return results['responseData']['cursor']['estimatedResultCount']
  39. def formatnumber(n):
  40. """Format a number with beautiful commas."""
  41. parts = list(str(n))
  42. for i in range((len(parts) - 3), 0, -3):
  43. parts.insert(i, ',')
  44. return ''.join(parts)
  45. @commands('g', 'google')
  46. @example('.g swhack')
  47. def g(bot, trigger):
  48. """Queries Google for the specified input."""
  49. query = trigger.group(2)
  50. if not query:
  51. return bot.reply('.g what?')
  52. uri = google_search(query)
  53. if uri:
  54. bot.reply(uri)
  55. bot.memory['last_seen_url'][trigger.sender] = uri
  56. elif uri is False:
  57. bot.reply("Problem getting data from Google.")
  58. else:
  59. bot.reply("No results found for '%s'." % query)
  60. @commands('gc')
  61. @example('.gc extrapolate')
  62. def gc(bot, trigger):
  63. """Returns the number of Google results for the specified input."""
  64. query = trigger.group(2)
  65. if not query:
  66. return bot.reply('.gc what?')
  67. num = formatnumber(google_count(query))
  68. bot.say(query + ': ' + num)
  69. r_query = re.compile(
  70. r'\+?"[^"\\]*(?:\\.[^"\\]*)*"|\[[^]\\]*(?:\\.[^]\\]*)*\]|\S+'
  71. )
  72. @commands('gcs', 'comp')
  73. @example('.gcs foo bar')
  74. def gcs(bot, trigger):
  75. """Compare the number of Google search results"""
  76. if not trigger.group(2):
  77. return bot.reply("Nothing to compare.")
  78. queries = r_query.findall(trigger.group(2))
  79. if len(queries) > 6:
  80. return bot.reply('Sorry, can only compare up to six things.')
  81. results = []
  82. for i, query in enumerate(queries):
  83. query = query.strip('[]')
  84. n = int((formatnumber(google_count(query)) or '0').replace(',', ''))
  85. results.append((n, query))
  86. if i >= 2:
  87. time.sleep(0.25)
  88. if i >= 4:
  89. time.sleep(0.25)
  90. results = [(term, n) for (n, term) in reversed(sorted(results))]
  91. reply = ', '.join('%s (%s)' % (t, formatnumber(n)) for (t, n) in results)
  92. bot.say(reply)
  93. r_bing = re.compile(r'<h3><a href="([^"]+)"')
  94. def bing_search(query, lang='en-GB'):
  95. base = 'http://www.bing.com/search?mkt=%s&q=' % lang
  96. bytes = web.get(base + query)
  97. m = r_bing.search(bytes)
  98. if m:
  99. return m.group(1)
  100. r_duck = re.compile(r'nofollow" class="[^"]+" href="(.*?)">')
  101. def duck_search(query):
  102. query = query.replace('!', '')
  103. uri = 'http://duckduckgo.com/html/?q=%s&kl=uk-en' % query
  104. bytes = web.get(uri)
  105. m = r_duck.search(bytes)
  106. if m:
  107. return web.decode(m.group(1))
  108. def duck_api(query):
  109. if '!bang' in query.lower():
  110. return 'https://duckduckgo.com/bang.html'
  111. uri = 'http://api.duckduckgo.com/?q=%s&format=json&no_html=1&no_redirect=1' % query
  112. results = json.loads(web.get(uri))
  113. if results['Redirect']:
  114. return results['Redirect']
  115. else:
  116. return None
  117. @commands('duck', 'ddg')
  118. @example('.duck privacy or .duck !mcwiki obsidian')
  119. def duck(bot, trigger):
  120. """Queries Duck Duck Go for the specified input."""
  121. query = trigger.group(2)
  122. if not query:
  123. return bot.reply('.ddg what?')
  124. #If the API gives us something, say it and stop
  125. result = duck_api(query)
  126. if result:
  127. bot.reply(result)
  128. return
  129. #Otherwise, look it up on the HTMl version
  130. uri = duck_search(query)
  131. if uri:
  132. bot.reply(uri)
  133. bot.memory['last_seen_url'][trigger.sender] = uri
  134. else:
  135. bot.reply("No results found for '%s'." % query)
  136. @commands('search')
  137. @example('.search nerdfighter')
  138. def search(bot, trigger):
  139. """Searches Google, Bing, and Duck Duck Go."""
  140. if not trigger.group(2):
  141. return bot.reply('.search for what?')
  142. query = trigger.group(2)
  143. gu = google_search(query) or '-'
  144. bu = bing_search(query) or '-'
  145. du = duck_search(query) or '-'
  146. if (gu == bu) and (bu == du):
  147. result = '%s (g, b, d)' % gu
  148. elif (gu == bu):
  149. result = '%s (g, b), %s (d)' % (gu, du)
  150. elif (bu == du):
  151. result = '%s (b, d), %s (g)' % (bu, gu)
  152. elif (gu == du):
  153. result = '%s (g, d), %s (b)' % (gu, bu)
  154. else:
  155. if len(gu) > 250:
  156. gu = '(extremely long link)'
  157. if len(bu) > 150:
  158. bu = '(extremely long link)'
  159. if len(du) > 150:
  160. du = '(extremely long link)'
  161. result = '%s (g), %s (b), %s (d)' % (gu, bu, du)
  162. bot.reply(result)
  163. @commands('suggest')
  164. def suggest(bot, trigger):
  165. """Suggest terms starting with given input"""
  166. if not trigger.group(2):
  167. return bot.reply("No query term.")
  168. query = trigger.group(2)
  169. uri = 'http://websitedev.de/temp-bin/suggest.pl?q='
  170. answer = web.get(uri+query.replace('+', '%2B'))
  171. if answer:
  172. bot.say(answer)
  173. else:
  174. bot.reply('Sorry, no result.')