From 8fad2f464a8049c047a5bf31e377398b79871096 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 8 Nov 2011 23:48:32 +0100 Subject: Update version to 0.7.2 --- src/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/connection.py b/src/connection.py index f407dfe9..19b2c5e4 100644 --- a/src/connection.py +++ b/src/connection.py @@ -51,7 +51,7 @@ class Connection(sleekxmpp.ClientXMPP): self.register_plugin('xep_0085') if config.get('send_poezio_info', 'true') == 'true': info = {'name':'poezio', - 'version':'0.7.2-dev'} + 'version':'0.7.2'} if config.get('send_os_info', 'true') == 'true': info['os'] = common.get_os_info() self.register_plugin('xep_0092', pconfig=info) -- cgit v1.2.3 From cfb074c17875e389b894cdc3447773a1ead928ca Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 9 Nov 2011 01:35:27 +0100 Subject: Set version to 0.7.5 and update the changelog --- src/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/connection.py b/src/connection.py index 19b2c5e4..dfc8ba85 100644 --- a/src/connection.py +++ b/src/connection.py @@ -51,7 +51,7 @@ class Connection(sleekxmpp.ClientXMPP): self.register_plugin('xep_0085') if config.get('send_poezio_info', 'true') == 'true': info = {'name':'poezio', - 'version':'0.7.2'} + 'version':'0.7.5-dev'} if config.get('send_os_info', 'true') == 'true': info['os'] = common.get_os_info() self.register_plugin('xep_0092', pconfig=info) -- cgit v1.2.3 From 98b9506983b57d7da1f5543f8cefd68dca0827ae Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 14:02:17 +0100 Subject: Remove poezio_event_handler to keep only event_handler --- src/plugin.py | 10 ++-------- src/plugin_manager.py | 29 ++++++++++------------------- 2 files changed, 12 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/plugin.py b/src/plugin.py index 80bc4dfc..c87ba2f1 100644 --- a/src/plugin.py +++ b/src/plugin.py @@ -79,14 +79,8 @@ class BasePlugin(object, metaclass=SafetyMetaclass): def del_command(self, name): return self.plugin_manager.del_command(self.__module__, name) - def add_event_handler(self, event_name, handler): - return self.plugin_manager.add_event_handler(self.__module__, event_name, handler) + def add_event_handler(self, event_name, handler, position=0): + return self.plugin_manager.add_event_handler(self.__module__, event_name, handler, position) def del_event_handler(self, event_name, handler): return self.plugin_manager.del_event_handler(self.__module__, event_name, handler) - - def add_poezio_event_handler(self, event_name, handler, position=0): - return self.plugin_manager.add_poezio_event_handler(self.__module__, event_name, handler, position) - - def del_poezio_event_handler(self, event_name, handler): - return self.plugin_manager.del_poezio_event_handler(self.__module__, event_name, handler) diff --git a/src/plugin_manager.py b/src/plugin_manager.py index bdf94a5b..067cb10e 100644 --- a/src/plugin_manager.py +++ b/src/plugin_manager.py @@ -34,7 +34,6 @@ class PluginManager(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: @@ -61,7 +60,6 @@ class PluginManager(object): 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): @@ -70,15 +68,12 @@ class PluginManager(object): 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.del_event_handler(name, event_name, 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()) @@ -97,26 +92,22 @@ class PluginManager(object): commands[name] = (handler, help, completion) self.core.commands[name] = (handler, help, completion) - def add_event_handler(self, module_name, event_name, handler): + def add_event_handler(self, module_name, event_name, handler, position=0): eh = self.event_handlers[module_name] eh.append((event_name, handler)) - self.core.xmpp.add_event_handler(event_name, handler) + if event_name in self.core.events.events: + self.core.events.add_event_handler(event_name, handler, position) + else: + 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) + if event_name in self.core.events.events: + self.core.events.del_event_handler(None, handler) + else: + 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 -- cgit v1.2.3 From cc7f010aed20c726b69f99b58f9c7578e5ff1dc1 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 14:07:10 +0100 Subject: Do not create a private tab when receiving only a chatstate --- src/core.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index e2ba8ce1..f1f48a2b 100644 --- a/src/core.py +++ b/src/core.py @@ -560,13 +560,14 @@ class Core(object): jid = message['from'] nick_from = jid.resource room_from = jid.bare + body = xhtml.get_body_from_message_stanza(message) tab = self.get_tab_by_name(jid.full, tabs.PrivateTab) # get the tab with the private conversation if not tab: # It's the first message we receive: create the tab - tab = self.open_private_window(room_from, nick_from, False) + if body: + tab = self.open_private_window(room_from, nick_from, False) if not tab: return self.events.trigger('private_msg', message) - body = xhtml.get_body_from_message_stanza(message) if not body: return tab.add_message(body, time=None, nickname=nick_from, -- cgit v1.2.3 From 5e840e64373522c484dfd4e24d4a60bcb7c21825 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 14:23:38 +0100 Subject: Give the concerned tab to the _msg handlers --- src/core.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index f1f48a2b..a7c331ef 100644 --- a/src/core.py +++ b/src/core.py @@ -567,7 +567,7 @@ class Core(object): tab = self.open_private_window(room_from, nick_from, False) if not tab: return - self.events.trigger('private_msg', message) + self.events.trigger('private_msg', message, tab) if not body: return tab.add_message(body, time=None, nickname=nick_from, @@ -616,13 +616,17 @@ class Core(object): When receiving "normal" messages (from someone in our roster) """ jid = message['from'] - self.events.trigger('conversation_msg', message) body = xhtml.get_body_from_message_stanza(message) + conversation = self.get_tab_of_conversation_with_jid(jid, create=False) if not body: if message['type'] == 'error': self.information(self.get_error_message_from_error_stanza(message), 'Error') - return + return + elif not conversation: + return conversation = self.get_tab_of_conversation_with_jid(jid, create=True) + self.events.trigger('conversation_msg', message, conversation) + body = xhtml.get_body_from_message_stanza(message) if roster.get_contact_by_jid(jid.bare): remote_nick = roster.get_contact_by_jid(jid.bare).get_name() or jid.user else: @@ -1057,7 +1061,7 @@ class Core(object): if tab.get_user_by_name(nick_from) and\ tab.get_user_by_name(nick_from) in tab.ignores: return - self.events.trigger('muc_msg', message) + self.events.trigger('muc_msg', message, tab) body = xhtml.get_body_from_message_stanza(message) if body: date = date if delayed == True else None -- cgit v1.2.3 From aee7baab245e7edabc960e52f6062393197b6a38 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 14:29:13 +0100 Subject: Same as previous commit, but with _say --- src/tabs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index 6f100741..93f48757 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -722,7 +722,7 @@ class MucTab(ChatTab): # trigger the event BEFORE looking for colors. # This lets a plugin insert \x19xxx} colors, that will # be converted in xhtml. - self.core.events.trigger('muc_say', msg) + self.core.events.trigger('muc_say', msg, self) if msg['body'].find('\x19') != -1: msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) msg['body'] = xhtml.clean_text(msg['body']) @@ -1217,7 +1217,7 @@ class PrivateTab(ChatTab): # trigger the event BEFORE looking for colors. # This lets a plugin insert \x19xxx} colors, that will # be converted in xhtml. - self.core.events.trigger('private_say', msg) + self.core.events.trigger('private_say', msg, self) self.core.add_message_to_text_buffer(self._text_buffer, msg['body'], None, self.core.own_nick or self.own_nick) if msg['body'].find('\x19') != -1: msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) @@ -1894,7 +1894,7 @@ class ConversationTab(ChatTab): # and before displaying the message in the window # This lets a plugin insert \x19xxx} colors, that will # be converted in xhtml. - self.core.events.trigger('conversation_say', msg) + self.core.events.trigger('conversation_say', msg, self) self.core.add_message_to_text_buffer(self._text_buffer, msg['body'], None, self.core.own_nick) if msg['body'].find('\x19') != -1: msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) -- cgit v1.2.3 From 0e10c04cce83b7b3c0bedd128457d797b605bdbe Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 17:55:43 +0100 Subject: Fixed a display bug (the info buffer popped even in the RosterInfoTab) --- src/core.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index a7c331ef..35e2040f 100644 --- a/src/core.py +++ b/src/core.py @@ -1537,7 +1537,9 @@ class Core(object): Displays an informational message in the "Info" buffer """ nb_lines = self.information_buffer.add_message(msg, nickname=typ) - if typ != '' and typ.lower() in config.get('information_buffer_popup_on', + if isinstance(self.current_tab(), tabs.RosterInfoTab): + self.refresh_window() + elif typ != '' and typ.lower() in config.get('information_buffer_popup_on', 'error roster warning help info').split(): popup_time = config.get('popup_time', 4) + (nb_lines - 1) * 2 self.pop_information_win_up(nb_lines, popup_time) -- cgit v1.2.3 From e8e4b0bb4c9b98f64934cebcc3e4faff63b1f562 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 18:38:56 +0100 Subject: Plugin docstrings --- src/events.py | 5 ++--- src/plugin.py | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/events.py b/src/events.py index 22d60ddf..cd45448f 100644 --- a/src/events.py +++ b/src/events.py @@ -20,7 +20,6 @@ class EventHandler(object): """ def __init__(self): self.events = { - # when you are highlighted in a muc tab 'highlight': [], 'muc_say': [], 'conversation_say': [], @@ -35,7 +34,7 @@ class EventHandler(object): Add a callback to a given event. Note that if that event name doesn’t exist, it just returns False. If it was successfully added, it returns True - position: 0 means insert a the beginning, -1 means end + position: 0 means insert at the beginning, -1 means end """ if name not in self.events: return False @@ -49,7 +48,7 @@ class EventHandler(object): def trigger(self, name, *args, **kwargs): """ - Call all the callbacks associated to the given event name + Call all the callbacks associated to the given event name. """ callbacks = self.events[name] for callback in callbacks: diff --git a/src/plugin.py b/src/plugin.py index c87ba2f1..40f96871 100644 --- a/src/plugin.py +++ b/src/plugin.py @@ -50,9 +50,7 @@ class SafetyMetaclass(type): class BasePlugin(object, metaclass=SafetyMetaclass): """ - Class that all plugins derive from. Any methods beginning with command_ - are interpreted as a command and beginning with on_ are interpreted as - event handlers + Class that all plugins derive from. """ def __init__(self, plugin_manager, core, plugins_conf_dir): @@ -65,22 +63,45 @@ class BasePlugin(object, metaclass=SafetyMetaclass): self.init() def init(self): + """ + Method called at the creation of the plugin. + Do not overwrite __init__ and use this instead. + """ pass def cleanup(self): + """ + Called when the plugin is unloaded. + Overwrite this if you want to erase or save things before the plugin is disabled. + """ pass def unload(self): self.cleanup() def add_command(self, name, handler, help, completion=None): + """ + Add a global command. + You cannot overwrite the existing commands. + """ return self.plugin_manager.add_command(self.__module__, name, handler, help, completion) def del_command(self, name): + """ + Remove a global command. + This only works if the command was added by the plugin + """ return self.plugin_manager.del_command(self.__module__, name) def add_event_handler(self, event_name, handler, position=0): + """ + Add an event handler to the event event_name. + An optional position in the event handler list can be provided. + """ return self.plugin_manager.add_event_handler(self.__module__, event_name, handler, position) def del_event_handler(self, event_name, handler): + """ + Remove 'handler' from the event list for 'event_name'. + """ return self.plugin_manager.del_event_handler(self.__module__, event_name, handler) -- cgit v1.2.3 From a7ed473437b6bc476c579e2e778947c572e7cd40 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 18:39:33 +0100 Subject: What. --- src/tabs.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index 93f48757..0e9f345a 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1027,7 +1027,6 @@ class MucTab(ChatTab): self.core.doupdate() hide_exit_join = config.get('hide_exit_join', -1) if config.get('hide_exit_join', -1) >= -1 else -1 if hide_exit_join == -1 or user.has_talked_since(hide_exit_join): - log.debug("\n\nALLO: USERCOLOR: %s\n\n" % user.color.__repr__()) color = user.color[0] if config.get('display_user_color_in_join_part', '') == 'true' else 3 if not jid.full: leave_msg = _('\x191}%(spec)s \x19%(color)d}%(nick)s\x195} has left the room') % {'nick':from_nick, 'color':color, 'spec':get_theme().CHAR_QUIT} -- cgit v1.2.3 From e6663c317c27efba3cfeea498d9ff91695e913ec Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 21:02:37 +0100 Subject: Do not display an empty message when only a chatstate is received (again). --- src/core.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index 35e2040f..b352f627 100644 --- a/src/core.py +++ b/src/core.py @@ -621,9 +621,7 @@ class Core(object): if not body: if message['type'] == 'error': self.information(self.get_error_message_from_error_stanza(message), 'Error') - return - elif not conversation: - return + return conversation = self.get_tab_of_conversation_with_jid(jid, create=True) self.events.trigger('conversation_msg', message, conversation) body = xhtml.get_body_from_message_stanza(message) -- cgit v1.2.3 From 1f5d1048344b3e68b5fb294371f269c398c8f69a Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 22:00:38 +0100 Subject: -get -set +@property +@property.setter --- src/contact.py | 81 +++++++++++++++++++++++++++++++++------------------------- src/core.py | 34 ++++++++++++------------ src/roster.py | 2 +- src/tabs.py | 40 ++++++++++++++--------------- src/windows.py | 40 ++++++++++++++--------------- 5 files changed, 104 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/contact.py b/src/contact.py index 99c24a32..1874ff59 100644 --- a/src/contact.py +++ b/src/contact.py @@ -26,30 +26,37 @@ class Resource(object): self._presence = 'unavailable' self._priority = 0 - def get_jid(self): + @property + def jid(self): return self._jid def __repr__(self): return '%s' % self._jid - def set_priority(self, priority): - assert isinstance(priority, int) - self._priority = priority - - def get_priority(self): + @property + def priority(self): return self._priority - def set_presence(self, pres): - self._presence = pres + @priority.setter + def priority(self, value): + assert isinstance(value, int) + self._priority = value - def get_presence(self): + @property + def presence(self): return self._presence - def get_status(self): + @presence.setter + def presence(self, value): + self._presence = value + + @property + def status(self): return self._status - def set_status(self, s): - self._status = s + @status.setter + def status(self, value): + self._status = value class Contact(object): """ @@ -66,16 +73,14 @@ class Contact(object): self._ask = None self._groups = [] # a list of groups the contact is in - def get_groups(self): - """ - Return the groups the contact is in - """ + @property + def groups(self): + """Groups the contact is in""" return self._groups - def get_bare_jid(self): - """ - Just get the bare_jid or the contact - """ + @property + def bare_jid(self): + """The bare_jid or the contact""" return self._jid def get_highest_priority_resource(self): @@ -84,7 +89,7 @@ class Contact(object): """ ret = None for resource in self._resources: - if not ret or ret.get_priority() < resource.get_priority(): + if not ret or ret.priority < resource.priority: ret = resource return ret @@ -94,7 +99,7 @@ class Contact(object): (the first, or any subsequent one) """ def f(o): - return o.get_priority() + return o.priority self._resources.append(resource) self._resources = sorted(self._resources, key=f, reverse=True) @@ -109,7 +114,7 @@ class Contact(object): Like 'remove_resource' but just by knowing the full jid """ for resource in self._resources: - if resource.get_jid().full == fulljid: + if resource.jid == fulljid: self._resources.remove(resource) return assert False @@ -119,7 +124,7 @@ class Contact(object): Return the resource with the given fulljid """ for resource in self._resources: - if resource.get_jid().full == fulljid: + if resource.jid.full == fulljid: return resource return None @@ -129,24 +134,30 @@ class Contact(object): """ self._folded = not self._folded - def set_name(self, name): - self._display_name = name - - def get_name(self): + @property + def name(self): return self._display_name - def set_ask(self, ask): - self._ask = ask + @name.setter + def name(self, value): + self._display_name = value - def get_ask(self): + @property + def ask(self): return self._ask - def set_subscription(self, sub): - self._subscription = sub + @ask.setter + def ask(self, value): + self._ask = value - def get_subscription(self): + @property + def subscription(self): return self._subscription + @subscription.setter + def subscription(self, value): + self._subscription = value + def get_nb_resources(self): """ Get the number of connected resources @@ -157,7 +168,7 @@ class Contact(object): """ Return all resources, sorted by priority """ - compare_resources = lambda x: x.get_priority() + compare_resources = lambda x: x.priority return sorted(self._resources, key=compare_resources) def __repr__(self): diff --git a/src/core.py b/src/core.py index b352f627..9109cff6 100644 --- a/src/core.py +++ b/src/core.py @@ -372,13 +372,13 @@ class Core(object): return # If a resource got offline, display the message in the conversation with this # precise resource. - self.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x191}offline' % (resource.get_jid().full)) + self.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x191}offline' % (resource.jid.full)) contact.remove_resource(resource) # Display the message in the conversation with the bare JID only if that was # the only resource online (i.e. now the contact is completely disconnected) if not contact.get_highest_priority_resource(): # No resource left: that was the last one self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x191}offline' % (jid.bare)) - self.information('\x193}%s \x195}is \x191}offline' % (resource.get_jid().bare), "Roster") + self.information('\x193}%s \x195}is \x191}offline' % (resource.jid.bare), "Roster") if isinstance(self.current_tab(), tabs.RosterInfoTab): self.refresh_window() @@ -395,18 +395,18 @@ class Core(object): status = presence['type'] status_message = presence['status'] priority = presence.getPriority() or 0 - resource.set_status(status_message) - resource.set_presence(status) - resource.set_priority(priority) + resource.status = status_message + resource.presence = status + resource.priority = priority self.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x194}online' % (jid.full)) if not contact.get_highest_priority_resource(): # No connected resource yet: the user's just connecting if time.time() - self.connection_time > 12: # We do not display messages if we recently logged in if status_message: - self.information("\x193}%s \x195}is \x194}online\x195} (\x19o%s\x195})" % (resource.get_jid().bare, status_message), "Roster") + self.information("\x193}%s \x195}is \x194}online\x195} (\x19o%s\x195})" % (resource.jid.bare, status_message), "Roster") else: - self.information("\x193}%s \x195}is \x194}online\x195}" % resource.get_jid().bare, "Roster") + self.information("\x193}%s \x195}is \x194}online\x195}" % resource.jid.bare, "Roster") self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x194}online' % (jid.bare)) contact.add_resource(resource) if isinstance(self.current_tab(), tabs.RosterInfoTab): @@ -655,9 +655,9 @@ class Core(object): status = presence['type'] status_message = presence['status'] priority = presence.getPriority() or 0 - resource.set_presence(status) - resource.set_priority(priority) - resource.set_status(status_message) + resource.presence = status + resource.priority = priority + resource.status = status_message if isinstance(self.current_tab(), tabs.RosterInfoTab): self.refresh_window() @@ -673,19 +673,19 @@ class Core(object): contact = Contact(jid) roster.add_contact(contact, jid) if 'ask' in item.attrib: - contact.set_ask(item.attrib['ask']) + contact.ask = item.attrib['ask'] else: - contact.set_ask(None) + contact.ask = None if 'name' in item.attrib: - contact.set_name(item.attrib['name']) + contact.name = item.attrib['name'] else: - contact.set_name(None) + contact.name = None if item.attrib['subscription']: - contact.set_subscription(item.attrib['subscription']) + contact.subscription = item.attrib['subscription'] groups = item.findall('{jabber:iq:roster}group') roster.edit_groups_of_contact(contact, [group.text for group in groups]) if item.attrib['subscription'] == 'remove': - roster.remove_contact(contact.get_bare_jid()) + roster.remove_contact(contact.bare_jid) if isinstance(self.current_tab(), tabs.RosterInfoTab): self.refresh_window() @@ -700,7 +700,7 @@ class Core(object): contact = Contact(jid) roster.add_contact(contact, jid) roster.edit_groups_of_contact(contact, []) - contact.set_ask('asked') + contact.ask = 'asked' self.get_tab_by_number(0).state = 'highlight' self.information('%s wants to subscribe to your presence'%jid, 'Roster') if isinstance(self.current_tab(), tabs.RosterInfoTab): diff --git a/src/roster.py b/src/roster.py index df84d4d8..5f214bb0 100644 --- a/src/roster.py +++ b/src/roster.py @@ -234,7 +234,7 @@ class RosterGroup(object): def compare_contact(a): if not a.get_highest_priority_resource(): return 0 - show = a.get_highest_priority_resource().get_presence() + show = a.get_highest_priority_resource() if show not in PRESENCE_PRIORITY: return 5 return PRESENCE_PRIORITY[show] diff --git a/src/tabs.py b/src/tabs.py index 0e9f345a..6ba94c50 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1487,10 +1487,10 @@ class RosterInfoTab(Tab): self.core.information(_('No such JID in roster'), 'Error') return - groups = set(contact.get_groups()) - subscription = contact.get_subscription() + groups = set(contact.groups) + subscription = contact.subscription if self.core.xmpp.update_roster(jid, name=name, groups=groups, subscription=subscription): - contact.set_name(name) + contact.name = name def command_groupadd(self, args): """ @@ -1507,7 +1507,7 @@ class RosterInfoTab(Tab): self.core.information(_('No such JID in roster'), 'Error') return - new_groups = set(contact.get_groups()) + new_groups = set(contact.groups) if group in new_groups: self.core.information(_('JID already in group'), 'Error') return @@ -1518,8 +1518,8 @@ class RosterInfoTab(Tab): except KeyError: pass - name = contact.get_name() - subscription = contact.get_subscription() + name = contact.name + subscription = contact.subscription if self.core.xmpp.update_roster(jid, name=name, groups=new_groups, subscription=subscription): roster.edit_groups_of_contact(contact, new_groups) @@ -1538,7 +1538,7 @@ class RosterInfoTab(Tab): self.core.information(_('No such JID in roster'), 'Error') return - new_groups = set(contact.get_groups()) + new_groups = set(contact.groups) try: new_groups.remove('none') except KeyError: @@ -1548,8 +1548,8 @@ class RosterInfoTab(Tab): return new_groups.remove(group) - name = contact.get_name() - subscription = contact.get_subscription() + name = contact.name + subscription = contact.subscription if self.core.xmpp.update_roster(jid, name=name, groups=new_groups, subscription=subscription): roster.edit_groups_of_contact(contact, new_groups) @@ -1624,7 +1624,7 @@ class RosterInfoTab(Tab): """ From with any JID presence in the roster """ - jids = [contact.get_bare_jid() for contact in roster.get_contacts()] + jids = [contact.bare_jid for contact in roster.get_contacts()] return the_input.auto_completion(jids, '') def completion_name(self, the_input): @@ -1634,7 +1634,7 @@ class RosterInfoTab(Tab): n += 1 if n == 2: - jids = [contact.get_bare_jid() for contact in roster.get_contacts()] + jids = [contact.bare_jid for contact in roster.get_contacts()] return the_input.auto_completion(jids, '') return False @@ -1645,7 +1645,7 @@ class RosterInfoTab(Tab): n += 1 if n == 2: - jids = [contact.get_bare_jid() for contact in roster.get_contacts()] + jids = [contact.bare_jid for contact in roster.get_contacts()] return the_input.auto_completion(jids, '') elif n == 3: groups = [group.name for group in roster.get_groups() if group.name != 'none'] @@ -1660,13 +1660,13 @@ class RosterInfoTab(Tab): n += 1 if n == 2: - jids = [contact.get_bare_jid() for contact in roster.get_contacts()] + jids = [contact.bare_jid for contact in roster.get_contacts()] return the_input.auto_completion(jids, '') elif n == 3: contact = roster.get_contact_by_jid(args[1]) if not contact: return False - groups = list(contact.get_groups()) + groups = list(contact.groups) try: groups.remove('none') except ValueError: @@ -1679,8 +1679,8 @@ class RosterInfoTab(Tab): Complete the first argument from the list of the contact with ask=='subscribe' """ - jids = [contact.get_bare_jid() for contact in roster.get_contacts()\ - if contact.get_ask() == 'asked'] + jids = [contact.bare_jid for contact in roster.get_contacts()\ + if contact.ask == 'asked'] return the_input.auto_completion(jids, '') def command_accept(self, args): @@ -1915,7 +1915,7 @@ class ConversationTab(ChatTab): else: resource = contact.get_highest_priority_resource() if resource: - self._text_buffer.add_message("\x195}Status: %s\x193}" %resource.get_status(), None, None, None, None, None) + self._text_buffer.add_message("\x195}Status: %s\x193}" %resource.status, None, None, None, None, None) self.refresh() self.core.doupdate() @@ -2219,7 +2219,7 @@ def jid_and_name_match(contact, txt): """ if not txt: return True - if txt in JID(contact.get_bare_jid()).user: + if txt in JID(contact.bare_jid).user: return True return False @@ -2230,9 +2230,9 @@ def jid_and_name_match_slow(contact, txt): """ if not txt: return True # Everything matches when search is empty - user = JID(contact.get_bare_jid()).user + user = JID(contact.bare_jid).user if diffmatch(txt, user): return True - if contact.get_name() and diffmatch(txt, contact.get_name()): + if contact.name and diffmatch(txt, contact.name): return True return False diff --git a/src/windows.py b/src/windows.py index 2253b871..ed5dfca2 100644 --- a/src/windows.py +++ b/src/windows.py @@ -415,7 +415,7 @@ class ConversationInfoWin(InfoWin): if not resource: presence = "unavailable" else: - presence = resource.get_presence() + presence = resource.presence color = RosterWin.color_show[presence]() self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.addstr(" ", to_curses_attr(color)) @@ -428,7 +428,7 @@ class ConversationInfoWin(InfoWin): if not contact: self.addstr("(contact not in roster)", to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) return - display_name = contact.get_name() or contact.get_bare_jid() + display_name = contact.name or contact.bare_jid self.addstr('%s '%(display_name), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_contact_jid(self, jid): @@ -468,7 +468,7 @@ class ConversationStatusMessageWin(InfoWin): self._refresh() def write_status_message(self, resource): - self.addstr(resource.get_status(), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr(resource.status, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) class MucInfoWin(InfoWin): """ @@ -1471,14 +1471,14 @@ class RosterWin(Win): presence = 'unavailable' nb = '' else: - presence = resource.get_presence() + presence = resource.presence nb = ' (%s)' % (contact.get_nb_resources(),) color = RosterWin.color_show[presence]() - if contact.get_name(): - display_name = '%s (%s)%s' % (contact.get_name(), - contact.get_bare_jid(), nb,) + if contact.name: + display_name = '%s (%s)%s' % (contact.name, + contact.bare_jid, nb,) else: - display_name = '%s%s' % (contact.get_bare_jid(), nb,) + display_name = '%s%s' % (contact.bare_jid, nb,) self.addstr(y, 0, ' ') self.addstr(" ", to_curses_attr(color)) if resource: @@ -1488,7 +1488,7 @@ class RosterWin(Win): self.addstr(display_name, to_curses_attr(get_theme().COLOR_SELECTED_ROW)) else: self.addstr(display_name) - if contact.get_ask() == 'asked': + if contact.ask == 'asked': self.addstr('?', to_curses_attr(get_theme().COLOR_HIGHLIGHT_NICK)) self.finish_line() @@ -1496,12 +1496,12 @@ class RosterWin(Win): """ Draw a specific resource line """ - color = RosterWin.color_show[resource.get_presence()]() + color = RosterWin.color_show[resource.presence]() self.addstr(y, 4, " ", to_curses_attr(color)) if colored: - self.addstr(y, 6, resource.get_jid().full, to_curses_attr(get_theme().COLOR_SELECTED_ROW)) + self.addstr(y, 6, resource.jid.full, to_curses_attr(get_theme().COLOR_SELECTED_ROW)) else: - self.addstr(y, 6, resource.get_jid().full) + self.addstr(y, 6, resource.jid.full) self.finish_line() def get_selected_row(self): @@ -1517,22 +1517,22 @@ class ContactInfoWin(Win): """ resource = contact.get_highest_priority_resource() if contact: - jid = contact.get_bare_jid() + jid = contact.bare_jid else: - jid = jid or resource.get_jid().full + jid = jid or resource.jid.full if resource: - presence = resource.get_presence() + presence = resource.presence else: presence = 'unavailable' self.addstr(0, 0, '%s (%s)'%(jid, presence,), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR) - self.addstr(1, 0, 'Subscription: %s' % (contact.get_subscription(),)) - if contact.get_ask(): + self.addstr(1, 0, 'Subscription: %s' % (contact.subscription,)) + if contact.ask: self.addstr(' ') - if contact.get_ask() == 'asked': - self.addstr('Ask: %s' % (contact.get_ask(),), to_curses_attr(get_theme().COLOR_HIGHLIGHT_NICK)) + if contact.ask == 'asked': + self.addstr('Ask: %s' % (contact.ask,), to_curses_attr(get_theme().COLOR_HIGHLIGHT_NICK)) else: - self.addstr('Ask: %s' % (contact.get_ask(),)) + self.addstr('Ask: %s' % (contact.ask,)) self.finish_line() -- cgit v1.2.3 From f55a0c92f21e8b0c5cbd1e0413f2c2a95b29a8ae Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 22:34:16 +0100 Subject: Do not send chatstates when the contact is offline --- src/core.py | 8 ++++---- src/tabs.py | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index 9109cff6..e6b1239b 100644 --- a/src/core.py +++ b/src/core.py @@ -626,7 +626,7 @@ class Core(object): self.events.trigger('conversation_msg', message, conversation) body = xhtml.get_body_from_message_stanza(message) if roster.get_contact_by_jid(jid.bare): - remote_nick = roster.get_contact_by_jid(jid.bare).get_name() or jid.user + remote_nick = roster.get_contact_by_jid(jid.bare).name or jid.user else: remote_nick = jid.user conversation._text_buffer.add_message(body, nickname=remote_nick, nick_color=get_theme().COLOR_REMOTE_USER) @@ -1590,10 +1590,10 @@ class Core(object): when enter is pressed on the roster window """ if isinstance(roster_row, Contact): - if not self.get_conversation_by_jid(roster_row.get_bare_jid()): - self.open_conversation_window(roster_row.get_bare_jid()) + if not self.get_conversation_by_jid(roster_row.bare_jid): + self.open_conversation_window(roster_row.bare_jid) else: - self.focus_tab_named(roster_row.get_bare_jid()) + self.focus_tab_named(roster_row.bare_jid) if isinstance(roster_row, Resource): if not self.get_conversation_by_jid(roster_row.get_jid().full): self.open_conversation_window(roster_row.get_jid().full) diff --git a/src/tabs.py b/src/tabs.py index 6ba94c50..7639f54f 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1975,17 +1975,31 @@ class ConversationTab(ChatTab): return False def on_lose_focus(self): + contact = roster.get_contact_by_jid(self.get_name()) + jid = JID(self.get_name()) + if jid.resource: + resource = contact.get_resource_by_fulljid(jid.full) + else: + resource = contact.get_highest_priority_resource() self.state = 'normal' self.text_win.remove_line_separator() self.text_win.add_line_separator() if config.get('send_chat_states', 'true') == 'true' and not self.input.get_text() or not self.input.get_text().startswith('//'): - self.send_chat_state('inactive') + if resource: + self.send_chat_state('inactive') def on_gain_focus(self): + contact = roster.get_contact_by_jid(self.get_name()) + jid = JID(self.get_name()) + if jid.resource: + resource = contact.get_resource_by_fulljid(jid.full) + else: + resource = contact.get_highest_priority_resource() self.state = 'current' curses.curs_set(1) if config.get('send_chat_states', 'true') == 'true' and not self.input.get_text() or not self.input.get_text().startswith('//'): - self.send_chat_state('active') + if resource: + self.send_chat_state('active') def on_scroll_up(self): self.text_win.scroll_up(self.text_win.height-1) -- cgit v1.2.3 From 4e0c1b0820432460750ea69c5bdeb47670f4c013 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 23:17:00 +0100 Subject: New events in the plugins API --- src/core.py | 5 +++++ src/events.py | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/core.py b/src/core.py index e6b1239b..986d1222 100644 --- a/src/core.py +++ b/src/core.py @@ -325,6 +325,7 @@ class Core(object): tab = self.get_tab_of_conversation_with_jid(message['from'], False) if not tab: return False + self.events.trigger('normal_chatstate', message, tab) tab.chatstate = state if tab == self.current_tab(): tab.refresh_info_header() @@ -335,6 +336,7 @@ class Core(object): tab = self.get_tab_by_name(message['from'].full, tabs.PrivateTab) if not tab: return + self.events.trigger('private_chatstate', message, tab) tab.chatstate = state if tab == self.current_tab(): tab.refresh_info_header() @@ -346,6 +348,7 @@ class Core(object): room_from = message.getMucroom() tab = self.get_tab_by_name(room_from, tabs.MucTab) if tab and tab.get_user_by_name(nick): + self.events.trigger('muc_chatstate', message, tab) tab.get_user_by_name(nick).chatstate = state if tab == self.current_tab(): tab.user_win.refresh(tab.users) @@ -487,6 +490,7 @@ class Core(object): from_room = presence['from'].bare tab = self.get_tab_by_name(from_room, tabs.MucTab) if tab: + self.events.trigger('muc_presence', presence, tab) tab.handle_presence(presence) def rename_private_tabs(self, room_name, old_nick, new_nick): @@ -652,6 +656,7 @@ class Core(object): resource = contact.get_resource_by_fulljid(jid.full) if not resource: return + self.events.trigger('normal_presence', presence, resource) status = presence['type'] status_message = presence['status'] priority = presence.getPriority() or 0 diff --git a/src/events.py b/src/events.py index cd45448f..1464b2d8 100644 --- a/src/events.py +++ b/src/events.py @@ -27,6 +27,11 @@ class EventHandler(object): 'conversation_msg': [], 'private_msg': [], 'muc_msg': [], + 'normal_chatstate': [], + 'muc_chatsate': [], + 'private_chatsate': [], + 'normal_presence': [], + 'muc_presence': [], } def add_event_handler(self, name, callback, position=0): -- cgit v1.2.3 From e467020e29aae638d018b8a793b1816f7a65c893 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 9 Nov 2011 23:28:01 +0100 Subject: Add messages on plugin load/unload --- src/plugin_manager.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/plugin_manager.py b/src/plugin_manager.py index 067cb10e..83ae53d5 100644 --- a/src/plugin_manager.py +++ b/src/plugin_manager.py @@ -61,6 +61,7 @@ class PluginManager(object): self.commands[name] = {} self.event_handlers[name] = [] self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir) + self.core.information('Plugin %s loaded' % name, 'Info') def unload(self, name): if name in self.plugins: @@ -74,6 +75,7 @@ class PluginManager(object): del self.plugins[name] del self.commands[name] del self.event_handlers[name] + self.core.information('Plugin %s unloaded' % name, 'Info') except Exception as e: import traceback self.core.information(_("Could not unload plugin (may not be safe to try again): ") + traceback.format_exc()) -- cgit v1.2.3 From 138a0b78cd17ff508be80c5c54b98b1a3fcce8d6 Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 11:29:17 +0100 Subject: Forgotten changes --- src/tabs.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index 7639f54f..64eda75a 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1449,8 +1449,8 @@ class RosterInfoTab(Tab): args = args.split() if not args: item = self.roster_win.selected_row - if isinstance(item, Contact) and item.get_ask() == 'asked': - jid = item.get_bare_jid() + if isinstance(item, Contact) and item.ask == 'asked': + jid = item.bare_jid else: self.core.information('No subscription to deny') return @@ -1563,7 +1563,7 @@ class RosterInfoTab(Tab): else: item = self.roster_win.selected_row if isinstance(item, Contact): - jid = item.get_bare_jid() + jid = item.bare_jid else: self.core.information('No roster item to remove') return @@ -1690,8 +1690,8 @@ class RosterInfoTab(Tab): args = args.split() if not args: item = self.roster_win.selected_row - if isinstance(item, Contact) and item.get_ask() == 'asked': - jid = item.get_bare_jid() + if isinstance(item, Contact) and item.ask == 'asked': + jid = item.bare_jid else: self.core.information('No subscription to accept') return -- cgit v1.2.3 From 953dc36c470ed8012322651abe8bc010e37153eb Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 11:45:23 +0100 Subject: typo --- src/events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/events.py b/src/events.py index 1464b2d8..ee08936e 100644 --- a/src/events.py +++ b/src/events.py @@ -28,8 +28,8 @@ class EventHandler(object): 'private_msg': [], 'muc_msg': [], 'normal_chatstate': [], - 'muc_chatsate': [], - 'private_chatsate': [], + 'muc_chatstate': [], + 'private_chatstate': [], 'normal_presence': [], 'muc_presence': [], } -- cgit v1.2.3 From 628ff3b0d982526aad48151bdce623d12b8db2b7 Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 14:39:19 +0100 Subject: Add per_tab_type commands for the plugins --- src/plugin.py | 12 ++++++++++++ src/plugin_manager.py | 31 +++++++++++++++++++++++++++++++ src/tabs.py | 25 +++++++++++++++++++++++++ 3 files changed, 68 insertions(+) (limited to 'src') diff --git a/src/plugin.py b/src/plugin.py index 40f96871..4dd88697 100644 --- a/src/plugin.py +++ b/src/plugin.py @@ -93,6 +93,18 @@ class BasePlugin(object, metaclass=SafetyMetaclass): """ return self.plugin_manager.del_command(self.__module__, name) + def add_tab_command(self, tab_type, name, handler, help, completion=None): + """ + Add a command only for a type of tab. + """ + return self.plugin_manager.add_tab_command(self.__module__, tab_type, name, handler, help, completion) + + def del_tab_command(self, tab_type, name): + """ + Delete a command added through add_tab_command. + """ + return self.plugin_manager.del_tab_command(self.__module__, tab_type, name) + def add_event_handler(self, event_name, handler, position=0): """ Add an event handler to the event event_name. diff --git a/src/plugin_manager.py b/src/plugin_manager.py index 83ae53d5..36887084 100644 --- a/src/plugin_manager.py +++ b/src/plugin_manager.py @@ -1,6 +1,7 @@ import imp import os import sys +import tabs from config import config from gettext import gettext as _ @@ -34,6 +35,7 @@ class PluginManager(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.tab_commands = {} #module name -> dict of tab types; tab type -> commands loaded by the module def load(self, name): if name in self.plugins: @@ -59,6 +61,7 @@ class PluginManager(object): self.modules[name] = module self.commands[name] = {} + self.tab_commands[name] = {} self.event_handlers[name] = [] self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir) self.core.information('Plugin %s loaded' % name, 'Info') @@ -68,12 +71,17 @@ class PluginManager(object): try: for command in self.commands[name].keys(): del self.core.commands[command] + for tab in list(self.tab_commands[name].keys()): + for command in self.tab_commands[name][tab]: + self.del_tab_command(name, getattr(tabs, tab), command[0]) + del self.tab_commands[name][tab] for event_name, handler in self.event_handlers[name]: self.del_event_handler(name, event_name, handler) self.plugins[name].unload() del self.plugins[name] del self.commands[name] + del self.tab_commands[name] del self.event_handlers[name] self.core.information('Plugin %s unloaded' % name, 'Info') except Exception as e: @@ -86,6 +94,29 @@ class PluginManager(object): if name in self.core.commands: del self.core.commands[name] + def add_tab_command(self, module_name, tab_type, name, handler, help, completion=None): + commands = self.tab_commands[module_name] + t = tab_type.__name__ + if not t in commands: + commands[t] = [] + commands[t].append((name, handler, help, completion)) + for tab in self.core.tabs: + if isinstance(tab, tab_type): + tab.add_plugin_command(name, handler, help, completion) + + def del_tab_command(self, module_name, tab_type, name): + commands = self.tab_commands[module_name] + t = tab_type.__name__ + if not t in commands: + return + for command in commands[t]: + if command[0] == name: + commands[t].remove(command) + del tab_type.plugin_commands[name] + for tab in self.core.tabs: + if isinstance(tab, tab_type) and name in tab.commands: + del tab.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,)) diff --git a/src/tabs.py b/src/tabs.py index 64eda75a..f037a368 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -91,6 +91,7 @@ class Tab(object): # and use them in on_input self.commands = {} # and their own commands + @property def core(self): if not Tab.tab_core: @@ -220,6 +221,18 @@ class Tab(object): def on_input(self, key): pass + def add_plugin_command(self, name, handler, help, completion=None): + if name in self.plugin_commands or name in self.commands: + return + self.plugin_commands[name] = (handler, help, completion) + self.commands[name] = (handler, help, completion) + self.update_commands() + + def update_commands(self): + for c in self.plugin_commands: + if not c in self.commands: + self.commands[name] = self.plugin_commands[c] + def on_lose_focus(self): """ called when this tab loses the focus. @@ -275,6 +288,7 @@ class ChatTab(Tab): Also, ^M is already bound to on_enter And also, add the /say command """ + plugin_commands = {} def __init__(self): Tab.__init__(self) self._text_buffer = TextBuffer() @@ -295,6 +309,7 @@ class ChatTab(Tab): _("""Usage: /say \nSay: Just send the message. Useful if you want your message to begin with a '/'."""), None) self.chat_state = None + self.update_commands() def last_words_completion(self): """ @@ -402,6 +417,7 @@ class MucTab(ChatTab): It contains an userlist, an input, a topic, an information and a chat zone """ message_type = 'groupchat' + plugin_commands = {} def __init__(self, jid, nick): ChatTab.__init__(self) self.own_nick = nick @@ -445,6 +461,7 @@ class MucTab(ChatTab): self.commands['clear'] = (self.command_clear, _('Usage: /clear\nClear: Clear the current buffer.'), None) self.resize() + self.update_commands() def scroll_user_list_up(self): self.user_win.scroll_up() @@ -1185,6 +1202,7 @@ class PrivateTab(ChatTab): The tab containg a private conversation (someone from a MUC) """ message_type = 'chat' + plugin_commands = {} def __init__(self, name, nick): ChatTab.__init__(self) self.own_nick = nick @@ -1203,6 +1221,7 @@ class PrivateTab(ChatTab): self.resize() self.parent_muc = self.core.get_tab_by_name(JID(name).bare, MucTab) self.on = True + self.update_commands() def completion(self): self.complete_commands(self.input) @@ -1380,6 +1399,7 @@ class RosterInfoTab(Tab): """ A tab, splitted in two, containing the roster and infos """ + plugin_commands = {} def __init__(self): Tab.__init__(self) self.name = "Roster" @@ -1414,6 +1434,7 @@ class RosterInfoTab(Tab): self.commands['import'] = (self.command_import, _("Usage: /import [/path/to/file]\nImport: Import your contacts from /path/to/file if specified, or $HOME/poezio_contacts if not."), None) self.commands['clear_infos'] = (self.command_clear_infos, _("Usage: /clear_infos\nClear Infos: Use this command to clear the info buffer."), None) self.resize() + self.update_commands() def resize(self): if not self.visible: @@ -1863,6 +1884,7 @@ class ConversationTab(ChatTab): """ The tab containg a normal conversation (not from a MUC) """ + plugin_commands = {} message_type = 'chat' def __init__(self, jid): ChatTab.__init__(self) @@ -1881,6 +1903,7 @@ class ConversationTab(ChatTab): self.commands['version'] = (self.command_version, _('Usage: /version\nVersion: Get the software version of the current interlocutor (usually its XMPP client and Operating System).'), None) self.commands['info'] = (self.command_info, _('Usage: /info\nInfo: Get the status of the contact.'), None) self.resize() + self.update_commands() def completion(self): self.complete_commands(self.input) @@ -2029,6 +2052,7 @@ class MucListTab(Tab): A tab listing rooms from a specific server, displaying various information, scrollable, and letting the user join them, etc """ + plugin_commands = {} def __init__(self, server): Tab.__init__(self) self.state = 'normal' @@ -2059,6 +2083,7 @@ class MucListTab(Tab): self.listview.refresh() self.tab_win.refresh() self.input.refresh() + self.update_commands() def resize(self): if not self.visible: -- cgit v1.2.3 From 5c122163921fd6baef67e7a40afefdd83f9ef9ca Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 15:17:30 +0100 Subject: Also in the DataFormTab --- src/data_forms.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/data_forms.py b/src/data_forms.py index 8445d3d2..8f19e41b 100644 --- a/src/data_forms.py +++ b/src/data_forms.py @@ -23,6 +23,7 @@ class DataFormsTab(Tab): A tab contaning various window type, displaying a form that the user needs to fill. """ + plugin_commands = {} def __init__(self, form, on_cancel, on_send, kwargs): Tab.__init__(self) self._form = form @@ -41,6 +42,7 @@ class DataFormsTab(Tab): self.key_func['^G'] = self.on_cancel self.key_func['^Y'] = self.on_send self.resize() + self.update_commands() def on_cancel(self): self._on_cancel(self._form) -- cgit v1.2.3 From eaced10c1667d0ddf8cf41aebf060a6c2be7173b Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 15:26:34 +0100 Subject: Also, do not crash when receiving a message from someone who is not a contact --- src/tabs.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index f037a368..5b9c9fe8 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -2000,10 +2000,13 @@ class ConversationTab(ChatTab): def on_lose_focus(self): contact = roster.get_contact_by_jid(self.get_name()) jid = JID(self.get_name()) - if jid.resource: - resource = contact.get_resource_by_fulljid(jid.full) + if contact: + if jid.resource: + resource = contact.get_resource_by_fulljid(jid.full) + else: + resource = contact.get_highest_priority_resource() else: - resource = contact.get_highest_priority_resource() + resource = None self.state = 'normal' self.text_win.remove_line_separator() self.text_win.add_line_separator() @@ -2014,10 +2017,14 @@ class ConversationTab(ChatTab): def on_gain_focus(self): contact = roster.get_contact_by_jid(self.get_name()) jid = JID(self.get_name()) - if jid.resource: - resource = contact.get_resource_by_fulljid(jid.full) + if contact: + if jid.resource: + resource = contact.get_resource_by_fulljid(jid.full) + else: + resource = contact.get_highest_priority_resource() else: - resource = contact.get_highest_priority_resource() + resource = None + self.state = 'current' curses.curs_set(1) if config.get('send_chat_states', 'true') == 'true' and not self.input.get_text() or not self.input.get_text().startswith('//'): -- cgit v1.2.3 From bd2d1caa0ab8f83500633d011b8c01b4213484fc Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 17:06:28 +0100 Subject: Autoload plugins in session_start instead of core.__init__ --- src/core.py | 3 +-- src/plugin_manager.py | 10 ++++++---- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index 986d1222..3ecf76f2 100644 --- a/src/core.py +++ b/src/core.py @@ -177,8 +177,6 @@ class Core(object): self.connected_events = {} - self.autoload_plugins() - def autoload_plugins(self): plugins = config.get('plugins_autoload', '') for plugin in plugins.split(): @@ -456,6 +454,7 @@ class Core(object): Called when we are connected and authenticated """ self.connection_time = time.time() + self.autoload_plugins() self.information(_("Authentication success.")) self.information(_("Your JID is %s") % self.xmpp.boundjid.full) if not self.xmpp.anon: diff --git a/src/plugin_manager.py b/src/plugin_manager.py index 36887084..fe4d2b7e 100644 --- a/src/plugin_manager.py +++ b/src/plugin_manager.py @@ -37,7 +37,7 @@ class PluginManager(object): self.event_handlers = {} # module name -> list of event_name/handler pairs loaded for the module self.tab_commands = {} #module name -> dict of tab types; tab type -> commands loaded by the module - def load(self, name): + def load(self, name, notify=True): if name in self.plugins: self.unload(name) @@ -64,9 +64,10 @@ class PluginManager(object): self.tab_commands[name] = {} self.event_handlers[name] = [] self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir) - self.core.information('Plugin %s loaded' % name, 'Info') + if notify: + self.core.information('Plugin %s loaded' % name, 'Info') - def unload(self, name): + def unload(self, name, notify=True): if name in self.plugins: try: for command in self.commands[name].keys(): @@ -83,7 +84,8 @@ class PluginManager(object): del self.commands[name] del self.tab_commands[name] del self.event_handlers[name] - self.core.information('Plugin %s unloaded' % name, 'Info') + if notify: + self.core.information('Plugin %s unloaded' % name, 'Info') except Exception as e: import traceback self.core.information(_("Could not unload plugin (may not be safe to try again): ") + traceback.format_exc()) -- cgit v1.2.3 From 80edd248ecbf1d983c796c6436c80e9e8c6726e9 Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 17:20:25 +0100 Subject: Make custom_host and custom_port work better --- src/connection.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/connection.py b/src/connection.py index dfc8ba85..0be94097 100644 --- a/src/connection.py +++ b/src/connection.py @@ -63,9 +63,11 @@ class Connection(sleekxmpp.ClientXMPP): # With anon auth. # (domain, config.get('port', 5222)) custom_host = config.get('custom_host', '') - custom_port = config.get('custom_port', -1) - if custom_host and custom_port != -1: + custom_port = config.get('custom_port', 5222) + if custom_host: res = self.connect((custom_host, custom_port), reattempt=False) + elif custom_port != 5222: + res = self.connect((self.boundjid.host, custom_port), reattempt=False) else: res = self.connect(reattempt=False) if not res: -- cgit v1.2.3 From fde8a8a1c96943a7531f3059eb8976d6894e3681 Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 20:59:55 +0100 Subject: Fixes #2231 --- src/tabs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index 5b9c9fe8..1e5775fc 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -2010,7 +2010,7 @@ class ConversationTab(ChatTab): self.state = 'normal' self.text_win.remove_line_separator() self.text_win.add_line_separator() - if config.get('send_chat_states', 'true') == 'true' and not self.input.get_text() or not self.input.get_text().startswith('//'): + if config.get('send_chat_states', 'true') == 'true' and (not self.input.get_text() or not self.input.get_text().startswith('//')): if resource: self.send_chat_state('inactive') @@ -2027,7 +2027,7 @@ class ConversationTab(ChatTab): self.state = 'current' curses.curs_set(1) - if config.get('send_chat_states', 'true') == 'true' and not self.input.get_text() or not self.input.get_text().startswith('//'): + if config.get('send_chat_states', 'true') == 'true' and (not self.input.get_text() or not self.input.get_text().startswith('//')): if resource: self.send_chat_state('active') -- cgit v1.2.3 From 0cb9a5a61f1ee01e1b9e2543393f0ee52580dfbc Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 10 Nov 2011 21:12:33 +0100 Subject: Fixes #2271 --- src/core.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index 3ecf76f2..993b40ca 100644 --- a/src/core.py +++ b/src/core.py @@ -1378,7 +1378,12 @@ class Core(object): else: tab.own_nick = nick tab.users = [] - self.enable_private_tabs(room) + if tab and tab.joined: + self.enable_private_tabs(room) + tab.state = "normal" + if tab == self.current_tab(): + tab.refresh() + self.doupdate() def get_bookmark_nickname(self, room_name): """ -- cgit v1.2.3 From ea5692544ad196b90d64e46d7b43ae8c68c34e64 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 11 Nov 2011 21:47:52 +0100 Subject: Fixes presence handhake --- src/core.py | 18 ++++++++++++++++-- src/tabs.py | 8 +++++++- 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index 993b40ca..50acf784 100644 --- a/src/core.py +++ b/src/core.py @@ -697,16 +697,30 @@ class Core(object): """ Triggered whenever a presence stanza with a type of subscribe, subscribed, unsubscribe, or unsubscribed is received. """ + jid = presence['from'].bare + contact = roster.get_contact_by_jid(jid) if presence['type'] == 'subscribe': - jid = presence['from'].bare - contact = roster.get_contact_by_jid(jid) if not contact: contact = Contact(jid) roster.add_contact(contact, jid) + log.debug("CONTACT: %s" % contact) + if contact.subscription in ('from', 'both'): + log.debug('FROM OR BOTH') + return + elif contact.subscription in ('to'): + log.debug('TO') + self.xmpp.sendPresence(pto=jid, ptype='subscribed') + self.xmpp.sendPresence(pto=jid, ptype='') + return roster.edit_groups_of_contact(contact, []) contact.ask = 'asked' self.get_tab_by_number(0).state = 'highlight' self.information('%s wants to subscribe to your presence'%jid, 'Roster') + elif presence['type'] == 'unsubscribed': + self.information('%s unsubscribed you from his presence'%jid, 'Roster') + elif presence['type'] == 'unsubscribe': + self.information('%s unsubscribed from your presence'%jid, 'Roster') + if isinstance(self.current_tab(), tabs.RosterInfoTab): self.refresh_window() diff --git a/src/tabs.py b/src/tabs.py index 1e5775fc..5a1a33a3 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1491,7 +1491,6 @@ class RosterInfoTab(Tab): self.core.information(_('No JID specified'), 'Error') return self.core.xmpp.sendPresence(pto=jid, ptype='subscribe') - self.core.xmpp.sendPresence(pto=jid, ptype='subscribed') def command_name(self, args): """ @@ -1588,6 +1587,7 @@ class RosterInfoTab(Tab): else: self.core.information('No roster item to remove') return + self.core.xmpp.sendPresence(pto=jid, ptype='unavailable') self.core.xmpp.sendPresence(pto=jid, ptype='unsubscribe') self.core.xmpp.sendPresence(pto=jid, ptype='unsubscribed') self.core.xmpp.del_roster_item(jid=jid) @@ -1719,6 +1719,12 @@ class RosterInfoTab(Tab): else: jid = args[0] self.core.xmpp.sendPresence(pto=jid, ptype='subscribed') + self.core.xmpp.sendPresence(pto=jid, ptype='') + contact = roster.get_contact_by_jid(jid) + if not contact: + return + if contact.subscription in ('to', 'none'): + self.core.xmpp.sendPresence(pto=jid, ptype='subscribe') def refresh(self): if self.need_resize: -- cgit v1.2.3 From 0cfe87a9a6d3ce85ed11114b0607ac178f2a5821 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 11 Nov 2011 22:13:51 +0100 Subject: Fix a (possible) traceback on /remove --- src/tabs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index 5a1a33a3..e0419fda 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1590,7 +1590,10 @@ class RosterInfoTab(Tab): self.core.xmpp.sendPresence(pto=jid, ptype='unavailable') self.core.xmpp.sendPresence(pto=jid, ptype='unsubscribe') self.core.xmpp.sendPresence(pto=jid, ptype='unsubscribed') - self.core.xmpp.del_roster_item(jid=jid) + try: + self.core.xmpp.del_roster_item(jid=jid) + except: + pass def command_import(self, arg): """ -- cgit v1.2.3 From e53446a7b2061f7e52dfbf19b0ad23b18b213bda Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 11 Nov 2011 22:15:04 +0100 Subject: Add a /presence command for directed presences --- src/core.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/core.py b/src/core.py index 50acf784..a4211a3f 100644 --- a/src/core.py +++ b/src/core.py @@ -15,6 +15,7 @@ import threading import traceback from datetime import datetime +from xml.etree import cElementTree as ET from inspect import getargspec @@ -131,6 +132,7 @@ class Core(object): 'load': (self.command_load, _('Usage: /load \nLoad: Load the specified plugin'), self.plugin_manager.completion_load), 'unload': (self.command_unload, _('Usage: /unload \nUnload: Unload the specified plugin'), self.plugin_manager.completion_unload), 'plugins': (self.command_plugins, _('Usage: /plugins\nPlugins: Show the plugins in use.'), None), + 'presence': (self.command_presence, _('Usage: /presence\nPresence: Send a directed presence.'), None), } self.key_func = { @@ -1156,6 +1158,19 @@ class Core(object): if isinstance(current, tabs.MucTab) and current.joined and show not in ('away', 'xa'): current.send_chat_state('active') + def command_presence(self, arg): + """ + /presence + """ + if not arg: + return + try: + self.xmpp.Presence(xml=ET.fromstring(arg)).send() + except : + import traceback + self.information(_('Could not send directed presence'), 'Error') + log.debug(_("Could not send directed presence:\n") + traceback.format_exc()) + def completion_status(self, the_input): return the_input.auto_completion([status for status in possible_show], ' ') -- cgit v1.2.3 From b13f8786cf2ef229e5dcaa3c5fd8770ec0c6ee10 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 11 Nov 2011 22:36:43 +0100 Subject: Modify /presence --- src/core.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index a4211a3f..04f89172 100644 --- a/src/core.py +++ b/src/core.py @@ -132,7 +132,7 @@ class Core(object): 'load': (self.command_load, _('Usage: /load \nLoad: Load the specified plugin'), self.plugin_manager.completion_load), 'unload': (self.command_unload, _('Usage: /unload \nUnload: Unload the specified plugin'), self.plugin_manager.completion_unload), 'plugins': (self.command_plugins, _('Usage: /plugins\nPlugins: Show the plugins in use.'), None), - 'presence': (self.command_presence, _('Usage: /presence\nPresence: Send a directed presence.'), None), + 'presence': (self.command_presence, _('Usage: /presence [type] [status]\nPresence: Send a directed presence to and using [type] and [status] if provided.'), None), } self.key_func = { @@ -1160,12 +1160,21 @@ class Core(object): def command_presence(self, arg): """ - /presence + /presence [type] [status] """ - if not arg: + args = common.shell_split(arg) + if len(args) == 1: + jid, type, status = args[0], None, None + elif len(args) == 2: + jid, type, status = args[0], args[1], None + elif len(args) == 3: + jid, type, status = args[0], args[1], args[2] + else: return + if type == 'available': + type = None try: - self.xmpp.Presence(xml=ET.fromstring(arg)).send() + self.xmpp.make_presence(pto=jid, ptype=type, pstatus=status).send() except : import traceback self.information(_('Could not send directed presence'), 'Error') -- cgit v1.2.3 From 101b20724f897824e047b32dcd01bf365d4aa9ba Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 11 Nov 2011 22:45:44 +0100 Subject: Fix a refresh issue in the ConversationTab on status change --- src/core.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/core.py b/src/core.py index 04f89172..5f173d63 100644 --- a/src/core.py +++ b/src/core.py @@ -664,8 +664,12 @@ class Core(object): resource.presence = status resource.priority = priority resource.status = status_message + tab = self.get_tab_of_conversation_with_jid(jid, create=False) if isinstance(self.current_tab(), tabs.RosterInfoTab): self.refresh_window() + elif self.current_tab() == tab: + tab.refresh() + self.doupdate() def on_roster_update(self, iq): """ -- cgit v1.2.3 From 1cca4b8a1fa125ab1cb6d5e9ce806c053e4a95f3 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 11 Nov 2011 22:58:48 +0100 Subject: /rawxml command --- src/core.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/core.py b/src/core.py index 5f173d63..6cd7b97b 100644 --- a/src/core.py +++ b/src/core.py @@ -26,6 +26,7 @@ import singleton import collections from sleekxmpp.xmlstream.stanzabase import JID +from sleekxmpp.xmlstream.stanzabase import StanzaBase log = logging.getLogger(__name__) @@ -133,6 +134,7 @@ class Core(object): 'unload': (self.command_unload, _('Usage: /unload \nUnload: Unload the specified plugin'), self.plugin_manager.completion_unload), 'plugins': (self.command_plugins, _('Usage: /plugins\nPlugins: Show the plugins in use.'), None), 'presence': (self.command_presence, _('Usage: /presence [type] [status]\nPresence: Send a directed presence to and using [type] and [status] if provided.'), None), + 'rawxml': (self.command_rawxml, _('Usage: /rawxml\nRawXML: Send a custom xml stanza.'), None), } self.key_func = { @@ -1162,6 +1164,20 @@ class Core(object): if isinstance(current, tabs.MucTab) and current.joined and show not in ('away', 'xa'): current.send_chat_state('active') + def command_rawxml(self, arg): + """" + /rawxml + """ + if not arg: + return + + try: + StanzaBase(self.xmpp, xml=ET.fromstring(arg)).send() + except: + import traceback + self.information(_('Could not send custom stanza'), 'Error') + log.debug(_("Could not send custom stanza:\n") + traceback.format_exc()) + def command_presence(self, arg): """ /presence [type] [status] -- cgit v1.2.3 From 632175b79fb4d15a2358fc0604fe1bb85a076188 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 11 Nov 2011 23:55:31 +0100 Subject: Fix the xhtml parser (do not add wrong colors) --- src/xhtml.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xhtml.py b/src/xhtml.py index 99e0bf01..e7a045fa 100644 --- a/src/xhtml.py +++ b/src/xhtml.py @@ -258,7 +258,9 @@ def xhtml_to_poezio_colors(text): if key == 'background-color': pass#shell += '\x191' elif key == 'color': - shell += '\x19%d}' % get_color(value) + color = get_color(value) + if color != -1: + shell += '\x19%d}' % color elif key == 'font-style': shell += '\x19i' elif key == 'font-weight': -- cgit v1.2.3 From 4d5e2d21a464e6af56e5c968490c2dea61670011 Mon Sep 17 00:00:00 2001 From: mathieui Date: Sat, 12 Nov 2011 00:00:17 +0100 Subject: /xhtml command, Fixes #2237 --- src/tabs.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index e0419fda..02678e7e 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -46,6 +46,7 @@ from os import getenv, path from logger import logger from datetime import datetime, timedelta +from xml.etree import cElementTree as ET SHOW_NAME = { 'dnd': _('busy'), @@ -308,6 +309,7 @@ class ChatTab(Tab): self.commands['say'] = (self.command_say, _("""Usage: /say \nSay: Just send the message. Useful if you want your message to begin with a '/'."""), None) + self.commands['xhtml'] = (self.command_xhtml, _("Usage: /xhtml \nXHTML: Send custom XHTML."), None) self.chat_state = None self.update_commands() @@ -339,6 +341,29 @@ class ChatTab(Tab): self.command_say(xhtml.convert_simple_to_full_colors(txt)) self.cancel_paused_delay() + def command_xhtml(self, arg): + """" + /xhtml + """ + if not arg: + return + try: + body = xhtml.clean_text(xhtml.xhtml_to_poezio_colors(arg)) + ET.fromstring(arg) + except: + self.core.information('Could not send custom xhtml', 'Error') + return + + msg = self.core.xmpp.make_message(self.get_name()) + msg['body'] = body + msg['xhtml_im'] = arg + if isinstance(self, MucTab): + msg['type'] = 'groupchat' + if isinstance(self, ConversationTab): + self.core.add_message_to_text_buffer(self._text_buffer, body, None, self.core.own_nick) + self.refresh() + msg.send() + def send_chat_state(self, state, always_send=False): """ Send an empty chatstate message -- cgit v1.2.3 From 0c7674efb1e922f5aee2a2fe6efa7c4a794ba4de Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 12 Nov 2011 02:40:24 +0100 Subject: New event: send_normal_presence --- src/core.py | 10 ++++++++-- src/events.py | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index 6cd7b97b..b7e24c50 100644 --- a/src/core.py +++ b/src/core.py @@ -397,6 +397,7 @@ class Core(object): resource = contact.get_resource_by_fulljid(jid.full) assert not resource resource = Resource(jid.full) + self.events.trigger('normal_presence', presence, resource) status = presence['type'] status_message = presence['status'] priority = presence.getPriority() or 0 @@ -465,7 +466,9 @@ class Core(object): # request the roster self.xmpp.getRoster() # send initial presence - self.xmpp.makePresence().send() + pres = self.xmpp.make_presence() + self.events.trigger('send_normal_presence', pres) + pres.send() rooms = config.get('rooms', '') if rooms == '' or not isinstance(rooms, str): return @@ -1153,6 +1156,7 @@ class Core(object): if msg: pres['status'] = msg pres['type'] = show + self.events.trigger('send_normal_presence', pres) pres.send() current = self.current_tab() if isinstance(current, tabs.MucTab) and current.joined and show in ('away', 'xa'): @@ -1194,7 +1198,9 @@ class Core(object): if type == 'available': type = None try: - self.xmpp.make_presence(pto=jid, ptype=type, pstatus=status).send() + pres = self.xmpp.make_presence(pto=jid, ptype=type, pstatus=status) + self.events.trigger('send_normal_presence', pres) + pres.send() except : import traceback self.information(_('Could not send directed presence'), 'Error') diff --git a/src/events.py b/src/events.py index ee08936e..3a8e4d08 100644 --- a/src/events.py +++ b/src/events.py @@ -32,6 +32,7 @@ class EventHandler(object): 'private_chatstate': [], 'normal_presence': [], 'muc_presence': [], + 'send_normal_presence': [], } def add_event_handler(self, name, callback, position=0): -- cgit v1.2.3 From 3dda32ea5b2e5329e035f2b3f8ee49271e1512b3 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 12 Nov 2011 02:46:44 +0100 Subject: Do not ignore presence coming from a JID not in our roster. --- src/core.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index b7e24c50..9622c0a0 100644 --- a/src/core.py +++ b/src/core.py @@ -658,11 +658,12 @@ class Core(object): jid = presence['from'] contact = roster.get_contact_by_jid(jid.bare) if not contact: - return - resource = contact.get_resource_by_fulljid(jid.full) + resource = None + else: + resource = contact.get_resource_by_fulljid(jid.full) + self.events.trigger('normal_presence', presence, resource) if not resource: return - self.events.trigger('normal_presence', presence, resource) status = presence['type'] status_message = presence['status'] priority = presence.getPriority() or 0 -- cgit v1.2.3 From 744af2459d7d3a3c7a7e9d1f3861d4d494a837ba Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 12 Nov 2011 03:42:07 +0100 Subject: Add three new events to modify a message JUST before we send it. It is NOT safe, and the doc says that pretty clearly. It is used to encrypt messages just before sending them (this way we can remove ALL potential in-clear bodies). --- src/events.py | 3 +++ src/tabs.py | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/events.py b/src/events.py index 3a8e4d08..e94acb80 100644 --- a/src/events.py +++ b/src/events.py @@ -22,8 +22,11 @@ class EventHandler(object): self.events = { 'highlight': [], 'muc_say': [], + 'muc_say_after': [], 'conversation_say': [], + 'conversation_say_after': [], 'private_say': [], + 'private_say_after': [], 'conversation_msg': [], 'private_msg': [], 'muc_msg': [], diff --git a/src/tabs.py b/src/tabs.py index 02678e7e..d7f1323b 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -771,6 +771,7 @@ class MucTab(ChatTab): if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: msg['chat_state'] = needed self.cancel_paused_delay() + self.core.events.trigger('muc_say_after', msg, self) msg.send() self.chat_state = needed @@ -1268,6 +1269,7 @@ class PrivateTab(ChatTab): if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed + self.core.events.trigger('private_say_after', msg, self) msg.send() self.cancel_paused_delay() self.text_win.refresh() @@ -1958,6 +1960,7 @@ class ConversationTab(ChatTab): if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed + self.core.events.trigger('conversation_say_after', msg, self) msg.send() logger.log_message(JID(self.get_name()).bare, self.core.own_nick, line) self.cancel_paused_delay() -- cgit v1.2.3 From 9e8706a2e8bfb5dc1242ca42f87a6e3df90d9138 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 12 Nov 2011 05:48:29 +0100 Subject: =?UTF-8?q?a=20plugin=20can=20now=20add=20informations=20in=20Conv?= =?UTF-8?q?ersationTab=E2=80=99s=20InfoWin.=20And=20the=20GPG=20plugin=20d?= =?UTF-8?q?oes=20that.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tabs.py | 16 ++++++++++++++-- src/windows.py | 24 ++++++++++++++++-------- 2 files changed, 30 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/tabs.py b/src/tabs.py index d7f1323b..472a15fa 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1921,6 +1921,7 @@ class ConversationTab(ChatTab): The tab containg a normal conversation (not from a MUC) """ plugin_commands = {} + additional_informations = {} message_type = 'chat' def __init__(self, jid): ChatTab.__init__(self) @@ -1941,6 +1942,17 @@ class ConversationTab(ChatTab): self.resize() self.update_commands() + @staticmethod + def add_information_element(plugin_name, callback): + """ + Lets a plugin add its own information to the ConversationInfoWin + """ + ConversationTab.additional_informations[plugin_name] = callback + + @staticmethod + def remove_information_element(plugin_name): + del ConversationTab.additional_informations[plugin_name] + def completion(self): self.complete_commands(self.input) @@ -2013,13 +2025,13 @@ class ConversationTab(ChatTab): log.debug(' TAB Refresh: %s'%self.__class__.__name__) self.text_win.refresh() self.upper_bar.refresh(self.get_name(), roster.get_contact_by_jid(self.get_name())) - self.info_header.refresh(self.get_name(), roster.get_contact_by_jid(self.get_name()), self.text_win, self.chatstate) + self.info_header.refresh(self.get_name(), roster.get_contact_by_jid(self.get_name()), self.text_win, self.chatstate, ConversationTab.additional_informations) self.info_win.refresh() self.tab_win.refresh() self.input.refresh() def refresh_info_header(self): - self.info_header.refresh(self.get_name(), roster.get_contact_by_jid(self.get_name()), self.text_win, self.chatstate) + self.info_header.refresh(self.get_name(), roster.get_contact_by_jid(self.get_name()), self.text_win, self.chatstate, ConversationTab.additional_informations) self.input.refresh() def get_name(self): diff --git a/src/windows.py b/src/windows.py index ed5dfca2..d7471d40 100644 --- a/src/windows.py +++ b/src/windows.py @@ -368,19 +368,19 @@ class ConversationInfoWin(InfoWin): about the user we are talking to """ color_show = {'xa': lambda: get_theme().COLOR_STATUS_XA, - 'none': lambda: get_theme().COLOR_STATUS_ONLINE, - '': lambda: get_theme().COLOR_STATUS_ONLINE, - 'available': lambda: get_theme().COLOR_STATUS_ONLINE, - 'dnd': lambda: get_theme().COLOR_STATUS_DND, - 'away': lambda: get_theme().COLOR_STATUS_AWAY, - 'chat': lambda: get_theme().COLOR_STATUS_CHAT, - 'unavailable': lambda: get_theme().COLOR_STATUS_UNAVAILABLE + 'none': lambda: get_theme().COLOR_STATUS_ONLINE, + '': lambda: get_theme().COLOR_STATUS_ONLINE, + 'available': lambda: get_theme().COLOR_STATUS_ONLINE, + 'dnd': lambda: get_theme().COLOR_STATUS_DND, + 'away': lambda: get_theme().COLOR_STATUS_AWAY, + 'chat': lambda: get_theme().COLOR_STATUS_CHAT, + 'unavailable': lambda: get_theme().COLOR_STATUS_UNAVAILABLE } def __init__(self): InfoWin.__init__(self) - def refresh(self, jid, contact, window, chatstate): + def refresh(self, jid, contact, window, chatstate, informations): # contact can be None, if we receive a message # from someone not in our roster. In this case, we display # only the maximum information from the message we can get. @@ -405,9 +405,17 @@ class ConversationInfoWin(InfoWin): self.write_resource_information(resource) self.print_scroll_position(window) self.write_chatstate(chatstate) + self.write_additional_informations(informations, jid) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh() + def write_additional_informations(self, informations, jid): + """ + Write all informations added by plugins by getting the + value returned by the callbacks. + """ + for key in informations: + self.addstr(informations[key](jid), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) def write_resource_information(self, resource): """ Write the informations about the resource -- cgit v1.2.3 From a1096281e0c344846c4a86fe5b5a385c94604a13 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 12 Nov 2011 06:02:05 +0100 Subject: Fix an tb because the get_jid method was changed. --- src/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index 9622c0a0..ddb63502 100644 --- a/src/core.py +++ b/src/core.py @@ -1669,10 +1669,10 @@ class Core(object): else: self.focus_tab_named(roster_row.bare_jid) if isinstance(roster_row, Resource): - if not self.get_conversation_by_jid(roster_row.get_jid().full): - self.open_conversation_window(roster_row.get_jid().full) + if not self.get_conversation_by_jid(roster_row.jid.full): + self.open_conversation_window(roster_row.jid.full) else: - self.focus_tab_named(roster_row.get_jid().full) + self.focus_tab_named(roster_row.jid.full) self.refresh_window() def remove_timed_event(self, event): -- cgit v1.2.3 From e677a5bec1fec0bca3131754dd7cb3260ff10c94 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 12 Nov 2011 06:09:22 +0100 Subject: When we receive a message, open a tab with the concerned FULL jid. --- src/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core.py b/src/core.py index ddb63502..1f93324d 100644 --- a/src/core.py +++ b/src/core.py @@ -615,8 +615,8 @@ class Core(object): conversation = self.get_tab_by_name(jid.bare, tabs.ConversationTab) if not conversation: if create: - # We create the conversation with the bare Jid if nothing was found - conversation = self.open_conversation_window(jid.bare, False) + # We create the conversation with the full Jid if nothing was found + conversation = self.open_conversation_window(jid.full, False) else: conversation = None return conversation -- cgit v1.2.3