1
0
Fork 0
nemubot/nemubot/modulecontext.py

146 lines
5.0 KiB
Python

# Nemubot is a smart and modulable IM bot.
# Copyright (C) 2012-2015 Mercier Pierre-Olivier
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
class ModuleContext:
def __init__(self, context, module_name, logger):
"""Initialize the module context
arguments:
context -- the bot context
module_name -- the module name
logger -- a logger
"""
# Load module configuration if exists
if (context is not None and
module_name in context.modules_configuration):
self.config = context.modules_configuration[module_name]
else:
from nemubot.config.module import Module
self.config = Module(module_name)
self.hooks = list()
self.events = list()
self.debug = context.verbosity > 0 if context is not None else False
from nemubot.hooks import Abstract as AbstractHook
# Define some callbacks
if context is not None:
def load_data():
return context.datastore.load(module_name)
def add_hook(hook, *triggers):
assert isinstance(hook, AbstractHook), hook
self.hooks.append((triggers, hook))
return context.treater.hm.add_hook(hook, *triggers)
def del_hook(hook, *triggers):
assert isinstance(hook, AbstractHook), hook
self.hooks.remove((triggers, hook))
return context.treater.hm.del_hooks(*triggers, hook=hook)
def subtreat(msg):
yield from context.treater.treat_msg(msg)
def add_event(call=None, **kwargs):
evt = context.add_event(call, **kwargs)
if evt is not None:
self.events.append(evt)
return evt
def del_event(evt):
if context.del_event(evt):
self._clean_events()
return True
return False
def send_response(server, res):
if server in context.servers:
if res.server is not None:
return context.servers[res.server].send_response(res)
else:
return context.servers[server].send_response(res)
else:
logger.error("Try to send a message to the unknown server: %s", server)
return False
else: # Used when using outside of nemubot
def load_data():
from nemubot.tools.xmlparser import module_state
return module_state.ModuleState("nemubotstate")
def add_hook(hook, *triggers):
assert isinstance(hook, AbstractHook), hook
self.hooks.append((triggers, hook))
def del_hook(hook, *triggers):
assert isinstance(hook, AbstractHook), hook
self.hooks.remove((triggers, hook))
def subtreat(msg):
return None
def add_event(evt):
return context.add_event(evt)
def del_event(evt):
return context.del_event(evt, module_src=module)
def send_response(server, res):
logger.info("Send response: %s", res)
def save():
context.datastore.save(module_name, self.data)
def subparse(orig, cnt):
if orig.server in context.servers:
return context.servers[orig.server].subparse(orig, cnt)
self.load_data = load_data
self.add_hook = add_hook
self.del_hook = del_hook
self.add_event = add_event
self.del_event = del_event
self.save = save
self.send_response = send_response
self.subtreat = subtreat
self.subparse = subparse
@property
def data(self):
if not hasattr(self, "_data"):
self._data = self.load_data()
return self._data
def _clean_events(self):
"""Look for None weakref in the events list"""
for i in range(len(self.events), 0, -1):
if self.events[i-1]() is None:
self.events.remove()
def unload(self):
"""Perform actions for unloading the module"""
# Remove registered hooks
for (s, h) in self.hooks:
self.del_hook(h, *s)
# Remove registered events
for e in self.events:
self.del_event(e)
self.save()