From 8fac5ad7c278ec2c95926e4dbd55e18935289911 Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 2 Jun 2010 17:00:11 -0400 Subject: [PATCH] Reworked how adding lists is handled (so the child thread does the actual work and we can employ a Condition object to allow the add_to_notebook function to have the list information available) and put in code that should list the lists a user is in. Currently seems to not function as expected, however. --- apithreads.py | 25 +++++++++---------------- hrafn.py | 46 +++++++++++++++++++++++++++++++++++++++------- twitterwidgets.py | 26 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 23 deletions(-) diff --git a/apithreads.py b/apithreads.py index e8ca475..0f68b3f 100644 --- a/apithreads.py +++ b/apithreads.py @@ -22,21 +22,14 @@ class CustomApi(OAuthApi): instantiated ''' - def __init__(self, access_token): + def __init__(self, access_token, hrafn_obj): OAuthApi.__init__(self, CONSUMER_KEY, CONSUMER_SECRET, access_token) self.lock = RLock() - self.sig_proxy = SigProxy() self.username = self.GetUserInfo().screen_name self._username = self.username - thread = GetUserLists(api=self) - thread.sig_proxy.connect('lists-ready', self.on_lists_ready) - thread.start() - - - def on_lists_ready(self, widget, lists, ignored): - self.sig_proxy.emit('lists-ready', self.username, lists) + thread = GetUserLists(self, hrafn_obj).start() # End class CustomApi @@ -250,9 +243,9 @@ class GetUserInfo(ApiThread): class GetUserLists(ApiThread): - def __init__(self, api): + def __init__(self, api, hrafn_obj): ApiThread.__init__(self, api) - self.sig_proxy = SigProxy() + self.hrafn_obj = hrafn_obj def run(self): @@ -272,7 +265,11 @@ class GetUserLists(ApiThread): sleep(30) done = False - self.sig_proxy.emit('lists-ready', lists, None) + gtk.gdk.threads_enter() + try: + self.hrafn_obj.add_lists(self.api.username, lists) + finally: + gtk.gdk.threads_leave() ### End class GetUserLists @@ -374,10 +371,6 @@ class SigProxy(gtk.Alignment): # End class SigProxy -gobject.signal_new("lists-ready", SigProxy, - gobject.SIGNAL_RUN_LAST, - gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,gobject.TYPE_PYOBJECT)) - gobject.signal_new("update-posted", SigProxy, gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) diff --git a/hrafn.py b/hrafn.py index 6cced84..83f3cff 100755 --- a/hrafn.py +++ b/hrafn.py @@ -6,7 +6,7 @@ import sys, ConfigParser, os, re, optparse, shelve import gtk, gtk.glade, gobject from urllib2 import HTTPError,URLError from twitterwidgets import TweetPane -from threading import enumerate +from threading import enumerate,Condition import apithreads @@ -61,7 +61,7 @@ class Hrafn(): # Now set up the accounts and their corresponding APIs self.accounts = {} for token in self.db['tokens']: - api = apithreads.CustomApi(token) + api = apithreads.CustomApi(token, self) self.add_account(api) self.username = self.db['active_user'] @@ -82,6 +82,7 @@ class Hrafn(): self.reply_id = None self.lists = {} + self.lists_cond = Condition() # Load up all the programmatic GUI stuff self.init_widgets() @@ -335,6 +336,29 @@ class Hrafn(): new_pane.connect('tweets-read', self.on_read_tweets_changed) if is_user: + # Find the lists this user is currently in, and pass those + # to the pane + found_lists = [] + username = re.sub('user: ', '', name) + + + # We're not going to change the data, just access it. + # This condition only exists to let us know when the lists are + # ready + # Ergo, we can release it right after we get out of the conditional + self.lists_cond.acquire() + while not self.lists.has_key(self.username): + self.lists_cond.wait() + self.lists_cond.release() + + for list_name in self.lists[self.username].keys(): + try: + i = self.lists[self.username][list_name].index(username) + found_lists.append(list_name) + except: + pass + new_pane.set_lists(found_lists) + new_pane.connect('at-clicked', self.on_at_button_clicked) new_pane.connect('follow-clicked', self.on_follow_button_clicked) apithreads.GetFollowing(api=self.api, pane=new_pane, user=name).start() @@ -491,18 +515,27 @@ class Hrafn(): apithreads.GetFollowing(api=self.api, pane=pane, user=user).start() - def on_lists_ready(self, widget, username, list_data): - ''' This callback takes information from a child thread that grabs list info from the API, and stores that info for later use ''' - + def add_lists(self, username, list_data): + ''' + This function is called by a child thread. + It takes list info from the API, stores it for later use, and uses + the data to populate the Views menu + ''' + # Setup the new sub-menu outer_menu_item = gtk.MenuItem(username, False) self.view_menu.append(outer_menu_item) new_menu = gtk.Menu() outer_menu_item.set_submenu(new_menu) + self.lists_cond.acquire() + # Save the member info in a data structure for later usage self.lists[username] = list_data + self.lists_cond.notify() + self.lists_cond.release() + list_names = list_data.keys() list_names.sort() @@ -557,7 +590,7 @@ class Hrafn(): if token is None: return - api = apithreads.CustomApi(token) + api = apithreads.CustomApi(token, self) if not self.accounts.has_key(api.username): tokens = self.db['tokens'] @@ -569,7 +602,6 @@ class Hrafn(): def add_account(self, api): username = api.username self.accounts[username] = api - self.accounts[username].sig_proxy.connect('lists-ready', self.on_lists_ready) # Add account's menu item menu_item = gtk.RadioMenuItem(self.first_account_item, label=username, use_underline=False) diff --git a/twitterwidgets.py b/twitterwidgets.py index e574991..85cb709 100644 --- a/twitterwidgets.py +++ b/twitterwidgets.py @@ -225,6 +225,13 @@ class TweetPane(gtk.ScrolledWindow): def on_follow_clicked(self, widget, data): self.emit('follow-clicked', data) + + def set_lists(self, lists): + if not self.is_user: + return + + self.user_box.set_lists(lists) + ### end class TweetPane # signals for TweetPane @@ -629,15 +636,19 @@ class UserBox(gtk.VBox): self.at_button = gtk.Button('@') self.follow_label = gtk.Label('You are following this user') self.verified_label = gtk.Label('Verified account') + self.list_box = gtk.combo_box_entry_new_text() + self.list_label = gtk.Label('') self.name_label.set_alignment(0.0, 0.0) self.follow_label.set_alignment(0.0, 0.0) self.verified_label.set_alignment(0.0, 0.0) + self.list_label.set_alignment(0.0, 0.0) text_col = gtk.VBox() text_col.pack_start(self.name_label, expand=False) text_col.pack_start(self.verified_label, expand=False) text_col.pack_start(self.follow_label, expand=False) + text_col.pack_start(self.list_label, expand=False) info_row = gtk.HBox() info_row.pack_start(self.avatar, expand=False) @@ -693,6 +704,9 @@ class UserBox(gtk.VBox): self.at_button.show() self.follow_button.show() + if self.list_label.get_text() != '': + self.list_label.show() + self.info_loaded = True @@ -740,6 +754,18 @@ class UserBox(gtk.VBox): self.name_label.hide() self.avatar.hide() + + def set_lists(self, lists): + if not lists: + return + + list_label_text = 'In lists: ' + + for l in lists: + list_label_text += l + ' ' + + self.list_label.set_text(list_label_text) + # end class UserBox # signals for UserBox