class AsyncHTTPFetcherWithAuth(object): """Small proxy class which expects username/password combinations for fetch(), and supports invoking a callback on 401.""" def __init__(self): super(AsyncHTTPFetcherWithAuth, self).__init__() self.__fetcher = AsyncHTTPFetcher() def fetch(self, url, username, password, cb, errcb, authcb): self.__fetcher.fetch_extended(url=url, cb=cb, no_store=True, response_errcb=functools.partial(self.__handle_response_error, authcb, errcb), setupfn=functools.partial(self.__http_setupfn, username, password)) def __http_setupfn(self, username, password, h): h.add_credentials(username, password) h.follow_all_redirects = True def __handle_response_error(self, authcb, errcb, url, response, content): if response.status == 401: _logger.debug("auth failure for fetch of %s; invoking auth callback", url) gobject.idle_add(lambda: authcb(url) and False) else: _logger.error("caught error for fetch of %s (status %s)", url, response.status) # in my experience sys.exc_info() is some kind of junk here, while "e" is useful gobject.idle_add(lambda: errcb(url, response) and False)
class URLImageCache(Singleton): def __init__(self): self._cache = {} self._loads = {} self.__logger = logging.getLogger('bigboard.URLImageCache') self._fetcher = AsyncHTTPFetcher() def get(self, url, cb, errcb, format='surface'): if self._cache.has_key(url): # TODO expire pixbuf = self._cache[url] cb(url, format == 'surface' and hippo.cairo_surface_from_gdk_pixbuf(pixbuf) or pixbuf) return cbdata = (cb, errcb, format) if self._loads.has_key(url): self._loads[url].append(cbdata) else: self._loads[url] = [cbdata] self.__logger.debug("adding url='%s' to pending loads (%d outstanding)" % (url, len(self._loads.keys()))) self._fetcher.refetch(url, self._do_load, self._do_load_error) def _do_load(self, url, data, is_refetch=False): try: loader = gtk.gdk.PixbufLoader() # the write and close can both throw loader.write(data) loader.close() pixbuf = loader.get_pixbuf() self.__logger.debug("invoking callback for %s url='%s'" % (self, url)) self._cache[url] = pixbuf for cb, errcb, fmt in self._loads[url]: cb(url, fmt == 'surface' and hippo.cairo_surface_from_gdk_pixbuf(pixbuf) or pixbuf) except: for cb, errcb, fmt in self._loads[url]: errcb(url, sys.exc_info()) if not is_refetch: del self._loads[url] def _do_load_error(self, url, resp): for cb,errcb,fmt in self._loads[url]: errcb(url, resp) del self._loads[url]
def __init__(self): self._cache = {} self._loads = {} self.__logger = logging.getLogger('bigboard.URLImageCache') self._fetcher = AsyncHTTPFetcher()
def __init__(self): super(AsyncHTTPFetcherWithAuth, self).__init__() self.__fetcher = AsyncHTTPFetcher()