Created
May 6, 2013 00:58
-
-
Save adnissen/5522785 to your computer and use it in GitHub Desktop.
custom handlers.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" | |
Handler class for processing built-in commands and delegating messages. | |
""" | |
from __future__ import absolute_import, division, unicode_literals | |
import re | |
import logging | |
from random import choice | |
import shlex | |
from inspect import getmembers, ismethod | |
from sevabot.bot import modules | |
from sevabot.utils import ensure_unicode | |
logger = logging.getLogger('sevabot') | |
class CommandHandler: | |
"""A handler for processing built-in commands and delegating messages to reloadable modules. | |
""" | |
def __init__(self, sevabot): | |
self.sevabot = sevabot | |
self.calls = {} | |
self.cache_builtins() | |
def cache_builtins(self): | |
"""Scan all built-in commands defined in this handler. | |
""" | |
def wanted(member): | |
return ismethod(member) and member.__name__.startswith('builtin_') | |
self.builtins = {} | |
for member in getmembers(self, wanted): | |
command_name = re.split('^builtin_', member[0])[1] | |
self.builtins[command_name] = member[1] | |
logger.info('Built-in command {} is available.'.format(command_name)) | |
def handle(self, msg, status): | |
"""Handle command messages. | |
""" | |
# If you are talking to yourself when testing | |
# Ignore non-sent messages (you get both SENDING and SENT events) | |
if status == "SENDING": | |
return | |
# Some Skype clients (iPad?) | |
# double reply to the chat messages with some sort of ACK by | |
# echoing them back | |
# and we need to ignore them as they are not real chat messages | |
# and not even displayed in chat UI | |
if status == "READ": | |
return | |
# Check all stateful handlers | |
for handler in modules.get_message_handlers(): | |
processed = handler(msg, status) | |
if processed: | |
# Handler processed the message | |
return | |
# We need utf-8 for shlex | |
body = ensure_unicode(msg.Body).encode('utf-8') | |
logger.debug(u"Processing message, body %s" % msg.Body) | |
# shlex dies on unicode on OSX with null bytes all over the string | |
try: | |
words = shlex.split(body, comments=False, posix=True) | |
except ValueError: | |
# ValueError: No closing quotation | |
return | |
words = [word.decode('utf-8') for word in words] | |
responses = ["Guess who has a boner! :D", "Gotta love me!", "woah hey woah", "T҉́o i̛͜n͠vo҉҉k̕e̷͘̕ t̵̨h̢̕é͞ h̸͡͝í͟v͏̴e̵͏-̴̨m̕i͟n͘d͢ ͟r̀͡e͜pr̴͜ę̶͜s͝e͜n̵ţ̶͢i͟n̷ģ̕͡ ͝c̵h͟a̷ò̢s.̧̨͘In̡vók̵in͏g ͏t̶͏he̵̢ ̵̛f̵͟͟eeĺ҉i̴͡n̷͟g̷̶̕ ̶̶ơ͢f͢҉ ̨̧ch̵̛͝a̛o̷͡s͟҉͞.̀͟W̢i̶̢͢t̶h ͟҉̛o̴̴̵u̵̧ţ̶̶ ̷o̴̡r̷̴̵ḑ̶e̕r̨.͏̵T̷h͢e͟͝ ̕N̸̨͡e͏̡z̵p͏̷erd̵͝i͝à̕n͞ ̸͘h̶i̛v͢͞è͞-m͜i̶n̸͡͠d̢̛ ̢҉̕of ̷̡̀c̵͞h̨͠a̛͝҉o͜s̷̶.҉ ̡Z̶a͏̶͡l̨̕͜g̨o͏.͘ ̛̀͠H͏e ̷̕ẁh͜o ̸҉̕W̵a͢͡i̵ts͏ ͏͜B̷͢ę͘͢hin̢͞ḑ̀ ̵͟T̴he͜ ̷̛Ẃ̡a̸ĺl̨͘͢.ZAL҉̨҉G͞O̵͜!͏"] | |
for word in words: | |
if word == "nerdbot": | |
msg.Chat.SendMessage(choice(responses)) | |
elif word == "420": | |
msg.Chat.SendMessage("time to blaze up (smoking)") | |
elif word == "??": | |
msg.Chat.SendMessage("?¿?HELP I AM SO CONFUSED?¿?") | |
if len(words) < 1: | |
return | |
command_name = words[0] | |
command_args = words[1:] | |
# Beyond this point we process script commands only | |
if not command_name.startswith('.'): | |
return | |
command_name = command_name[1:] | |
script_module = modules.get_script_module(command_name) | |
if command_name in self.builtins: | |
# Execute a built-in command | |
logger.debug('Executing built-in command {}: {}'.format(command_name, command_args)) | |
self.builtins[command_name](command_args, msg, status) | |
elif script_module: | |
# Execute a module asynchronously | |
def callback(output): | |
msg.Chat.SendMessage(output) | |
script_module.run(msg, command_args, callback) | |
else: | |
msg.Chat.SendMessage("Whatever you just typed in isn't a real thing.") | |
def builtin_reload(self, args, msg, status): | |
"""Reload command modules. | |
""" | |
commands = modules.load_modules(self.sevabot) | |
msg.Chat.SendMessage('Available commands: %s' % ', '.join(commands)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment