Threaded the calls to GetUserList, so that the View menu is populated asynchronously and startup time can be faster.

This commit is contained in:
Anna 2010-05-11 17:38:26 -04:00
parent b6a71b594a
commit a8abc21dd6
2 changed files with 82 additions and 28 deletions

View File

@ -1,20 +1,38 @@
# Python module that handles calls to the twitter API as a separate thread # Python module that handles calls to the twitter API as a separate thread
import re import re
import gtk import gtk, gobject
from threading import Thread,RLock from threading import Thread,RLock
from twitter import Api from twitter import Api
from urllib2 import HTTPError,URLError from urllib2 import HTTPError,URLError
class SafeApi(Api): class CustomApi(Api):
''' This is just a Twitter API with an RLock for multi-threaded access ''' '''
This is a Twitter API with an RLock for multi-threaded access
Also included is logic for processing the list names when the object is
instantiated
'''
def __init__(self, username, password): def __init__(self, username, password):
Api.__init__(self, username, password) Api.__init__(self, username, password)
self.lock = RLock() self.lock = RLock()
self.sig_proxy = SigProxy()
# End class SafeApi self.username = 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):
list_names = []
for l in lists['lists']:
list_names.append(l.name)
list_names.sort()
self.sig_proxy.emit('lists-ready', self.username, list_names)
# End class CustomApi
class ApiThread(Thread): class ApiThread(Thread):
@ -152,6 +170,41 @@ class GetVerified(ApiThread):
### End class GetVerified ### End class GetVerified
class GetUserLists(ApiThread):
def __init__(self, api):
ApiThread.__init__(self, api)
self.sig_proxy = SigProxy()
def run(self):
lists = []
done = False
while not done:
done = True
try:
with self.api.lock:
lists = self.api.GetUserLists()
except (HTTPError, URLError):
done = False
self.sig_proxy.emit('lists-ready', lists, None)
### End class GetUserLists
class SigProxy(gtk.Alignment):
def __init__(self):
gtk.Alignment.__init__(self)
# End class SigProxy
gobject.signal_new("lists-ready", SigProxy,
gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,gobject.TYPE_PYOBJECT))
# We use these classes to emulate a Status object when we need # We use these classes to emulate a Status object when we need
# one to be built out of something else. # one to be built out of something else.

View File

@ -46,7 +46,8 @@ class MyTwitter():
for item in config.sections(): for item in config.sections():
if (re.match(r'account', item)): if (re.match(r'account', item)):
username = config.get(item, 'username') username = config.get(item, 'username')
self.accounts[username] = apithreads.SafeApi(username=username, password=config.get(item, 'password')) self.accounts[username] = apithreads.CustomApi(username=username, password=config.get(item, 'password'))
self.accounts[username].sig_proxy.connect('lists-ready', self.on_lists_ready)
self.username = self.accounts.keys()[0] self.username = self.accounts.keys()[0]
self.api = self.accounts[self.username] self.api = self.accounts[self.username]
@ -107,31 +108,9 @@ class MyTwitter():
for tab, single_tweet in self.db['open_tabs']: for tab, single_tweet in self.db['open_tabs']:
self.add_to_notebook(tab, single_tweet, update=False) self.add_to_notebook(tab, single_tweet, update=False)
self.tweet_notebook.set_current_page(page_num) self.tweet_notebook.set_current_page(page_num)
self.update_windows() self.update_windows()
# Put Home, @user, Direct Messages, and lists in the View menu for
# each user
for username in self.accounts.keys():
outer_menu_item = gtk.MenuItem(username)
self.view_menu.append(outer_menu_item)
new_menu = gtk.Menu()
outer_menu_item.set_submenu(new_menu)
lists = self.accounts[username].GetUserLists()
list_names = []
for l in lists['lists']:
list_names.append(l.name)
list_names.sort()
list_names.insert(0, 'Home')
list_names.insert(1, '@' + username)
list_names.insert(2, 'Direct Messages')
for l in list_names:
menu_item = gtk.MenuItem(l)
new_menu.append(menu_item)
menu_item.connect('activate', self.on_view_selected, username, l)
menu_item.show()
outer_menu_item.show()
# Timer to update periodically # Timer to update periodically
gobject.timeout_add(self.refresh_time * 1000, self.update_windows) gobject.timeout_add(self.refresh_time * 1000, self.update_windows)
@ -450,6 +429,28 @@ class MyTwitter():
self.username = new_user self.username = new_user
self.api = self.accounts[self.username] self.api = self.accounts[self.username]
def on_lists_ready(self, widget, username, list_names):
# Setup the new sub-menu
outer_menu_item = gtk.MenuItem(username)
self.view_menu.append(outer_menu_item)
new_menu = gtk.Menu()
outer_menu_item.set_submenu(new_menu)
# Insert the default list items
list_names.insert(0, 'Home')
list_names.insert(1, '@' + username)
list_names.insert(2, 'Direct Messages')
# Add the items to the submenu, connect handler
for l in list_names:
menu_item = gtk.MenuItem(l)
new_menu.append(menu_item)
menu_item.connect('activate', self.on_view_selected, username, l)
menu_item.show()
outer_menu_item.show()
### end class MyTwitter ### end class MyTwitter