diff --git a/modules/Countdown.py b/modules/Countdown.py index 40019b4..64804c4 100644 --- a/modules/Countdown.py +++ b/modules/Countdown.py @@ -18,6 +18,7 @@ along with this program. If not, see . from ConfigParser import NoOptionError, NoSectionError from datetime import datetime +import re from dateutil.parser import * from dateutil.relativedelta import * @@ -33,69 +34,77 @@ class Countdown(Module): def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): """Add/retrieve countdown items.""" - whats = what.split(' ') - if whats[0] == 'countdown' and len(whats) >= 2: - if whats[1] == 'add' and len(whats) >= 4: - item = whats[2] - target = parse(' '.join(whats[3:]), default=datetime.now().replace(tzinfo=tzlocal())) - if not self.config.has_section(self.__class__.__name__): - self.config.add_section(self.__class__.__name__) + match = re.search('^!countdown\s+add\s+(\S+)\s+(.*)$', what) + if match: + item = match.group(1) + target = parse(match.group(2), default=datetime.now().replace(tzinfo=tzlocal())) - self.config.set(self.__class__.__name__, item, target.astimezone(tzutc()).isoformat()) - replystr = 'added countdown item ' + whats[2] - return self.reply(connection, replypath, replystr) - elif whats[1] == 'remove': - try: - if self.config.remove_option(self.__class__.__name__, whats[2]): - replystr = 'removed countdown item ' + whats[2] - return self.reply(connection, replypath, replystr) - except NoSectionError: pass - elif whats[1] == 'list': - try: - cdlist = self.config.options(self.__class__.__name__) - self.remove_metaoptions(cdlist) - cdlist.sort() - liststr = ', '.join(cdlist) - return self.reply(connection, replypath, liststr) - except NoSectionError: pass - else: - try: - timestr = self.config.get(self.__class__.__name__, whats[1]) - time = parse(timestr) - rdelta = relativedelta(time, datetime.now().replace(tzinfo=tzlocal())) - relstr = whats[1] + ' will occur in ' - if rdelta.years != 0: - relstr += str(rdelta.years) + ' years ' - if rdelta.years > 1: - relstr += 's' - relstr += ', ' - if rdelta.months != 0: - relstr += str(rdelta.months) + ' month' - if rdelta.months > 1: - relstr += 's' - relstr += ', ' - if rdelta.days != 0: - relstr += str(rdelta.days) + ' day' - if rdelta.days > 1: - relstr += 's' - relstr += ', ' - if rdelta.hours != 0: - relstr += str(rdelta.hours) + ' hour' - if rdelta.hours > 1: - relstr += 's' - relstr += ', ' - if rdelta.minutes != 0: - relstr += str(rdelta.minutes) + ' minute' - if rdelta.minutes > 1: - relstr += 's' - relstr += ', ' - if rdelta.seconds != 0: - relstr += str(rdelta.seconds) + ' second' - if rdelta.seconds > 1: - relstr += 's' - relstr += ', ' - return self.reply(connection, replypath, relstr[0:-2]) - except NoOptionError: pass + if not self.config.has_section(self.__class__.__name__): + self.config.add_section(self.__class__.__name__) + + self.config.set(self.__class__.__name__, item, target.astimezone(tzutc()).isoformat()) + replystr = 'added countdown item ' + item + return self.reply(connection, replypath, replystr) + + match = re.search('^!countdown\s+remove\s+(\S+)$', what) + if match: + try: + item = match.group(1) + if self.config.remove_option(self.__class__.__name__, item): + replystr = 'removed countdown item ' + item + return self.reply(connection, replypath, replystr) + except NoSectionError: pass + + match = re.search('^!countdown\s+list$', what) + if match: + try: + cdlist = self.config.options(self.__class__.__name__) + self.remove_metaoptions(cdlist) + cdlist.sort() + liststr = ', '.join(cdlist) + return self.reply(connection, replypath, liststr) + except NoSectionError: pass + + match = re.search('^!countdown\s+(\S+)$', what) + if match: + try: + item = match.group(1) + timestr = self.config.get(self.__class__.__name__, item) + time = parse(timestr) + rdelta = relativedelta(time, datetime.now().replace(tzinfo=tzlocal())) + relstr = item + ' will occur in ' + if rdelta.years != 0: + relstr += str(rdelta.years) + ' years ' + if rdelta.years > 1: + relstr += 's' + relstr += ', ' + if rdelta.months != 0: + relstr += str(rdelta.months) + ' month' + if rdelta.months > 1: + relstr += 's' + relstr += ', ' + if rdelta.days != 0: + relstr += str(rdelta.days) + ' day' + if rdelta.days > 1: + relstr += 's' + relstr += ', ' + if rdelta.hours != 0: + relstr += str(rdelta.hours) + ' hour' + if rdelta.hours > 1: + relstr += 's' + relstr += ', ' + if rdelta.minutes != 0: + relstr += str(rdelta.minutes) + ' minute' + if rdelta.minutes > 1: + relstr += 's' + relstr += ', ' + if rdelta.seconds != 0: + relstr += str(rdelta.seconds) + ' second' + if rdelta.seconds > 1: + relstr += 's' + relstr += ', ' + return self.reply(connection, replypath, relstr[0:-2]) + except NoOptionError: pass # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on; diff --git a/modules/Dice.py b/modules/Dice.py index aced73f..7a619b5 100644 --- a/modules/Dice.py +++ b/modules/Dice.py @@ -261,17 +261,18 @@ class Dice(Module): return output def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): - whats = what.split(' ') - - if whats[0] == 'roll': - dicestr = ' '.join(whats[1:]) + match = re.search('^!roll\s+(.*)$', what) + if match: + dicestr = match.group(1) self.build() yacc.parse(dicestr) reply = self.get_result() if reply is not "": return self.reply(connection, replypath, nick + ': ' + reply) - if whats[0] == 'ctech': - rollitrs = re.split(';\s*', ' '.join(whats[1:])) + + match = re.search('^!ctech\s+(.*)$', what) + if match: + rollitrs = re.split(';\s*', match.group(1)) reply = "" for count, roll in enumerate(rollitrs): pattern = '^(\d+)d(?:(\+|\-)(\d+))?(?:\s+(.*))?' diff --git a/modules/Echo.py b/modules/Echo.py index 9e18bff..d9012c5 100644 --- a/modules/Echo.py +++ b/modules/Echo.py @@ -16,6 +16,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ +import re + from extlib import irclib from Module import Module @@ -27,9 +29,9 @@ class Echo(Module): def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): """Repeat provided text.""" - whats = what.split(' ') - if whats[0] == 'echo' and len(whats) >= 2: - return self.reply(connection, replypath, ' '.join(whats[1:])) + match = re.search('^!echo\s+(.*)$', what) + if match: + return self.reply(connection, replypath, match.group(1)) # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on; diff --git a/modules/EightBall.py b/modules/EightBall.py index 43e5c34..3f13cd9 100644 --- a/modules/EightBall.py +++ b/modules/EightBall.py @@ -17,6 +17,7 @@ along with this program. If not, see . """ import random +import re from extlib import irclib @@ -59,8 +60,8 @@ class EightBall(Module): def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): """Determine the response to the question. Spoiler alert: it's random.""" - whats = what.split(' ') - if whats[0] == '8ball': + match = re.search('^!8ball', what) + if match: response = self.responses[random.randint(1,len(self.responses))-1] return self.reply(connection, replypath, response) diff --git a/modules/Facts.py b/modules/Facts.py index c114862..3b25c90 100644 --- a/modules/Facts.py +++ b/modules/Facts.py @@ -59,33 +59,40 @@ class Facts(Module): def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): """Add or retrieve a fact from the database.""" - whats = what.split(' ') - - if whats[0] == 'facts' and len(whats) >= 2: + try: db = self.get_db() - try: - cur = db.cursor() - if len(whats) == 2: - category_facts = cur.execute('SELECT * FROM facts_facts WHERE category=?', (whats[1],)) - else: - # before doing a query, see if this is actually an add attempt - if whats[1] == 'add' and len(whats) >= 4: - cur.execute('''INSERT INTO facts_facts (category, fact, who, userhost) - VALUES (?, ?, ?, ?)''', (whats[2], ' '.join(whats[3:]), nick, userhost)) - db.commit() - return self.reply(connection, replypath, "fact added") - else: - category_facts = cur.execute('SELECT * FROM facts_facts WHERE category=? AND fact REGEXP ?', (whats[1], ' '.join(whats[2:]))) - facts = category_facts.fetchall() + cur = db.cursor() + match = re.search('^!facts\s+add\s+(\S+)\s+(.*)$', what) + if match: + category = match.group(1) + fact = match.group(2) + cur.execute('''INSERT INTO facts_facts (category, fact, who, userhost) + VALUES (?, ?, ?, ?)''', (category, fact, nick, userhost)) + db.commit() + return self.reply(connection, replypath, category + ' added.') + + match = re.search('^!facts\s+(\S+)\s+(.*)$', what) + if match: + category = match.group(1) + regex = match.group(2) + category_facts = cur.execute('SELECT * FROM facts_facts WHERE category=? AND fact REGEXP ?', (category, regex)) + facts = category_facts.fetchall() if len(facts) > 0: fact = facts[random.randint(1,len(facts))-1] - - # success return self.reply(connection, replypath, fact['fact'].rstrip().encode('utf-8', 'ignore')) - except sqlite3.Error as e: - return self.reply(connection, replypath, "sqlite error: " + str(e)) + match = re.search('^!facts\s+(\S+)$', what) + if match: + category = match.group(1) + category_facts = cur.execute('SELECT * FROM facts_facts WHERE category=?', (category,)) + facts = category_facts.fetchall() + if len(facts) > 0: + fact = facts[random.randint(1,len(facts))-1] + return self.reply(connection, replypath, fact['fact'].rstrip().encode('utf-8', 'ignore')) + + except sqlite3.Error as e: + return self.reply(connection, replypath, "sqlite error: " + str(e)) # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on; diff --git a/modules/GoogleTranslate.py b/modules/GoogleTranslate.py index 8372401..97a3330 100644 --- a/modules/GoogleTranslate.py +++ b/modules/GoogleTranslate.py @@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ +import re from urllib2 import urlopen from urllib import urlencode @@ -36,11 +37,11 @@ class GoogleTranslate(Module): Leaves the input alone to let google make the best guess. """ - whats = what.split(' ') - if whats[0] == 'translate' and len(whats) >= 4: - fromlang = whats[1] - tolang = whats[2] - text = ' '.join(whats[3:]) + match = re.search('^!translate\s+(\S+)\s+(\S+)\s+(.*)$', what) + if match: + fromlang = match.group(1) + tolang = match.group(2) + text = match.group(3) langpair = '%s|%s' % (fromlang, tolang) gt_url = 'http://ajax.googleapis.com/ajax/services/language/translate' diff --git a/modules/IrcAdmin.py b/modules/IrcAdmin.py index 7002d03..ffe13a0 100644 --- a/modules/IrcAdmin.py +++ b/modules/IrcAdmin.py @@ -63,23 +63,23 @@ class IrcAdmin(Module): whats = what.split(' ') - if whats[0] == 'join' and admin_unlocked and len(whats) >= 2: + if whats[0] == '!join' and admin_unlocked and len(whats) >= 2: return self.sub_join_channel(connection, event, nick, userhost, replypath, what, admin_unlocked) - elif whats[0] == 'part' and admin_unlocked and len(whats) >= 2: + elif whats[0] == '!part' and admin_unlocked and len(whats) >= 2: return self.sub_part_channel(connection, event, nick, userhost, replypath, what, admin_unlocked) - elif whats[0] == 'quit' and admin_unlocked: + elif whats[0] == '!quit' and admin_unlocked: return self.sub_quit_irc(connection, event, nick, userhost, replypath, what, admin_unlocked) - elif whats[0] == 'autojoin' and admin_unlocked and len(whats) >= 3: + elif whats[0] == '!autojoin' and admin_unlocked and len(whats) >= 3: return self.sub_autojoin_manipulate(connection, event, nick, userhost, replypath, what, admin_unlocked) - elif whats[0] == 'config' and whats[1] == 'save' and admin_unlocked: + elif whats[0] == '!config' and whats[1] == 'save' and admin_unlocked: return self.reply(connection, replypath, self.irc.save_config()) - elif whats[0] == 'nick' and admin_unlocked and len(whats) >= 2: + elif whats[0] == '!nick' and admin_unlocked and len(whats) >= 2: return self.sub_change_nick(connection, event, nick, userhost, replypath, what, admin_unlocked) - elif whats[0] == 'load' and admin_unlocked and len(whats) >= 2: + elif whats[0] == '!load' and admin_unlocked and len(whats) >= 2: return self.sub_load_module(connection, event, nick, userhost, replypath, what, admin_unlocked) - elif whats[0] == 'reload' and admin_unlocked and len(whats) >= 2: + elif whats[0] == '!reload' and admin_unlocked and len(whats) >= 2: return self.sub_reload_module(connection, event, nick, userhost, replypath, what, admin_unlocked) - elif whats[0] == 'unload' and admin_unlocked and len(whats) >= 2: + elif whats[0] == '!unload' and admin_unlocked and len(whats) >= 2: return self.sub_unload_module(connection, event, nick, userhost, replypath, what, admin_unlocked) def sub_join_channel(self, connection, event, nick, userhost, replypath, what, admin_unlocked): diff --git a/modules/Karma.py b/modules/Karma.py index 122f10d..c2580d8 100644 --- a/modules/Karma.py +++ b/modules/Karma.py @@ -35,9 +35,9 @@ class Karma(Module): pattern = "(?:(\S+)|\((.+)\))" karmapattern = pattern + '(\+\+|--|\+-|-\+)' + '(\s+|$)' - querypattern = '^rank\s+(.*)' - reportpattern = '^karma\s+report\s+(highest|lowest|positive|negative)' - statpattern = '^karma\s+stat\s+(.*)' + querypattern = '^!rank\s+(.*)' + reportpattern = '^!karma\s+report\s+(highest|lowest|positive|negative)' + statpattern = '^!karma\s+stat\s+(.*)' self.karmare = re.compile(karmapattern) self.queryre = re.compile(querypattern) diff --git a/modules/MegaHAL.py b/modules/MegaHAL.py index e8e55b3..8fda542 100644 --- a/modules/MegaHAL.py +++ b/modules/MegaHAL.py @@ -64,7 +64,7 @@ class MegaHAL(Module): append_nick = True reply = mh_python.doreply(line) - elif re.search('^megahal$', line, re.IGNORECASE) is not None: + elif re.search('^!megahal$', line, re.IGNORECASE) is not None: reply = mh_python.doreply('') elif replypath is not None: # only learn if the command is not an internal one diff --git a/modules/Pi.py b/modules/Pi.py index c69bc7b..bc08af4 100644 --- a/modules/Pi.py +++ b/modules/Pi.py @@ -18,6 +18,7 @@ along with this program. If not, see . import math import random +import re import sqlite3 from extlib import irclib @@ -67,7 +68,8 @@ class Pi(Module): raise def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): - if what == "pi": + match = re.search('^!pi$', what) + if match: db = self.get_db() try: cur = db.cursor() diff --git a/modules/Seen.py b/modules/Seen.py index 0b3a132..31cffc0 100644 --- a/modules/Seen.py +++ b/modules/Seen.py @@ -1,18 +1,20 @@ -# Seen - track when a person speaks, and allow data to be queried -# Copyright (C) 2010 Brian S. Stephan -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +""" +Seen - track when a person speaks, and allow data to be queried +Copyright (C) 2010 Brian S. Stephan + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" from ConfigParser import NoOptionError import re @@ -23,10 +25,10 @@ from extlib import irclib from Module import Module -# Keeps track of when people say things in public channels, and reports on when -# they last said something. - class Seen(Module): + + """Track when people say things in public channels, and report on it.""" + def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): # whatever it is, store it if not self.config.has_section(self.__class__.__name__): @@ -34,9 +36,9 @@ class Seen(Module): self.config.set(self.__class__.__name__, nick, userhost + '|:|' + datetime.utcnow().isoformat() + '|:|' + what) - whats = what.split(' ') - if whats[0] == 'seen' and len(whats) >= 2: - query = whats[1] + match = re.search('^!seen\s+(\S+)$', what) + if match: + query = match.group(1) if query != 'debug': try: seendata = self.config.get(self.__class__.__name__, query).split('|:|') diff --git a/modules/TextTransform.py b/modules/TextTransform.py index 76b5120..a19fe51 100644 --- a/modules/TextTransform.py +++ b/modules/TextTransform.py @@ -17,6 +17,7 @@ along with this program. If not, see . """ import base64 +import re from extlib import irclib @@ -47,9 +48,10 @@ class TextTransform(Module): Apply a rot13 method to the text if first word is 'rot13'. """ - whats = what.split(' ') - if whats[0] == "rot13": - reply[0] = ' '.join(whats[1:]).encode('rot13', 'ignore') + match = re.search('^!rot13\s+(.*)$', what) + if match: + text = match.group(1) + reply[0] = text.encode('rot13', 'ignore') return True def base64(self, what, reply): @@ -57,12 +59,16 @@ class TextTransform(Module): Encode/decode base64 string. """ - whats = what.split(' ') - if whats[0] == 'base64e' or whats[0] == 'base64': - reply[0] = base64.encodestring(' '.join(whats[1:])).replace('\n','') + match = re.search('^!base64\s+encode\s+(.*)$', what) + if match: + text = match.group(1) + reply[0] = base64.encodestring(text).replace('\n','') return True - if whats[0] == 'base64d': - reply[0] = base64.decodestring(' '.join(whats[1:])).replace('\n','') + + match = re.search('^!base64\s+decode\s+(.*)$', what) + if match: + text = match.group(1) + reply[0] = base64.decodestring(text).replace('\n','') return True def upper(self, what, reply): @@ -70,9 +76,10 @@ class TextTransform(Module): Convert a string to uppercase. """ - whats = what.split(' ') - if whats[0] == 'upper' and len(whats) >= 2: - reply[0] = ' '.join(whats[1:]).upper() + match = re.search('^!upper\s+(.*)$', what) + if match: + text = match.group(1) + reply[0] = text.upper() return True # vi:tabstop=4:expandtab:autoindent diff --git a/modules/Twitter.py b/modules/Twitter.py index 7490f6d..17fbaab 100644 --- a/modules/Twitter.py +++ b/modules/Twitter.py @@ -16,8 +16,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import urlparse +import re import oauth2 as oauth +import urlparse from extlib import irclib from extlib import twitter @@ -25,13 +26,11 @@ from extlib import twitter from Module import Module class Twitter(Module): - """ - Access Twitter via the bot as an authenticated client. - """ + """Access Twitter via the bot as an authenticated client.""" def __init__(self, irc, config, server): - """ - Prompt the user for oauth stuff when starting up. + + """Prompt the user for oauth stuff when starting up. TODO: make this optional, and have API calls log if they need auth. """ @@ -58,68 +57,81 @@ class Twitter(Module): Attempt to do twitter things. """ - whats = what.split(' ') - if whats[0] == 'twitter' and len(whats) >= 2: - if whats[1] == 'status' and len(whats) == 3: - try: - tweet = self.twit.GetStatus(whats[2]) - return self.reply(connection, replypath, self.tweet_or_retweet_text(tweet=tweet, print_source=True)) - except twitter.TwitterError as e: - return self.reply(connection, replypath, 'Couldn\'t obtain status: ' + str(e)) - elif whats[1] == 'user' and len(whats) >= 3: - if len(whats) >= 4: - index = int(whats[3]) - if index > 0: - index = 0 - else: + match = re.search('^!twitter\s+getstatus\s+(\S+)$', what) + if match: + status = match.group(1) + try: + tweet = self.twit.GetStatus(status) + return self.reply(connection, replypath, self.tweet_or_retweet_text(tweet=tweet, print_source=True)) + except twitter.TwitterError as e: + return self.reply(connection, replypath, 'Couldn\'t obtain status: ' + str(e)) + + match = re.search('^!twitter\s+getuserstatus\s+(\S+)(\s+.*|$)', what) + if match: + user = match.group(1) + index = match.group(2) + + if index: + index = int(index) + if index > 0: index = 0 + else: + index = 0 + count = (-1*index) + 1 - count = (-1*index) + 1 - try: - tweets = self.twit.GetUserTimeline(screen_name=whats[2], count=count, include_rts=True) - if tweets: - tweet = tweets[-1*index] - return self.reply(connection, replypath, self.tweet_or_retweet_text(tweet=tweet)) - except twitter.TwitterError as e: - return self.reply(connection, replypath, 'Couldn\'t obtain status: ' + str(e)) - elif whats[1] == 'tweet' and len(whats) >= 3: - if self.authed is False: - return self.reply(connection, replypath, 'You must be authenticated to tweet.') - if admin_unlocked is False: - return self.reply(connection, replypath, 'Only admins can tweet.') + try: + tweets = self.twit.GetUserTimeline(screen_name=user, count=count, include_rts=True) + if tweets: + tweet = tweets[-1*index] + return self.reply(connection, replypath, self.tweet_or_retweet_text(tweet=tweet)) + except twitter.TwitterError as e: + return self.reply(connection, replypath, 'Couldn\'t obtain status: ' + str(e)) - try: - if self.twit.PostUpdates(' '.join(whats[2:]), continuation='\xe2\x80\xa6') is not None: - return self.reply(connection, replypath, 'Tweet(s) sent.') - else: - return self.reply(connection, replypath, 'Unknown error sending tweet(s).') - except twitter.TwitterError as e: - return self.reply(connection, replypath, 'Couldn\'t tweet: ' + str(e)) - elif whats[1] == 'gettoken': - # get request token - resp, content = self.client.request(self.request_token_url, "GET") - if resp['status'] != '200': - raise Exception("Invalid response %s." % resp['status']) + match = re.search('^!twitter\s+tweet\s+(.*)', what) + if match: + tweet = match.group(1) + if self.authed is False: + return self.reply(connection, replypath, 'You must be authenticated to tweet.') + if admin_unlocked is False: + return self.reply(connection, replypath, 'Only admins can tweet.') - self.request_token = dict(urlparse.parse_qsl(content)) + try: + if self.twit.PostUpdates(tweet, continuation='\xe2\x80\xa6') is not None: + return self.reply(connection, replypath, 'Tweet(s) sent.') + else: + return self.reply(connection, replypath, 'Unknown error sending tweet(s).') + except twitter.TwitterError as e: + return self.reply(connection, replypath, 'Couldn\'t tweet: ' + str(e)) - # have the user auth - return self.reply(connection, replypath, 'Go to the following link in your browser: %s?oauth_token=%s and then send me the pin.' % (self.authorize_url, self.request_token['oauth_token'])) - elif whats[1] == 'auth' and len(whats) >= 3: - oauth_verifier = whats[2] + match = re.search('^!twitter\s+gettoken$', what) + if match: + # get request token + resp, content = self.client.request(self.request_token_url, "GET") + if resp['status'] != '200': + raise Exception("Invalid response %s." % resp['status']) - # request access token - token = oauth.Token(self.request_token['oauth_token'], self.request_token['oauth_token_secret']) - token.set_verifier(oauth_verifier) - client = oauth.Client(self.consumer, token) + self.request_token = dict(urlparse.parse_qsl(content)) - resp, content = client.request(self.access_token_url, "POST") - self.access_token = dict(urlparse.parse_qsl(content)) + # have the user auth + return self.reply(connection, replypath, 'Go to the following link in your browser: %s?oauth_token=%s and then send me the pin.' % (self.authorize_url, self.request_token['oauth_token'])) - # finally, create the twitter API object - self.twit = twitter.Api(self.consumer_key, self.consumer_secret, self.access_token['oauth_token'], self.access_token['oauth_token_secret']) - self.authed = True - return self.reply(connection, replypath, 'The bot is now logged in.') + match = re.search('^!twitter\s+auth\s+(\S+)$', what) + if match: + authtoken = match.group(1) + oauth_verifier = authtoken + + # request access token + token = oauth.Token(self.request_token['oauth_token'], self.request_token['oauth_token_secret']) + token.set_verifier(oauth_verifier) + client = oauth.Client(self.consumer, token) + + resp, content = client.request(self.access_token_url, "POST") + self.access_token = dict(urlparse.parse_qsl(content)) + + # finally, create the twitter API object + self.twit = twitter.Api(self.consumer_key, self.consumer_secret, self.access_token['oauth_token'], self.access_token['oauth_token_secret']) + self.authed = True + return self.reply(connection, replypath, 'The bot is now logged in.') def tweet_or_retweet_text(self, tweet, print_source=False): """ diff --git a/modules/Urls.py b/modules/Urls.py index e459e56..176be05 100644 --- a/modules/Urls.py +++ b/modules/Urls.py @@ -32,7 +32,7 @@ class Urls(Module): """Search for a URL from the store, or return a random one, or add one.""" whats = what.split(' ') - if whats[0] == "url": + if whats[0] == "!url": try: filename = self.config.get(self.__class__.__name__, 'urlfile') diff --git a/modules/Weather.py b/modules/Weather.py index 4111646..a973036 100644 --- a/modules/Weather.py +++ b/modules/Weather.py @@ -33,10 +33,11 @@ class Weather(Module): def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): """Query Google Weather for a location's weather.""" - whats = what.split(' ') - if whats[0] == "weather" and len(whats) >= 2: + match = re.search('^!weather\s+(.*)$', what) + if match: + query = match.group(1) try: - google_weather = pywapi.get_weather_from_google(quote(' '.join(whats[1:]))) + google_weather = pywapi.get_weather_from_google(quote(query)) city = google_weather['forecast_information']['city'].encode('utf-8') condition = google_weather['current_conditions']['condition'].encode('utf-8') temp_f = google_weather['current_conditions']['temp_f'].encode('utf-8')