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

@ -1185,14 +1185,14 @@ class Connection:
del roster[jid]
self.dispatch('ROSTER', roster)
#continue connection
# continue connection
if self.connected > 1 and self.continue_connect_info:
show = self.continue_connect_info[0]
msg = self.continue_connect_info[1]
signed = self.continue_connect_info[2]
self.connected = STATUS_LIST.index(show)
sshow = helpers.get_xmpp_show(show)
#send our presence
# send our presence
if show == 'invisible':
self.send_invisible_presence(msg, signed, True)
return
@ -1208,10 +1208,10 @@ class Connection:
if self.connection:
self.connection.send(p)
self.dispatch('STATUS', show)
#ask our VCard
# ask our VCard
self.request_vcard(None)
#Get bookmarks from private namespace
# Get bookmarks from private namespace
self.get_bookmarks()
self.continue_connect_info = None

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
# 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,7 +1212,11 @@ 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':{}}
self.windows = {'logs': {}}
# keep avatar (pixbuf) per jid
self.avatar_pixbufs = {}
for a in gajim.connections:
self.windows[a] = {'infos': {}, 'chats': {}, 'gc': {}, 'gc_config': {}}

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
w = gajim.config.get('avatar_width')
h = gajim.config.get('avatar_height')
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)
scaled_buf = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_HYPER)
x = None
if self.xmls.has_key(jid):
x = self.xmls[jid]
# 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']]
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
jid_with_resource = jid + '/' + vcard['resource']
if self.xmls.has_key(jid_with_resource):
x = self.xmls[jid_with_resource]
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
if x is not None:
image = x.get_widget('avatar_image')
image.set_from_pixbuf(scaled_buf)
image.show_all()
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