Permalink
Browse files

Make hamper auto find and load plugins.

  • Loading branch information...
1 parent 27cd282 commit 9f773bddbf0bb576b22a7dce7c657cac1bfe33c1 @mythmon mythmon committed Jul 16, 2011
Showing with 58 additions and 32 deletions.
  1. +20 −0 hamper/IHamper.py
  2. +13 −7 hamper/commander.py
  3. +0 −1 hamper/main.py
  4. 0 hamper/plugins/__init__.py
  5. +25 −24 hamper/{ → plugins}/commands.py
View
20 hamper/IHamper.py
@@ -0,0 +1,20 @@
+from zope.interface import implements, Interface, Attribute
+
+
+class ICommand(Interface):
+ """Interface for a command.."""
+
+ name = Attribute('Human readable name for the plugin.')
+ onlyDirected = Attribute('Only respond to messages directed at the bot.')
+ caseSensitive = Attribute('Compile the regex to be caseSensitive if True.')
+ regex = Attribute('What messages the command will be called for.')
+ priority = Attribute('Higher numbers are called first.')
+
+ def __call__(commander, options):
+ """
+ Called when a matching message comes in to the bot.
+
+ Return `True` if the next command should be called, when there are
+ multiple commands with the same priority. Returning `False` or not
+ returing a value will cause execution to stop.
+ """
View
20 hamper/commander.py
@@ -6,6 +6,10 @@
from twisted.words.protocols import irc
from twisted.internet import protocol, reactor
+from bravo.plugin import retrieve_plugins
+
+from hamper.IHamper import ICommand
+
class CommanderProtocol(irc.IRCClient):
"""Runs the IRC interactions, and calls out to plugins."""
@@ -71,25 +75,27 @@ def say(self, msg):
class CommanderFactory(protocol.ClientFactory):
protocol = CommanderProtocol
- commands = set()
def __init__(self, channel, nickname):
self.channel = channel
self.nickname = nickname
self.history = {}
+ self.commands = set()
+ for _, plugin in retrieve_plugins(ICommand, 'hamper.plugins').items():
+ self.registerCommand(plugin)
+
def clientConnectionLost(self, connector, reason):
print "Lost connection (%s)." % (reason)
def clientConnectionFailed(self, connector, reason):
print "Could not connect: %s" % (reason,)
- @classmethod
- def registerCommand(cls, Command):
+ def registerCommand(self, command):
"""Register a command. To be used as a decorator."""
- options = re.I if not Command.caseSensitive else None
- Command.regex = re.compile(Command.regex, options)
+ options = re.I if not command.caseSensitive else None
+ command.regex = re.compile(command.regex, options)
- cls.commands.add(Command())
- print 'registered', Command
+ self.commands.add(command)
+ print 'registered', command
View
1 hamper/main.py
@@ -4,7 +4,6 @@
from twisted.words.protocols import irc
from twisted.internet import protocol, reactor
-from hamper import commands
from hamper.commander import CommanderFactory
View
0 hamper/plugins/__init__.py
No changes.
View
49 hamper/commands.py → hamper/plugins/commands.py
@@ -2,29 +2,14 @@
from zope.interface import implements, Interface, Attribute
-from hamper.commander import CommanderFactory
-
-class ICommand(Interface):
- """Interface for a command.."""
-
- onlyDirected = Attribute('Only respond to messages directed at the bot.')
- caseSensitive = Attribute('Compile the regex to be caseSensitive if True.')
- regex = Attribute('What messages the command will be called for.')
- priority = Attribute('Higher numbers are called first.')
-
- def __call__(self, commander, options):
- """
- Called when a matching message comes in to the bot.
-
- Return `True` if the next command should be called, when there are
- multiple commands with the same priority. Returning `False` or not
- returing a value will cause execution to stop.
- """
+from hamper.IHamper import ICommand
class Command(object):
+
implements(ICommand)
+ name = 'Generic Command'
onlyDirected = True
caseSensitive = False
regex = ''
@@ -33,37 +18,45 @@ class Command(object):
def __call__(self, commander, options):
return True
-@CommanderFactory.registerCommand
class FriendlyCommand(Command):
+ implements(ICommand)
+
+ name = 'Friendly'
regex = 'hi'
def __call__(self, commander, options):
commander.say('Hello {0[user]}'.format(options))
-@CommanderFactory.registerCommand
class QuitCommand(Command):
+ implements(ICommand)
+
+ name = 'Quit'
regex = 'go away'
def __call__(self, commander, options):
commander.say('Bye!')
commander.quit()
-@CommanderFactory.registerCommand
class OmgPonies(Command):
+ implements(ICommand)
+
+ name = 'OMG!!! Ponies!!!'
regex = r'.*pon(y|ies).*'
onlyDirected = False
def __call__(self, commander, options):
- commander.say('OMG PONIES!!!')
+ commander.say('OMG!!! PONIES!!!')
-@CommanderFactory.registerCommand
class Sed(Command):
+ implements(ICommand)
+
+ name = 'sed'
regex = r'^!s/(.*)/(.*)/(g?i?)'
onlyDirected = False
priority = -1
@@ -81,9 +74,11 @@ def __call__(self, commander, options):
.format(comm['user'], new_msg))
break;
-@CommanderFactory.registerCommand
class LetMeGoogleThatForYou(Command):
+ implements(ICommand)
+
+ name = 'lmgtfy'
regex = '.*lmgtfy\s+(.*)'
onlyDirected = False
@@ -92,3 +87,9 @@ def __call__(self, commander, options):
if options['target']:
target = options['target'] + ': '
commander.say(target + 'http://lmgtfy.com/?q=' + options['groups'][0])
+
+lmgtfy = LetMeGoogleThatForYou()
+sed = Sed()
+omgponies = OmgPonies()
+quit = QuitCommand()
+hi = FriendlyCommand()

0 comments on commit 9f773bd

Please sign in to comment.