From 5ebe01386d46f0a3a50b2b02416d8e7ee222af7e Mon Sep 17 00:00:00 2001 From: "Sean B. Palmer" Date: Sat, 13 Nov 2010 11:55:04 +0000 Subject: [PATCH] Services fixes, and a standard JSON API. --- modules/oblique.py | 36 ++++++++++++++++++++++++------------ modules/search.py | 13 +------------ modules/translate.py | 18 +++--------------- modules/weather.py | 14 +------------- web.py | 11 +++++++++++ 5 files changed, 40 insertions(+), 52 deletions(-) diff --git a/modules/oblique.py b/modules/oblique.py index be1ca9d..e53ec29 100755 --- a/modules/oblique.py +++ b/modules/oblique.py @@ -40,26 +40,31 @@ def service(phenny, input, command, args): return phenny.reply('Sorry, the service is broken.') phenny.say(lines[0][:350]) -def o(phenny, input): - """Call a webservice.""" - text = input.group(2) +def refresh(phenny): if hasattr(phenny.config, 'services'): services = phenny.config.services else: services = definitions + old = o.services + o.serviceURI = services + o.services = mappings(o.serviceURI) + return len(o.services), set(o.services) - set(old) + +def o(phenny, input): + """Call a webservice.""" + text = input.group(2) + if (not o.services) or (text == 'refresh'): - old = o.services - o.services = mappings(services) + length, added = refresh(phenny) if text == 'refresh': - msg = 'Okay, found %s services.' % len(o.services) - added = set(o.services) - set(old) + msg = 'Okay, found %s services.' % length if added: msg += ' Added: ' + ', '.join(sorted(added)[:5]) if len(added) > 5: msg += ', &c.' return phenny.reply(msg) if not text: - return phenny.reply('Try %s for details.' % services) + return phenny.reply('Try %s for details.' % o.serviceURI) if ' ' in text: command, args = text.split(' ', 1) @@ -71,7 +76,7 @@ def o(phenny, input): return phenny.reply(msg) if not o.services.has_key(command): - return phenny.reply('Sorry, no such service. See %s' % services) + return phenny.reply('Sorry, no such service. See %s' % o.serviceURI) if hasattr(phenny.config, 'external'): default = phenny.config.external.get('*') @@ -86,13 +91,20 @@ def o(phenny, input): o.commands = ['o'] o.example = '.o servicename arg1 arg2 arg3' o.services = {} +o.serviceURI = None def snippet(phenny, input): + if not o.services: + refresh(phenny) + + search = urllib.quote(input.group(2).encode('utf-8')) py = "BeautifulSoup.BeautifulSoup(re.sub('<.*?>|(?<= ) +', '', " + \ + "''.join(chr(ord(c)) for c in " + \ "eval(urllib.urlopen('http://ajax.googleapis.com/ajax/serv" + \ - "ices/search/web?v=1.0&q=" + urllib.quote(input.group(2)) + \ - "').read().replace('null', 'None'))['responseData']['resul" + \ - "ts'][0]['content'].decode('unicode-escape')), convertEntities=True)" + "ices/search/web?v=1.0&q=" + search + "').read()" + \ + ".replace('null', 'None'))['responseData']['resul" + \ + "ts'][0]['content'].decode('unicode-escape')).replace(" + \ + "'"', '\x22')), convertEntities=True)" service(phenny, input, 'py', py) snippet.commands = ['snippet'] diff --git a/modules/search.py b/modules/search.py index df7ce65..7a0e3ad 100755 --- a/modules/search.py +++ b/modules/search.py @@ -10,23 +10,12 @@ 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): """Search using AjaxSearch, and return its JSON.""" uri = 'http://ajax.googleapis.com/ajax/services/search/web' args = '?v=1.0&safe=off&q=' + web.urllib.quote(query.encode('utf-8')) bytes = web.get(uri + args) - return json(bytes) + return web.json(bytes) def result(query): results = search(query) diff --git a/modules/translate.py b/modules/translate.py index baa430d..e637d01 100755 --- a/modules/translate.py +++ b/modules/translate.py @@ -11,23 +11,11 @@ http://inamidst.com/phenny/ import re, urllib import web -r_json = re.compile(r'^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]+$') -r_string = re.compile(r'("(\\.|[^"\\])*")') -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 detect(text): uri = 'http://ajax.googleapis.com/ajax/services/language/detect' q = urllib.quote(text) bytes = web.get(uri + '?q=' + q + '&v=1.0') - result = json(bytes) + result = web.json(bytes) try: return result['responseData']['language'] except Exception: return None @@ -36,7 +24,7 @@ def translate(text, input, output): q = urllib.quote(text) pair = input + '%7C' + output bytes = web.get(uri + '?q=' + q + '&v=1.0&langpair=' + pair) - result = json(bytes) + result = web.json(bytes) try: return result['responseData']['translatedText'].encode('cp1252') except Exception: return None @@ -59,7 +47,7 @@ def tr(phenny, context): if input != output: msg = translate(phrase, input, output) if msg: - msg = msg.replace(''', "'") + msg = web.decode(msg) # msg.replace(''', "'") msg = '"%s" (%s to %s, translate.google.com)' % (msg, input, output) else: msg = 'The %s to %s translation failed, sorry!' % (input, output) diff --git a/modules/weather.py b/modules/weather.py index 232e58f..29b01e5 100755 --- a/modules/weather.py +++ b/modules/weather.py @@ -13,18 +13,6 @@ from tools import deprecated r_from = re.compile(r'(?i)([+-]\d+):00 from') -r_json = re.compile(r'^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]+$') -r_string = re.compile(r'("(\\.|[^"\\])*")') -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 location(name): name = urllib.quote(name.encode('utf-8')) uri = 'http://ws.geonames.org/searchJSON?q=%s&maxRows=1' % name @@ -34,7 +22,7 @@ def location(name): bytes = u.read() u.close() - results = json(bytes) + results = web.json(bytes) try: name = results['geonames'][0]['name'] except IndexError: return '?', '?', '0', '0' diff --git a/web.py b/web.py index 1a2b5e8..67a4843 100755 --- a/web.py +++ b/web.py @@ -56,5 +56,16 @@ def entity(match): def decode(html): return r_entity.sub(entity, html) +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.') + if __name__=="__main__": main()