From 3355cf4ea3f7fe3afca891dcdd544fbfe882a10e Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Thu, 9 Mar 2006 18:41:57 +0000
Subject: [PATCH] room_contacts vcards are now saved in room_jid folder. Fixes
 #1105

---
 src/chat_control.py      | 15 +++---
 src/common/connection.py | 99 +++++++++++++++++++++++-----------------
 src/gajim.py             | 10 ++--
 src/gtkgui_helpers.py    | 14 ++++--
 4 files changed, 83 insertions(+), 55 deletions(-)

diff --git a/src/chat_control.py b/src/chat_control.py
index 15f7d2f1cc..66e7fbd9a8 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 bc7bc113fd..e2edcead95 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 b16a502cf9..508d16bea3 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 01038730d8..31bfe1b749 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'):
-- 
GitLab