summaryrefslogtreecommitdiffstats
path: root/modules/search.py
diff options
context:
space:
mode:
authorSean B. Palmer <http://inamidst.com/sbp/>2008-02-21 12:06:33 +0000
committerSean B. Palmer <http://inamidst.com/sbp/>2008-02-21 12:06:33 +0000
commit7931fab14599b739c18c8f1ebcc24b75688dbc09 (patch)
treebf4df9757f10c155e3b6f78aed48f15884ebbbe6 /modules/search.py
downloadbot-7931fab14599b739c18c8f1ebcc24b75688dbc09.tar.gz
bot-7931fab14599b739c18c8f1ebcc24b75688dbc09.tar.bz2
bot-7931fab14599b739c18c8f1ebcc24b75688dbc09.zip
Phenny2, now being tested on Freenode as the main phenny.
Diffstat (limited to 'modules/search.py')
-rwxr-xr-xmodules/search.py82
1 files changed, 82 insertions, 0 deletions
diff --git a/modules/search.py b/modules/search.py
new file mode 100755
index 0000000..9ad1a04
--- /dev/null
+++ b/modules/search.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+"""
+search.py - Phenny Web Search Module
+Copyright 2008, Sean B. Palmer, inamidst.com
+Licensed under the Eiffel Forum License 2.
+
+http://inamidst.com/phenny/
+"""
+
+import re
+import web
+
+r_string = re.compile(r'("(\\.|[^"\\])*")')
+r_json = re.compile(r'^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]+$')
+env = {'__builtins__': None, 'null': None, 'true': True, 'false': False}
+
+def json(text):
+ """Evaluate JSON text safely (we hope)."""
+ if r_json.match(r_string.sub('', text)):
+ text = r_string.sub(lambda m: 'u' + m.group(1), text)
+ return eval(text.strip(' \t\r\n'), env, {})
+ raise ValueError('Input must be serialised JSON.')
+
+def search(query, n=1):
+ """Search using SearchMash, return its JSON."""
+ q = web.urllib.quote(query.encode('utf-8'))
+ uri = 'http://www.searchmash.com/results/' + q + '?n=' + str(n)
+ bytes = web.get(uri)
+ return json(bytes)
+
+def result(query):
+ results = search(query)
+ return results['results'][0]['url']
+
+def count(query):
+ results = search(query)
+ return results['estimatedCount']
+
+def formatnumber(n):
+ """Format a number with beautiful commas."""
+ parts = list(str(n))
+ for i in range((len(parts) - 3), 0, -3):
+ parts.insert(i, ',')
+ return ''.join(parts)
+
+def g(phenny, input):
+ uri = result(input.group(2))
+ phenny.reply(uri)
+g.commands = ['g']
+g.priority = 'high'
+
+def gc(phenny, input):
+ query = input.group(2)
+ num = count(query)
+ phenny.say(query + ': ' + num)
+gc.commands = ['gc']
+gc.priority = 'high'
+
+r_query = re.compile(
+ r'\+?"[^"\\]*(?:\\.[^"\\]*)*"|\[[^]\\]*(?:\\.[^]\\]*)*\]|\S+'
+)
+
+def compare(phenny, input):
+ queries = r_query.findall(input.group(2))
+ if len(queries) > 6:
+ return phenny.reply('Sorry, can only compare up to six things.')
+
+ results = []
+ for i, query in enumerate(queries):
+ query = query.strip('[]')
+ n = int((count(query) or '0').replace(',', ''))
+ results.append((n, query))
+ if i >= 2: __import__('time').sleep(0.25)
+ if i >= 4: __import__('time').sleep(0.25)
+
+ results = [(term, n) for (n, term) in reversed(sorted(results))]
+ reply = ', '.join('%s (%s)' % (t, formatnumber(n)) for (t, n) in results)
+ phenny.say(reply)
+compare.commands = ['gco', 'comp']
+
+if __name__ == '__main__':
+ print __doc__.strip()