From 522a52212918f8433b6d6de13b5d73f62cf9c91c Mon Sep 17 00:00:00 2001
From: Anna <annabuches@gmail.com>
Date: Mon, 17 May 2010 11:24:32 -0400
Subject: [PATCH] Laid groundwork for displaying avatar images

---
 apithreads.py     |  1 +
 avcache.py        | 40 ++++++++++++++++++++++++++++++++++++++++
 twitterwidgets.py | 19 ++++++++++++++-----
 3 files changed, 55 insertions(+), 5 deletions(-)
 create mode 100644 avcache.py

diff --git a/apithreads.py b/apithreads.py
index 0c59618..0f612cd 100644
--- a/apithreads.py
+++ b/apithreads.py
@@ -6,6 +6,7 @@ from threading import Thread,RLock
 from twitter import Api
 from urllib2 import HTTPError,URLError
 
+
 class CustomApi(Api):
     '''
     This is a Twitter API with an RLock for multi-threaded access
diff --git a/avcache.py b/avcache.py
new file mode 100644
index 0000000..94936b6
--- /dev/null
+++ b/avcache.py
@@ -0,0 +1,40 @@
+from threading import RLock
+
+
+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
diff --git a/twitterwidgets.py b/twitterwidgets.py
index a043a1a..8627d9f 100644
--- a/twitterwidgets.py
+++ b/twitterwidgets.py
@@ -227,7 +227,7 @@ gobject.signal_new("verified-set", TweetPane,
 
 
 
-class TweetBox(gtk.VBox):
+class TweetBox(gtk.HBox):
 
     '''
     GUI for displaying one tweet and associated buttons
@@ -236,7 +236,7 @@ class TweetBox(gtk.VBox):
     '''
 
     def __init__(self):
-        gtk.VBox.__init__(self)
+        gtk.HBox.__init__(self)
 
         self.screen_name = None
         self.id = None
@@ -247,11 +247,20 @@ class TweetBox(gtk.VBox):
 
 
     def init_widgets(self):
+        # Build the image
+        self.avatar = gtk.Image()
+
+        self.pack_start(self.avatar, expand=False, fill=False)
+
+        # Everything else goes in a VBox beside the image
+        text_box = gtk.VBox()
+        self.pack_start(text_box)
+
         ## Build the header
         self.header = gtk.Button()
         label_eb = gtk.EventBox()
         label_eb.add(self.header)
-        self.pack_start(label_eb)
+        text_box.pack_start(label_eb)
 
         # Set the header's properties
         label_eb.modify_text(gtk.STATE_NORMAL,gtk.gdk.color_parse("#ffffff"))
@@ -268,7 +277,7 @@ class TweetBox(gtk.VBox):
         text_align.add(self.text)
         self.text_eb = gtk.EventBox()
         self.text_eb.add(text_align)
-        self.pack_start(self.text_eb)
+        text_box.pack_start(self.text_eb)
 
         # Set the text's properties
         text_align.set_padding(2, 5, 10, 5)
@@ -283,7 +292,7 @@ class TweetBox(gtk.VBox):
         button_box_align = gtk.Alignment()
         button_box_align.set_padding(0, 15, 0, 0)
         button_box = gtk.HBox()
-        self.pack_start(button_box)
+        text_box.pack_start(button_box)
 
         self.reply_to_button = gtk.Button("")
         self.reply_to_button.set_relief(gtk.RELIEF_NONE)