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:
parent
7518d20bf7
commit
6899985d5c
76
src/gajim.py
76
src/gajim.py
|
@ -66,11 +66,13 @@ import gtkexcepthook
|
||||||
import gobject
|
import gobject
|
||||||
if sys.version[:4] >= '2.4':
|
if sys.version[:4] >= '2.4':
|
||||||
gobject.threads_init()
|
gobject.threads_init()
|
||||||
|
|
||||||
import pango
|
import pango
|
||||||
import sre
|
import sre
|
||||||
import signal
|
import signal
|
||||||
import getopt
|
import getopt
|
||||||
import time
|
import time
|
||||||
|
import base64
|
||||||
|
|
||||||
from common import socks5
|
from common import socks5
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
@ -621,29 +623,30 @@ class Interface:
|
||||||
win = self.windows[account]['infos'][array['jid']]
|
win = self.windows[account]['infos'][array['jid']]
|
||||||
win.set_values(array)
|
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
|
win = None
|
||||||
if self.windows[account]['infos'].has_key(array['jid']):
|
if self.windows[account]['infos'].has_key(jid):
|
||||||
win = self.windows[account]['infos'][array['jid']]
|
win = self.windows[account]['infos'][jid]
|
||||||
elif self.windows[account]['infos'].has_key(array['jid'] + '/' + \
|
elif self.windows[account]['infos'].has_key(jid + '/' +vcard['resource']):
|
||||||
array['resource']):
|
win = self.windows[account]['infos'][jid + '/' + vcard['resource']]
|
||||||
win = self.windows[account]['infos'][array['jid'] + '/' + \
|
|
||||||
array['resource']]
|
|
||||||
if win:
|
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
|
win = None
|
||||||
if self.windows[account]['chats'].has_key(array['jid']):
|
if self.windows[account]['chats'].has_key(jid):
|
||||||
win = self.windows[account]['chats'][array['jid']]
|
win = self.windows[account]['chats'][jid]
|
||||||
elif self.windows[account]['chats'].has_key(array['jid'] + '/' + \
|
elif self.windows[account]['chats'].has_key(jid + '/' +vcard['resource']):
|
||||||
array['resource']):
|
win = self.windows[account]['chats'][jid + '/' + vcard['resource']]
|
||||||
win = self.windows[account]['chats'][array['jid'] + '/' + \
|
|
||||||
array['resource']]
|
|
||||||
if win:
|
if win:
|
||||||
win.set_avatar(array)
|
win.show_avatar(jid)
|
||||||
if self.remote is not None:
|
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):
|
def handle_event_os_info(self, account, array):
|
||||||
win = None
|
win = None
|
||||||
|
@ -863,6 +866,42 @@ 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 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):
|
def read_sleepy(self):
|
||||||
'''Check idle status and change that status if needed'''
|
'''Check idle status and change that status if needed'''
|
||||||
if not self.sleeper.poll():
|
if not self.sleeper.poll():
|
||||||
|
@ -1121,6 +1160,7 @@ class Interface:
|
||||||
'outmsgcolor': gajim.config.get('outmsgcolor'),
|
'outmsgcolor': gajim.config.get('outmsgcolor'),
|
||||||
'statusmsgcolor': gajim.config.get('statusmsgcolor'),
|
'statusmsgcolor': gajim.config.get('statusmsgcolor'),
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.read()
|
parser.read()
|
||||||
# Do not set gajim.verbose to False if -v option was given
|
# Do not set gajim.verbose to False if -v option was given
|
||||||
if gajim.config.get('verbose'):
|
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_email_hook(self.on_launch_browser_mailer, 'mail')
|
||||||
gtk.about_dialog_set_url_hook(self.on_launch_browser_mailer, 'url')
|
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:
|
for a in gajim.connections:
|
||||||
self.windows[a] = {'infos': {}, 'chats': {}, 'gc': {}, 'gc_config': {}}
|
self.windows[a] = {'infos': {}, 'chats': {}, 'gc': {}, 'gc_config': {}}
|
||||||
gajim.contacts[a] = {}
|
gajim.contacts[a] = {}
|
||||||
|
|
|
@ -58,8 +58,9 @@ class TabbedChatWindow(chat.Chat):
|
||||||
self.show_bigger_avatar_timeout_id = None
|
self.show_bigger_avatar_timeout_id = None
|
||||||
self.bigger_avatar_window = None
|
self.bigger_avatar_window = None
|
||||||
|
|
||||||
# keep avatar (pixbuf) per jid. FIXME: move this when we cache avatars
|
# list that holds all the jid we have asked vcard once
|
||||||
self.avatar_pixbufs = {}
|
# (so we do not have to ask again)
|
||||||
|
self.jids_for_which_we_asked_vcard_already = list()
|
||||||
|
|
||||||
self.TARGET_TYPE_URI_LIST = 80
|
self.TARGET_TYPE_URI_LIST = 80
|
||||||
self.dnd_list = [ ( 'text/uri-list', 0, self.TARGET_TYPE_URI_LIST ) ]
|
self.dnd_list = [ ( 'text/uri-list', 0, self.TARGET_TYPE_URI_LIST ) ]
|
||||||
|
@ -221,51 +222,30 @@ timestamp, contact):
|
||||||
def get_specific_unread(self, jid):
|
def get_specific_unread(self, jid):
|
||||||
return 0 # FIXME: always zero why??
|
return 0 # FIXME: always zero why??
|
||||||
|
|
||||||
def set_avatar(self, vcard):
|
def show_avatar(self, jid):
|
||||||
if not vcard.has_key('PHOTO'):
|
assert(not self.plugin.avatar_pixbufs.has_key(jid))
|
||||||
return
|
if not self.plugin.avatar_pixbufs.has_key(jid) or\
|
||||||
if not isinstance(vcard['PHOTO'], dict):
|
self.plugin.avatar_pixbufs[jid] is None:
|
||||||
return
|
return # contact does not have avatar stored (can this happen?) or has no avatar
|
||||||
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
|
|
||||||
|
|
||||||
|
pixbuf = self.plugin.avatar_pixbufs[jid]
|
||||||
w = gajim.config.get('avatar_width')
|
w = gajim.config.get('avatar_width')
|
||||||
h = gajim.config.get('avatar_height')
|
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
|
x = None
|
||||||
if self.xmls.has_key(jid):
|
if self.xmls.has_key(jid):
|
||||||
x = self.xmls[jid]
|
x = self.xmls[jid]
|
||||||
|
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
|
||||||
elif self.xmls.has_key(jid + '/' + vcard['resource']):
|
jid_with_resource = jid + '/' + vcard['resource']
|
||||||
x = self.xmls[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 = x.get_widget('avatar_image')
|
||||||
image.set_from_pixbuf(scaled_buf)
|
image.set_from_pixbuf(scaled_buf)
|
||||||
image.show_all()
|
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):
|
def set_state_image(self, jid):
|
||||||
prio = 0
|
prio = 0
|
||||||
|
@ -399,6 +379,18 @@ timestamp, contact):
|
||||||
self.childs[contact.jid] = self.xmls[contact.jid].get_widget('chats_vbox')
|
self.childs[contact.jid] = self.xmls[contact.jid].get_widget('chats_vbox')
|
||||||
self.contacts[contact.jid] = contact
|
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.childs[contact.jid].connect('drag_data_received',
|
||||||
self.on_drag_data_received, contact)
|
self.on_drag_data_received, contact)
|
||||||
|
@ -428,7 +420,6 @@ timestamp, contact):
|
||||||
if gajim.awaiting_messages[self.account].has_key(contact.jid):
|
if gajim.awaiting_messages[self.account].has_key(contact.jid):
|
||||||
self.read_queue(contact.jid)
|
self.read_queue(contact.jid)
|
||||||
|
|
||||||
gajim.connections[self.account].request_vcard(contact.jid)
|
|
||||||
self.childs[contact.jid].show_all()
|
self.childs[contact.jid].show_all()
|
||||||
|
|
||||||
# chatstates
|
# chatstates
|
||||||
|
|
Loading…
Reference in New Issue