Skip to content

Instantly share code, notes, and snippets.

@adnissen
Created May 6, 2013 00:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adnissen/5522785 to your computer and use it in GitHub Desktop.
Save adnissen/5522785 to your computer and use it in GitHub Desktop.
custom handlers.py
# -*- 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