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: | 233 |
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: |
325 lines (+116/-67) 5 files modified
Twitter/ChangeLog (+1/-0) Twitter/Twitter (+90/-61) Twitter/Twitter.conf (+2/-2) Twitter/auto-load.conf (+2/-2) Twitter/http.py (+21/-2) |
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+95911@code.launchpad.net |
Commit message
Description of the change
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.
To post a comment you must log in.
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-01-29 18:20:33 +0000 |
3 | +++ Twitter/ChangeLog 2012-03-05 14:58:31 +0000 |
4 | @@ -1,3 +1,4 @@ |
5 | +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 |
6 | 0.0.3: (January/14/2012): Possible to see user's info. Translation directives were added on the strings. |
7 | 0.0.2: (January/8/2012): Possible to see the received direct messages. |
8 | 0.0.1: (December/16/2011): Possible to send a tweety, and see the home timeline. |
9 | |
10 | === modified file 'Twitter/Twitter' |
11 | --- Twitter/Twitter 2012-01-29 18:20:33 +0000 |
12 | +++ Twitter/Twitter 2012-03-05 14:58:31 +0000 |
13 | @@ -26,9 +26,9 @@ |
14 | # To see the received direct messages right-click on the icon -> Twitter -> Received direct messages |
15 | # To see some user's info right-click on the icon -> Twitter -> Info |
16 | |
17 | -import urlparse, os, webbrowser, simplejson |
18 | +import urlparse, os, webbrowser, simplejson, threading, Queue, time, urllib2, simplejson |
19 | from oauth import oauth |
20 | -from http import post, get |
21 | +from http import post, get #, stream |
22 | from util import * |
23 | from CDApplet import CDApplet, _ |
24 | # TODO import ConfigParser later conver files to config syntax |
25 | @@ -75,45 +75,59 @@ |
26 | self.access_token = oauth.OAuthToken.from_string(response) |
27 | access_token_data = dict((x, y) for x, y in urlparse.parse_qsl(response)) # tuple to dict |
28 | return access_token_data['oauth_token'], access_token_data['oauth_token_secret'] |
29 | + |
30 | +# TODO: Separate things starting with this, check also the possible inheritance with TwitterOauth |
31 | +#class API(): |
32 | +# def __init__(self, access_key, access_secret): |
33 | +# self.signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() |
34 | +# consumer_key, consumer_secret = read_consumer_key_and_secret() |
35 | +# self.consumer = oauth.OAuthConsumer(consumer_key, consumer_secret) |
36 | +# self.access_token = oauth.OAuthToken(access_key, access_secret) |
37 | |
38 | -#class TwitterAPI(threading.Thread): |
39 | -class TwitterAPI(): |
40 | +#class TwitterAPI(API): |
41 | +class TwitterAPI: |
42 | def __init__(self, access_key, access_secret): |
43 | + #API.__init__(self, access_key, access_secret) |
44 | self.update_url = 'http://twitter.com/statuses/update.json' |
45 | self.home_timeline_url = 'http://twitter.com/statuses/home_timeline.json' |
46 | self.direct_messages_url = 'https://api.twitter.com/1/direct_messages.json' |
47 | self.verify_credentials_url = 'https://api.twitter.com/1/account/verify_credentials.json' |
48 | + self.user_stream_url = "https://userstream.twitter.com/2/user.json" |
49 | |
50 | self.signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() |
51 | consumer_key, consumer_secret = read_consumer_key_and_secret() |
52 | self.consumer = oauth.OAuthConsumer(consumer_key, consumer_secret) |
53 | self.access_token = oauth.OAuthToken(access_key, access_secret) |
54 | - |
55 | -# self.current_home_timeline = self.home_timeline() |
56 | -# self.current_last_status_time = time.strptime(self.current_home_timeline[0]['created_at'], "%a %b %d %H:%M:%S +0000 %Y") |
57 | -# print "==== initial last time =========" |
58 | -# print self.current_home_timeline[0]['text'] |
59 | -# print self.current_last_status_time |
60 | -# print "=============" |
61 | -# t = Thread(target=self.check_home_timeline()) |
62 | -# t.start() |
63 | -# t.join() |
64 | -# self.check_home_timeline() |
65 | - #threading.Thread.__init__(self) |
66 | - |
67 | -# def run(self): |
68 | -# self.check_home_timeline() |
69 | - |
70 | -# def tweety_streaming(self): |
71 | -# oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, |
72 | -# token = self.access_token, |
73 | -# http_url = self.tweety_streaming_url, |
74 | -# parameters = {'track':'recipe', 'delimited':'length'}, |
75 | -# http_method = "GET") |
76 | -# oauth_request.sign_request(self.signature_method, self.consumer, self.access_token) |
77 | -# url = oauth_request.to_url() |
78 | -# response = get(url) |
79 | -# return simplejson.loads(response) |
80 | + |
81 | + thread = threading.Thread(target=self.tweety_streaming) |
82 | + thread.start() |
83 | + self.stream_content = Queue.Queue() |
84 | + |
85 | + def tweety_streaming(self): |
86 | + oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, |
87 | + token = self.access_token, |
88 | + http_url = self.user_stream_url) |
89 | + oauth_request.sign_request(self.signature_method, self.consumer, self.access_token) |
90 | + #stream(oauth_request.to_url()) |
91 | + url = oauth_request.to_url() |
92 | + req = urllib2.urlopen(url) |
93 | + buffer = '' |
94 | + while True: |
95 | + chunk = req.read(1) |
96 | + if not chunk: |
97 | + print buffer |
98 | + break |
99 | + |
100 | + buffer += chunk |
101 | + tweets = buffer.split("\n",1) |
102 | + if len(tweets) > 1: |
103 | + content = tweets[0] |
104 | + if "text" in content: |
105 | + content = simplejson.loads(content) |
106 | + self.stream_content.put(content) |
107 | + self.stream_content.task_done() |
108 | + print content |
109 | + buffer = tweets[1] |
110 | |
111 | def tweety(self, message): # popularly "send a tweety" |
112 | oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, |
113 | @@ -125,36 +139,6 @@ |
114 | post_data = oauth_request.to_postdata() |
115 | return post(self.update_url, post_data) |
116 | |
117 | -# def check_home_timeline(self): |
118 | -# i = 0 |
119 | -# while i < 5: |
120 | -# new_home_timeline = self.home_timeline() |
121 | -# new_tweetys = [] |
122 | -# if self.current_home_timeline: |
123 | -# for status in new_home_timeline: |
124 | -# #if status['created_at'] > self.current_last_status_time: |
125 | -# if time.strptime(status['created_at'], "%a %b %d %H:%M:%S +0000 %Y") > self.current_last_status_time: |
126 | -# print "==== found greater last time =========" |
127 | -# print status['text'] |
128 | -# print status['created_at'] |
129 | -# print "=============" |
130 | -# new_tweetys.append(status) |
131 | -# logp("Thread - Changed home timeline") |
132 | -# self.current_home_timeline = new_home_timeline |
133 | -# message = "".join (["[%s] %s\n" % (status['user']['name'], status['text']) for status in new_tweetys]) |
134 | -# logp(message) |
135 | -# #self.show_popup_message(message) |
136 | -# self.current_last_status_time = time.strptime(self.current_home_timeline[0]['created_at'], "%a %b %d %H:%M:%S +0000 %Y") |
137 | -# print "==== novo greater last time =========" |
138 | -# print status['text'] |
139 | -# print status['created_at'] |
140 | -# print "=============" |
141 | -# #self.current_last_status_time = self.current_home_timeline[0]['created_at'] |
142 | -# else: |
143 | -# logp("Thread - Fetching home timeline") |
144 | -# self.current_home_timeline = new_home_timeline |
145 | -# time.sleep(20) |
146 | -# i+=1 |
147 | |
148 | def home_timeline(self): |
149 | oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, |
150 | @@ -202,6 +186,27 @@ |
151 | self.icon.SetQuickInfo("") |
152 | |
153 | # Twitter methods |
154 | + |
155 | + # TODO: Encapsulate this method inside the StreamAPI class |
156 | + # TODO: Make available a "Animation" option upon a new tweet arrival |
157 | + def check_twitter_user_stream(self): |
158 | + while True: |
159 | + time.sleep(30) # TODO: variable for this! |
160 | + logp("Checking Stream ...") |
161 | + if not self.api.stream_content.empty(): |
162 | + self.tweets_on_the_user_stream_queue = self.api.stream_content.qsize() |
163 | + logp("There are new %d items on the Stream Queue" % self.tweets_on_the_user_stream_queue) |
164 | + self.icon.SetQuickInfo(str(self.tweets_on_the_user_stream_queue)) |
165 | + |
166 | + def show_new_tweets(self): |
167 | + self.inform_start_of_waiting_process() |
168 | + message = '' |
169 | + while not self.api.stream_content.empty(): |
170 | + tweet = self.api.stream_content.get() |
171 | + message += "[<b>%s</b>] %s\n" % (tweet['user']['name'], tweet['text']) |
172 | + dialog = {'use-markup':True} |
173 | + self.inform_end_of_waiting_process() |
174 | + self.show_popup_message(message, dialog) |
175 | |
176 | def show_home_timeline(self): |
177 | self.inform_start_of_waiting_process() |
178 | @@ -328,6 +333,17 @@ |
179 | 'icon' : os.path.abspath("./data/credentials.png") |
180 | }) |
181 | self.icon.AddMenuItems(credentials_menu) |
182 | + |
183 | + # TODO: As soon as clean up the API code, the label will be: "New tweets (%d)" % self.tweets_on_the_user_stream_queue |
184 | + def build_user_stream_menu(self): |
185 | + user_stream_menu = [] |
186 | + user_stream_menu.append ({ |
187 | + 'type' : CDApplet.MENU_ENTRY, |
188 | + 'label' : _("New tweets"), |
189 | + 'id' : self.user_stream_menu_id, |
190 | + 'icon' : os.path.abspath("./data/new.png") |
191 | + }) |
192 | + self.icon.AddMenuItems(user_stream_menu) |
193 | |
194 | def __init__(self): |
195 | self.user = User() |
196 | @@ -340,6 +356,10 @@ |
197 | |
198 | self.direct_messages_menu_id = 1000 |
199 | self.credentials_menu_id = 2000 |
200 | + self.user_stream_menu_id = 3000 |
201 | + |
202 | + self.tweets_on_the_user_stream_queue = 0 |
203 | + # TODO: Array with the two threads here |
204 | |
205 | CDApplet.__init__(self) # call CDApplet interface init |
206 | |
207 | @@ -352,7 +372,12 @@ |
208 | else: # user not found |
209 | logp("User '%s' found" % self.user.screen_name) |
210 | self.api = TwitterAPI(self.user.access_key, self.user.access_secret) # getting control over the api |
211 | - |
212 | + thread = threading.Thread(target=self.check_twitter_user_stream) |
213 | + thread.start() |
214 | + |
215 | + #def end(self): |
216 | + # TODO: Iterate over the array of threads and join them here |
217 | + |
218 | # TODO: Fix it! |
219 | def reload(self): |
220 | self.read_user_data() |
221 | @@ -392,12 +417,16 @@ |
222 | def on_build_menu(self): |
223 | self.build_direct_messages_menu() |
224 | self.build_credentials_menu() |
225 | + if self.tweets_on_the_user_stream_queue > 0: |
226 | + self.build_user_stream_menu() |
227 | |
228 | def on_menu_select(self, selected_menu): |
229 | if selected_menu == self.direct_messages_menu_id: |
230 | self.show_direct_messages() |
231 | elif selected_menu == self.credentials_menu_id: |
232 | self.show_credentials() |
233 | + elif selected_menu == self.user_stream_menu_id: |
234 | + self.show_new_tweets() |
235 | |
236 | if __name__ == '__main__': |
237 | Applet().run() |
238 | |
239 | === modified file 'Twitter/Twitter.conf' |
240 | --- Twitter/Twitter.conf 2012-01-29 18:20:33 +0000 |
241 | +++ Twitter/Twitter.conf 2012-03-05 14:58:31 +0000 |
242 | @@ -1,4 +1,4 @@ |
243 | -#!en;0.0.3 |
244 | +#!en;0.1 |
245 | |
246 | #[gtk-about] |
247 | [Icon] |
248 | @@ -8,7 +8,7 @@ |
249 | #d Name of the dock it belongs to: |
250 | dock name = |
251 | |
252 | -#s Name of the icon as it will appear in its caption in the dock: |
253 | +#s Name of the icon as it will appear in its caption in the dock: |
254 | name = Twitter |
255 | |
256 | #F[Display] |
257 | |
258 | === modified file 'Twitter/auto-load.conf' |
259 | --- Twitter/auto-load.conf 2012-01-29 18:20:33 +0000 |
260 | +++ Twitter/auto-load.conf 2012-03-05 14:58:31 +0000 |
261 | @@ -4,13 +4,13 @@ |
262 | author = Eduardo Mucelli Rezende Oliveira |
263 | |
264 | # A short description of the applet and how to use it. |
265 | -description = You can send tweets, see your timeline, and the received directed messages.\nOn the first time, the applet is going to ask your nickname and authorization to connect with Twitter.\nThe applet is going to open your browser with the authorization page\nAs soon as you authorize it, a PIN number will be shown on the page, copy this number\nPaste this number on the next dialog box will be shown.\nThe plugin is going to inform that you are successfully connected.\nTo see the received direct messages right-click on the icon -> Twitter -> Received direct messages.\nTo see some user's info right-click on the icon -> Twitter -> Info. |
266 | +description = You can send tweets, see your timeline, the received directed messages, and new tweets.\nOn the first time, the applet is going to ask your nickname and authorization to connect with Twitter.\nThe applet is going to open your browser with the authorization page\nAs soon as you authorize it, a PIN number will be shown on the page, copy this number\nPaste this number on the next dialog box will be shown.\nThe plugin is going to inform that you are successfully connected.\nTo see the received direct messages right-click on the icon -> Twitter -> Received direct messages.\nTo see some user's info right-click on the icon -> Twitter -> Info.\nTo see the received tweets right-click on the icon -> Twitter -> New tweets. |
267 | |
268 | # Category of the applet : 2 = files, 3 = internet, 4 = Desktop, 5 = accessory, 6 = system, 7 = fun |
269 | category = 3 |
270 | |
271 | # 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. |
272 | -version = 0.0.3 |
273 | +version = 0.1 |
274 | |
275 | # Whether the applet can be instanciated several times or not. |
276 | multi-instance = true |
277 | |
278 | === added file 'Twitter/data/new.png' |
279 | Binary files Twitter/data/new.png 1970-01-01 00:00:00 +0000 and Twitter/data/new.png 2012-03-05 14:58:31 +0000 differ |
280 | === modified file 'Twitter/data/received.png' |
281 | Binary files Twitter/data/received.png 2012-01-08 05:09:48 +0000 and Twitter/data/received.png 2012-03-05 14:58:31 +0000 differ |
282 | === modified file 'Twitter/http.py' |
283 | --- Twitter/http.py 2011-12-17 03:28:23 +0000 |
284 | +++ Twitter/http.py 2012-03-05 14:58:31 +0000 |
285 | @@ -5,7 +5,7 @@ |
286 | # Author: Eduardo Mucelli Rezende Oliveira |
287 | # E-mail: edumucelli@gmail.com or eduardom@dcc.ufmg.br |
288 | |
289 | -import urllib2 |
290 | +import urllib2, json |
291 | from util import logp, logm |
292 | |
293 | # HTTP GET |
294 | @@ -19,7 +19,7 @@ |
295 | except urllib2.HTTPError: |
296 | tries += 1 |
297 | if tries > 3: |
298 | - raise |
299 | + raise |
300 | |
301 | # HTTP POST |
302 | def post(url, post_data, tries = 0): |
303 | @@ -30,3 +30,22 @@ |
304 | tries += 1 |
305 | if tries > 3: |
306 | raise |
307 | + |
308 | +#def stream(url): |
309 | +# req = urllib2.urlopen(url) |
310 | +# buffer = '' |
311 | +# while True: |
312 | +# chunk = req.read(1) |
313 | +# if not chunk: |
314 | +# print buffer |
315 | +# break |
316 | +# |
317 | +# chunk = unicode(chunk) |
318 | +# buffer += chunk |
319 | +# |
320 | +# tweets = buffer.split("\n",1) |
321 | +# if len(tweets) > 1: |
322 | +# print tweets[0] |
323 | +# #return json.loads(tweets[0]) |
324 | +# buffer = tweets[1] |
325 | +# #return tweety |
Thank you ;)
Ps: if you want to change your nickname (currently it's: 'eduardo <eduardo@ eduardo- desktop- 64>'), simply launch this command: address- linked- to-your- launchpad- account> "
$ bzr whoami "Your name, you nickname or what you want <your-email-