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 <nick/> at the beginning of a normal chat
- not implemented in MUC (wontfix)
This commit is contained in:
mathieui 2013-03-11 17:54:29 +01:00
parent 34af8f69c7
commit d2d0416214
6 changed files with 72 additions and 6 deletions

View file

@ -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

View file

@ -437,6 +437,11 @@ section of this documentation.
Set to 'false' if you dont 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.

View file

@ -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}

View file

@ -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):

View file

@ -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):

View file

@ -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):