diff --git a/hamper/commander.py b/hamper/commander.py index 5be03c6..d87a07d 100644 --- a/hamper/commander.py +++ b/hamper/commander.py @@ -5,7 +5,8 @@ from twisted.words.protocols import irc from twisted.internet import protocol, reactor - +import sqlalchemy +from sqlalchemy import orm from bravo.plugin import retrieve_plugins from hamper.interfaces import IPlugin @@ -110,6 +111,7 @@ def privmsg(self, user, channel, msg): self.factory.registerPlugin(p) def connectionLost(self, reason): + self.factory.db.commit() reactor.stop() def say(self, msg): @@ -131,12 +133,11 @@ class CommanderFactory(protocol.ClientFactory): protocol = CommanderProtocol - def __init__(self, channel, nickname): - self.channel = channel - self.nickname = nickname + def __init__(self, config): + self.channel = config['channel'] + self.nickname = config['nickname'] self.history = {} - self.plugins = [] # These are so plugins can be added/removed at run time. The # addition/removal will happen at a time when the list isn't being @@ -144,6 +145,15 @@ def __init__(self, channel, nickname): self.pluginsToAdd = [] self.pluginsToRemove = [] + if 'db' in config: + print('Loading db from config: ' + config['db']) + self.db_engine = sqlalchemy.create_engine(config['db']) + else: + print('Using in-memory db') + self.db_engine = sqlalchemy.create_engine('sqlite:///:memory:') + DBSession = orm.sessionmaker(self.db_engine) + self.db = DBSession() + for _, plugin in retrieve_plugins(IPlugin, 'hamper.plugins').items(): self.registerPlugin(plugin) @@ -157,6 +167,7 @@ def registerPlugin(self, plugin): """ Registers a plugin. """ + plugin.setup(self) self.plugins.append(plugin) self.plugins.sort() print 'registered plugin', plugin.name diff --git a/hamper/interfaces.py b/hamper/interfaces.py index 4d8c300..e170e7b 100644 --- a/hamper/interfaces.py +++ b/hamper/interfaces.py @@ -9,6 +9,11 @@ class IPlugin(Interface): name = Attribute('Human readable name for the plugin.') priority = Attribute('Priority of plugins. High numbers are called first') + def setup(factory): + """ + Called when the factory loads the plugin. + """ + def process(bot, comm): """ Called when a matching message comes in to the bot. @@ -34,6 +39,9 @@ def __init__(self): opts = 0 if self.caseSensitive else re.I self.regex = re.compile(self.regex, opts) + def setup(self, factory): + pass + def process(self, bot, comm): if self.onlyDirected and not comm['directed']: return @@ -42,5 +50,5 @@ def process(self, bot, comm): self.command(bot, comm, match.groups()) return True - def command(self, comm, groups): + def command(self, bot, comm, groups): pass diff --git a/hamper/plugins/friendly.py b/hamper/plugins/friendly.py index dd14a94..3705d9a 100644 --- a/hamper/plugins/friendly.py +++ b/hamper/plugins/friendly.py @@ -14,7 +14,7 @@ class Friendly(object): name = 'friendly' priority = 2 - def __init__(self): + def setup(self, factory): self.greetings = ['hi', 'hello', 'hey'] def process(self, bot, comm): @@ -36,8 +36,9 @@ class OmgPonies(object): cooldown = 30 #seconds - def __init__(self): + def setup(self, factory): self.last_pony_time = datetime.now() + pass def process(self, bot, comm): if re.match(r'.*pon(y|ies).*', comm['message'], re.I): diff --git a/hamper/plugins/quote.py b/hamper/plugins/quote.py new file mode 100644 index 0000000..6aa2836 --- /dev/null +++ b/hamper/plugins/quote.py @@ -0,0 +1,67 @@ +from datetime import datetime +import random + +from zope.interface import implements +from sqlalchemy import Integer, String, Date, Column +from sqlalchemy.ext.declarative import declarative_base +import sqlalchemy + +from hamper.interfaces import Command + + +SQLAlchemyBase = declarative_base() + +class Quotes(Command): + '''Remember quotes, and recall on demand.''' + + name = 'quotes' + priority = 0 + regex = r'^quotes?(?: +(.*))?$' + + def setup(self, factory): + SQLAlchemyBase.metadata.create_all(factory.db_engine) + + def command(self, bot, comm, groups): + if groups[0]: + args = groups[0].split(' ') + args = [a.strip() for a in args if a.strip()] + else: + args = [] + + if len(args) == 0: + # Deliver a quote + index = random.randrange(0, bot.db.query(Quote).count() + 1) + quote = bot.factory.db.query(Quote)[index] + # Lame twisted irc doesn't support unicode. + bot.say(str(quote.text)) + elif args[0] == '--args': + # Add a quote + text = ' '.join(args[1:]) + quote = Quote(text, comm['user']) + bot.factory.db.add(quote) + bot.say('Succesfully added quote.') + elif args[0] == '--count': + bot.say('I know {0} quotes.'.format(bot.db.query(Quote).count())) + else: + bot.say('Wait, what?') + + +class Quote(SQLAlchemyBase): + '''The object that will get persisted by the database.''' + + __tablename__ = 'quotes' + + id = Column(Integer, primary_key=True) + text = Column(String) + adder = Column(String) + added = Column(Date) + + def __init__(self, text, adder, added=None): + if not added: + added = datetime.now() + + self.text = text + self.adder = adder + self.added = added + +quotes = Quotes() diff --git a/scripts/hamper b/scripts/hamper index fcd45fc..bdd9af6 100644 --- a/scripts/hamper +++ b/scripts/hamper @@ -19,5 +19,5 @@ if __name__ == '__main__': sys.exit(); reactor.connectTCP(config['server'], config['port'], - CommanderFactory(config['channel'], config['nickname'])) + CommanderFactory(config)) reactor.run()