Broken commit, see new bug in TODO for details. Summary: new segfault at launch
This commit is contained in:
parent
5ab60f1278
commit
7cce83c0f3
3
TODO
3
TODO
|
@ -9,10 +9,11 @@ features:
|
||||||
* Status bar icon
|
* Status bar icon
|
||||||
* Support viewing a list of friends and unfollowing them
|
* Support viewing a list of friends and unfollowing them
|
||||||
* Support creating new lists and adding users to it (as well as removing users and deleting lists)
|
* Support creating new lists and adding users to it (as well as removing users and deleting lists)
|
||||||
|
* Need a new way to post failed tweet retrieval to the status bar
|
||||||
|
|
||||||
bugs:
|
bugs:
|
||||||
|
|
||||||
* Direct Messages have no names, only screen names (may not be fixable without
|
* Direct Messages have no names, only screen names (may not be fixable without
|
||||||
considerable tweets to python-twitter)
|
considerable tweets to python-twitter)
|
||||||
* Can't always kill tabs
|
* Can't always kill tabs
|
||||||
|
* New segfault at start that can't be reproduced with gdb. Must be a timing issue... adding locked access to some data in TweetPane didn't help... need locks to go with api objects.
|
||||||
|
|
|
@ -54,6 +54,76 @@ class GetTweets(Thread):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class GetSingleTweet(Thread):
|
||||||
|
def __init__(self, api, pane, single_tweet):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.api = api
|
||||||
|
self.pane = pane
|
||||||
|
self.single_tweet = single_tweet
|
||||||
|
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
statuses = []
|
||||||
|
statuses.append(self.api.GetStatus(self.single_tweet))
|
||||||
|
|
||||||
|
gtk.gdk.threads_enter()
|
||||||
|
try:
|
||||||
|
self.pane.update_window(statuses)
|
||||||
|
finally:
|
||||||
|
gtk.gdk.threads_leave()
|
||||||
|
|
||||||
|
|
||||||
|
### End class GetSingleTweet
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class GetFollowing(Thread):
|
||||||
|
def __init__(self, api, pane, user):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.api = api
|
||||||
|
self.pane = pane
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
screen_name = re.sub('user: ', '', self.user)
|
||||||
|
|
||||||
|
try:
|
||||||
|
relationship = self.api.ShowFriendships(target_screen_name=screen_name)
|
||||||
|
following = relationship.source.following
|
||||||
|
except HTTPError:
|
||||||
|
following = false
|
||||||
|
|
||||||
|
self.pane.set_following(following)
|
||||||
|
|
||||||
|
### End class GetFollowing
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class GetVerified(Thread):
|
||||||
|
def __init__(self, api, pane, user):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.api = api
|
||||||
|
self.pane = pane
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
screen_name = re.sub('user: ', '', self.user)
|
||||||
|
|
||||||
|
try:
|
||||||
|
user = self.api.GetUser(screen_name)
|
||||||
|
verified = user.verified
|
||||||
|
except HTTPError:
|
||||||
|
verified = false
|
||||||
|
|
||||||
|
self.pane.set_verified(verified)
|
||||||
|
|
||||||
|
|
||||||
|
### End class GetVerified
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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.
|
||||||
class Status():
|
class Status():
|
||||||
|
|
45
mytwitter.py
45
mytwitter.py
|
@ -288,9 +288,12 @@ class MyTwitter():
|
||||||
verified = False
|
verified = False
|
||||||
if re.match('user:', name):
|
if re.match('user:', name):
|
||||||
is_user = True
|
is_user = True
|
||||||
following = self.check_following(name)
|
new_pane = TweetPane(name, num_entries=self.num_entries, single_tweet=single_tweet, is_user=is_user)
|
||||||
verified = self.check_verified(name)
|
|
||||||
new_pane = TweetPane(name, num_entries=self.num_entries, single_tweet=single_tweet, is_user=is_user, following=following, verified=verified)
|
if is_user:
|
||||||
|
apithreads.GetFollowing(api=self.api, pane=new_pane, user=name).start()
|
||||||
|
apithreads.GetVerified(api=self.api, pane=new_pane, user=name).start()
|
||||||
|
|
||||||
self.tweet_notebook.append_page_menu(new_pane, new_pane.get_tab_label(), gtk.Label(name))
|
self.tweet_notebook.append_page_menu(new_pane, new_pane.get_tab_label(), gtk.Label(name))
|
||||||
self.tweet_notebook.set_tab_reorderable(new_pane, True)
|
self.tweet_notebook.set_tab_reorderable(new_pane, True)
|
||||||
new_pane.get_tab_label().connect('close-clicked', self.remove_view_callback, name, single_tweet)
|
new_pane.get_tab_label().connect('close-clicked', self.remove_view_callback, name, single_tweet)
|
||||||
|
@ -301,14 +304,9 @@ class MyTwitter():
|
||||||
|
|
||||||
# Special logic for single tweet pane
|
# Special logic for single tweet pane
|
||||||
if single_tweet is not None:
|
if single_tweet is not None:
|
||||||
try:
|
apithreads.GetSingleTweet(api=self.api,
|
||||||
statuses = []
|
pane=new_pane,
|
||||||
statuses.append(self.api.GetStatus(single_tweet))
|
single_tweet=single_tweet).start()
|
||||||
new_pane.update_window(statuses)
|
|
||||||
except HTTPError:
|
|
||||||
self.tweet_notebook.remove_page(-1)
|
|
||||||
self.update_status_bar('Error retrieving tweet id: ' + str(single_tweet))
|
|
||||||
return
|
|
||||||
|
|
||||||
self.update_windows()
|
self.update_windows()
|
||||||
self.tweet_notebook.set_current_page(-1) # switch to the new pane
|
self.tweet_notebook.set_current_page(-1) # switch to the new pane
|
||||||
|
@ -359,34 +357,15 @@ 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():
|
||||||
self.api.DestroyFriendship(user_name)
|
self.api.DestroyFriendship(user_name)
|
||||||
current_pane.set_following(self.check_following(user_name))
|
current_pane.set_following(False)
|
||||||
else:
|
else:
|
||||||
self.api.CreateFriendship(user_name)
|
self.api.CreateFriendship(user_name)
|
||||||
current_pane.set_following(self.check_following(user_name))
|
current_pane.set_following(True)
|
||||||
|
|
||||||
self.update_follow_button(current_pane)
|
self.update_follow_button(current_pane)
|
||||||
|
|
||||||
|
|
||||||
# Name is the name of a pane, with the 'user: ' in place
|
# pane should be the currently active pane
|
||||||
def check_following(self, name):
|
|
||||||
screen_name = re.sub('user: ', '', name)
|
|
||||||
try:
|
|
||||||
relationship = self.api.ShowFriendships(target_screen_name=screen_name)
|
|
||||||
except HTTPError:
|
|
||||||
return False
|
|
||||||
return relationship.source.following
|
|
||||||
|
|
||||||
|
|
||||||
# Name is the name of a pane, with the 'user: ' in place
|
|
||||||
def check_verified(self, name):
|
|
||||||
screen_name = re.sub('user: ', '', name)
|
|
||||||
try:
|
|
||||||
user = self.api.GetUser(screen_name)
|
|
||||||
except HTTPError:
|
|
||||||
return False
|
|
||||||
return user.verified
|
|
||||||
|
|
||||||
|
|
||||||
def update_follow_button(self, pane):
|
def update_follow_button(self, pane):
|
||||||
if not pane.get_is_user():
|
if not pane.get_is_user():
|
||||||
self.following_button.set_label('')
|
self.following_button.set_label('')
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import re
|
import re
|
||||||
import datetime, dateutil.tz
|
import datetime, dateutil.tz
|
||||||
import gtk, gobject
|
import gtk, gobject
|
||||||
|
from threading import RLock
|
||||||
|
|
||||||
|
|
||||||
class TweetPane(gtk.ScrolledWindow):
|
class TweetPane(gtk.ScrolledWindow):
|
||||||
'''
|
'''
|
||||||
|
@ -13,9 +15,11 @@ class TweetPane(gtk.ScrolledWindow):
|
||||||
It also gets some data from its parent, including num_entries
|
It also gets some data from its parent, including num_entries
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, list_name, num_entries=20, single_tweet=None, is_user=False, following=False, verified=False):
|
def __init__(self, list_name, num_entries=20, single_tweet=None, is_user=False):
|
||||||
gtk.ScrolledWindow.__init__(self)
|
gtk.ScrolledWindow.__init__(self)
|
||||||
|
|
||||||
|
self.data_lock = RLock()
|
||||||
|
|
||||||
self.updated_once = False
|
self.updated_once = False
|
||||||
|
|
||||||
self.list_name = list_name
|
self.list_name = list_name
|
||||||
|
@ -26,8 +30,8 @@ class TweetPane(gtk.ScrolledWindow):
|
||||||
self.num_entries = 1
|
self.num_entries = 1
|
||||||
|
|
||||||
self.is_user = is_user
|
self.is_user = is_user
|
||||||
self.following = following
|
self.following = False
|
||||||
self.verified = verified
|
self.verified = False
|
||||||
|
|
||||||
self.tab_label = CloseTabLabel(self.list_name)
|
self.tab_label = CloseTabLabel(self.list_name)
|
||||||
|
|
||||||
|
@ -158,17 +162,27 @@ class TweetPane(gtk.ScrolledWindow):
|
||||||
|
|
||||||
|
|
||||||
def get_following(self):
|
def get_following(self):
|
||||||
|
with self.data_lock:
|
||||||
return self.following
|
return self.following
|
||||||
|
|
||||||
|
|
||||||
def get_verified(self):
|
def get_verified(self):
|
||||||
|
with self.data_lock:
|
||||||
return self.verified
|
return self.verified
|
||||||
|
|
||||||
|
|
||||||
def set_following(self, following):
|
def set_following(self, following):
|
||||||
|
print 'debug: set_following(): ' + str(following)
|
||||||
|
with self.data_lock:
|
||||||
self.following = following
|
self.following = following
|
||||||
|
|
||||||
|
|
||||||
|
def set_verified(self, verified):
|
||||||
|
print 'debug: set_verified(): ' + str(verified)
|
||||||
|
with self.data_lock:
|
||||||
|
self.verified = verified
|
||||||
|
|
||||||
|
|
||||||
def get_is_user(self):
|
def get_is_user(self):
|
||||||
return self.is_user
|
return self.is_user
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user