from threading import RLock
from urllib2 import URLError,urlopen
import gtk


class AvCache:
    """
    Store a cache of avatar images we've already downloaded.
    This cache will be accessed by a number of threads, so it includes
    a lock as well.
    """

    class __impl:
        """ Implementation of the singleton interface """

        def __init__(self):
            self.lock = RLock()
            self.map = {}


    # storage for the instance reference
    __instance = None

    def __init__(self):
        """ Create singleton instance """
        # Check whether we already have an instance
        if AvCache.__instance is None:
            # Create and remember instance
            AvCache.__instance = AvCache.__impl()

        # Store instance reference as the only member in the handle
        self.__dict__['_AvCache__instance'] = AvCache.__instance

    def __getattr__(self, attr):
        """ Delegate access to implementation """
        return getattr(self.__instance, attr)

    def __setattr__(self, attr, value):
        """ Delegate access to implementation """
        return setattr(self.__instance, attr, value)

# end class AvCache


def add_to_cache(user):
    """
    This helping function takes a python-twitter User object, grabs the image
    data from the image_url and adds it to the AvCache with the screen_name as
    the key.
    """
    with AvCache().lock:
        hit = AvCache().map.has_key(user.screen_name)
    if not hit:
        try:
            url = urlopen(user.profile.image_url)
            data = url.read()
            loader = gtk.gdk.PixbufLoader()
            loader.write(str(data))
            image = loader.get_pixbuf()
            loader.close()
            
            with AvCache().lock:
                AvCache().map[user.screen_name] = image
        except (URLError, ValueError):
            pass # Nothing needs be done, just catch & ignore