You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
4.2 KiB
125 lines
4.2 KiB
#!/usr/bin/env python |
|
# -*- coding: utf-8 -*- |
|
|
|
# Mitter, a micro-blogging client with multiple interfaces. |
|
# Copyright (C) 2007-2010 Mitter Contributors |
|
# |
|
# This program is free software: you can redistribute it and/or modify |
|
# it under the terms of the GNU General Public License as published by |
|
# the Free Software Foundation, either version 3 of the License, or |
|
# (at your option) any later version. |
|
# |
|
# This program is distributed in the hope that it will be useful, |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
# GNU General Public License for more details. |
|
# |
|
# You should have received a copy of the GNU General Public License |
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
import logging |
|
import urllib2 |
|
|
|
import gtk |
|
|
|
# ---------------------------------------------------------------------- |
|
# Constants |
|
# ---------------------------------------------------------------------- |
|
_log = logging.getLogger('ui.helpers.avatarcache') |
|
|
|
# ---------------------------------------------------------------------- |
|
# The cache class |
|
# ---------------------------------------------------------------------- |
|
|
|
class AvatarCache(object): |
|
"""An avatar cache, storing GDK pixbufs references.""" |
|
|
|
def __init__(self, connection, default, timeout=None): |
|
"""Initialization of the cache. |
|
|
|
connection: |
|
A :class:`ThreadManager`, which will be used as thread pool to |
|
request the avatars. |
|
|
|
default: |
|
A gdk_pixbuf to be used as placeholder while the real avatar is |
|
being downloaded. |
|
|
|
timeout: |
|
Request timeout when downloading the avatars.""" |
|
|
|
self._connection = connection |
|
self._default = default |
|
self._cache = {} |
|
self._timeout = timeout |
|
|
|
def get(self, owner, avatar, url=None): |
|
"""Return the avatar from the cache or, if the avatar isn't available |
|
yet, returns the default avatar and queue the download of it. |
|
|
|
owner: |
|
The object requesting the avatar. Must have a "queue_draw()" |
|
method, which will be called once the avatar is available. Can be |
|
None. |
|
|
|
avatar: |
|
The identification of the avatar. Can be any string. |
|
|
|
url: |
|
URL to download the avatar. If not passed, *avatar* **must** be a |
|
valid URL.""" |
|
|
|
if avatar in self._cache: |
|
return self._cache[avatar] |
|
|
|
if not url: |
|
url = avatar |
|
|
|
self._connection.add_work(self._post_avatar_download, |
|
self._exception_avatar_download, |
|
self._download_pic, |
|
avatar, |
|
url, |
|
owner) |
|
|
|
# add the default avatar in the cache just to avoid a new request for |
|
# it. It will be overwritten anyway later. |
|
self._cache[avatar] = self._default |
|
return self._default |
|
|
|
# ------------------------------------------------------------ |
|
# Network functions |
|
# ------------------------------------------------------------ |
|
def _download_pic(self, avatar, url, owner): |
|
"""Download a picture from the web. Can be used in a thread.""" |
|
request = urllib2.Request(url=url) |
|
timeout = self._timeout |
|
_log.debug('Starting request of %s (timeout %ds)' % ( |
|
url, timeout)) |
|
response = urllib2.urlopen(request, timeout=timeout) |
|
data = response.read() |
|
_log.debug('Request completed') |
|
return (avatar, owner, data) |
|
|
|
def _post_avatar_download(self, widget, data): |
|
"""Called after the data from the picture is available.""" |
|
(avatar, owner, data) = data |
|
|
|
loader = gtk.gdk.PixbufLoader() |
|
loader.write(data) |
|
loader.close() |
|
|
|
user_pic = loader.get_pixbuf() |
|
user_pic = user_pic.scale_simple(48, 48, gtk.gdk.INTERP_BILINEAR) |
|
self._cache[avatar] = user_pic |
|
|
|
if owner: |
|
owner.queue_draw() |
|
return |
|
|
|
def _exception_avatar_download(self, widget, exception): |
|
"""Called in case we have a problem downloading an user avatar.""" |
|
_log.debug('Exception trying to get an avatar.') |
|
_log.debug(str(exception)) |
|
return |
|
|
|
|