diff options
author | Florent Le Coz <louiz@louiz.org> | 2011-11-09 01:26:54 +0100 |
---|---|---|
committer | Florent Le Coz <louiz@louiz.org> | 2011-11-09 01:26:54 +0100 |
commit | 75ae1772e49a59b373c26d1c942f25edd473921c (patch) | |
tree | 65d8faee081db6c3800a48eff7007a4b626e4252 /src/plugin_manager.py | |
parent | 8f02b6eb8e022ed1d34e0a0b0c7376eaf58acc32 (diff) | |
parent | 23d81901e7725bf67363113bc36a6e171bdb2033 (diff) | |
download | poezio-75ae1772e49a59b373c26d1c942f25edd473921c.tar.gz poezio-75ae1772e49a59b373c26d1c942f25edd473921c.tar.bz2 poezio-75ae1772e49a59b373c26d1c942f25edd473921c.tar.xz poezio-75ae1772e49a59b373c26d1c942f25edd473921c.zip |
Merge branch 'master' of http://git.louiz.org/poezio
Diffstat (limited to 'src/plugin_manager.py')
-rw-r--r-- | src/plugin_manager.py | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/plugin_manager.py b/src/plugin_manager.py new file mode 100644 index 00000000..bdf94a5b --- /dev/null +++ b/src/plugin_manager.py @@ -0,0 +1,137 @@ +import imp +import os +import sys +from config import config +from gettext import gettext as _ + +plugins_dir = config.get('plugins_dir', '') +plugins_dir = plugins_dir or\ + os.path.join(os.environ.get('XDG_DATA_HOME') or\ + os.path.join(os.environ.get('HOME'), '.local', 'share'), + 'poezio', 'plugins') + +config_home = os.environ.get("XDG_CONFIG_HOME") +if not config_home: + config_home = os.path.join(os.environ.get('HOME'), '.config') +plugins_conf_dir = os.path.join(config_home, 'poezio', 'plugins') + +try: + os.makedirs(plugins_dir) +except OSError: + pass + +try: + os.makedirs(plugins_conf_dir) +except OSError: + pass + +sys.path.append(plugins_dir) + +class PluginManager(object): + def __init__(self, core): + self.core = core + self.modules = {} # module name -> module object + self.plugins = {} # module name -> plugin object + self.commands = {} # module name -> dict of commands loaded for the module + self.event_handlers = {} # module name -> list of event_name/handler pairs loaded for the module + self.poezio_event_handlers = {} + + def load(self, name): + if name in self.plugins: + self.unload(name) + + try: + if name in self.modules: + imp.acquire_lock() + module = imp.reload(self.modules[name]) + imp.release_lock() + else: + file, filename, info = imp.find_module(name, [plugins_dir]) + imp.acquire_lock() + module = imp.load_module(name, file, filename, info) + imp.release_lock() + except Exception as e: + import traceback + self.core.information(_("Could not load plugin: ") + traceback.format_exc(), 'Error') + return + finally: + if imp.lock_held(): + imp.release_lock() + + self.modules[name] = module + self.commands[name] = {} + self.event_handlers[name] = [] + self.poezio_event_handlers[name] = [] + self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir) + + def unload(self, name): + if name in self.plugins: + try: + for command in self.commands[name].keys(): + del self.core.commands[command] + for event_name, handler in self.event_handlers[name]: + self.core.xmpp.del_event_handler(event_name, handler) + for handler in self.poezio_event_handlers[name]: + self.core.events.del_event_handler(None, handler) + + self.plugins[name].unload() + del self.plugins[name] + del self.commands[name] + del self.event_handlers[name] + del self.poezio_event_handlers[name] + except Exception as e: + import traceback + self.core.information(_("Could not unload plugin (may not be safe to try again): ") + traceback.format_exc()) + + def del_command(self, module_name, name): + if name in self.commands[module_name]: + del self.commands[module_name][name] + if name in self.core.commands: + del self.core.commands[name] + + def add_command(self, module_name, name, handler, help, completion=None): + if name in self.core.commands: + raise Exception(_("Command '%s' already exists") % (name,)) + + commands = self.commands[module_name] + commands[name] = (handler, help, completion) + self.core.commands[name] = (handler, help, completion) + + def add_event_handler(self, module_name, event_name, handler): + eh = self.event_handlers[module_name] + eh.append((event_name, handler)) + self.core.xmpp.add_event_handler(event_name, handler) + + def del_event_handler(self, module_name, event_name, handler): + self.core.xmpp.del_event_handler(event_name, handler) + eh = self.event_handlers[module_name] + eh = list(filter(lambda e : e != (event_name, handler), eh)) + + def add_poezio_event_handler(self, module_name, event_name, handler, position): + eh = self.poezio_event_handlers[module_name] + eh.append(handler) + self.core.events.add_event_handler(event_name, handler, position) + + def del_poezio_event_handler(self, module_name, event_name, handler): + self.core.events.del_event_handler(None, handler) + eh = self.poezio_event_handlers[module_name] + eh = list(filter(lambda e : e != handler, eh)) + + def completion_load(self, the_input): + """ + completion function that completes the name of the plugins, from + all .py files in plugins_dir + """ + try: + names = os.listdir(plugins_dir) + except OSError as e: + self.core.information(_('Completion failed: %s' % e), 'Error') + return + plugins_files = [name[:-3] for name in names if name.endswith('.py')] + return the_input.auto_completion(plugins_files, '') + + def completion_unload(self, the_input): + """ + completion function that completes the name of the plugins that are loaded + """ + return the_input.auto_completion(list(self.plugins.keys()), '') |