X-Git-Url: https://jfr.im/git/z_archive/twitter.git/blobdiff_plain/7f6c5ae3ec7a7ac9d77b8dd90fcb8cc46092e1b1..de072195b64f3535375f1a20b25f457586a29125:/twitter/ircbot.py diff --git a/twitter/ircbot.py b/twitter/ircbot.py index 1025057..e882ba7 100644 --- a/twitter/ircbot.py +++ b/twitter/ircbot.py @@ -24,10 +24,9 @@ email: password: If no config file is given "twitterbot.ini" will be used by default. - """ -BOT_VERSION = "TwitterBot 0.3.1 (mike.verdone.ca/twitter)" +BOT_VERSION = "TwitterBot 1.0 (http://mike.verdone.ca/twitter)" IRC_BOLD = chr(0x02) IRC_ITALIC = chr(0x16) @@ -37,9 +36,10 @@ IRC_REGULAR = chr(0x0f) import sys import time from dateutil.parser import parse -from ConfigParser import ConfigParser +from ConfigParser import SafeConfigParser from heapq import heappop, heappush import traceback +import os.path from api import Twitter, TwitterError from util import htmlentitydecode @@ -82,19 +82,17 @@ class Scheduler(object): now = time.time() task = heappop(self.task_heap) wait = task.next - now + task.next = now + task.delta + heappush(self.task_heap, task) if (wait > 0): time.sleep(wait) task() - task.next = now + task.delta - heappush(self.task_heap, task) debug("tasks: " + str(self.task_heap)) def run_forever(self): - try: - while True: - self.next_task() - except KeyboardInterrupt: - pass + while True: + self.next_task() + class TwitterBot(object): def __init__(self, configFilename): @@ -134,9 +132,9 @@ class TwitterBot(object): # to people who are not on our following list. if not text.startswith("@"): self.privmsg_channel( - "=^_^= %s%s%s %s" %( + u"=^_^= %s%s%s %s" %( IRC_BOLD, update['user']['screen_name'], - IRC_BOLD, text)) + IRC_BOLD, text.decode('utf-8'))) nextLastUpdate = crt else: @@ -179,7 +177,7 @@ class TwitterBot(object): def privmsg_channel(self, msg): return self.ircServer.privmsg( - self.config.get('irc', 'channel'), msg) + self.config.get('irc', 'channel'), msg.encode('utf-8')) def follow(self, conn, evt, name): userNick = evt.source().split('!')[0] @@ -227,27 +225,57 @@ class TwitterBot(object): self.config.getint('irc', 'port'), self.config.get('irc', 'nick')) self.ircServer.join(self.config.get('irc', 'channel')) - try: - self.sched.run_forever() - except KeyboardInterrupt: - pass + + while True: + try: + self.sched.run_forever() + except KeyboardInterrupt: + break + except TwitterError: + # twitter.com is probably down because it sucks. ignore the fault and keep going + pass def load_config(filename): defaults = dict(server=dict(port=6667, nick="twitterbot")) - cp = ConfigParser(defaults) + cp = SafeConfigParser(defaults) cp.read((filename,)) + + # attempt to read these properties-- they are required + cp.get('twitter', 'email'), + cp.get('twitter', 'password') + cp.get('irc', 'server') + cp.getint('irc', 'port') + cp.get('irc', 'nick') + cp.get('irc', 'channel') + return cp + +# Howdy, hacker!! You've found the secret Twitter business model!! +# +# 1. provide awesome status-update service +# 2. buy a lot of new hardware to keep it running +# 3. ??? +# 4. profit! +# +# I'm just kidding... :3 + + def main(): configFilename = "twitterbot.ini" if (sys.argv[1:]): configFilename = sys.argv[1] + try: + if not os.path.exists(configFilename): + raise Exception() load_config(configFilename) - except: - print >> sys.stderr, "Error loading ini file %s" %( + except Exception, e: + print >> sys.stderr, "Error while loading ini file %s" %( configFilename) - print __doc__ + print >> sys.stderr, e + print >> sys.stderr, __doc__ sys.exit(1) + bot = TwitterBot(configFilename) return bot.run()