From 3a72445779b6a642206c2e2140a1d85be9b2c483 Mon Sep 17 00:00:00 2001 From: jcao219 Date: Thu, 7 Jul 2011 14:49:30 -0500 Subject: [PATCH] simplified the irc client --- oyoyo/client.py | 18 +++++-- oyoyo/cmdhandler.py | 124 -------------------------------------------- wolfbot.py | 63 +++++++++++----------- 3 files changed, 45 insertions(+), 160 deletions(-) delete mode 100644 oyoyo/cmdhandler.py diff --git a/oyoyo/client.py b/oyoyo/client.py index 486e978..37d2fd8 100644 --- a/oyoyo/client.py +++ b/oyoyo/client.py @@ -19,7 +19,6 @@ import logging import socket from oyoyo.parse import parse_raw_irc_command -from oyoyo.cmdhandler import CommandError class IRCClientError(Exception): pass @@ -71,7 +70,7 @@ class IRCClient(object): self.blocking = True self.__dict__.update(kwargs) - self.command_handler = cmd_handler(self) + self.command_handler = cmd_handler self._end = 0 @@ -146,9 +145,20 @@ class IRCClient(object): for el in data: prefix, command, args = parse_raw_irc_command(el) - + logging.debug("processCommand {0}({1})".format(command, + [arg.decode('utf_8') + for arg in args + if isinstance(arg, bytes)])) try: - self.command_handler.run(command, prefix, *args) + largs = list(args) + if prefix: + largs.insert(0, prefix) + for i,arg in enumerate(largs): + if arg: largs[i] = arg.decode('utf_8') + if command in self.command_handler: + self.command_handler[command](self, *largs) + elif "" in self.command_handler: + self.command_handler[""](self, command, *largs) except CommandError: # error will of already been logged by the handler pass diff --git a/oyoyo/cmdhandler.py b/oyoyo/cmdhandler.py deleted file mode 100644 index 2f500e7..0000000 --- a/oyoyo/cmdhandler.py +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (c) 2008 Duncan Fordyce -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -import logging -import sys -import traceback - -from oyoyo.parse import parse_nick - -def protected(func): - """ decorator to protect functions from being called """ - func.protected = True - return func - - -class CommandError(Exception): - def __init__(self, cmd): - self.cmd = cmd - -class NoSuchCommandError(CommandError): - def __str__(self): - return 'No such command "{0}"'.format(".".join(self.cmd)) - -class ProtectedCommandError(CommandError): - def __str__(self): - return 'Command "{0}" is protected'.format(".".join(self.cmd)) - - -class CommandHandler(object): - """ The most basic CommandHandler """ - - def __init__(self, client): - self.client = client - - @protected - def get(self, in_command_parts): - """ finds a command - commands may be dotted. each command part is checked that it does - not start with and underscore and does not have an attribute - "protected". if either of these is true, ProtectedCommandError - is raised. - its possible to pass both "command.sub.func" and - ["command", "sub", "func"]. - """ - - if isinstance(in_command_parts, bytes): - in_command_parts = in_command_parts.split(b'.') - else: - in_command_parts = in_command_parts.split('.') - - command_parts = [] - for cmdpart in in_command_parts: - if isinstance(cmdpart, bytes): - cmdpart = cmdpart.decode('utf_8') - command_parts.append(cmdpart) - - p = self - while command_parts: - cmd = command_parts.pop(0) - if cmd.startswith('_'): - raise ProtectedCommandError(in_command_parts) - - try: - f = getattr(p, cmd) - except AttributeError: - raise NoSuchCommandError(in_command_parts) - - if hasattr(f, 'protected'): - raise ProtectedCommandError(in_command_parts) - - if isinstance(f, CommandHandler) and command_parts: - return f.get(command_parts) - p = f - - return f - - @protected - def run(self, command, *args): - """ finds and runs a command """ - logging.debug("processCommand {0}({1})".format(command, - [arg.decode('utf_8') - for arg in args - if isinstance(arg, bytes)])) - - try: - f = self.get(command) - except NoSuchCommandError: - self.__unhandled__(command, *args) - return - - logging.debug('f {0}'.format(f)) - try: - largs = list(args) - for i,arg in enumerate(largs): - if arg: largs[i] = arg.decode('utf_8') - f(*largs) - self.__unhandled__(command, *args) - except Exception as e: - logging.error('command raised {0}'.format(e)) - logging.error(traceback.format_exc()) - raise CommandError(command) - - @protected - def __unhandled__(self, cmd, *args): - """The default handler for commands. Override this method to - apply custom behavior (example, printing) unhandled commands. - """ - logging.debug('Unhandled command {0}({1})'.format(cmd, [arg.decode('utf_8') - for arg in args - if isinstance(arg, bytes)])) diff --git a/wolfbot.py b/wolfbot.py index d4ee833..2a80725 100644 --- a/wolfbot.py +++ b/wolfbot.py @@ -1,45 +1,44 @@ from oyoyo.client import IRCClient -from oyoyo.cmdhandler import CommandHandler, protected from oyoyo.parse import parse_nick import logging import botconfig import wolfgame -class WolfBotHandler(CommandHandler): - def __init__(self, client): - super().__init__(client) - - def privmsg(self, rawnick, chan, msg): - if chan != botconfig.NICK: #not a PM - for x in wolfgame.COMMANDS.keys(): - if msg.lower().startswith(x): - h = msg[len(x):] - if not h or h[0] == " " or not x: - wolfgame.COMMANDS[x](self.client, rawnick, chan, h.lstrip()) - else: - for x in wolfgame.PM_COMMANDS.keys(): - if msg.lower().startswith(x): - h = msg[len(x):] - if not h or h[0] == " " or not x: - wolfgame.PM_COMMANDS[x](self.client, rawnick, h.lstrip()) +def on_privmsg(cli, rawnick, chan, msg): + if chan != botconfig.NICK: #not a PM + for x in wolfgame.COMMANDS.keys(): + if msg.lower().startswith(x): + h = msg[len(x):] + if not h or h[0] == " " or not x: + wolfgame.COMMANDS[x](cli, rawnick, chan, h.lstrip()) + else: + for x in wolfgame.PM_COMMANDS.keys(): + if msg.lower().startswith(x): + h = msg[len(x):] + if not h or h[0] == " " or not x: + wolfgame.PM_COMMANDS[x](cli, rawnick, h.lstrip()) - @protected - def __unhandled__(self, cmd, *args): - if cmd in wolfgame.HOOKS.keys(): - largs = list(args) - for i,arg in enumerate(largs): - if isinstance(arg, bytes): largs[i] = arg.decode('ascii') - wolfgame.HOOKS[cmd](self.client, *largs) - else: - logging.debug('Unhandled command {0}({1})'.format(cmd, [arg.decode('utf_8') - for arg in args - if isinstance(arg, bytes)])) +def __unhandled__(cli, cmd, *args): + if cmd in wolfgame.HOOKS.keys(): + largs = list(args) + for i,arg in enumerate(largs): + if isinstance(arg, bytes): largs[i] = arg.decode('ascii') + wolfgame.HOOKS[cmd](cli, *largs) + else: + logging.debug('Unhandled command {0}({1})'.format(cmd, [arg.decode('utf_8') + for arg in args + if isinstance(arg, bytes)])) def main(): logging.basicConfig(level=logging.DEBUG) - cli = IRCClient(WolfBotHandler, host=botconfig.HOST, port=botconfig.PORT, nickname=botconfig.NICK, - connect_cb=wolfgame.connect_callback) - + cli = IRCClient( + {"privmsg":on_privmsg, + "":__unhandled__}, + host=botconfig.HOST, + port=botconfig.PORT, + nickname=botconfig.NICK, + connect_cb=wolfgame.connect_callback + ) cli.mainLoop()