we now save sha in stored vcard

we save the current sha in memory and we update it when we receive the vcard
we re-ask the vcard when we receive a presence with a new sha
This commit is contained in:
Yann Leboulanger 2005-10-31 17:31:30 +00:00
parent 20ba733622
commit a8cb9d69ff
3 changed files with 66 additions and 31 deletions

View file

@ -151,6 +151,7 @@ class Connection:
self.connection = None # xmpppy instance self.connection = None # xmpppy instance
self.gpg = None self.gpg = None
self.vcard_sha = None self.vcard_sha = None
self.vcard_shas = {} # sha of contacts
self.status = '' self.status = ''
self.old_show = '' self.old_show = ''
self.time_to_reconnect = None self.time_to_reconnect = None
@ -245,20 +246,32 @@ class Connection:
frm = our_jid frm = our_jid
if vc.getTag('vCard').getNamespace() == common.xmpp.NS_VCARD: if vc.getTag('vCard').getNamespace() == common.xmpp.NS_VCARD:
card = vc.getChildren()[0] card = vc.getChildren()[0]
vcard = self.node_to_dict(card)
if vcard.has_key('PHOTO') and type(vcard['PHOTO']) == type({}) and \
vcard['PHOTO'].has_key('BINVAL'):
photo = vcard['PHOTO']['BINVAL']
avatar_sha = sha.sha(photo).hexdigest()
else:
avatar_sha = ''
if avatar_sha:
card.getTag('PHOTO').setTagData('SHA', avatar_sha)
if frm != our_jid:
if avatar_sha:
self.vcard_shas[frm] = avatar_sha
elif self.vcard_shas.has_key(frm):
del self.vcard_shas[frm]
# Save it to file
path_to_file = os.path.join(gajim.VCARDPATH, frm) path_to_file = os.path.join(gajim.VCARDPATH, frm)
fil = open(path_to_file, 'w') fil = open(path_to_file, 'w')
fil.write(str(card)) fil.write(str(card))
fil.close() fil.close()
vcard = self.node_to_dict(card)
vcard['jid'] = frm vcard['jid'] = frm
vcard['resource'] = resource vcard['resource'] = resource
if frm == our_jid: if frm == our_jid:
if vcard.has_key('PHOTO') and type(vcard['PHOTO']) == type({}) and \ self.vcard_sha = avatar_sha
vcard['PHOTO'].has_key('BINVAL'):
photo = vcard['PHOTO']['BINVAL']
self.vcard_sha = sha.sha(photo).hexdigest()
else:
self.vcard_sha = ''
self.dispatch('MYVCARD', vcard) self.dispatch('MYVCARD', vcard)
#we re-send our presence with sha if we are not invisible #we re-send our presence with sha if we are not invisible
if STATUS_LIST[self.connected] == 'invisible': if STATUS_LIST[self.connected] == 'invisible':
@ -369,12 +382,16 @@ class Connection:
gajim.log.debug('PresenceCB: %s' % ptype) gajim.log.debug('PresenceCB: %s' % ptype)
is_gc = False # is it a GC presence ? is_gc = False # is it a GC presence ?
sigTag = None sigTag = None
avatar_sha = None
xtags = prs.getTags('x') xtags = prs.getTags('x')
for x in xtags: for x in xtags:
if x.getNamespace().startswith(common.xmpp.NS_MUC): if x.getNamespace().startswith(common.xmpp.NS_MUC):
is_gc = True is_gc = True
if x.getNamespace() == common.xmpp.NS_SIGNED: if x.getNamespace() == common.xmpp.NS_SIGNED:
sigTag = x sigTag = x
if x.getNamespace() == common.xmpp.NS_VCARD_UPDATE:
avatar_sha = x.getTagData('photo')
jid_from = prs.getFrom() jid_from = prs.getFrom()
who = unicode(jid_from) who = unicode(jid_from)
jid_stripped = jid_from.getStripped() jid_stripped = jid_from.getStripped()
@ -474,6 +491,15 @@ class Connection:
else: # print in the window the error else: # print in the window the error
self.dispatch('ERROR_ANSWER', ('', jid_stripped, self.dispatch('ERROR_ANSWER', ('', jid_stripped,
errmsg, errcode)) errmsg, errcode))
avatar_sha = None
if avatar_sha:
if self.vcard_shas.has_key(jid_stripped):
if avatar_sha != self.vcard_shas[jid_stripped]:
# avatar has been updated
self.request_vcard(self.name, jid_stripped)
else:
self.vcard_shas[jid_stripped] = avatar_sha
if not ptype or ptype == 'unavailable': if not ptype or ptype == 'unavailable':
gajim.logger.write('status', status, jid_stripped, show) gajim.logger.write('status', status, jid_stripped, show)
self.dispatch('NOTIFY', (jid_stripped, show, status, resource, prio, self.dispatch('NOTIFY', (jid_stripped, show, status, resource, prio,
@ -1867,18 +1893,29 @@ class Connection:
common.xmpp.NS_VERSION) common.xmpp.NS_VERSION)
self.to_be_sent.append(iq) self.to_be_sent.append(iq)
def get_cached_vcard(self, jid): def get_cached_vcard(self, fjid):
j = gajim.get_jid_without_resource(jid) '''return the vcard as a dict
path_to_file = os.path.join(gajim.VCARDPATH, j) 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.VCARDPATH, jid)
if os.path.isfile(path_to_file): if os.path.isfile(path_to_file):
# We have the vcard cached # We have the vcard cached
f = open(path_to_file) f = open(path_to_file)
c = f.read() c = f.read()
card = common.xmpp.Node(node = c) card = common.xmpp.Node(node = c)
vcard = self.node_to_dict(card) vcard = self.node_to_dict(card)
vcard['jid'] = j if vcard.has_key('PHOTO') and vcard['PHOTO'].has_key('SHA'):
vcard['resource'] = gajim.get_resource_from_jid(jid) cached_sha = vcard['PHOTO']['SHA']
del vcard['PHOTO']['SHA']
if self.vcard_shas.has_key(jid) and self.vcard_shas[jid] != \
cached_sha:
# we had an old cached vcard
return {}
vcard['jid'] = jid
vcard['resource'] = gajim.get_resource_from_jid(fjid)
return vcard return vcard
return None
def request_vcard(self, jid = None): def request_vcard(self, jid = None):
'''request the VCARD''' '''request the VCARD'''

View file

@ -947,13 +947,17 @@ class Interface:
def handle_event_vcard_not_published(self, account, array): def handle_event_vcard_not_published(self, account, array):
dialogs.InformationDialog(_('vCard publication failed'), _('There was an error while publishing your personal information, try again later.')) dialogs.InformationDialog(_('vCard publication failed'), _('There was an error while publishing your personal information, try again later.'))
def get_avatar_pixbuf_from_cache(self, account, jid): def get_avatar_pixbuf_from_cache(self, jid):
'''checks if jid has avatar cached and if that avatar is valid image '''checks if jid has cached avatar and if that avatar is valid image
(can be shown)''' (can be shown)
return None if there is no image in vcard
return 'ask' if vcard is too old or if we don't have the vcard'''
if jid not in os.listdir(gajim.VCARDPATH): if jid not in os.listdir(gajim.VCARDPATH):
return None return 'ask'
vcard_dict = gajim.connections[account].get_cached_vcard(jid) vcard_dict = gajim.connections.values()[0].get_cached_vcard(jid)
if not vcard_dict: # This can happen if cached vcard is too old
return 'ask'
if not vcard_dict.has_key('PHOTO'): if not vcard_dict.has_key('PHOTO'):
return None return None
pixbuf = vcard.get_avatar_pixbuf_encoded_mime(vcard_dict['PHOTO'])[0] pixbuf = vcard.get_avatar_pixbuf_encoded_mime(vcard_dict['PHOTO'])[0]

View file

@ -131,8 +131,7 @@ class TabbedChatWindow(chat.Chat):
'''we enter the eventbox area so we under conditions add a timeout '''we enter the eventbox area so we under conditions add a timeout
to show a bigger avatar after 0.5 sec''' to show a bigger avatar after 0.5 sec'''
jid = self.get_active_jid() jid = self.get_active_jid()
avatar_pixbuf = gajim.interface.get_avatar_pixbuf_from_cache(self.account, avatar_pixbuf = gajim.interface.get_avatar_pixbuf_from_cache(jid)
jid)
avatar_w = avatar_pixbuf.get_width() avatar_w = avatar_pixbuf.get_width()
avatar_h = avatar_pixbuf.get_height() avatar_h = avatar_pixbuf.get_height()
@ -156,8 +155,7 @@ class TabbedChatWindow(chat.Chat):
'''resizes the avatar, if needed, so it has at max half the screen size '''resizes the avatar, if needed, so it has at max half the screen size
and shows it''' and shows it'''
jid = self.get_active_jid() jid = self.get_active_jid()
avatar_pixbuf = gajim.interface.get_avatar_pixbuf_from_cache(self.account, avatar_pixbuf = gajim.interface.get_avatar_pixbuf_from_cache(jid)
jid)
screen_w = gtk.gdk.screen_width() screen_w = gtk.gdk.screen_width()
screen_h = gtk.gdk.screen_height() screen_h = gtk.gdk.screen_height()
avatar_w = avatar_pixbuf.get_width() avatar_w = avatar_pixbuf.get_width()
@ -281,12 +279,12 @@ class TabbedChatWindow(chat.Chat):
def show_avatar(self, jid, resource): def show_avatar(self, jid, resource):
# Get the XML instance # Get the XML instance
jid_with_resource = jid + '/' + resource
xml = None xml = None
if self.xmls.has_key(jid): if self.xmls.has_key(jid):
xml = self.xmls[jid] xml = self.xmls[jid]
else: else:
# it can be xmls[jid/resource] if it's a vcard from pm # it can be xmls[jid/resource] if it's a vcard from pm
jid_with_resource = jid + '/' + resource
if self.xmls.has_key(jid_with_resource): if self.xmls.has_key(jid_with_resource):
xml = self.xmls[jid_with_resource] xml = self.xmls[jid_with_resource]
if not xml: if not xml:
@ -295,8 +293,10 @@ class TabbedChatWindow(chat.Chat):
# we assume contact has no avatar # we assume contact has no avatar
scaled_buf = None scaled_buf = None
pixbuf = gajim.interface.get_avatar_pixbuf_from_cache(self.account, pixbuf = gajim.interface.get_avatar_pixbuf_from_cache(jid)
jid) if pixbuf == 'ask': # we don't have the vcard or it's too old
gajim.connections[self.account].request_vcard(jid_with_resource)
return
if pixbuf is not None: if pixbuf is not None:
# resize to a width / height for the avatar not to have distortion # resize to a width / height for the avatar not to have distortion
# (keep aspect ratio) # (keep aspect ratio)
@ -449,13 +449,7 @@ class TabbedChatWindow(chat.Chat):
self.on_message_textview_mykeypress_event) self.on_message_textview_mykeypress_event)
message_scrolledwindow.add(msg_textview) message_scrolledwindow.add(msg_textview)
# should we ask vcard? (only the first time we should ask)
if contact.jid in os.listdir(gajim.VCARDPATH):
# show avatar from HD
self.show_avatar(contact.jid, contact.resource) self.show_avatar(contact.jid, contact.resource)
else:
# it's the first time, so we should ask vcard
gajim.connections[self.account].request_vcard(contact.jid)
self.childs[contact.jid].connect('drag_data_received', self.childs[contact.jid].connect('drag_data_received',
self.on_drag_data_received, contact) self.on_drag_data_received, contact)