From ed87f26db763432505072eb5a2875f30fc4061d1 Mon Sep 17 00:00:00 2001 From: mathieui Date: Sat, 1 Oct 2011 23:48:42 +0200 Subject: [PATCH] Added a connect() function to the plugins API, for internal event --- plugins/test.py | 4 +++ src/core.py | 61 +++++++++++++++++++++++++++++++++++++++++++ src/plugin_manager.py | 3 +++ src/tabs.py | 1 + 4 files changed, 69 insertions(+) diff --git a/plugins/test.py b/plugins/test.py index 13ba1e9c..0d5cdb0a 100644 --- a/plugins/test.py +++ b/plugins/test.py @@ -5,10 +5,14 @@ class Plugin(BasePlugin): self.add_command('plugintest', self.command_plugintest, 'Test command') self.add_event_handler('message', self.on_message) self.core.information("Plugin loaded") + self.core.connect('enter', self.on_enter) def cleanup(self): self.core.information("Plugin unloaded") + def on_enter(self, line): + self.core.information('Text sent: {}'.format(line)) + def on_message(self, message): self.core.information("Test plugin received message: {}".format(message)) diff --git a/src/core.py b/src/core.py index 0e09cf04..41a54b23 100644 --- a/src/core.py +++ b/src/core.py @@ -16,6 +16,7 @@ import threading import traceback from datetime import datetime +from inspect import getargspec import common import theming @@ -78,6 +79,13 @@ class Core(object): """ User interface using ncurses """ + + # dict containing the name of the internal events + # used with the plugins, the key is the name of the event + # and the value is the number of arguments the handler must take + internal_events = { + 'enter': 2, + } def __init__(self): # All uncaught exception are given to this callback, instead # of being displayed on the screen and exiting the program. @@ -174,6 +182,8 @@ class Core(object): self.xmpp.add_event_handler("chatstate_inactive", self.on_chatstate_inactive) self.timed_events = set() + + self.connected_events = {} self.autoload_plugins() def autoload_plugins(self): @@ -210,6 +220,57 @@ class Core(object): )) self.refresh_window() + def connect(self, event, handler): + """ + Connect an handler to an internal event of poezio + (eg "enter pressed in a chattab") + """ + # Fail if the method doesn’t take at least the good number of arguments + # or if the event is unknown + if not event in self.internal_events \ + or len(getargspec(handler).args) < self.internal_events[event]: + return False + + module_name = handler.__module__ + if not event in self.connected_events: + self.connected_events[event] = {} + if not module_name in self.connected_events[event]: + self.connected_events[event][module_name] = [] + + self.connected_events[event][module_name].append(handler) + return True + + def run_event(self, event, **kwargs): + """ + Call the handlers associated with an event + """ + if event in self.connected_events: + for module in self.connected_events[event]: + for handler in self.connected_events[event][module]: + try: + handler(**kwargs) + except: + import traceback + tp = traceback.format_exc() + module_name = handler.__name__ + log.debug('ERROR: in plugin %s, \n%s' % (module_name, tp)) + + def disconnect(self, event, handler): + """ + Disconnect a handler from an event + """ + if not event in self.internal_events: + return False + + module_name = getmodule(handler).__name__ + if not event in self.connected_events: + return False + if not module_name in self.connected_events[event]: + return False + + self.connected_events[event][module_name].remove(handler) + return True + def resize_global_information_win(self): """ Resize the global_information_win only once at each resize. diff --git a/src/plugin_manager.py b/src/plugin_manager.py index df96e9ab..82be8632 100644 --- a/src/plugin_manager.py +++ b/src/plugin_manager.py @@ -69,6 +69,9 @@ class PluginManager(object): del self.core.commands[command] for event_name, handler in self.event_handlers[name]: self.core.xmpp.del_event_handler(event_name, handler) + for event_name in self.core.internal_events: + if name in event_name: + del event_name[name] self.plugins[name].unload() del self.plugins[name] diff --git a/src/tabs.py b/src/tabs.py index bc656cdd..a349da0b 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -298,6 +298,7 @@ class ChatTab(Tab): if not self.execute_command(clean_text): if txt.startswith('//'): txt = txt[1:] + self.core.run_event('enter', line=txt) self.command_say(txt) self.cancel_paused_delay()