From d2d04162146e6df454d67a4e48ee6655af1d6c0a Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 11 Mar 2013 17:54:29 +0100 Subject: [PATCH] Fix #1841 (User nickname) - add a use_pep_nick boolean option - use it as a nickname for roster contacts, but it does not supercede the user-defined handle - send a at the beginning of a normal chat - not implemented in MUC (wontfix) --- data/default_config.cfg | 4 ++++ doc/en/configure.txt | 5 +++++ src/connection.py | 2 ++ src/contact.py | 8 ++++++- src/core.py | 50 +++++++++++++++++++++++++++++++++++++---- src/tabs.py | 9 +++++++- 6 files changed, 72 insertions(+), 6 deletions(-) diff --git a/data/default_config.cfg b/data/default_config.cfg index dacfd91c..cbab6f64 100644 --- a/data/default_config.cfg +++ b/data/default_config.cfg @@ -349,6 +349,10 @@ display_tune_notifications = false # option will be ignored. receive_user_tune = true +# If set to true, use the nickname broadcasted by the user if none has been +# set manually. +use_pep_nick = true + # if true, chat states will be sent to the people you are talking to. # Chat states are, for example, messages informing that you are composing # a message or that you closed the tab, etc diff --git a/doc/en/configure.txt b/doc/en/configure.txt index d0bc57b1..ecd1fc40 100644 --- a/doc/en/configure.txt +++ b/doc/en/configure.txt @@ -437,6 +437,11 @@ section of this documentation. Set to 'false' if you don’t want to save logs of all the messages in files. +*use_pep_nick*:: true + + Use the nickname broadcasted by the user if set to true, and if none + has already been set manually. + *use_remote_bookmarks*:: true Use this option to force the use of local bookmarks if needed. diff --git a/src/connection.py b/src/connection.py index 51fef78d..d5a393c5 100644 --- a/src/connection.py +++ b/src/connection.py @@ -74,6 +74,8 @@ class Connection(sleekxmpp.ClientXMPP): if config.get('receive_user_tune', 'true') != 'false': self.register_plugin('xep_0118') + if config.get('use_pep_nick', 'true') != 'false': + self.register_plugin('xep_0172') if config.get('send_poezio_info', 'true') == 'true': info = {'name':'poezio', 'version': options.version} diff --git a/src/contact.py b/src/contact.py index 27a0c701..46cf8e6f 100644 --- a/src/contact.py +++ b/src/contact.py @@ -65,6 +65,7 @@ class Contact(object): """ self.__item = item self.folded_states = defaultdict(lambda: True) + self._name = '' self.error = None self.tune = {} @@ -81,7 +82,12 @@ class Contact(object): @property def name(self): """The name of the contact or an empty string.""" - return self.__item['name'] or '' + return self.__item['name'] or self._name or '' + + @name.setter + def name(self, value): + """Set the name of the contact with user nickname""" + self._name = value @property def ask(self): diff --git a/src/core.py b/src/core.py index 8a5408d2..1a53baa7 100644 --- a/src/core.py +++ b/src/core.py @@ -260,6 +260,8 @@ class Core(object): self.xmpp.add_event_handler("attention", self.on_attention) self.xmpp.add_event_handler("ssl_cert", self.validate_ssl) self.all_stanzas = Callback('custom matcher', connection.MatchAll(None), self.incoming_stanza) + if config.get('use_pep_nick', 'true') != 'false': + self.xmpp.add_event_handler("user_nick_publish", self.on_nick_received) self.xmpp.register_handler(self.all_stanzas) self.initial_joins = [] @@ -2545,6 +2547,22 @@ class Core(object): When receiving "normal" messages (from someone in our roster) """ jid = message['from'] + + + # check for a name + if jid.bare in roster: + remote_nick = roster[jid.bare].name + else: + remote_nick = '' + # check for a received nick + if not remote_nick and config.get('use_pep_nick', 'true') != 'false': + if message.xml.find('{http://jabber.org/protocol/nick}nick') is not None: + remote_nick = message['nick']['nick'] + # bind the nick to the conversation + conversation = self.get_conversation_by_jid(jid, create=False) + if conversation and remote_nick and jid.bare not in roster: + conversation.nick = remote_nick + body = xhtml.get_body_from_message_stanza(message) if message['type'] == 'error': return self.information(self.get_error_message(message, deprecated=True), 'Error') @@ -2553,16 +2571,21 @@ class Core(object): if not body: return conversation = self.get_conversation_by_jid(jid, create=True) + + if not remote_nick and conversation.nick: + remote_nick = conversation.nick + elif jid.bare not in roster and remote_nick: + conversation.nick = remote_nick + elif not remote_nick: + remote_nick = jid.user + self.events.trigger('conversation_msg', message, conversation) body = xhtml.get_body_from_message_stanza(message) if not body: return if isinstance(conversation, tabs.DynamicConversationTab): conversation.lock(jid.resource) - if jid.bare in roster: - remote_nick = roster[jid.bare].name or jid.user - else: - remote_nick = jid.user + conversation.nick = remote_nick delay_tag = message.find('{urn:xmpp:delay}delay') if delay_tag is not None: delayed = True @@ -2599,7 +2622,23 @@ class Core(object): else: self.refresh_window() + def on_nick_received(self, message): + """ + Called when a pep notification for an user nickname + is received + """ + contact = roster[message['from'].bare] + if not contact: + return + item = message['pubsub_event']['items']['item'] + if item.xml.find('{http://jabber.org/protocol/nick}nick') is not None: + contact.name = item['nick']['nick'] + def on_tune_event(self, message): + """ + Called when a pep notification for an user tune + is received + """ contact = roster[message['from'].bare] if not contact: return @@ -3029,6 +3068,9 @@ class Core(object): status=self.status.message, show=self.status.show) + if config.get('use_pep_nick', 'true') != 'false': + self.xmpp.plugin['xep_0172'].publish_nick(nick=self.own_nick) + ### Other handlers ### def on_status_codes(self, message): diff --git a/src/tabs.py b/src/tabs.py index b0ad9569..3805a690 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -2679,7 +2679,7 @@ class RosterInfoTab(Tab): self.core.xmpp.send_presence(pto=jid, ptype='subscribed') self.core.xmpp.client_roster.send_last_presence() if contact.subscription in ('from', 'none') and not contact.pending_out: - self.core.xmpp.send_presence(pto=jid, ptype='subscribe') + self.core.xmpp.send_presence(pto=jid, ptype='subscribe', pnick=self.core.own_nick) def refresh(self): if self.need_resize: @@ -2938,6 +2938,8 @@ class ConversationTab(ChatTab): message_type = 'chat' def __init__(self, jid): ChatTab.__init__(self, jid) + self.nick = None + self.nick_sent = False self.state = 'normal' self.name = jid # a conversation tab is linked to one specific full jid OR bare jid self.text_win = windows.TextWin() @@ -2988,6 +2990,9 @@ class ConversationTab(ChatTab): msg = self.core.xmpp.make_message(self.get_dest_jid()) msg['type'] = 'chat' msg['body'] = line + if not self.nick_sent: + msg['nick'] = self.core.own_nick + self.nick_sent = True # trigger the event BEFORE looking for colors. # and before displaying the message in the window # This lets a plugin insert \x19xxx} colors, that will @@ -3143,6 +3148,8 @@ class ConversationTab(ChatTab): if contact: return contact.name or jid.user else: + if self.nick: + return self.nick return jid.user def on_input(self, key, raw):