diff --git a/src/chat_control.py b/src/chat_control.py index f23def559..0b92884b5 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -1599,6 +1599,8 @@ class ChatControl(ChatControlBase): gajim.ged.register_event_handler('pep-received', ged.GUI1, self._nec_pep_received) + gajim.ged.register_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) # PluginSystem: adding GUI extension point for this ChatControl # instance object @@ -2585,6 +2587,8 @@ class ChatControl(ChatControlBase): gajim.ged.remove_event_handler('pep-received', ged.GUI1, self._nec_pep_received) + gajim.ged.remove_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) self.send_chatstate('gone', self.contact) self.contact.chatstate = None @@ -2706,6 +2710,14 @@ class ChatControl(ChatControlBase): image.set_from_pixbuf(scaled_pixbuf) image.show_all() + def _nec_vcard_received(self, obj): + if obj.conn.name != self.account: + return + j = gajim.get_jid_without_resource(self.contact.jid) + if obj.jid != j: + return + self.show_avatar() + def _on_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp): if not selection.data: diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index 070d64f40..372e6e7cd 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -639,10 +639,10 @@ class ConnectionVcard: if frm and frm != our_jid: # Write an empty file self._save_vcard_to_hd(frm, '') - jid, resource = gajim.get_room_and_nick_from_fjid(frm) - self.dispatch('VCARD', {'jid': jid, 'resource': resource}) - elif frm == our_jid: - self.dispatch('MYVCARD', {'jid': frm}) + jid, resource = gajim.get_room_and_nick_from_fjid(frm) + vcard = {'jid': jid, 'resource': resource} + gajim.nec.push_incoming_event(VcardReceivedEvent(None, + conn=self, vcard_dict=vcard)) elif self.awaiting_answers[id_][0] == AGENT_REMOVED: jid = self.awaiting_answers[id_][1] gajim.nec.push_incoming_event(AgentRemovedEvent(None, conn=self, @@ -874,8 +874,9 @@ class ConnectionVcard: vcard['jid'] = frm vcard['resource'] = resource + gajim.nec.push_incoming_event(VcardReceivedEvent(None, conn=self, + vcard_dict=vcard)) if frm_jid == our_jid: - self.dispatch('MYVCARD', vcard) # we re-send our presence with sha if has changed and if we are # not invisible if self.vcard_sha == avatar_sha: @@ -890,9 +891,6 @@ class ConnectionVcard: show=sshow, status=self.status) p = self.add_sha(p) self.connection.send(p) - else: - #('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...}) - self.dispatch('VCARD', vcard) # basic connection handlers used here and in zeroconf class ConnectionHandlersBase: @@ -1676,6 +1674,18 @@ ConnectionJingle, ConnectionIBBytestream): obj.contact = c break + if obj.avatar_sha is not None and obj.ptype != 'error': + if obj.jid not in self.vcard_shas: + cached_vcard = self.get_cached_vcard(obj.jid) + if cached_vcard and 'PHOTO' in cached_vcard and \ + 'SHA' in cached_vcard['PHOTO']: + self.vcard_shas[obj.jid] = cached_vcard['PHOTO']['SHA'] + else: + self.vcard_shas[obj.jid] = '' + if obj.avatar_sha != self.vcard_shas[obj.jid]: + # avatar has been updated + self.request_vcard(obj.jid) + if obj.contact: if obj.contact.show in statuss: obj.old_show = statuss.index(obj.contact.show) @@ -1788,18 +1798,6 @@ ConnectionJingle, ConnectionIBBytestream): sess.terminate() del self.sessions[jid][sess.thread_id] - if obj.avatar_sha is not None and obj.ptype != 'error': - if obj.jid not in self.vcard_shas: - cached_vcard = self.get_cached_vcard(obj.jid) - if cached_vcard and 'PHOTO' in cached_vcard and \ - 'SHA' in cached_vcard['PHOTO']: - self.vcard_shas[obj.jid] = cached_vcard['PHOTO']['SHA'] - else: - self.vcard_shas[obj.jid] = '' - if obj.avatar_sha != self.vcard_shas[obj.jid]: - # avatar has been updated - self.request_vcard(obj.jid) - if gajim.config.get('log_contact_status_changes') and \ gajim.config.should_log(self.name, obj.jid): try: diff --git a/src/common/connection_handlers_events.py b/src/common/connection_handlers_events.py index 363a11c62..e4d6dbb6e 100644 --- a/src/common/connection_handlers_events.py +++ b/src/common/connection_handlers_events.py @@ -1474,4 +1474,21 @@ class PrivacyListRemovedEvent(nec.NetworkIncomingEvent): class PrivacyListActiveDefaultEvent(nec.NetworkIncomingEvent): name = 'privacy-list-active-default' - base_network_events = [] \ No newline at end of file + base_network_events = [] + +class VcardReceivedEvent(nec.NetworkIncomingEvent): + name = 'vcard-received' + base_network_events = [] + + def generate(self): + self.nickname = None + if 'NICKNAME' in self.vcard_dict: + self.nickname = self.vcard_dict['NICKNAME'] + elif 'FN' in self.vcard_dict: + self.nickname = self.vcard_dict['FN'] + self.jid = self.vcard_dict['jid'] + self.resource = self.vcard_dict['resource'] + self.fjid = self.jid + if self.resource: + self.fjid += '/' + self.resource + return True diff --git a/src/groupchat_control.py b/src/groupchat_control.py index 5c45836e8..5e3b13e1b 100644 --- a/src/groupchat_control.py +++ b/src/groupchat_control.py @@ -458,6 +458,8 @@ class GroupchatControl(ChatControlBase): self._nec_gc_message_received) gajim.ged.register_event_handler('vcard-published', ged.GUI1, self._nec_vcard_published) + gajim.ged.register_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) gajim.gc_connected[self.account][self.room_jid] = False # disable win, we are not connected yet ChatControlBase.got_disconnected(self) @@ -878,6 +880,13 @@ class GroupchatControl(ChatControlBase): status = obj.conn.status obj.conn.send_gc_status(self.nick, self.room_jid, show, status) + def _nec_vcard_received(self, obj): + if obj.conn.name != self.account: + return + if obj.jid != self.room_jid: + return + self.draw_avatar(obj.resource) + def _nec_gc_message_received(self, obj): if obj.room_jid != self.room_jid or obj.conn.name != self.account: return diff --git a/src/gui_interface.py b/src/gui_interface.py index 65b1c43db..882639e6e 100644 --- a/src/gui_interface.py +++ b/src/gui_interface.py @@ -564,60 +564,15 @@ class Interface: gajim.interface.instances[account]['pep_services'].items_received( array[2]) - def handle_event_myvcard(self, account, array): - nick = '' - if 'NICKNAME' in array and array['NICKNAME']: - gajim.nicks[account] = array['NICKNAME'] - elif 'FN' in array and array['FN']: - gajim.nicks[account] = array['FN'] - if 'profile' in self.instances[account]: - win = self.instances[account]['profile'] - win.set_values(array) - if account in self.show_vcard_when_connect: - self.show_vcard_when_connect.remove(account) - jid = array['jid'] - if jid in self.instances[account]['infos']: - self.instances[account]['infos'][jid].set_values(array) - - def handle_event_vcard(self, account, vcard): + def handle_event_vcard(self, obj): # ('VCARD', account, data) '''vcard holds the vcard data''' - jid = vcard['jid'] - resource = vcard.get('resource', '') - fjid = jid + '/' + str(resource) - - # vcard window - win = None - if jid in self.instances[account]['infos']: - win = self.instances[account]['infos'][jid] - elif resource and fjid in self.instances[account]['infos']: - win = self.instances[account]['infos'][fjid] - if win: - win.set_values(vcard) - - # show avatar in chat - ctrl = None - if resource and self.msg_win_mgr.has_window(fjid, account): - win = self.msg_win_mgr.get_window(fjid, account) - ctrl = win.get_control(fjid, account) - elif self.msg_win_mgr.has_window(jid, account): - win = self.msg_win_mgr.get_window(jid, account) - ctrl = win.get_control(jid, account) - - if ctrl and ctrl.type_id != message_control.TYPE_GC: - ctrl.show_avatar() - - # Show avatar in roster or gc_roster - gc_ctrl = self.msg_win_mgr.get_gc_control(jid, account) - if not gc_ctrl and \ - jid in self.minimized_controls[account]: - gc_ctrl = self.minimized_controls[account][jid] - if gc_ctrl and gc_ctrl.type_id == message_control.TYPE_GC: - gc_ctrl.draw_avatar(resource) - else: - self.roster.draw_avatar(jid, account) - if self.remote_ctrl: - self.remote_ctrl.raise_signal('VcardInfo', (account, vcard)) + our_jid = gajim.get_jid_from_account(obj.conn.name) + if obj.jid == our_jid: + if obj.nickname: + gajim.nicks[obj.conn.name] = obj.nickname + if obj.conn.name in self.show_vcard_when_connect: + self.show_vcard_when_connect.remove(obj.conn.name) def handle_event_last_status_time(self, obj): # ('LAST_STATUS_TIME', account, (jid, resource, seconds, status)) @@ -1547,8 +1502,6 @@ class Interface: 'MSGERROR': [self.handle_event_msgerror], 'REGISTER_AGENT_INFO': [self.handle_event_register_agent_info], 'AGENT_INFO_ITEMS': [self.handle_event_agent_info_items], - 'MYVCARD': [self.handle_event_myvcard], - 'VCARD': [self.handle_event_vcard], 'GC_SUBJECT': [self.handle_event_gc_subject], 'GC_CONFIG_CHANGE': [self.handle_event_gc_config_change], 'FILE_REQUEST': [self.handle_event_file_request], @@ -1599,6 +1552,7 @@ class Interface: self.handle_event_subscribed_presence], 'unsubscribed-presence-received': [ self.handle_event_unsubscribed_presence], + 'vcard-received': [self.handle_event_vcard], } def register_core_handlers(self): diff --git a/src/profile_window.py b/src/profile_window.py index 0699607a8..f39ea5af3 100644 --- a/src/profile_window.py +++ b/src/profile_window.py @@ -69,6 +69,8 @@ class ProfileWindow: self._nec_vcard_published) gajim.ged.register_event_handler('vcard-not-published', ged.GUI1, self._nec_vcard_not_published) + gajim.ged.register_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) self.window.show_all() def update_progressbar(self): @@ -88,6 +90,8 @@ class ProfileWindow: self._nec_vcard_published) gajim.ged.remove_event_handler('vcard-not-published', ged.GUI1, self._nec_vcard_not_published) + gajim.ged.remove_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) del gajim.interface.instances[self.account]['profile'] if self.dialog: # Image chooser dialog self.dialog.destroy() @@ -284,6 +288,13 @@ class ProfileWindow: self.progressbar.set_fraction(0) self.update_progressbar_timeout_id = None + def _nec_vcard_received(self, obj): + if obj.conn.name != self.account: + return + if obj.jid != self.jid: + return + self.set_values(obj.vcard_dict) + def add_to_vcard(self, vcard_, entry, txt): """ Add an information to the vCard dictionary diff --git a/src/remote_control.py b/src/remote_control.py index c30d9dcfc..1ada41a14 100644 --- a/src/remote_control.py +++ b/src/remote_control.py @@ -125,10 +125,12 @@ class Remote: ged.POSTGUI, self.on_unsubscribed_presence_received) gajim.ged.register_event_handler('gc-message-received', ged.POSTGUI, self.on_gc_message_received) - gajim.ged.register_event_handler('our-show', - ged.POSTGUI, self.on_our_status) - gajim.ged.register_event_handler('account-created', - ged.POSTGUI, self.on_account_created) + gajim.ged.register_event_handler('our-show', ged.POSTGUI, + self.on_our_status) + gajim.ged.register_event_handler('account-created', ged.POSTGUI, + self.on_account_created) + gajim.ged.register_event_handler('vcard-received', ged.POSTGUI, + self.on_vcard_received) def on_last_status_time(self, obj): self.raise_signal('LastStatusTime', (obj.conn.name, [ @@ -188,6 +190,9 @@ class Remote: def on_account_created(self, obj): self.raise_signal('NewAccount', (obj.conn.name, obj.account_info)) + def on_vcard_received(self, obj): + self.raise_signal('VcardInfo', (obj.conn.name, obj.vcard_dict)) + def raise_signal(self, signal, arg): if self.signal_object: try: diff --git a/src/roster_window.py b/src/roster_window.py index b0517b2ec..b3b49fda6 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -2501,6 +2501,12 @@ class RosterWindow: else: self.draw_pep(obj.jid, obj.conn.name, obj.pep_type) + def _nec_vcard_received(self, obj): + if obj.resource: + # it's a muc occupant vcard + return + self.draw_avatar(obj.jid, obj.conn.name) + ################################################################################ ### Menu and GUI callbacks ### FIXME: order callbacks in itself... @@ -6254,3 +6260,5 @@ class RosterWindow: self._nec_agent_removed) gajim.ged.register_event_handler('pep-received', ged.GUI1, self._nec_pep_received) + gajim.ged.register_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) diff --git a/src/vcard.py b/src/vcard.py index d33770c3e..71e5ae5c0 100644 --- a/src/vcard.py +++ b/src/vcard.py @@ -132,6 +132,8 @@ class VcardWindow: self.set_last_status_time) gajim.ged.register_event_handler('time-result-received', ged.GUI1, self.set_entity_time) + gajim.ged.register_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) self.fill_jabber_page() annotations = gajim.connections[self.account].annotations @@ -164,6 +166,8 @@ class VcardWindow: self.set_last_status_time) gajim.ged.remove_event_handler('time-result-received', ged.GUI1, self.set_entity_time) + gajim.ged.remove_event_handler('vcard-received', ged.GUI1, + self._nec_vcard_received) def on_vcard_information_window_key_press_event(self, widget, event): if event.keyval == gtk.keysyms.Escape: @@ -233,6 +237,20 @@ class VcardWindow: self.vcard_arrived = True self.test_remove_progressbar() + def _nec_vcard_received(self, obj): + if obj.conn.name != self.account: + return + if obj.resource: + # It's a muc occupant vcard + if obj.jid != self.gc_contact.room_jid: + return + if obj.resource != self.gc_contact.name: + return + else: + if obj.jid != self.contact.jid: + return + self.set_values(obj.vcard_dict) + def test_remove_progressbar(self): if self.update_progressbar_timeout_id is not None and \ self.vcard_arrived and self.os_info_arrived and self.entity_time_arrived: