Permalink
Browse files

Fixes a lot of ugly warts in my plugin reimplementation

  • Loading branch information...
1 parent 2d07664 commit a4d5699e7041085a59ce4dd9cc3a8fd1e134261b @DrMegahertz DrMegahertz committed Dec 2, 2010
Showing with 46 additions and 37 deletions.
  1. +11 −18 ircbot.py
  2. +29 −18 plugins/__init__.py
  3. +1 −1 plugins/dice.py
  4. +5 −0 plugins/load.py
View
@@ -1,14 +1,10 @@
-# -*- coding: utf-8 -*-
-
-import sys, os
-from copy import copy
-
from twisted.words.protocols import irc
-from twisted.internet import reactor, protocol, threads
+from twisted.internet import reactor, protocol
from plugins import Plugin
import settings
+
class IRCBot(irc.IRCClient):
nickname = settings.NICKNAME
@@ -19,7 +15,8 @@ def signedOn(self):
self.join(self.factory.channel)
def privmsg(self, user, channel, msg):
- """Handle incomming messages.
+ """
+ Handle incoming privmsgs.
If starting with a prefix, check for matching command and run!
"""
@@ -30,20 +27,15 @@ def privmsg(self, user, channel, msg):
cmd = args.pop(0)
# Search plugins for commands
- module_method = Plugin.commands.get(cmd, None)
+ method = Plugin.commands.get(cmd, None)
- if not module_method:
+ if not method:
return
- module, method = module_method.split('.')
-
- method = getattr(Plugin.library[module], method, None)
-
- if method and callable(method):
- result = method(*args)
+ result = method(*args)
- if result:
- self.say(channel, result)
+ if result:
+ self.say(channel, result)
def handleCommand(self, command, prefix, params):
@@ -68,7 +60,8 @@ def __init__(self, channel, prefix):
self.prefix = prefix
def startFactory(self):
- Plugin.autoload()
+ for plugin in settings.PLUGINS:
+ Plugin.load(plugin)
protocol.ClientFactory.startFactory(self)
View
@@ -1,4 +1,5 @@
import imp
+import inspect
import settings
@@ -12,49 +13,59 @@ def __init__(cls, name, bases, attrs):
type.__init__(cls, name, bases, attrs)
- def __repr__(cls):
- cls.__name__
-
class Plugin(object):
__metaclass__ = PluginLibrary
commands = {}
- def __repr__(self):
- return '{0}()'.format(self.__class__)
-
- @classmethod
- def autoload(cls):
- for plugin in settings.PLUGINS:
- cls.load(plugin)
-
@classmethod
def load(cls, name):
fp, pathname, description = imp.find_module(name, ['plugins'])
try:
imp.load_module(name, fp, pathname, description)
+
+ # Collect the methods that's marked as commands
+ for name, obj in inspect.getmembers(cls.library[name]):
+ if not name.startswith('_') and inspect.ismethod(obj):
+ if hasattr(obj, 'command'):
+ commands = [obj.command] + obj.aliases
+
+ for command in commands:
+ cls.commands[command] = obj
+
finally:
if fp:
fp.close()
@classmethod
- def reload(cls, name):
+ def unload(cls, name):
+ plugin = cls.library[name]
+
+ commands_to_unload = []
+ for command, method in cls.commands.iteritems():
+ if method.im_self is plugin:
+ commands_to_unload.append(command)
+
+ for command in commands_to_unload:
+ del cls.commands[command]
+
del cls.library[name]
+
+
+ @classmethod
+ def reload(cls, name):
+ cls.unload(name)
cls.load(name)
def command(func=None, name='', aliases=None):
if aliases is None:
aliases = []
def decorator(func):
- module_method = '%s.%s' % (func.__module__, func.__name__)
-
- for alias in aliases:
- Plugin.commands[alias] = module_method
-
- Plugin.commands[name or func.__name__] = module_method
+ func.command = name or func.__name__
+ func.aliases = aliases
return func
View
@@ -19,6 +19,6 @@ def roll(self, dice):
'''
multiplier, sides = (int(x) for x in dice.split('d'))
- result = random.choice(range(multiplier, multiplier * sides + 1))
+ result = random.choice(xrange(multiplier, multiplier * sides + 1))
return result
View
@@ -1,11 +1,16 @@
from plugins import Plugin, command
+
class LoadPlugin(Plugin):
@command
def load(self, name):
Plugin.load(name)
@command
+ def unload(self, name):
+ Plugin.unload(name)
+
+ @command
def reload(self, name):
if name == 'all':
for module in Plugin.library:

0 comments on commit a4d5699

Please sign in to comment.