Added error handling when API calls timeout
This commit is contained in:
parent
6044fa27d2
commit
f37246f30b
|
@ -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)
|
||||||
|
|
31
mytwitter.py
31
mytwitter.py
|
@ -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,16 +369,24 @@ 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)
|
||||||
|
|
||||||
|
|
||||||
# pane should be the currently active pane
|
# pane should be the currently active pane
|
||||||
def update_follow_button(self, pane):
|
def update_follow_button(self, pane):
|
||||||
if not pane.get_is_user():
|
if not pane.get_is_user():
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user