Alias module to turn text into other text.

mostly for sending commands to the bot without addressing the bot with
bot: (and potentially triggering MegaHAL) yet also without exposing
sensitive commands to the non-addressable mode (like wtf/quit). speak
the alias and the bot will run the looked-up text through the modules,
regardless of their addressable settings
This commit is contained in:
Brian S. Stephan 2010-09-04 11:29:18 -05:00
parent bf8fe46522
commit a5dbb27622

139
modules/Alias.py Normal file
View File

@ -0,0 +1,139 @@
"""
Alias - have internal shortcuts to commands
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 <http://www.gnu.org/licenses/>.
"""
from ConfigParser import NoOptionError, NoSectionError
import re
from extlib import irclib
from Module import Module
class Alias(Module):
"""
Allows for commands to be aliased as !command, circumventing bot addressing stuff.
"""
def on_pubmsg(self, connection, event):
"""
Handle pubmsg events. Does some variable setup and initial sanity checking before
calling Module.do, which should be implemented by subclasses and what can be
ultimately responsible for the work.
Reimplemented so that the recursion stuff doesn't happen (in case we want to
write an alias that would use recursion).
"""
nick = irclib.nm_to_n(event.source())
userhost = irclib.nm_to_uh(event.source())
replypath = event.target()
what = event.arguments()[0]
admin_unlocked = False
try:
if userhost == self.config.get('dr.botzo', 'admin_userhost'):
admin_unlocked = True
except NoOptionError: pass
# only do commands if the bot has been addressed directly
addressed_pattern = '^' + connection.get_nickname() + '[:,]?\s+'
addressed_re = re.compile(addressed_pattern)
need_prefix = True
try:
need_prefix = self.config.getboolean(self.__class__.__name__, 'meta.pubmsg_needs_bot_prefix')
except NoOptionError: pass
except NoSectionError: pass
if not addressed_re.match(what) and need_prefix:
return
else:
what = addressed_re.sub('', what)
# try reloading
self.reload(connection, event, nick, userhost, replypath, what, admin_unlocked)
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
def on_privmsg(self, connection, event):
"""
Handle privmsg events. Does some variable setup and initial sanity checking before
calling Module.do, which should be implemented by subclasses and what can be
ultimately responsible for the work.
Reimplemented so that the recursion stuff doesn't happen (in case we want to
write an alias that would use recursion).
"""
nick = irclib.nm_to_n(event.source())
userhost = irclib.nm_to_uh(event.source())
replypath = nick
what = event.arguments()[0]
admin_unlocked = False
try:
if userhost == self.config.get('dr.botzo', 'admin_userhost'):
admin_unlocked = True
except NoOptionError: pass
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
"""
See if there is an alias ("!command") in the text, and if so, translate it into
an internal bot command and run it.
"""
# first see if the aliases are being directly manipulated via add/remove
whats = what.split(' ')
try:
if whats[0] == '!alias' and whats[1] == 'add' and len(whats) >= 4:
if not self.config.has_section(self.__class__.__name__):
self.config.add_section(self.__class__.__name__)
self.config.set(self.__class__.__name__, whats[2], ' '.join(whats[3:]))
replystr = 'added alias ' + whats[2]
return self.reply(connection, replypath, replystr)
if whats[0] == '!alias' and whats[1] == 'remove' and len(whats) >= 3:
if not self.config.has_section(self.__class__.__name__):
self.config.add_section(self.__class__.__name__)
if self.config.remove_option(self.__class__.__name__, whats[2]):
replystr = 'removed alias ' + whats[2]
return self.reply(connection, replypath, replystr)
except NoOptionError: pass
except NoSectionError: pass
# now that that's over, try doing alias work
try:
alias_list = self.config.options(self.__class__.__name__)
self.remove_metaoptions(alias_list)
for alias in alias_list:
alias_re = re.compile(alias)
if alias_re.match(what):
command = re.sub(alias, self.config.get(self.__class__.__name__, alias), what)
reply = self.try_recursion(connection, event, nick, userhost, None, command, admin_unlocked)
return self.reply(connection, replypath, reply)
except NoOptionError: pass
except NoSectionError: pass
# vi:tabstop=4:expandtab:autoindent
# kate: indent-mode python;indent-width 4;replace-tabs on;