Module: remove reply(), use DrBotIRC's

obviously this means all of the modules changed to accomodate. this is
one of many steps to reduce the number of times we pass connections and
servers and other such info around, when it's mostly unnecessary because
modules have a reference to DrBotIRC
This commit is contained in:
Brian S. Stephan 2012-12-19 20:51:35 -06:00
parent e4225abba4
commit 3e76f75bba
21 changed files with 79 additions and 110 deletions

View File

@ -527,6 +527,15 @@ class DrBotIRC(irclib.IRC):
def reply(self, event, replystr, stop=False):
"""Reply over IRC to replypath or return a string with the reply.
The primary utility for this is to properly handle recursion. The
recursion code in DrBotIRC will set up a couple hints that this method
picks up on and will appropriately send an IRC event or return a
string.
Unless you know what you are doing, the modules you write should use
this method rather than send a privmsg reply, as failing to call this
method will certainly have recursion do odd things with your module.
Args:
event incoming event
replystr the message to reply with

View File

@ -121,46 +121,6 @@ class Module(object):
return self.do(connection, event, nick, userhost, what, admin_unlocked)
def reply(self, connection, event, replystr, stop=False):
"""Reply over IRC to replypath or return a string with the reply.
The primary utility for this is to properly handle recursion. The
recursion code in DrBotIRC will set up a couple hints that this method
picks up on and will appropriately send an IRC event or return a
string.
Unless you know what you are doing, the modules you write should return
this method rather than send a privmsg reply, as failing to call this
method will certainly have recursion do odd things with your module.
Args:
connection source connection
event incoming event
replystr the message to reply with
stop whether or not to let other handlers see this
Returns:
The replystr if the event is inside recursion, or, potentially,
"NO MORE" to stop other event handlers from acting.
"""
replypath = event.target()
# check for privmsg
if replypath == connection.get_nickname():
replypath = irclib.nm_to_n(event.source())
if replystr is not None:
if event._recursing:
return replystr
else:
replies = replystr.split('\n')
for reply in replies:
connection.privmsg(replypath, reply)
if stop:
return "NO MORE"
def sendmsg(self, connection, target, msg):
"""Send a privmsg over IRC to target.

View File

@ -206,21 +206,21 @@ class Achievements(Module):
"""Do stuff when commanded."""
if self.joinre.search(what):
return self.reply(connection, event, self._join_system(nick))
return self.irc.reply(event, self._join_system(nick))
elif self.leavere.search(what):
return self.reply(connection, event, self._leave_system(nick))
return self.irc.reply(event, self._leave_system(nick))
elif self.infore.search(what):
match = self.infore.search(what)
achievement = match.group(1)
desc = self._get_achievement_info(achievement)
if desc:
return self.reply(connection, event, achievement + ': ' + desc)
return self.irc.reply(event, achievement + ': ' + desc)
elif self.rankre.search(what):
match = self.rankre.search(what)
player = match.group(1)
achievements = self._get_player_achievements(player)
if len(achievements):
return self.reply(connection, event, player + ' has obtained ' + ', '.join(achievements))
return self.irc.reply(event, player + ' has obtained ' + ', '.join(achievements))
def thread_do(self):
"""Do the scan for achievements and other miscellaneous tasks."""

View File

@ -93,17 +93,17 @@ class Acro(Module):
target = event.target()
if self.statusre.search(what):
return self.reply(connection, event, self.do_status(what))
return self.irc.reply(event, self.do_status(what))
if self.startre.search(what):
return self.reply(connection, event, self.do_start(connection, target, what))
return self.irc.reply(event, self.do_start(connection, target, what))
if self.submitre.search(what):
match = self.submitre.search(what)
return self.reply(connection, event, self.do_submit(nick, match.group(1)))
return self.irc.reply(event, self.do_submit(nick, match.group(1)))
if self.votere.search(what):
match = self.votere.search(what)
return self.reply(connection, event, self.do_vote(nick, match.group(1)))
return self.irc.reply(event, self.do_vote(nick, match.group(1)))
if self.quitre.search(what):
return self.reply(connection, event, self.do_quit(what))
return self.irc.reply(event, self.do_quit(what))
def do_status(self, what):
"""Return the status of the currently-running game, if there is one."""

View File

@ -38,7 +38,7 @@ class Babelfish(Module):
tolang = match.group(2)
text = match.group(3)
return self.reply(connection, event, self.translate(fromlang, tolang, text))
return self.irc.reply(event, self.translate(fromlang, tolang, text))
def translate(self, fromlang, tolang, text):

View File

@ -44,11 +44,11 @@ class Countdown(Module):
self.config.set(self.__class__.__name__, item, target.astimezone(tzutc()).isoformat())
replystr = 'added countdown item ' + item
return self.reply(connection, event, replystr)
return self.irc.reply(event, replystr)
except ValueError as e:
self.log.error("could not parse countdown item")
self.log.exception(e)
return self.reply(connection, event,
return self.irc.reply(event,
"could not parse countdown item: {0:s}".format(str(e)))
match = re.search('^!countdown\s+remove\s+(\S+)$', what)
@ -57,7 +57,7 @@ class Countdown(Module):
item = match.group(1)
if self.config.remove_option(self.__class__.__name__, item):
replystr = 'removed countdown item ' + item
return self.reply(connection, event, replystr)
return self.irc.reply(event, replystr)
except NoSectionError: pass
match = re.search('^!countdown\s+list$', what)
@ -67,7 +67,7 @@ class Countdown(Module):
self.remove_metaoptions(cdlist)
cdlist.sort()
liststr = ', '.join(cdlist)
return self.reply(connection, event, liststr)
return self.irc.reply(event, liststr)
except NoSectionError: pass
match = re.search('^!countdown\s+(\S+)$', what)
@ -108,7 +108,7 @@ class Countdown(Module):
if rdelta.seconds > 1:
relstr += 's'
relstr += ', '
return self.reply(connection, event, relstr[0:-2])
return self.irc.reply(event, relstr[0:-2])
except NoOptionError: pass
# vi:tabstop=4:expandtab:autoindent

View File

@ -292,7 +292,7 @@ class Dice(Module):
dicestr = match.group(1)
reply = nick + ": " + self.do_roll(dicestr)
# irc format it
return self.reply(connection, event,
return self.irc.reply(event,
re.sub(r"(\d+)(.*?\s+)(\(.*?\))", r"\1\214\3", reply))
match = re.search('!ctech\s+(.*)$', what)
@ -394,7 +394,7 @@ class Dice(Module):
if count is not len(rollitrs)-1:
reply += "; "
if reply is not "":
return self.reply(connection, event, nick + ': ' + reply)
return self.irc.reply(event, nick + ': ' + reply)
# vi:tabstop=4:expandtab:autoindent
# kate: indent-mode python;indent-width 4;replace-tabs on;

View File

@ -29,7 +29,7 @@ class Echo(Module):
match = re.search('^!echo\s+(.*)$', what)
if match:
return self.reply(connection, event, match.group(1))
return self.irc.reply(event, match.group(1))
# vi:tabstop=4:expandtab:autoindent
# kate: indent-mode python;indent-width 4;replace-tabs on;

View File

@ -61,7 +61,7 @@ class EightBall(Module):
match = re.search('^!8ball', what)
if match:
response = self.responses[random.randint(1,len(self.responses))-1]
return self.reply(connection, event, response)
return self.irc.reply(event, response)
# vi:tabstop=4:expandtab:autoindent
# kate: indent-mode python;indent-width 4;replace-tabs on;

View File

@ -80,23 +80,23 @@ class Facts(Module):
cur.execute('''INSERT INTO facts_facts (category, fact, who, userhost)
VALUES (%s, %s, %s, %s)''', (category, fact, nick, userhost))
db.commit()
return self.reply(connection, event, category + ' added.')
return self.irc.reply(event, category + ' added.')
match = re.search('^!facts\s+(\S+)\s+(.*)$', what)
if match:
category = match.group(1)
regex = match.group(2)
return self.reply(connection, event, self._get_fact(category, regex))
return self.irc.reply(event, self._get_fact(category, regex))
match = re.search('^!facts\s+(\S+)$', what)
if match:
category = match.group(1)
return self.reply(connection, event, self._get_fact(category))
return self.irc.reply(event, self._get_fact(category))
except mdb.Error as e:
db.rollback()
self.log.error("database error during add/retrieve")
self.log.exception(e)
return self.reply(connection, event, "database error during add/retrieve fact")
return self.irc.reply(event, "database error during add/retrieve fact")
finally: cur.close()
def _get_fact(self, category, search=""):

View File

@ -42,11 +42,11 @@ class Help(Module):
if match:
(module, key) = match.group(2,4)
if (module == None):
return self.reply(connection, event, self.handle_help_descriptions())
return self.irc.reply(event, self.handle_help_descriptions())
elif (key == None):
return self.reply(connection, event, self.handle_help_module(module))
return self.irc.reply(event, self.handle_help_module(module))
else:
return self.reply(connection, event, self.handle_help_detail(module, key))
return self.irc.reply(event, self.handle_help_detail(module, key))
def handle_help_descriptions(self):
"""print the general help"""

View File

@ -72,25 +72,25 @@ class IrcAdmin(Module):
whats = what.split(' ')
if whats[0] == '!join' and admin_unlocked and len(whats) >= 2:
return self.reply(connection, event, self.sub_join_channel(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_join_channel(connection, event, nick, userhost, what, admin_unlocked))
elif whats[0] == '!part' and admin_unlocked and len(whats) >= 2:
return self.reply(connection, event, self.sub_part_channel(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_part_channel(connection, event, nick, userhost, what, admin_unlocked))
elif whats[0] == '!quit' and admin_unlocked:
return self.reply(connection, event, self.sub_quit_irc(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_quit_irc(connection, event, nick, userhost, what, admin_unlocked))
elif whats[0] == '!autojoin' and admin_unlocked and len(whats) >= 3:
return self.reply(connection, event, self.sub_autojoin_manipulate(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_autojoin_manipulate(connection, event, nick, userhost, what, admin_unlocked))
elif whats[0] == '!save' and admin_unlocked:
self.irc.save_modules()
self.irc.save_config()
return self.reply(connection, event, 'Saved.')
return self.irc.reply(event, 'Saved.')
elif whats[0] == '!nick' and admin_unlocked and len(whats) >= 2:
return self.reply(connection, event, self.sub_change_nick(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_change_nick(connection, event, nick, userhost, what, admin_unlocked))
elif whats[0] == '!load' and admin_unlocked and len(whats) >= 2:
return self.reply(connection, event, self.sub_load_module(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_load_module(connection, event, nick, userhost, what, admin_unlocked))
elif whats[0] == '!unload' and admin_unlocked and len(whats) >= 2:
return self.reply(connection, event, self.sub_unload_module(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_unload_module(connection, event, nick, userhost, what, admin_unlocked))
elif whats[0] == '!modules':
return self.reply(connection, event, self.sub_list_modules(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.sub_list_modules(connection, event, nick, userhost, what, admin_unlocked))
def sub_join_channel(self, connection, event, nick, userhost, what, admin_unlocked):
whats = what.split(' ')

View File

@ -94,11 +94,11 @@ class Karma(Module):
self.handle_karma_change(connection, nick, userhost, what)
if (self.queryre.search(what)):
return self.reply(connection, event, self.handle_karma_query(connection, nick, userhost, what))
return self.irc.reply(event, self.handle_karma_query(connection, nick, userhost, what))
elif (self.statre.search(what)):
return self.reply(connection, event, self.handle_stat_query(connection, nick, userhost, what))
return self.irc.reply(event, self.handle_stat_query(connection, nick, userhost, what))
elif (self.reportre.search(what)):
return self.reply(connection, event, self.handle_report_query(connection, nick, userhost, what))
return self.irc.reply(event, self.handle_report_query(connection, nick, userhost, what))
def handle_karma_change(self, connection, nick, userhost, what):
"""

View File

@ -167,10 +167,10 @@ class Markov(Module):
target = event.target()
if self.learnre.search(what):
return self.reply(connection, event, self.markov_learn(connection, event, nick,
return self.irc.reply(event, self.markov_learn(connection, event, nick,
userhost, what, admin_unlocked))
elif self.replyre.search(what) and not self.shut_up:
return self.reply(connection, event, self.markov_reply(connection, event, nick,
return self.irc.reply(event, self.markov_reply(connection, event, nick,
userhost, what, admin_unlocked))
if not self.shut_up:
@ -181,12 +181,12 @@ class Markov(Module):
if addressed_re.match(what):
# i was addressed directly, so respond, addressing the speaker
self.lines_seen.append(('.self.said.', datetime.now()))
return self.reply(connection, event, '{0:s}: {1:s}'.format(nick,
return self.irc.reply(event, '{0:s}: {1:s}'.format(nick,
self._generate_line(target, line=addressed_re.match(what).group(1))))
else:
# i wasn't addressed directly, so just respond
self.lines_seen.append(('.self.said.', datetime.now()))
return self.reply(connection, event, '{0:s}'.format(self._generate_line(target, line=what)))
return self.irc.reply(event, '{0:s}'.format(self._generate_line(target, line=what)))
def markov_learn(self, connection, event, nick, userhost, what, admin_unlocked):
"""Learn one line, as provided to the command."""

View File

@ -104,11 +104,11 @@ class Pi(Module):
db.rollback()
self.log.error("database error doing pi stuff")
self.log.exception(e)
return self.reply(connection, event,
return self.irc.reply(event,
"database error while estimating pi: {0:s}".format(str(e)))
finally: cur.close()
return self.reply(connection, event,
return self.irc.reply(event,
"({0:.10f}, {1:.10f}) is {2}within the unit circle. "\
"pi is {5:.10f}. (i:{3:d} p:{4:d})".format(x, y,
"" if inside else "not ",

View File

@ -73,7 +73,7 @@ class Radio(Module):
"""Handle commands and inputs from IRC events."""
if self.statusre.search(what):
return self.reply(connection, event, self.get_status())
return self.irc.reply(event, self.get_status())
def get_status(self):
"""Get the status (playlist entries, mostly) of the MPD server."""

View File

@ -91,9 +91,9 @@ class Seen(Module):
if result:
seentime = result['time'].replace(tzinfo=tzlocal())
replystr = 'last saw {0:s} in {3:s} at {1:s} saying \'{2:s}\'.'.format(result['nick'], seentime.astimezone(tzlocal()).strftime('%Y/%m/%d %H:%M:%S %Z'), result['what'], result['location'])
return self.reply(connection, event, replystr)
return self.irc.reply(event, replystr)
else:
return self.reply(connection, event, 'i have not seen {0:s} in {1:s}.'.format(nick, where))
return self.irc.reply(event, 'i have not seen {0:s} in {1:s}.'.format(nick, where))
except mdb.Error as e:
db.rollback()
self.log.error("database error retrieving seen data")

View File

@ -172,23 +172,23 @@ class Storycraft(Module):
"""Pass storycraft control commands to the appropriate method based on input."""
if self.statusre.search(what):
return self.reply(connection, event, self.storycraft_status(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_status(connection, event, nick, userhost, what, admin_unlocked))
elif self.newgamere.search(what):
return self.reply(connection, event, self.storycraft_newgame(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_newgame(connection, event, nick, userhost, what, admin_unlocked))
elif self.joingamere.search(what):
return self.reply(connection, event, self.storycraft_joingame(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_joingame(connection, event, nick, userhost, what, admin_unlocked))
elif self.listgamesre.search(what):
return self.reply(connection, event, self.storycraft_listgames(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_listgames(connection, event, nick, userhost, what, admin_unlocked))
elif self.startgamere.search(what):
return self.reply(connection, event, self.storycraft_startgame(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_startgame(connection, event, nick, userhost, what, admin_unlocked))
elif self.showlinere.search(what):
return self.reply(connection, event, self.storycraft_showline(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_showline(connection, event, nick, userhost, what, admin_unlocked))
elif self.addlinere.search(what):
return self.reply(connection, event, self.storycraft_addline(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_addline(connection, event, nick, userhost, what, admin_unlocked))
elif self.gamestatusre.search(what):
return self.reply(connection, event, self.storycraft_gamestatus(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_gamestatus(connection, event, nick, userhost, what, admin_unlocked))
elif self.exportre.search(what):
return self.reply(connection, event, self.storycraft_export(connection, event, nick, userhost, what, admin_unlocked))
return self.irc.reply(event, self.storycraft_export(connection, event, nick, userhost, what, admin_unlocked))
def storycraft_status(self, connection, event, nick, userhost, what, admin_unlocked):
"""Print information about the storycraft games, or one specific game."""

View File

@ -35,15 +35,15 @@ class TextTransform(Module):
reply = ['']
if self.rot13(what, reply):
return self.reply(connection, event, reply[0])
return self.irc.reply(event, reply[0])
elif self.base64(what, reply):
return self.reply(connection, event, reply[0])
return self.irc.reply(event, reply[0])
elif self.upper(what, reply):
return self.reply(connection, event, reply[0])
return self.irc.reply(event, reply[0])
elif self.lower(what, reply):
return self.reply(connection, event, reply[0])
return self.irc.reply(event, reply[0])
elif self.al_bhed(what, reply):
return self.reply(connection, event, reply[0])
return self.irc.reply(event, reply[0])
def rot13(self, what, reply):
"""

View File

@ -128,22 +128,22 @@ class Twitter(Module):
"""Attempt to do twitter things."""
if self.getstatusre.search(what):
return self.reply(connection, event, self.twitter_getstatus(connection, event, nick,
return self.irc.reply(event, self.twitter_getstatus(connection, event, nick,
userhost, what, admin_unlocked))
elif self.getuserstatusre.search(what):
return self.reply(connection, event, self.twitter_getuserstatus(connection, event, nick,
return self.irc.reply(event, self.twitter_getuserstatus(connection, event, nick,
userhost, what, admin_unlocked))
elif self.tweetre.search(what):
return self.reply(connection, event, self.twitter_tweet(connection, event, nick,
return self.irc.reply(event, self.twitter_tweet(connection, event, nick,
userhost, what, admin_unlocked))
elif self.replytore.search(what):
return self.reply(connection, event, self.twitter_replyto(connection, event, nick,
return self.irc.reply(event, self.twitter_replyto(connection, event, nick,
userhost, what, admin_unlocked))
elif self.gettokenre.search(what):
return self.reply(connection, event, self.twitter_gettoken(connection, event, nick,
return self.irc.reply(event, self.twitter_gettoken(connection, event, nick,
userhost, what, admin_unlocked))
elif self.authre.search(what):
return self.reply(connection, event, self.twitter_auth(connection, event, nick,
return self.irc.reply(event, self.twitter_auth(connection, event, nick,
userhost, what, admin_unlocked))
def twitter_getstatus(self, connection, event, nick, userhost, what, admin_unlocked):

View File

@ -80,15 +80,15 @@ class Weather(Module):
if queryitems[0] == "conditions":
# current weather query
results = self.get_conditions_for_query(queryitems[1:])
return self.reply(connection, event, results)
return self.irc.reply(event, results)
elif queryitems[0] == "forecast":
# forecast query
results = self.get_forecast_for_query(queryitems[1:])
return self.reply(connection, event, results)
return self.irc.reply(event, results)
else:
# assume they wanted current weather
results = self.get_conditions_for_query(queryitems)
return self.reply(connection, event, results)
return self.irc.reply(event, results)
def get_conditions_for_query(self, queryitems):
"""Make a wunderground conditions call, return as string."""