Added error handling when API calls timeout

This commit is contained in:
Anna 2010-05-04 14:32:43 -04:00
parent 6044fa27d2
commit f37246f30b
3 changed files with 66 additions and 32 deletions

View File

@ -4,6 +4,7 @@ import re
import gtk import gtk
from threading import Thread,RLock from threading import Thread,RLock
from twitter import Api from twitter import Api
from urllib2 import HTTPError,URLError
class SafeApi(Api): class SafeApi(Api):
''' This is just a Twitter API with an RLock for multi-threaded access ''' ''' This is just a Twitter API with an RLock for multi-threaded access '''
@ -28,34 +29,37 @@ class GetTweets(Thread):
def run(self): def run(self):
with self.api.lock: with self.api.lock:
try:
# username/Home entries need to load the appropriate Home feed
if self.list_name == self.username + '/Home':
statuses = self.api.GetHomeTimeline(count=self.num_entries)
# username/Home entries need to load the appropriate Home feed # For @username, check if it is one of our usernames, or
if self.list_name == self.username + '/Home': # just needs to be searched on
statuses = self.api.GetHomeTimeline(count=self.num_entries) elif self.list_name == '@' + self.username:
statuses = self.api.GetMentions(count=self.num_entries)
elif re.match('@', self.list_name):
statuses = results_to_statuses(self.api.Search(self.list_name, rpp=self.num_entries))
# For @username, check if it is one of our usernames, or # Direct Messages should match like /Home, above
# just needs to be searched on elif self.list_name == self.username + '/Direct Messages':
elif self.list_name == '@' + self.username: statuses = dms_to_statuses(self.api.GetDirectMessages())
statuses = self.api.GetMentions(count=self.num_entries)
elif re.match('@', self.list_name):
statuses = results_to_statuses(self.api.Search(self.list_name, rpp=self.num_entries))
# Direct Messages should match like /Home, above # User lookups go straight to the user
elif self.list_name == self.username + '/Direct Messages': elif re.match(r'user: ', self.list_name):
statuses = dms_to_statuses(self.api.GetDirectMessages()) statuses = self.api.GetUserTimeline(re.sub(r'^user: ', r'', self.list_name), count=self.num_entries)
# User lookups go straight to the user # Lists load the appropriate list from the appropriate account
elif re.match(r'user: ', self.list_name): elif re.match(r'list: ', self.list_name):
statuses = self.api.GetUserTimeline(re.sub(r'^user: ', r'', self.list_name), count=self.num_entries) real_list = re.sub(r'list: .*/(.*)', r'\1', self.list_name)
statuses = self.api.GetListStatuses(real_list, per_page=self.num_entries)
# Lists load the appropriate list from the appropriate account # Everything else is a straight search
elif re.match(r'list: ', self.list_name): else:
real_list = re.sub(r'list: .*/(.*)', r'\1', self.list_name) statuses = results_to_statuses(self.api.Search(self.list_name, rpp=self.num_entries))
statuses = self.api.GetListStatuses(real_list, per_page=self.num_entries)
# Everything else is a straight search except HTTPError,URLError:
else: statuses = None
statuses = results_to_statuses(self.api.Search(self.list_name, rpp=self.num_entries))
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
@ -79,7 +83,10 @@ class GetSingleTweet(Thread):
def run(self): def run(self):
statuses = [] statuses = []
with self.api.lock: with self.api.lock:
statuses.append(self.api.GetStatus(self.single_tweet)) try:
statuses.append(self.api.GetStatus(self.single_tweet))
except HTTPError,URLError:
statuses = None
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
@ -107,7 +114,7 @@ class GetFollowing(Thread):
with self.api.lock: with self.api.lock:
relationship = self.api.ShowFriendships(target_screen_name=screen_name) relationship = self.api.ShowFriendships(target_screen_name=screen_name)
following = relationship.source.following following = relationship.source.following
except HTTPError: except HTTPError,URLError:
following = false following = false
self.pane.set_following(following) self.pane.set_following(following)
@ -131,7 +138,7 @@ class GetVerified(Thread):
with self.api.lock: with self.api.lock:
user = self.api.GetUser(screen_name) user = self.api.GetUser(screen_name)
verified = user.verified verified = user.verified
except HTTPError: except HTTPError,URLError:
verified = false verified = false
self.pane.set_verified(verified) self.pane.set_verified(verified)

View File

@ -4,7 +4,7 @@
import sys, ConfigParser, os, re, optparse, shelve import sys, ConfigParser, os, re, optparse, shelve
import gtk, gtk.glade, gobject import gtk, gtk.glade, gobject
from urllib2 import HTTPError from urllib2 import HTTPError,URLError
from twitterwidgets import TweetPane from twitterwidgets import TweetPane
import apithreads import apithreads
@ -189,7 +189,13 @@ class MyTwitter():
text = self.update_entry.get_text() text = self.update_entry.get_text()
self.update_entry.set_text("") self.update_entry.set_text("")
with self.api.lock: with self.api.lock:
self.api.PostUpdate(text, in_reply_to_status_id=self.reply_id) try:
self.api.PostUpdate(text, in_reply_to_status_id=self.reply_id)
except HTTPError,URLError:
self.update_status_bar('Failed to post tweet')
self.reply_id = None
return
self.reply_id = None self.reply_id = None
self.update_status_bar('Tweet Posted') self.update_status_bar('Tweet Posted')
@ -226,7 +232,10 @@ class MyTwitter():
def on_retweet(self, widget, data): def on_retweet(self, widget, data):
with self.api.lock: with self.api.lock:
self.api.PostRetweet(data['id']) try:
self.api.PostRetweet(data['id'])
except HTTPError,URLError:
self.update_status_bar('Failed to retweet')
def on_reply_to(self, widget, data): def on_reply_to(self, widget, data):
@ -360,11 +369,19 @@ class MyTwitter():
user_name = re.sub('^user: ', '', current_pane.get_list_name()) user_name = re.sub('^user: ', '', current_pane.get_list_name())
if current_pane.get_following(): if current_pane.get_following():
with self.api.lock: with self.api.lock:
self.api.DestroyFriendship(user_name) try:
self.api.DestroyFriendship(user_name)
except HTTPError,URLError:
self.update_status_bar('Failed to unfollow user.')
return
current_pane.set_following(False) current_pane.set_following(False)
else: else:
with self.api.lock: with self.api.lock:
self.api.CreateFriendship(user_name) try:
self.api.CreateFriendship(user_name)
except HTTPError,URLError:
self.update_status_bar('Failed to follow user.')
return
current_pane.set_following(True) current_pane.set_following(True)
self.update_follow_button(current_pane) self.update_follow_button(current_pane)

View File

@ -35,6 +35,8 @@ class TweetPane(gtk.ScrolledWindow):
self.tab_label = CloseTabLabel(self.list_name) self.tab_label = CloseTabLabel(self.list_name)
self.error_message = gtk.Label('Failed to load tweet(s)')
# These handle determining which tweets are unread # These handle determining which tweets are unread
self.last_tweet_read = None self.last_tweet_read = None
self.latest_tweet = None self.latest_tweet = None
@ -52,6 +54,8 @@ class TweetPane(gtk.ScrolledWindow):
viewport = gtk.Viewport() viewport = gtk.Viewport()
# Build us some labels... # Build us some labels...
tweet_box.pack_start(self.error_message)
for i in range(0, self.num_entries): for i in range(0, self.num_entries):
self.tweets.append(TweetBox()) self.tweets.append(TweetBox())
tweet_box.pack_start(self.tweets[i], expand=False) tweet_box.pack_start(self.tweets[i], expand=False)
@ -73,11 +77,17 @@ class TweetPane(gtk.ScrolledWindow):
self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
self.show_all() self.show_all()
self.error_message.hide()
for tweet in self.tweets: for tweet in self.tweets:
tweet.hide() tweet.hide()
def update_window(self, statuses): def update_window(self, statuses):
if statuses is None:
self.error_message.show()
for i in range(0, self.num_entries):
self.tweets[i].hide()
if self.updated_once is False: if self.updated_once is False:
self.updated_once = True self.updated_once = True