diff --git a/src/chat_control.py b/src/chat_control.py index 15f7d2f1ccf2cb46f6fc4892efd7e2fc57692e0a..66e7fbd9a88df5924be70a3381c6ce299a5e23c8 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -1309,13 +1309,16 @@ class ChatControl(ChatControlBase): # we assume contact has no avatar scaled_pixbuf = None - real_jid = gajim.get_real_jid_from_fjid(self.account, jid) pixbuf = None - if real_jid: - pixbuf = gtkgui_helpers.get_avatar_pixbuf_from_cache(real_jid) - if not real_jid or pixbuf == 'ask': - # we don't have the vcard or it's pm and we don't have the real jid - gajim.connections[self.account].request_vcard(jid_with_resource) + is_fake = False + if gajim.contacts.is_pm_from_jid(self.account, jid): + is_fake = True + pixbuf = gtkgui_helpers.get_avatar_pixbuf_from_cache(jid_with_resource, + is_fake) + if pixbuf == 'ask': + # we don't have the vcard + gajim.connections[self.account].request_vcard(jid_with_resource, + is_fake) return if pixbuf is not None: scaled_pixbuf = gtkgui_helpers.get_scaled_pixbuf(pixbuf, 'chat') diff --git a/src/common/connection.py b/src/common/connection.py index bc7bc113fd3da808d8e225f1617074ad4069af31..e2edcead951f3ed0e29faec7ea3e6ca61e59e045 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -205,6 +205,7 @@ class Connection: self.on_connect_success = None self.retrycount = 0 self.jids_for_auto_auth = [] # list of jid to auto-authorize + self.room_jids = [] # list of gc jids so that vcard are saved in a folder # END __init__ def get_full_jid(self, iq_obj): @@ -269,6 +270,23 @@ class Connection: dict[name][c.getName()] = c.getData() return dict + def save_vcard_to_hd(self, full_jid, card): + jid, nick = gajim.get_room_and_nick_from_fjid(full_jid) + path = os.path.join(gajim.VCARD_PATH, jid) + if jid in self.room_jids: + # remove room_jid file if needed + if os.path.isfile(path): + os.remove(path) + # create folder if needed + if not os.path.isdir(path): + os.mkdir(path, 0700) + path_to_file = os.path.join(gajim.VCARD_PATH, jid, nick) + else: + path_to_file = path + fil = open(path_to_file, 'w') + fil.write(str(card)) + fil.close() + def _vCardCB(self, con, vc): '''Called when we receive a vCard Parse the vCard and send it to plugins''' @@ -281,7 +299,7 @@ class Connection: who = self.get_full_jid(vc) frm, resource = gajim.get_room_and_nick_from_fjid(who) else: - frm = our_jid + who = frm = our_jid if vc.getTag('vCard').getNamespace() == common.xmpp.NS_VCARD: card = vc.getChildren()[0] vcard = self.node_to_dict(card) @@ -301,10 +319,7 @@ class Connection: card.getTag('PHOTO').setTagData('SHA', avatar_sha) # Save it to file - path_to_file = os.path.join(gajim.VCARD_PATH, frm) - fil = open(path_to_file, 'w') - fil.write(str(card)) - fil.close() + self.save_vcard_to_hd(who, card) # Save the decoded avatar to a separate file too, and generate files for dbus notifications if photo_decoded: avatar_file = os.path.join(gajim.AVATAR_PATH, frm + '_notif_size_colored.png') @@ -1613,10 +1628,7 @@ class Connection: # Save it to file our_jid = gajim.get_jid_from_account(self.name) - path_to_file = os.path.join(gajim.VCARD_PATH, our_jid) - fil = open(path_to_file, 'w') - fil.write(str(vcard_iq)) - fil.close() + self.save_vcard_to_hd(our_jid, vcard_iq) # Send new presence if sha changed and we are not invisible if self.vcard_sha != new_sha and STATUS_LIST[self.connected] != \ @@ -1638,12 +1650,9 @@ class Connection: jid = self.awaiting_answers[id][1] our_jid = gajim.get_jid_from_account(self.name) if jid and jid != our_jid: - self.dispatch('VCARD', {'jid': jid}) - jid = gajim.get_jid_without_resource(jid) # Write an empty file - path_to_file = os.path.join(gajim.VCARD_PATH, jid) - fil = open(path_to_file, 'w') - fil.close() + self.save_vcard_to_hd(jid, '') + self.dispatch('VCARD', {'jid': jid}) elif jid == our_jid: self.dispatch('MYVCARD', {'jid': jid}) del self.awaiting_answers[id] @@ -2342,35 +2351,39 @@ class Connection: common.xmpp.NS_VERSION) self.connection.send(iq) - def get_cached_vcard(self, fjid): + def get_cached_vcard(self, fjid, is_fake_jid = False): '''return the vcard as a dict return {} if vcard was too old return None if we don't have cached vcard''' - jid = gajim.get_jid_without_resource(fjid) - path_to_file = os.path.join(gajim.VCARD_PATH, jid) - if os.path.isfile(path_to_file): - # We have the vcard cached - f = open(path_to_file) - c = f.read() - f.close() - card = common.xmpp.Node(node = c) - vcard = self.node_to_dict(card) - if vcard.has_key('PHOTO'): - if not isinstance(vcard['PHOTO'], dict): - del vcard['PHOTO'] - elif vcard['PHOTO'].has_key('SHA'): - cached_sha = vcard['PHOTO']['SHA'] - if self.vcard_shas.has_key(jid) and self.vcard_shas[jid] != \ - cached_sha: - # user change his vcard so don't use the cached one - return {} - vcard['jid'] = jid - vcard['resource'] = gajim.get_resource_from_jid(fjid) - return vcard - return None - - def request_vcard(self, jid = None): - '''request the VCARD''' + jid, nick = gajim.get_room_and_nick_from_fjid(fjid) + if is_fake_jid: + path_to_file = os.path.join(gajim.VCARD_PATH, jid, nick) + else: + path_to_file = os.path.join(gajim.VCARD_PATH, jid) + if not os.path.isfile(path_to_file): + return None + # We have the vcard cached + f = open(path_to_file) + c = f.read() + f.close() + card = common.xmpp.Node(node = c) + vcard = self.node_to_dict(card) + if vcard.has_key('PHOTO'): + if not isinstance(vcard['PHOTO'], dict): + del vcard['PHOTO'] + elif vcard['PHOTO'].has_key('SHA'): + cached_sha = vcard['PHOTO']['SHA'] + if self.vcard_shas.has_key(jid) and self.vcard_shas[jid] != \ + cached_sha: + # user change his vcard so don't use the cached one + return {} + vcard['jid'] = jid + vcard['resource'] = gajim.get_resource_from_jid(fjid) + return vcard + + def request_vcard(self, jid = None, is_fake_jid = False): + '''request the VCARD. If is_fake_jid is True, it means we request a vcard + to a fake jid, like in private messages in groupchat''' if not self.connection: return iq = common.xmpp.Iq(typ = 'get') @@ -2381,10 +2394,14 @@ class Connection: id = self.connection.getAnID() iq.setID(id) self.awaiting_answers[id] = (VCARD_ARRIVED, jid) + if is_fake_jid: + room_jid, nick = gajim.get_room_and_nick_from_fjid(jid) + if not room_jid in self.room_jids: + self.room_jids.append(room_jid) self.connection.send(iq) #('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...}) - def send_vcard(self, vcard): + def send_vcard(self, vcard, is_fake_jid): if not self.connection: return iq = common.xmpp.Iq(typ = 'set') diff --git a/src/gajim.py b/src/gajim.py index b16a502cf99c8c520a92ae7090616e7b842a8682..508d16bea36a378dd21669caefc58a91b2127b05 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -752,12 +752,14 @@ class Interface: # show avatar in chat win = None ctrl = None - if gajim.interface.msg_win_mgr.has_window(jid, account): + if resource and gajim.interface.msg_win_mgr.has_window( + jid + '/' + resource, account): + win = gajim.interface.msg_win_mgr.get_window(jid + '/' + resource, + account) + ctrl = win.get_control(jid + '/' + resource, account) + elif gajim.interface.msg_win_mgr.has_window(jid, account): win = gajim.interface.msg_win_mgr.get_window(jid, account) ctrl = win.get_control(jid, account) - elif resource and gajim.interface.msg_win_mgr.has_window(jid + '/' + resource, account): - win = gajim.interface.msg_win_mgr.get_window(jid + '/' + resource, account) - ctrl = win.get_control(jid + '/' + resource, account) if win and ctrl.type_id != message_control.TYPE_GC: ctrl.show_avatar() diff --git a/src/gtkgui_helpers.py b/src/gtkgui_helpers.py index 01038730d8d0becccbda09ee8b4fb80fc0d9c21c..31bfe1b74944fafaa46f2209f44dfe67eaef2bc8 100644 --- a/src/gtkgui_helpers.py +++ b/src/gtkgui_helpers.py @@ -430,22 +430,28 @@ def get_scaled_pixbuf(pixbuf, kind): scaled_buf = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_HYPER) return scaled_buf -def get_avatar_pixbuf_from_cache(jid): +def get_avatar_pixbuf_from_cache(fjid, is_fake_jid = False): '''checks if jid has cached avatar and if that avatar is valid image (can be shown) returns None if there is no image in vcard returns 'ask' if cached vcard should not be used (user changed his vcard, so we have new sha) or if we don't have the vcard''' + jid, nick = gajim.get_room_and_nick_from_fjid(fjid) if gajim.config.get('hide_avatar_of_transport') and\ gajim.jid_is_transport(jid): # don't show avatar for the transport itself return None - - if jid not in os.listdir(gajim.VCARD_PATH): + + if is_fake_jid: + path = os.path.join(gajim.VCARD_PATH, jid, nick) + else: + path = os.path.join(gajim.VCARD_PATH, jid) + if not os.path.isfile(path): return 'ask' - vcard_dict = gajim.connections.values()[0].get_cached_vcard(jid) + vcard_dict = gajim.connections.values()[0].get_cached_vcard(fjid, + is_fake_jid) if not vcard_dict: # This can happen if cached vcard is too old return 'ask' if not vcard_dict.has_key('PHOTO'):