diff --git a/plugins/events_dump/plugin.py b/plugins/events_dump/plugin.py index 055af8772..b5d37cd06 100644 --- a/plugins/events_dump/plugin.py +++ b/plugins/events_dump/plugin.py @@ -45,43 +45,60 @@ class EventsDumpPlugin(GajimPlugin): self.config_dialog = None #self.gui_extension_points = {} #self.config_default_values = {} + events_from_old_dbus_support = [ + 'Roster', 'AccountPresence', 'ContactPresence', + 'ContactAbsence', 'ContactStatus', 'NewMessage', + 'Subscribe', 'Subscribed', 'Unsubscribed', + 'NewAccount', 'VcardInfo', 'LastStatusTime', + 'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo', + 'NewGmail'] - self.events_names = ['Roster', 'AccountPresence', 'ContactPresence', - 'ContactAbsence', 'ContactStatus', 'NewMessage', - 'Subscribe', 'Subscribed', 'Unsubscribed', - 'NewAccount', 'VcardInfo', 'LastStatusTime', - 'OsInfo', 'GCPresence', 'GCMessage', 'RosterInfo', - 'NewGmail','ROSTER', 'WARNING', 'ERROR', - 'INFORMATION', 'ERROR_ANSWER', 'STATUS', - 'NOTIFY', 'MSGERROR', 'MSGSENT', 'MSGNOTSENT', - 'SUBSCRIBED', 'UNSUBSCRIBED', 'SUBSCRIBE', - 'AGENT_ERROR_INFO', 'AGENT_ERROR_ITEMS', - 'AGENT_REMOVED', 'REGISTER_AGENT_INFO', - 'AGENT_INFO_ITEMS', 'AGENT_INFO_INFO', - 'QUIT', 'NEW_ACC_CONNECTED', - 'NEW_ACC_NOT_CONNECTED', 'ACC_OK', 'ACC_NOT_OK', - 'MYVCARD', 'VCARD', 'LAST_STATUS_TIME', 'OS_INFO', - 'GC_NOTIFY', 'GC_MSG', 'GC_SUBJECT', 'GC_CONFIG', - 'GC_CONFIG_CHANGE', 'GC_INVITATION', - 'GC_AFFILIATION', 'GC_PASSWORD_REQUIRED', - 'BAD_PASSPHRASE', 'ROSTER_INFO', 'BOOKMARKS', - 'CON_TYPE', 'CONNECTION_LOST', 'FILE_REQUEST', - 'GMAIL_NOTIFY', 'FILE_REQUEST_ERROR', - 'FILE_SEND_ERROR', 'STANZA_ARRIVED', 'STANZA_SENT', - 'HTTP_AUTH', 'VCARD_PUBLISHED', - 'VCARD_NOT_PUBLISHED', 'ASK_NEW_NICK', 'SIGNED_IN', - 'METACONTACTS', 'ATOM_ENTRY', 'FAILED_DECRYPT', - 'PRIVACY_LISTS_RECEIVED', 'PRIVACY_LIST_RECEIVED', - 'PRIVACY_LISTS_ACTIVE_DEFAULT', - 'PRIVACY_LIST_REMOVED', 'ZC_NAME_CONFLICT', - 'PING_SENT', 'PING_REPLY', 'PING_ERROR', - 'SEARCH_FORM', 'SEARCH_RESULT', - 'RESOURCE_CONFLICT', 'PEP_CONFIG', - 'UNIQUE_ROOM_ID_UNSUPPORTED', - 'UNIQUE_ROOM_ID_SUPPORTED', 'SESSION_NEG', - 'GPG_PASSWORD_REQUIRED', 'SSL_ERROR', - 'FINGERPRINT_ERROR', 'PLAIN_CONNECTION', - 'PUBSUB_NODE_REMOVED', 'PUBSUB_NODE_NOT_REMOVED'] + events_from_src_gajim = [ + 'ROSTER', 'WARNING', 'ERROR', + 'INFORMATION', 'ERROR_ANSWER', 'STATUS', + 'NOTIFY', 'MSGERROR', 'MSGSENT', 'MSGNOTSENT', + 'SUBSCRIBED', 'UNSUBSCRIBED', 'SUBSCRIBE', + 'AGENT_ERROR_INFO', 'AGENT_ERROR_ITEMS', + 'AGENT_REMOVED', 'REGISTER_AGENT_INFO', + 'AGENT_INFO_ITEMS', 'AGENT_INFO_INFO', + 'QUIT', 'NEW_ACC_CONNECTED', + 'NEW_ACC_NOT_CONNECTED', 'ACC_OK', 'ACC_NOT_OK', + 'MYVCARD', 'VCARD', 'LAST_STATUS_TIME', 'OS_INFO', + 'GC_NOTIFY', 'GC_MSG', 'GC_SUBJECT', 'GC_CONFIG', + 'GC_CONFIG_CHANGE', 'GC_INVITATION', + 'GC_AFFILIATION', 'GC_PASSWORD_REQUIRED', + 'BAD_PASSPHRASE', 'ROSTER_INFO', 'BOOKMARKS', + 'CON_TYPE', 'CONNECTION_LOST', 'FILE_REQUEST', + 'GMAIL_NOTIFY', 'FILE_REQUEST_ERROR', + 'FILE_SEND_ERROR', 'STANZA_ARRIVED', 'STANZA_SENT', + 'HTTP_AUTH', 'VCARD_PUBLISHED', + 'VCARD_NOT_PUBLISHED', 'ASK_NEW_NICK', 'SIGNED_IN', + 'METACONTACTS', 'ATOM_ENTRY', 'FAILED_DECRYPT', + 'PRIVACY_LISTS_RECEIVED', 'PRIVACY_LIST_RECEIVED', + 'PRIVACY_LISTS_ACTIVE_DEFAULT', + 'PRIVACY_LIST_REMOVED', 'ZC_NAME_CONFLICT', + 'PING_SENT', 'PING_REPLY', 'PING_ERROR', + 'SEARCH_FORM', 'SEARCH_RESULT', + 'RESOURCE_CONFLICT', 'PEP_CONFIG', + 'UNIQUE_ROOM_ID_UNSUPPORTED', + 'UNIQUE_ROOM_ID_SUPPORTED', 'SESSION_NEG', + 'GPG_PASSWORD_REQUIRED', 'SSL_ERROR', + 'FINGERPRINT_ERROR', 'PLAIN_CONNECTION', + 'PUBSUB_NODE_REMOVED', 'PUBSUB_NODE_NOT_REMOVED'] + + network_events_from_core = ['raw-message-received', + 'raw-iq-received', + 'raw-pres-received'] + + network_events_generated_in_nec = [ + 'customized-message-received', + 'more-customized-message-received', + 'modify-only-message-received', + 'enriched-chat-message-received'] + + self.events_names = [] + self.events_names += network_events_from_core + self.events_names += network_events_generated_in_nec self.events_handlers = {} self._set_handling_methods() @@ -105,6 +122,6 @@ class EventsDumpPlugin(GajimPlugin): def _generate_handling_method(self, event_name): def handler(self, *args): - print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(*args)) + print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(args)) return handler \ No newline at end of file diff --git a/plugins/new_events_example/__init__.py b/plugins/new_events_example/__init__.py new file mode 100644 index 000000000..a0eca896c --- /dev/null +++ b/plugins/new_events_example/__init__.py @@ -0,0 +1 @@ +from plugin import NewEventsExamplePlugin \ No newline at end of file diff --git a/plugins/new_events_example/plugin.py b/plugins/new_events_example/plugin.py new file mode 100644 index 000000000..451f300c2 --- /dev/null +++ b/plugins/new_events_example/plugin.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +## +## This file is part of Gajim. +## +## Gajim is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## Gajim 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 General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Gajim. If not, see . +## +''' +New Events Example plugin. + +Demonstrates how to use Network Events Controller to generate new events +based on existing one. + +:author: Mateusz Biliński +:since: 15th August 2008 +:copyright: Copyright (2008) Mateusz Biliński +:license: GPL +''' + +import new +from pprint import pformat + +from common import helpers +from common import gajim + +from plugins import GajimPlugin +from plugins.helpers import log_calls, log +from common import ged +from common import nec + +class NewEventsExamplePlugin(GajimPlugin): + name = u'New Events Example' + short_name = u'new_events_example' + version = u'0.1' + description = u'''Shows how to generate new network events based on existing one using Network Events Controller.''' + authors = [u'Mateusz Biliński '] + homepage = u'http://blog.bilinski.it' + + @log_calls('NewEventsExamplePlugin') + def init(self): + self.config_dialog = None + #self.gui_extension_points = {} + #self.config_default_values = {} + + self.events_handlers = {'raw-message-received' : + (ged.POSTCORE, + self.raw_message_received), + 'customized-message-received' : + (ged.POSTCORE, + self.customized_message_received), + 'enriched-chat-message-received' : + (ged.POSTCORE, + self.enriched_chat_message_received)} + + self.events = [CustomizedMessageReceivedEvent, + MoreCustomizedMessageReceivedEvent, + ModifyOnlyMessageReceivedEvent, + EnrichedChatMessageReceivedEvent] + + def enriched_chat_message_received(self, event_object): + pass + #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name, + #event_object) + + def raw_message_received(self, event_object): + pass + #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name, + #event_object) + + def customized_message_received(self, event_object): + pass + #print "Event '%s' occured. Event object: %s\n\n===\n"%(event_object.name, + #event_object) + + def activate(self): + pass + + def deactivate(self): + pass + +class CustomizedMessageReceivedEvent(nec.NetworkIncomingEvent): + name = 'customized-message-received' + base_network_events = ['raw-message-received'] + + def generate(self): + return True + +class MoreCustomizedMessageReceivedEvent(nec.NetworkIncomingEvent): + ''' + Shows chain of custom created events. + + This one is based on custom 'customized-messsage-received'. + ''' + name = 'more-customized-message-received' + base_network_events = ['customized-message-received'] + + def generate(self): + return True + +class ModifyOnlyMessageReceivedEvent(nec.NetworkIncomingEvent): + name = 'modify-only-message-received' + base_network_events = ['raw-message-received'] + + def generate(self): + msg_type = self.base_event.xmpp_msg.attrs['type'] + if msg_type == u'chat': + msg_text = "".join(self.base_event.xmpp_msg.kids[0].data) + self.base_event.xmpp_msg.kids[0].setData( + u'%s [MODIFIED BY CUSTOM NETWORK EVENT]'%(msg_text)) + + return False + +class EnrichedChatMessageReceivedEvent(nec.NetworkIncomingEvent): + ''' + Generates more friendly (in use by handlers) network event for + received chat message. + ''' + name = 'enriched-chat-message-received' + base_network_events = ['raw-message-received'] + + def generate(self): + msg_type = self.base_event.xmpp_msg.attrs['type'] + if msg_type == u'chat': + self.xmpp_msg = self.base_event.xmpp_msg + self.conn = self.base_event.conn + self.from_jid = helpers.get_full_jid_from_iq(self.xmpp_msg) + self.from_jid_without_resource = gajim.get_jid_without_resource(self.from_jid) + self.account = unicode(self.xmpp_msg.attrs['to']) + self.from_nickname = gajim.get_contact_name_from_jid( + self.account, + self.from_jid_without_resource) + self.msg_text = "".join(self.xmpp_msg.kids[0].data) + + return True + + return False diff --git a/plugins/snarl_notifications/plugin.py b/plugins/snarl_notifications/plugin.py index e6ef5ae18..9835cca28 100644 --- a/plugins/snarl_notifications/plugin.py +++ b/plugins/snarl_notifications/plugin.py @@ -30,7 +30,7 @@ Fancy events notifications under Windows using Snarl infrastructure. import new from pprint import pformat -import PySnarl +#import PySnarl from common import gajim from plugins import GajimPlugin @@ -62,7 +62,7 @@ PySnarl bindings are used (http://code.google.com/p/pysnarl/).''' def newMessage(self, args): event_name = "NewMessage" - data = args[0] + data = args account = data[0] jid = data[1][0] jid_without_resource = gajim.get_jid_without_resource(jid) @@ -74,15 +74,15 @@ PySnarl bindings are used (http://code.google.com/p/pysnarl/).''' elif msg_type == 'pm': nickname = gajim.get_resource_from_jid(jid) - print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(*args)) + print "Event '%s' occured. Arguments: %s\n\n===\n"%(event_name, pformat(args)) print "Event '%s' occured. Arguments: \naccount = %s\njid = %s\nmsg = %s\nnickname = %s"%( event_name, account, jid, msg, nickname) - if PySnarl.snGetVersion() != False: - (major, minor) = PySnarl.snGetVersion() - print "Found Snarl version",str(major)+"."+str(minor),"running." - PySnarl.snShowMessage(nickname, msg[:20]+'...') - else: - print "Sorry Snarl does not appear to be running" + #if PySnarl.snGetVersion() != False: + #(major, minor) = PySnarl.snGetVersion() + #print "Found Snarl version",str(major)+"."+str(minor),"running." + #PySnarl.snShowMessage(nickname, msg[:20]+'...') + #else: + #print "Sorry Snarl does not appear to be running" \ No newline at end of file diff --git a/src/common/connection.py b/src/common/connection.py index c5cc190a2..9a13488bb 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -174,8 +174,8 @@ class Connection(ConnectionHandlers): def dispatch(self, event, data): '''always passes account name as first param''' - self.put_event((event, data)) - gajim.ged.raise_event(event, data) + #self.put_event((event, data)) + gajim.ged.raise_event(event, self.name, data) def _reconnect(self): diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index 04d633ecb..3e5de416d 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -43,6 +43,7 @@ from common import exceptions from common.commands import ConnectionCommands from common.pubsub import ConnectionPubSub from common.caps import ConnectionCaps +from common.nec import NetworkEvent from common import dbus_support if dbus_support.supported: @@ -1004,6 +1005,10 @@ class ConnectionVcard: def _IqCB(self, con, iq_obj): id = iq_obj.getID() + + gajim.nec.push_incoming_event(NetworkEvent('raw-iq-received', + conn = con, + xmpp_iq = iq_obj)) # Check if we were waiting a timeout for this id found_tim = None @@ -1601,7 +1606,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, def _messageCB(self, con, msg): '''Called when we receive a message''' gajim.log.debug('MessageCB') - + + gajim.nec.push_incoming_event(NetworkEvent('raw-message-received', + conn = con, + xmpp_msg = msg)) + frm = helpers.get_full_jid_from_iq(msg) # check if the message is pubsub#event @@ -1916,6 +1925,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, def _presenceCB(self, con, prs): '''Called when we receive a presence''' + gajim.nec.push_incoming_event(NetworkEvent('raw-pres-received', + conn = con, + xmpp_pres = prs)) ptype = prs.getType() if ptype == 'available': ptype = None diff --git a/src/common/gajim.py b/src/common/gajim.py index 3943f2bd4..a8533a1fc 100644 --- a/src/common/gajim.py +++ b/src/common/gajim.py @@ -61,8 +61,10 @@ version = config.get('version') connections = {} # 'account name': 'account (connection.Connection) instance' verbose = False ipython_window = None -plugin_manager = None + ged = None # Global Events Dispatcher +nec = None # Network Events Controller +plugin_manager = None # Plugins Manager h = logging.StreamHandler() f = logging.Formatter('%(asctime)s %(name)s: %(message)s', '%d %b %Y %H:%M:%S') diff --git a/src/common/ged.py b/src/common/ged.py index 07a7aea10..342bb13f6 100644 --- a/src/common/ged.py +++ b/src/common/ged.py @@ -24,7 +24,7 @@ Global Events Dispatcher module. :license: GPL ''' -from plugins.helpers import log +#from plugins.helpers import log PRECORE = 30 CORE = 40 @@ -39,9 +39,9 @@ class GlobalEventsDispatcher(object): if event_name in self.handlers: handlers_list = self.handlers[event_name] i = 0 - if len(handlers_list) > 0: - while priority > handlers_list[i][0]: # sorting handlers by priority - i += 1 + for i,h in enumerate(handlers_list): + if priority < h[0]: + break handlers_list.insert(i, (priority, handler)) else: @@ -52,13 +52,13 @@ class GlobalEventsDispatcher(object): try: self.handlers[event_name].remove((priority, handler)) except ValueError, error: - log.debug('''Function (%s) with priority "%s" never registered + print('''Function (%s) with priority "%s" never registered as handler of event "%s". Couldn\'t remove. Error: %s''' %(handler, priority, event_name, error)) - def raise_event(self, event_name, *args): + def raise_event(self, event_name, *args, **kwargs): #log.debug('[GED] Event: %s\nArgs: %s'%(event_name, str(args))) if event_name in self.handlers: for priority, handler in self.handlers[event_name]: - handler(args) + handler(*args, **kwargs) \ No newline at end of file diff --git a/src/common/nec.py b/src/common/nec.py new file mode 100644 index 000000000..6f433ca3c --- /dev/null +++ b/src/common/nec.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- + +## This file is part of Gajim. +## +## Gajim is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## Gajim 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 General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Gajim. If not, see . +## + +''' +Network Events Controller. + +:author: Mateusz Biliński +:since: 10th August 2008 +:copyright: Copyright (2008) Mateusz Biliński +:license: GPL +''' + +from pprint import pformat + +#from plugins.helpers import log +from common import gajim + +class NetworkEventsController(object): + + def __init__(self): + self.incoming_events_generators = {} + ''' + Keys: names of events + Values: list of class objects that are subclasses + of `NetworkIncomingEvent` + ''' + + def register_incoming_event(self, event_class): + for base_event_name in event_class.base_network_events: + self.incoming_events_generators.setdefault(base_event_name,[]).append(event_class) + + def unregister_incoming_event(self, event_class): + for base_event_name in event_class.base_network_events: + if base_event_name in self.incoming_events_generators: + self.incoming_events_generators[base_event_name].remove(event_class) + + def register_outgoing_event(self, event_class): + pass + + def unregister_outgoing_event(self, event_class): + pass + + def push_incoming_event(self, event_object): + if self._generate_events_based_on_incoming_event(event_object): + gajim.ged.raise_event(event_object.name, event_object) + + def push_outgoing_event(self, event_object): + pass + + def _generate_events_based_on_incoming_event(self, event_object): + ''' + :return: True if even_object should be dispatched through Global + Events Dispatcher, False otherwise. This can be used to replace + base events with those that more data computed (easier to use + by handlers). + :note: replacing mechanism is not implemented currently, but will be + based on attribute in new network events object. + ''' + base_event_name = event_object.name + if base_event_name in self.incoming_events_generators: + for new_event_class in self.incoming_events_generators[base_event_name]: + new_event_object = new_event_class(None, base_event=event_object) + if new_event_object.generate(): + if self._generate_events_based_on_incoming_event(new_event_object): + gajim.ged.raise_event(new_event_object.name, new_event_object) + return True + +class NetworkEvent(object): + name = '' + + def __init__(self, new_name, **kwargs): + if new_name: + self.name = new_name + + self._set_kwargs_as_attributes(**kwargs) + + self.init() + + def init(self): + pass + + def _set_kwargs_as_attributes(self, **kwargs): + for k,v in kwargs.iteritems(): + setattr(self, k, v) + + def __str__(self): + return ' Attributes: %s'%(pformat(self.__dict__)) + + def __repr__(self): + return ' Attributes: %s'%(pformat(self.__dict__)) + +class NetworkIncomingEvent(NetworkEvent): + base_network_events = [] + ''' + Names of base network events that new event is going to be generated on. + ''' + + def init(self): + pass + + def generate(self): + ''' + Generates new event (sets it's attributes) based on event object. + + Base event object name is one of those in `base_network_events`. + + Reference to base event object is stored in `self.base_event` attribute. + + Note that this is a reference, so modifications to that event object + are possible before dispatching to Global Events Dispatcher. + + :return: True if generated event should be dispatched, False otherwise. + ''' + pass + + +class NetworkOutgoingEvent(NetworkEvent): + + def init(self): + pass + \ No newline at end of file diff --git a/src/gajim.py b/src/gajim.py index 19f5232c1..bb1c361c2 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -615,6 +615,7 @@ parser = optparser.OptionsParser(config_filename) import roster_window import profile_window import config +from common import ged class GlibIdleQueue(idlequeue.IdleQueue): ''' @@ -3348,6 +3349,9 @@ class Interface: # Creating Global Events Dispatcher from common import ged gajim.ged = ged.GlobalEventsDispatcher() + # Creating Network Events Controller + from common import nec + gajim.nec = nec.NetworkEventsController() self.register_core_handlers() self.register_handlers() @@ -3496,8 +3500,6 @@ class Interface: gobject.timeout_add_seconds(gajim.config.get( 'check_idle_every_foo_seconds'), self.read_sleepy) - - # Creating plugin manager import plugins gajim.plugin_manager = plugins.PluginManager() @@ -3509,7 +3511,88 @@ class Interface: This part of rewriting whole evetns handling system to use GED. Of course this can be done anywhere else. ''' - pass + handlers = { + 'ROSTER': self.handle_event_roster, + 'WARNING': self.handle_event_warning, + 'ERROR': self.handle_event_error, + 'INFORMATION': self.handle_event_information, + 'ERROR_ANSWER': self.handle_event_error_answer, + 'STATUS': self.handle_event_status, + 'NOTIFY': self.handle_event_notify, + 'MSGERROR': self.handle_event_msgerror, + 'MSGSENT': self.handle_event_msgsent, + 'MSGNOTSENT': self.handle_event_msgnotsent, + 'SUBSCRIBED': self.handle_event_subscribed, + 'UNSUBSCRIBED': self.handle_event_unsubscribed, + 'SUBSCRIBE': self.handle_event_subscribe, + 'AGENT_ERROR_INFO': self.handle_event_agent_info_error, + 'AGENT_ERROR_ITEMS': self.handle_event_agent_items_error, + 'AGENT_REMOVED': self.handle_event_agent_removed, + 'REGISTER_AGENT_INFO': self.handle_event_register_agent_info, + 'AGENT_INFO_ITEMS': self.handle_event_agent_info_items, + 'AGENT_INFO_INFO': self.handle_event_agent_info_info, + 'QUIT': self.handle_event_quit, + 'NEW_ACC_CONNECTED': self.handle_event_new_acc_connected, + 'NEW_ACC_NOT_CONNECTED': self.handle_event_new_acc_not_connected, + 'ACC_OK': self.handle_event_acc_ok, + 'ACC_NOT_OK': self.handle_event_acc_not_ok, + 'MYVCARD': self.handle_event_myvcard, + 'VCARD': self.handle_event_vcard, + 'LAST_STATUS_TIME': self.handle_event_last_status_time, + 'OS_INFO': self.handle_event_os_info, + 'GC_NOTIFY': self.handle_event_gc_notify, + 'GC_MSG': self.handle_event_gc_msg, + 'GC_SUBJECT': self.handle_event_gc_subject, + 'GC_CONFIG': self.handle_event_gc_config, + 'GC_CONFIG_CHANGE': self.handle_event_gc_config_change, + 'GC_INVITATION': self.handle_event_gc_invitation, + 'GC_AFFILIATION': self.handle_event_gc_affiliation, + 'GC_PASSWORD_REQUIRED': self.handle_event_gc_password_required, + 'BAD_PASSPHRASE': self.handle_event_bad_passphrase, + 'ROSTER_INFO': self.handle_event_roster_info, + 'BOOKMARKS': self.handle_event_bookmarks, + 'CON_TYPE': self.handle_event_con_type, + 'CONNECTION_LOST': self.handle_event_connection_lost, + 'FILE_REQUEST': self.handle_event_file_request, + 'GMAIL_NOTIFY': self.handle_event_gmail_notify, + 'FILE_REQUEST_ERROR': self.handle_event_file_request_error, + 'FILE_SEND_ERROR': self.handle_event_file_send_error, + 'STANZA_ARRIVED': self.handle_event_stanza_arrived, + 'STANZA_SENT': self.handle_event_stanza_sent, + 'HTTP_AUTH': self.handle_event_http_auth, + 'VCARD_PUBLISHED': self.handle_event_vcard_published, + 'VCARD_NOT_PUBLISHED': self.handle_event_vcard_not_published, + 'ASK_NEW_NICK': self.handle_event_ask_new_nick, + 'SIGNED_IN': self.handle_event_signed_in, + 'METACONTACTS': self.handle_event_metacontacts, + 'ATOM_ENTRY': self.handle_atom_entry, + 'FAILED_DECRYPT': self.handle_event_failed_decrypt, + 'PRIVACY_LISTS_RECEIVED': self.handle_event_privacy_lists_received, + 'PRIVACY_LIST_RECEIVED': self.handle_event_privacy_list_received, + 'PRIVACY_LISTS_ACTIVE_DEFAULT': \ + self.handle_event_privacy_lists_active_default, + 'PRIVACY_LIST_REMOVED': self.handle_event_privacy_list_removed, + 'ZC_NAME_CONFLICT': self.handle_event_zc_name_conflict, + 'PING_SENT': self.handle_event_ping_sent, + 'PING_REPLY': self.handle_event_ping_reply, + 'PING_ERROR': self.handle_event_ping_error, + 'SEARCH_FORM': self.handle_event_search_form, + 'SEARCH_RESULT': self.handle_event_search_result, + 'RESOURCE_CONFLICT': self.handle_event_resource_conflict, + 'PEP_CONFIG': self.handle_event_pep_config, + 'UNIQUE_ROOM_ID_UNSUPPORTED': \ + self.handle_event_unique_room_id_unsupported, + 'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported, + 'SESSION_NEG': self.handle_session_negotiation, + 'GPG_PASSWORD_REQUIRED': self.handle_event_gpg_password_required, + 'SSL_ERROR': self.handle_event_ssl_error, + 'FINGERPRINT_ERROR': self.handle_event_fingerprint_error, + 'PLAIN_CONNECTION': self.handle_event_plain_connection, + 'PUBSUB_NODE_REMOVED': self.handle_event_pubsub_node_removed, + 'PUBSUB_NODE_NOT_REMOVED': self.handle_event_pubsub_node_not_removed, + } + for event_name, handler in handlers.iteritems(): + gajim.ged.register_event_handler(event_name, ged.CORE, handler) if __name__ == '__main__': def sigint_cb(num, stack): diff --git a/src/plugins/plugin.py b/src/plugins/plugin.py index fb0651cc5..5c9edf072 100644 --- a/src/plugins/plugin.py +++ b/src/plugins/plugin.py @@ -132,6 +132,13 @@ class GajimPlugin(object): :type: {} with 2-element tuples ''' + events = [] + ''' + New network event classes to be registered in Network Events Controller. + + :type: [] of `nec.NetworkIncomingEvent` or `nec.NetworkOutgoingEvent` + subclasses. + ''' @log_calls('GajimPlugin') def __init__(self): diff --git a/src/plugins/pluginmanager.py b/src/plugins/pluginmanager.py index 23d514a1c..95952a124 100644 --- a/src/plugins/pluginmanager.py +++ b/src/plugins/pluginmanager.py @@ -30,7 +30,8 @@ import os import sys import fnmatch -import common.gajim as gajim +from common import gajim +from common import nec from plugins.helpers import log, log_calls, Singleton from plugins.plugin import GajimPlugin @@ -252,6 +253,20 @@ class PluginManager(object): gajim.ged.remove_event_handler(event_name, priority, handler_function) + + def _register_network_events_in_nec(self, plugin): + for event_class in plugin.events: + if issubclass(event_class, nec.NetworkIncomingEvent): + gajim.nec.register_incoming_event(event_class) + elif issubclass(event_class, nec.NetworkOutgoingEvent): + gajim.nec.register_outgoing_event(event_class) + + def _remove_network_events_from_nec(self, plugin): + for event_class in plugin.events: + if issubclass(event_class, nec.NetworkIncomingEvent): + gajim.nec.unregister_incoming_event(event_class) + elif issubclass(event_class, nec.NetworkOutgoingEvent): + gajim.nec.unregister_outgoing_event(event_class) @log_calls('PluginManager') def activate_plugin(self, plugin): @@ -270,6 +285,7 @@ class PluginManager(object): self._add_gui_extension_points_handlers_from_plugin(plugin) self._handle_all_gui_extension_points_with_plugin(plugin) self._register_events_handlers_in_ged(plugin) + self._register_network_events_in_nec(plugin) success = True @@ -300,6 +316,7 @@ class PluginManager(object): handler(*gui_extension_point_args) self._remove_events_handler_from_ged(plugin) + self._remove_network_events_from_nec(plugin) # removing plug-in from active plug-ins list plugin.deactivate()