X-Git-Url: https://jfr.im/git/z_archive/twitter.git/blobdiff_plain/6da3627e857d0a923b5f44de90e339ab51f173f2..a77486538f56a0385d7aab12b47313b1c363e48c:/twitter/ircbot.py diff --git a/twitter/ircbot.py b/twitter/ircbot.py index f702b79..a10a5f1 100644 --- a/twitter/ircbot.py +++ b/twitter/ircbot.py @@ -24,12 +24,9 @@ email: password: If no config file is given "twitterbot.ini" will be used by default. - """ -# TODO add delimiter if first word isn't "is" or "was" - -BOT_VERSION = "TwitterBot 0.2.1 (mike.verdone.ca/twitter)" +BOT_VERSION = "TwitterBot 1.0 (http://mike.verdone.ca/twitter)" IRC_BOLD = chr(0x02) IRC_ITALIC = chr(0x16) @@ -39,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 @@ -84,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): @@ -130,10 +126,16 @@ class TwitterBot(object): text = (htmlentitydecode( update['text'].replace('\n', ' ')) .encode('utf-8', 'replace')) - self.privmsg_channel( - "=^_^= %s%s%s %s" %( - IRC_BOLD, update['user']['screen_name'], - IRC_BOLD, text)) + + # Skip updates beginning with @ + # TODO This would be better if we only ignored messages + # to people who are not on our following list. + if not text.startswith("@"): + self.privmsg_channel( + u"=^_^= %s%s%s %s" %( + IRC_BOLD, update['user']['screen_name'], + IRC_BOLD, text.decode('utf-8'))) + nextLastUpdate = crt else: break @@ -175,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] @@ -223,27 +225,56 @@ 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 +# So there was a joke here about the twitter business model +# but I got rid of it. Not because I want this codebase to +# be "professional" in any way, but because someone forked +# this and deleted the comment because they couldn't take +# a joke. Hi guy! +# +# Fact: The number one use of Google Code is to look for that +# comment in the Linux kernel that goes "FUCK me gently with +# a chainsaw." Pretty sure Linus himself wrote it. + 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()