JEP 172 support (user nickname) Fixes #464 and #884

This commit is contained in:
Yann Leboulanger 2006-06-01 15:23:38 +00:00
parent 25e6d9f4aa
commit 59c3b7b3c8
8 changed files with 91 additions and 29 deletions

View File

@ -97,7 +97,8 @@ class ChatControlBase(MessageControl):
event_keymod):
pass # Derived should implement this rather than connecting to the event itself.
def __init__(self, type_id, parent_win, widget_name, display_names, contact, acct, resource = None):
def __init__(self, type_id, parent_win, widget_name, display_names, contact,
acct, resource = None):
MessageControl.__init__(self, type_id, parent_win, widget_name,
display_names, contact, acct, resource = resource);
# when/if we do XHTML we will but formatting buttons back
@ -175,6 +176,10 @@ class ChatControlBase(MessageControl):
self.style_event_id = 0
self.conv_textview.tv.show()
# For JEP-0172
self.user_nick = None
# moved from ChatControl
def _on_banner_eventbox_button_press_event(self, widget, event):
'''If right-clicked, show popup'''
@ -425,13 +430,18 @@ class ChatControlBase(MessageControl):
if not message or message == '\n':
return
if not self._process_command(message):
MessageControl.send_message(self, message, keyID, type = type,
chatstate = chatstate, msg_id = msg_id,
composing_jep = composing_jep, resource = resource)
composing_jep = composing_jep, resource = resource,
user_nick = self.user_nick)
# Record message history
self.save_sent_message(message)
# Be sure to send user nickname only once according to JEP-0172
self.user_nick = None
# Clear msg input
message_buffer = self.msg_textview.get_buffer()
message_buffer.set_text('') # clear message buffer (and tv of course)

View File

@ -87,8 +87,18 @@ class Connection(ConnectionHandlers):
self.on_connect_failure = None
self.retrycount = 0
self.jids_for_auto_auth = [] # list of jid to auto-authorize
# END __init__
def build_user_nick(self, user_nick):
df = common.xmpp.DataForm(typ = 'result')
field = df.setField('FORM_TYPE')
field.setType('hidden')
field.setValue(common.xmpp.NS_PROFILE)
field = df.setField('nickname')
field.delAttr('type')
field.setValue(user_nick)
return df
def put_event(self, ev):
if gajim.handlers.has_key(ev[0]):
gajim.handlers[ev[0]](self.name, ev[1])
@ -606,7 +616,8 @@ class Connection(ConnectionHandlers):
self.connection.send(msg_iq)
def send_message(self, jid, msg, keyID, type = 'chat', subject='',
chatstate = None, msg_id = None, composing_jep = None, resource = None):
chatstate = None, msg_id = None, composing_jep = None, resource = None,
user_nick = None):
if not self.connection:
return
if not msg and chatstate is None:
@ -637,6 +648,11 @@ class Connection(ConnectionHandlers):
if msgenc:
msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
# JEP-0172: user_nickname
if user_nick:
df = self.build_user_nick(user_nick)
msg_iq.addChild(node = df)
# chatstates - if peer supports jep85 or jep22, send chatstates
# please note that the only valid tag inside a message containing a <body>
# tag is the active event
@ -691,7 +707,7 @@ class Connection(ConnectionHandlers):
self.connection.send(p)
def request_subscription(self, jid, msg = '', name = '', groups = [],
auto_auth = False):
auto_auth = False, user_nick = ''):
if not self.connection:
return
gajim.log.debug('subscription request for %s' % jid)
@ -709,6 +725,9 @@ class Connection(ConnectionHandlers):
self.connection.send(iq)
p = common.xmpp.Presence(jid, 'subscribe')
if user_nick:
df = self.build_user_nick(user_nick)
p.addChild(node = df)
p = self.add_sha(p)
if not msg:
msg = _('I would like to add you to my roster.')

View File

@ -1295,6 +1295,16 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
composing_jep = 'JEP-0022'
if not msgtxt and chatstate_child.getTag('composing'):
chatstate = 'composing'
# JEP-0172 User Nickname
user_nick = ''
xtags = msg.getTags('x', attrs = {'type': 'result'},
namespace = common.xmpp.NS_DATA)
for xtag in xtags:
df = common.xmpp.DataForm(node = xtag)
field = df.getField('FORM_TYPE')
if not field or field.getValue() != common.xmpp.NS_PROFILE:
continue
user_nick = df.getField('nickname').getValue()
if encTag and GnuPG.USE_GPG:
#decrypt
@ -1338,7 +1348,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
msg_id = gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim,
subject = subject)
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype, subject,
chatstate, msg_id, composing_jep))
chatstate, msg_id, composing_jep, user_nick))
else: # it's single message
if self.name not in no_log_for and jid not in no_log_for and msgtxt:
gajim.logger.write('single_msg_recv', frm, msgtxt, tim = tim,
@ -1352,7 +1362,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
self.dispatch('GC_INVITATION',(frm, jid_from, reason, password))
else:
self.dispatch('MSG', (frm, msgtxt, tim, encrypted, 'normal',
subject, chatstate, msg_id, composing_jep))
subject, chatstate, msg_id, composing_jep, user_nick))
# END messageCB
def _presenceCB(self, con, prs):
@ -1367,25 +1377,36 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
is_gc = False # is it a GC presence ?
sigTag = None
avatar_sha = None
user_nick = '' # for JEP-0172
transport_auto_auth = False
xtags = prs.getTags('x')
for x in xtags:
if x.getNamespace().startswith(common.xmpp.NS_MUC):
namespace = x.getNamespace()
if namespace.startswith(common.xmpp.NS_MUC):
is_gc = True
if x.getNamespace() == common.xmpp.NS_SIGNED:
if namespace == common.xmpp.NS_SIGNED:
sigTag = x
if x.getNamespace() == common.xmpp.NS_VCARD_UPDATE:
if namespace == common.xmpp.NS_VCARD_UPDATE:
avatar_sha = x.getTagData('photo')
if x.getNamespace() == common.xmpp.NS_DELAY:
if namespace == common.xmpp.NS_DELAY:
# JEP-0091
tim = prs.getTimestamp()
tim = time.strptime(tim, '%Y%m%dT%H:%M:%S')
timestamp = time.localtime(timegm(tim))
if x.getNamespace() == 'http://delx.cjb.net/protocol/roster-subsync':
if namespace == 'http://delx.cjb.net/protocol/roster-subsync':
# see http://trac.gajim.org/ticket/326
agent = gajim.get_server_from_jid(jid_stripped)
if self.connection.getRoster().getItem(agent): # to be sure it's a transport contact
transport_auto_auth = True
if namespace == common.xmpp.NS_DATA:
# JEP-0172
df = common.xmpp.DataForm(node = x)
if df.getType() != 'result':
continue
field = df.getField('FORM_TYPE')
if not field or field.getValue() != common.xmpp.NS_PROFILE:
continue
user_nick = df.getField('nickname').getValue()
no_log_for = gajim.config.get_per('accounts', self.name,
'no_log_for').split()
@ -1475,11 +1496,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
resource, prio, keyID, timestamp))
if transport_auto_auth:
self.automatically_added.append(jid_stripped)
self.request_subscription(jid_stripped)
self.request_subscription(jid_stripped, name = user_nick)
else:
if not status:
status = _('I would like to add you to my roster.')
self.dispatch('SUBSCRIBE', (who, status))
self.dispatch('SUBSCRIBE', (who, status, user_nick))
elif ptype == 'subscribed':
if jid_stripped in self.automatically_added:
self.automatically_added.remove(jid_stripped)

View File

@ -67,6 +67,7 @@ NS_PHYSLOC ='http://jabber.org/protocol/physloc' # JEP-01
NS_PRESENCE ='presence' # Jabberd2
NS_PRIVACY ='jabber:iq:privacy'
NS_PRIVATE ='jabber:iq:private'
NS_PROFILE ='http://jabber.org/protocol/profile' # JEP-0154
NS_PUBSUB ='http://jabber.org/protocol/pubsub' # JEP-0060
NS_REGISTER ='jabber:iq:register'
NS_ROSTER ='jabber:iq:roster'

View File

@ -362,7 +362,7 @@ class ChangeStatusMessageDialog:
class AddNewContactWindow:
'''Class for AddNewContactWindow'''
def __init__(self, account = None, jid = None):
def __init__(self, account = None, jid = None, user_nick = None):
self.account = account
if account == None:
# fill accounts with active accounts
@ -431,7 +431,10 @@ _('Please fill in the data of the contact you want to add in account %s') %accou
else:
self.uid_entry.set_text(jid)
self.protocol_combobox.set_active(0)
self.set_nickname()
if user_nick:
self.nickname_entry.set_text(user_nick)
else:
self.set_nickname()
self.nickname_entry.grab_focus()
self.group_comboboxentry = self.xml.get_widget('group_comboboxentry')
liststore = gtk.ListStore(str)
@ -860,11 +863,12 @@ ok_handler = None):
return response
class SubscriptionRequestWindow:
def __init__(self, jid, text, account):
def __init__(self, jid, text, account, user_nick = None):
xml = gtkgui_helpers.get_glade('subscription_request_window.glade')
self.window = xml.get_widget('subscription_request_window')
self.jid = jid
self.account = account
self.user_nick = user_nick
if len(gajim.connections) >= 2:
prompt_text = _('Subscription request for account %s from %s')\
% (account, self.jid)
@ -883,7 +887,7 @@ class SubscriptionRequestWindow:
gajim.connections[self.account].send_authorization(self.jid)
self.window.destroy()
if self.jid not in gajim.contacts.get_jid_list(self.account):
AddNewContactWindow(self.account, self.jid)
AddNewContactWindow(self.account, self.jid, self.user_nick)
def on_contact_info_button_clicked(self, widget):
'''ask vcard'''

View File

@ -468,7 +468,7 @@ class Interface:
def handle_event_msg(self, account, array):
# 'MSG' (account, (jid, msg, time, encrypted, msg_type, subject,
# chatstate))
# chatstate, msg_id, composing_jep, user_nick)) user_nick is JEP-0172
full_jid_with_resource = array[0]
jid = gajim.get_jid_without_resource(full_jid_with_resource)
@ -555,7 +555,7 @@ class Interface:
else:
# array: (jid, msg, time, encrypted, msg_type, subject)
self.roster.on_message(jid, message, array[2], account, array[3],
msg_type, array[5], resource, msg_id)
msg_type, array[5], resource, msg_id, array[9])
nickname = gajim.get_name_from_jid(account, jid)
# Check and do wanted notifications
notify.notify('new_message', jid, account, [msg_type, first, nickname, message])
@ -611,8 +611,8 @@ class Interface:
helpers.play_sound('message_sent')
def handle_event_subscribe(self, account, array):
#('SUBSCRIBE', account, (jid, text))
dialogs.SubscriptionRequestWindow(array[0], array[1], account)
#('SUBSCRIBE', account, (jid, text, user_nick)) user_nick is JEP-0172
dialogs.SubscriptionRequestWindow(array[0], array[1], account, array[2])
if self.remote_ctrl:
self.remote_ctrl.raise_signal('Subscribe', (account, array))

View File

@ -131,10 +131,12 @@ class MessageControl:
return n
def send_message(self, message, keyID = '', type = 'chat',
chatstate = None, msg_id = None, composing_jep = None, resource = None):
chatstate = None, msg_id = None, composing_jep = None, resource = None,
user_nick = None):
'''Send the given message to the active tab'''
jid = self.contact.jid
# Send and update history
gajim.connections[self.account].send_message(jid, message, keyID,
type = type, chatstate = chatstate, msg_id = msg_id,
composing_jep = composing_jep, resource = self.resource)
type = type, chatstate = chatstate, msg_id = msg_id,
composing_jep = composing_jep, resource = self.resource,
user_nick = user_nick)

View File

@ -1606,7 +1606,7 @@ class RosterWindow:
menu.popup(None, self.tree, None, event_button, event.time)
def on_add_to_roster(self, widget, contact, account):
dialogs.AddNewContactWindow(account, contact.jid)
dialogs.AddNewContactWindow(account, contact.jid, contact.name)
def authorize(self, widget, jid, account):
'''Authorize a contact (by re-sending auth menuitem)'''
@ -1622,7 +1622,7 @@ class RosterWindow:
else:
group = []
gajim.connections[account].request_subscription(jid, txt, pseudo, group,
auto_auth)
auto_auth, gajim.nicks[account])
contact = gajim.contacts.get_contact_with_highest_priority(account, jid)
if not contact:
keyID = ''
@ -2118,7 +2118,8 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
mw.new_tab(gc_control)
def on_message(self, jid, msg, tim, account, encrypted = False,
msg_type = '', subject = None, resource = '', msg_id = None):
msg_type = '', subject = None, resource = '', msg_id = None,
user_nick = ''):
'''when we receive a message'''
contact = None
# if chat window will be for specific resource
@ -2141,8 +2142,12 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
'attached_gpg_keys').split()
if jid in attached_keys:
keyID = attached_keys[attached_keys.index(jid) + 1]
if user_nick:
nick = user_nick
else:
nick = jid.split('@')[0]
contact = gajim.contacts.create_contact(jid = jid,
name = jid.split('@')[0], groups = [_('Not in Roster')],
name = nick, groups = [_('Not in Roster')],
show = 'not in roster', status = '', ask = 'none',
keyID = keyID, resource = resource)
gajim.contacts.add_contact(account, contact)