Merge lp:~eduardo-mucelli/cairo-dock-plug-ins-extras/Twitter into lp:~cairo-dock-team/cairo-dock-plug-ins-extras/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
Reviewer Review Type Date Requested Status
Matthieu Baerts Approve
Review via email: mp+95911@code.launchpad.net

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.
Revision history for this message
Matthieu Baerts (matttbe) wrote :

Thank you ;)

Ps: if you want to change your nickname (currently it's: 'eduardo <eduardo@eduardo-desktop-64>'), simply launch this command:
  $ bzr whoami "Your name, you nickname or what you want <your-email-address-linked-to-your-launchpad-account>"

review: Approve

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'
279Binary 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'
281Binary 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

Subscribers

People subscribed via source and target branches