we now cache avatar, so we only ask once. TODO: ask, store and show in roster; TODO2: on new sha reask vcard to get new avatar

This commit is contained in:
Nikos Kouremenos 2005-10-03 16:14:41 +00:00
parent 7518d20bf7
commit 6899985d5c
3 changed files with 102 additions and 67 deletions

View File

@ -66,11 +66,13 @@ import gtkexcepthook
import gobject
if sys.version[:4] >= '2.4':
gobject.threads_init()
import pango
import sre
import signal
import getopt
import time
import base64
from common import socks5
import gtkgui_helpers
@ -621,29 +623,30 @@ class Interface:
win = self.windows[account]['infos'][array['jid']]
win.set_values(array)
def handle_event_vcard(self, account, array):
def handle_event_vcard(self, account, vcard):
'''vcard holds the vcard data'''
jid = vcard['jid']
self.store_avatar(vcard)
# vcard window
win = None
if self.windows[account]['infos'].has_key(array['jid']):
win = self.windows[account]['infos'][array['jid']]
elif self.windows[account]['infos'].has_key(array['jid'] + '/' + \
array['resource']):
win = self.windows[account]['infos'][array['jid'] + '/' + \
array['resource']]
if self.windows[account]['infos'].has_key(jid):
win = self.windows[account]['infos'][jid]
elif self.windows[account]['infos'].has_key(jid + '/' +vcard['resource']):
win = self.windows[account]['infos'][jid + '/' + vcard['resource']]
if win:
win.set_values(array)
win.set_values(vcard) #FIXME: maybe store all vcard data?
# show avatar in chat
win = None
if self.windows[account]['chats'].has_key(array['jid']):
win = self.windows[account]['chats'][array['jid']]
elif self.windows[account]['chats'].has_key(array['jid'] + '/' + \
array['resource']):
win = self.windows[account]['chats'][array['jid'] + '/' + \
array['resource']]
if self.windows[account]['chats'].has_key(jid):
win = self.windows[account]['chats'][jid]
elif self.windows[account]['chats'].has_key(jid + '/' +vcard['resource']):
win = self.windows[account]['chats'][jid + '/' + vcard['resource']]
if win:
win.set_avatar(array)
win.show_avatar(jid)
if self.remote is not None:
self.remote.raise_signal('VcardInfo', (account, array))
self.remote.raise_signal('VcardInfo', (account, vcard))
def handle_event_os_info(self, account, array):
win = None
@ -863,6 +866,42 @@ class Interface:
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.'))
def store_avatar(self, vcard):
'''stores avatar per jid so we do not have to ask everytime for vcard'''
jid = vcard['jid']
# we assume contact has no avatar
self.avatar_pixbufs[jid] = None
if not vcard.has_key('PHOTO'):
return
if not isinstance(vcard['PHOTO'], dict):
return
img_decoded = None
if vcard['PHOTO'].has_key('BINVAL'):
try:
img_decoded = base64.decodestring(vcard['PHOTO']['BINVAL'])
except:
pass
elif vcard['PHOTO'].has_key('EXTVAL'):
url = vcard['PHOTO']['EXTVAL']
try:
fd = urllib.urlopen(url)
img_decoded = fd.read()
except:
pass
if img_decoded:
pixbufloader = gtk.gdk.PixbufLoader()
try:
pixbufloader.write(img_decoded)
pixbuf = pixbufloader.get_pixbuf()
pixbufloader.close()
# store avatar for jid
self.avatar_pixbufs[jid] = pixbuf
# we may get "unknown image format" and/or something like pixbuf can be None
except (gobject.GError, AttributeError):
pass
def read_sleepy(self):
'''Check idle status and change that status if needed'''
if not self.sleeper.poll():
@ -1121,6 +1160,7 @@ class Interface:
'outmsgcolor': gajim.config.get('outmsgcolor'),
'statusmsgcolor': gajim.config.get('statusmsgcolor'),
}
parser.read()
# Do not set gajim.verbose to False if -v option was given
if gajim.config.get('verbose'):
@ -1172,8 +1212,12 @@ class Interface:
gtk.about_dialog_set_email_hook(self.on_launch_browser_mailer, 'mail')
gtk.about_dialog_set_url_hook(self.on_launch_browser_mailer, 'url')
self.windows = {'logs': {}}
# keep avatar (pixbuf) per jid
self.avatar_pixbufs = {}
for a in gajim.connections:
self.windows[a] = {'infos': {}, 'chats': {}, 'gc': {}, 'gc_config': {}}
gajim.contacts[a] = {}

View File

@ -58,8 +58,9 @@ class TabbedChatWindow(chat.Chat):
self.show_bigger_avatar_timeout_id = None
self.bigger_avatar_window = None
# keep avatar (pixbuf) per jid. FIXME: move this when we cache avatars
self.avatar_pixbufs = {}
# list that holds all the jid we have asked vcard once
# (so we do not have to ask again)
self.jids_for_which_we_asked_vcard_already = list()
self.TARGET_TYPE_URI_LIST = 80
self.dnd_list = [ ( 'text/uri-list', 0, self.TARGET_TYPE_URI_LIST ) ]
@ -221,51 +222,30 @@ timestamp, contact):
def get_specific_unread(self, jid):
return 0 # FIXME: always zero why??
def set_avatar(self, vcard):
if not vcard.has_key('PHOTO'):
return
if not isinstance(vcard['PHOTO'], dict):
return
img_decoded = None
if vcard['PHOTO'].has_key('BINVAL'):
try:
img_decoded = base64.decodestring(vcard['PHOTO']['BINVAL'])
except:
pass
elif vcard['PHOTO'].has_key('EXTVAL'):
url = vcard['PHOTO']['EXTVAL']
try:
fd = urllib.urlopen(url)
img_decoded = fd.read()
except:
pass
if img_decoded:
pixbufloader = gtk.gdk.PixbufLoader()
try:
pixbufloader.write(img_decoded)
pixbuf = pixbufloader.get_pixbuf()
pixbufloader.close()
jid = vcard['jid']
self.avatar_pixbufs[jid] = pixbuf
def show_avatar(self, jid):
assert(not self.plugin.avatar_pixbufs.has_key(jid))
if not self.plugin.avatar_pixbufs.has_key(jid) or\
self.plugin.avatar_pixbufs[jid] is None:
return # contact does not have avatar stored (can this happen?) or has no avatar
pixbuf = self.plugin.avatar_pixbufs[jid]
w = gajim.config.get('avatar_width')
h = gajim.config.get('avatar_height')
scaled_buf = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_HYPER)
x = None
if self.xmls.has_key(jid):
x = self.xmls[jid]
else:
# it can be xmls[jid/resource] if it's a vcard from pm
elif self.xmls.has_key(jid + '/' + vcard['resource']):
x = self.xmls[jid + '/' + vcard['resource']]
jid_with_resource = jid + '/' + vcard['resource']
if self.xmls.has_key(jid_with_resource):
x = self.xmls[jid_with_resource]
if x is not None:
image = x.get_widget('avatar_image')
image.set_from_pixbuf(scaled_buf)
image.show_all()
# we may get "unknown image format" and/or something like pixbuf can be None
except (gobject.GError, AttributeError):
pass
def set_state_image(self, jid):
prio = 0
@ -399,6 +379,18 @@ timestamp, contact):
self.childs[contact.jid] = self.xmls[contact.jid].get_widget('chats_vbox')
self.contacts[contact.jid] = contact
#FIXME: request in thread or idle and show in roster
# this is to prove cache code works:
# should we ask vcard? (only the first time we should ask)
if not self.plugin.avatar_pixbufs.has_key(contact.jid):
# it's the first time, so we should ask vcard
gajim.connections[self.account].request_vcard(contact.jid)
#please do not remove this commented print until I'm done with showing
#avatars in roster
#print 'REQUESTING VCARD for', contact.jid
else:
self.show_avatar(contact.jid) # show avatar from stored place
self.childs[contact.jid].connect('drag_data_received',
self.on_drag_data_received, contact)
@ -428,7 +420,6 @@ timestamp, contact):
if gajim.awaiting_messages[self.account].has_key(contact.jid):
self.read_queue(contact.jid)
gajim.connections[self.account].request_vcard(contact.jid)
self.childs[contact.jid].show_all()
# chatstates