Merge lp:~eduardo-mucelli/cairo-dock-plug-ins-extras/Twitter into lp:~cairo-dock-team/cairo-dock-plug-ins-extras/third-party
- Merge into third-party
Proposed by
Eduardo Mucelli Rezende Oliveira
Status: | Merged |
---|---|
Merged at revision: | 234 |
Proposed branch: | lp:~eduardo-mucelli/cairo-dock-plug-ins-extras/Twitter |
Merge into: | lp:~cairo-dock-team/cairo-dock-plug-ins-extras/third-party |
Diff against target: |
254 lines (+59/-62) 4 files modified
Twitter/ChangeLog (+1/-0) Twitter/Twitter (+56/-60) Twitter/Twitter.conf (+1/-1) Twitter/auto-load.conf (+1/-1) |
To merge this branch: | bzr merge lp:~eduardo-mucelli/cairo-dock-plug-ins-extras/Twitter |
Related bugs: | |
Related blueprints: |
Twitter applet
(Medium)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matthieu Baerts | Approve | ||
Review via email: mp+96162@code.launchpad.net |
Commit message
Description of the change
Using callback instead of a thread to check for the new tweet from the stream, faster, better, and cleaner. Fixed new tweets count that was not being updated. Increased modularization.
To post a comment you must log in.
Revision history for this message
Eduardo Mucelli Rezende Oliveira (eduardo-mucelli) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Twitter/ChangeLog' |
2 | --- Twitter/ChangeLog 2012-03-05 14:44:13 +0000 |
3 | +++ Twitter/ChangeLog 2012-03-06 16:22:21 +0000 |
4 | @@ -1,3 +1,4 @@ |
5 | +0.1.1: (March/6/2012): Using callback instead of a thread to check for the new tweet from the stream, faster, better, and cleaner. Fixed new tweets count that was not being updated. Increased modularization. |
6 | 0.1: (March/5/2012): Finally, after long work, compatible with Twitter Stream, and using it to show the tweets that just arrived. Changed the "received" icon for direct messages, and added the "new" for new tweets, both are from the icon pack Basic made by Pixel Maker, http://pixel-mixer.com |
7 | 0.0.3: (January/14/2012): Possible to see user's info. Translation directives were added on the strings. |
8 | 0.0.2: (January/8/2012): Possible to see the received direct messages. |
9 | |
10 | === modified file 'Twitter/Twitter' |
11 | --- Twitter/Twitter 2012-03-05 14:44:13 +0000 |
12 | +++ Twitter/Twitter 2012-03-06 16:22:21 +0000 |
13 | @@ -23,6 +23,7 @@ |
14 | # Paste this number on the next dialog box will be shown. |
15 | # The plugin is going to inform that you are successfully connected. |
16 | |
17 | +# To see the received tweets right-click on the icon -> Twitter -> New tweets. |
18 | # To see the received direct messages right-click on the icon -> Twitter -> Received direct messages |
19 | # To see some user's info right-click on the icon -> Twitter -> Info |
20 | |
21 | @@ -76,41 +77,32 @@ |
22 | access_token_data = dict((x, y) for x, y in urlparse.parse_qsl(response)) # tuple to dict |
23 | return access_token_data['oauth_token'], access_token_data['oauth_token_secret'] |
24 | |
25 | -# TODO: Separate things starting with this, check also the possible inheritance with TwitterOauth |
26 | -#class API(): |
27 | -# def __init__(self, access_key, access_secret): |
28 | -# self.signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() |
29 | -# consumer_key, consumer_secret = read_consumer_key_and_secret() |
30 | -# self.consumer = oauth.OAuthConsumer(consumer_key, consumer_secret) |
31 | -# self.access_token = oauth.OAuthToken(access_key, access_secret) |
32 | - |
33 | -#class TwitterAPI(API): |
34 | -class TwitterAPI: |
35 | +# TODO: Check also the possible inheritance with TwitterOauth |
36 | +class API(): |
37 | def __init__(self, access_key, access_secret): |
38 | - #API.__init__(self, access_key, access_secret) |
39 | - self.update_url = 'http://twitter.com/statuses/update.json' |
40 | - self.home_timeline_url = 'http://twitter.com/statuses/home_timeline.json' |
41 | - self.direct_messages_url = 'https://api.twitter.com/1/direct_messages.json' |
42 | - self.verify_credentials_url = 'https://api.twitter.com/1/account/verify_credentials.json' |
43 | - self.user_stream_url = "https://userstream.twitter.com/2/user.json" |
44 | - |
45 | self.signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() |
46 | consumer_key, consumer_secret = read_consumer_key_and_secret() |
47 | self.consumer = oauth.OAuthConsumer(consumer_key, consumer_secret) |
48 | self.access_token = oauth.OAuthToken(access_key, access_secret) |
49 | - |
50 | - thread = threading.Thread(target=self.tweety_streaming) |
51 | + |
52 | +class TwitterStreamAPI(API): |
53 | + def __init__(self, access_key, access_secret, callback): |
54 | + API.__init__(self, access_key, access_secret) |
55 | + |
56 | + self.user_stream_url = "https://userstream.twitter.com/2/user.json" |
57 | + self.callback = callback # this method is going to be called as soon as a new entry on the stream appears |
58 | + thread = threading.Thread(target=self.tweet_streaming) |
59 | thread.start() |
60 | - self.stream_content = Queue.Queue() |
61 | - |
62 | - def tweety_streaming(self): |
63 | + |
64 | + def tweet_streaming(self): |
65 | oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, |
66 | token = self.access_token, |
67 | http_url = self.user_stream_url) |
68 | oauth_request.sign_request(self.signature_method, self.consumer, self.access_token) |
69 | - #stream(oauth_request.to_url()) |
70 | + |
71 | url = oauth_request.to_url() |
72 | req = urllib2.urlopen(url) |
73 | + |
74 | buffer = '' |
75 | while True: |
76 | chunk = req.read(1) |
77 | @@ -124,12 +116,20 @@ |
78 | content = tweets[0] |
79 | if "text" in content: |
80 | content = simplejson.loads(content) |
81 | - self.stream_content.put(content) |
82 | - self.stream_content.task_done() |
83 | - print content |
84 | + logp("Received from Twitter Stream: %s" % content) |
85 | + self.callback(content) # at the moment this method is called 'on_receive_new_tweet_callback' |
86 | buffer = tweets[1] |
87 | + |
88 | +class TwitterAPI(API): |
89 | + def __init__(self, access_key, access_secret): |
90 | + API.__init__(self, access_key, access_secret) |
91 | + |
92 | + self.update_url = 'http://twitter.com/statuses/update.json' |
93 | + self.home_timeline_url = 'http://twitter.com/statuses/home_timeline.json' |
94 | + self.direct_messages_url = 'https://api.twitter.com/1/direct_messages.json' |
95 | + self.verify_credentials_url = 'https://api.twitter.com/1/account/verify_credentials.json' |
96 | |
97 | - def tweety(self, message): # popularly "send a tweety" |
98 | + def tweet(self, message): # popularly "send a tweet" |
99 | oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, |
100 | token = self.access_token, |
101 | http_url = self.update_url, |
102 | @@ -186,23 +186,21 @@ |
103 | self.icon.SetQuickInfo("") |
104 | |
105 | # Twitter methods |
106 | - |
107 | - # TODO: Encapsulate this method inside the StreamAPI class |
108 | + |
109 | # TODO: Make available a "Animation" option upon a new tweet arrival |
110 | - def check_twitter_user_stream(self): |
111 | - while True: |
112 | - time.sleep(30) # TODO: variable for this! |
113 | - logp("Checking Stream ...") |
114 | - if not self.api.stream_content.empty(): |
115 | - self.tweets_on_the_user_stream_queue = self.api.stream_content.qsize() |
116 | - logp("There are new %d items on the Stream Queue" % self.tweets_on_the_user_stream_queue) |
117 | - self.icon.SetQuickInfo(str(self.tweets_on_the_user_stream_queue)) |
118 | + # This method is a callback that is called as soon as a new tweet that arrives on the stream |
119 | + # It is passed as parameter when creating the instance for the TwitterStreamAPI |
120 | + # TwitterStreamAPI(access_key, access_secret, self.on_receive_new_tweet_callback) |
121 | + def on_receive_new_tweet_callback(self, tweet): |
122 | + logp("Inserting new tweet on the stream Queue: %s" % tweet) |
123 | + self.stream.put(tweet) # put the new tweet on the stream queue |
124 | + self.icon.SetQuickInfo(str(self.stream.qsize())) # update the new tweets counter on the icon |
125 | |
126 | def show_new_tweets(self): |
127 | self.inform_start_of_waiting_process() |
128 | message = '' |
129 | - while not self.api.stream_content.empty(): |
130 | - tweet = self.api.stream_content.get() |
131 | + while not self.stream.empty(): # iterate on the stream composing the message |
132 | + tweet = self.stream.get() |
133 | message += "[<b>%s</b>] %s\n" % (tweet['user']['name'], tweet['text']) |
134 | dialog = {'use-markup':True} |
135 | self.inform_end_of_waiting_process() |
136 | @@ -230,12 +228,11 @@ |
137 | self.inform_end_of_waiting_process() |
138 | self.show_popup_message(message, dialog) |
139 | |
140 | - def tweety(self, message): # popularly "send a tweety" |
141 | + def tweet(self, message): # popularly "send a tweet" |
142 | self.inform_start_of_waiting_process() |
143 | self.api.update_status(message) |
144 | self.inform_end_of_waiting_process() |
145 | |
146 | - # TODO |
147 | def show_credentials(self): |
148 | self.inform_start_of_waiting_process() |
149 | credentials = self.api.verify_credentials() |
150 | @@ -246,11 +243,11 @@ |
151 | |
152 | # Applet methods |
153 | |
154 | - def ask_for_tweety(self): |
155 | + def ask_for_tweet(self): |
156 | dialog = {'buttons':'ok;cancel'} |
157 | - widget = {'widget-type':'text-entry', 'nb-chars':140} # 140 characters max, a tweety :) |
158 | - self.show_popup_message((_("%s, send a tweety")) % self.user.screen_name, dialog, widget) |
159 | - self.dialog_type = self.responding_tweety |
160 | + widget = {'widget-type':'text-entry', 'nb-chars':140} # 140 characters max, a tweet :) |
161 | + self.show_popup_message((_("%s, send a tweet")) % self.user.screen_name, dialog, widget) |
162 | + self.dialog_type = self.responding_tweet |
163 | |
164 | # TODO: Implement it as a config file using screen_name as section index |
165 | def read_user_data(self): |
166 | @@ -350,30 +347,29 @@ |
167 | self.user_file = os.path.abspath(os.path.join(os.getcwd(), '..','..','..','.twitter_users')) # ~/.config/.twitter_users |
168 | self.twitter_auth = TwitterOauth() |
169 | self.api = None |
170 | + self.stream_api = None |
171 | (self.responding_screen_name, self.responding_authorization, self.responding_pin, |
172 | - self.responding_success, self.responding_tweety, self.responding_initial_informations) = range(6) |
173 | + self.responding_success, self.responding_tweet, self.responding_initial_informations) = range(6) |
174 | self.dialog_type = None |
175 | |
176 | self.direct_messages_menu_id = 1000 |
177 | self.credentials_menu_id = 2000 |
178 | self.user_stream_menu_id = 3000 |
179 | |
180 | - self.tweets_on_the_user_stream_queue = 0 |
181 | - # TODO: Array with the two threads here |
182 | + self.stream = Queue.Queue() |
183 | |
184 | - CDApplet.__init__(self) # call CDApplet interface init |
185 | + CDApplet.__init__(self) # call CDApplet interface init |
186 | |
187 | # Inherited methods from CDApplet |
188 | def begin(self): |
189 | logp("Looking for user ...") |
190 | - if not self.read_user_data(): # first time for the user |
191 | + if not self.read_user_data(): # first time for the user |
192 | logm("User not found") |
193 | - self.show_initial_informations() # start the wizard |
194 | - else: # user not found |
195 | + self.show_initial_informations() # start the wizard |
196 | + else: # user not found |
197 | logp("User '%s' found" % self.user.screen_name) |
198 | - self.api = TwitterAPI(self.user.access_key, self.user.access_secret) # getting control over the api |
199 | - thread = threading.Thread(target=self.check_twitter_user_stream) |
200 | - thread.start() |
201 | + self.api = TwitterAPI(self.user.access_key, self.user.access_secret) # getting control over the api |
202 | + self.stream_api = TwitterStreamAPI(self.user.access_key, self.user.access_secret, self.on_receive_new_tweet_callback) # setting the callback to receive the data of every entry on the stream |
203 | |
204 | #def end(self): |
205 | # TODO: Iterate over the array of threads and join them here |
206 | @@ -404,12 +400,12 @@ |
207 | self.show_popup_successful_connection() |
208 | else: |
209 | logm("A problem has occurred while getting access to the API") |
210 | - elif self.dialog_type == self.responding_tweety: |
211 | - logp("Sending a tweety '%s'" % content) |
212 | - self.api.tweety(content) |
213 | + elif self.dialog_type == self.responding_tweet: |
214 | + logp("Sending a tweet '%s'" % content) |
215 | + self.api.tweet(content) |
216 | |
217 | def on_click(self, key): |
218 | - self.ask_for_tweety() |
219 | + self.ask_for_tweet() |
220 | |
221 | def on_middle_click(self): |
222 | self.show_home_timeline() |
223 | @@ -417,7 +413,7 @@ |
224 | def on_build_menu(self): |
225 | self.build_direct_messages_menu() |
226 | self.build_credentials_menu() |
227 | - if self.tweets_on_the_user_stream_queue > 0: |
228 | + if self.stream.qsize() > 0: |
229 | self.build_user_stream_menu() |
230 | |
231 | def on_menu_select(self, selected_menu): |
232 | |
233 | === modified file 'Twitter/Twitter.conf' |
234 | --- Twitter/Twitter.conf 2012-03-05 14:44:13 +0000 |
235 | +++ Twitter/Twitter.conf 2012-03-06 16:22:21 +0000 |
236 | @@ -1,4 +1,4 @@ |
237 | -#!en;0.1 |
238 | +#!en;0.1.1 |
239 | |
240 | #[gtk-about] |
241 | [Icon] |
242 | |
243 | === modified file 'Twitter/auto-load.conf' |
244 | --- Twitter/auto-load.conf 2012-03-05 14:44:13 +0000 |
245 | +++ Twitter/auto-load.conf 2012-03-06 16:22:21 +0000 |
246 | @@ -10,7 +10,7 @@ |
247 | category = 3 |
248 | |
249 | # Version of the applet; change it everytime you change something in the config file. Don't forget to update the version both in this file and in the config file. |
250 | -version = 0.1 |
251 | +version = 0.1.1 |
252 | |
253 | # Whether the applet can be instanciated several times or not. |
254 | multi-instance = true |
I mean, I'm still using one thread, instead of two :)