#!/usr/bin/env python import cgitb cgitb.enable() import sys, os, re, urllib from htmlentitydefs import name2codepoint class Grab(urllib.URLopener): def __init__(self, *args): self.version = 'Mozilla/5.0 (Phenny)' urllib.URLopener.__init__(self, *args) def http_error_default(self, url, fp, errcode, errmsg, headers): return urllib.addinfourl(fp, [headers, errcode], "http:" + url) urllib._urlopener = Grab() 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.') r_entity = re.compile(r'&([^;\s]+);') def entity(match): value = match.group(1).lower() if value.startswith('#x'): return unichr(int(value[2:], 16)) elif value.startswith('#'): return unichr(int(value[1:])) elif name2codepoint.has_key(value): return unichr(name2codepoint[value]) return '[' + value + ']' def decode(html): return r_entity.sub(entity, html) def tweet(username): uri = 'http://api.twitter.com/statuses/show/%s.xml?include_rts=1' % username u = urllib.urlopen(uri) bytes = u.read() u.close() print 'Content-Type: text/plain; charset=utf-8' print # print bytes error = "Couldn't get that tweet, sorry!" result = (re.findall(r'(?is)(.*?)', bytes) + [error])[0] result = result.replace('\n\n', ' ').replace('\n', ' ') name = (re.findall(r'(?is)(.*?)', bytes) + ['?'])[0] name = name.encode('utf-8') print decode(result).encode('utf-8') + (" (@%s)" % name) sys.exit() def main(): query = os.environ.get('PATH_INFO', '/').lstrip('/') if not query: print 'Content-Type: text/plain' print print 'You must provide a username or tweet id.' sys.exit() if '/status/' in query: query = query.split('/status/').pop() if query.isdigit(): tweet(query) else: username = query uri = 'http://api.twitter.com/1/statuses/user_timeline.json?include_rts=1&screen_name=' u = urllib.urlopen(uri + username) bytes = u.read() u.close() print 'Content-Type: text/plain; charset=utf-8' print message = json(bytes) if isinstance(message, dict): if message.has_key(u'error'): print "Twitter error: " + message[u'error'].encode('utf-8') else: print "Got an error, but Twitter gave no explanation." sys.exit() try: message = message[0] except IndexError: print "The user @%s has no tweets that I can get." % username sys.exit() try: message = message['text'] except KeyError: print "Can't get a tweet out of @%s" % username sys.exit() message = message.replace('\/', '/') message = message.replace('\r', '') message = message.replace('\n', '') message = decode(message).encode('utf-8') print message + (' (@%s)' % username) if __name__ == '__main__': main()