2 Colorful user's timeline stream
5 from __future__
import print_function
6 from multiprocessing
import Process
15 from twitter
.stream
import TwitterStream
, Timeout
, HeartbeatTimeout
, Hangup
16 from twitter
.api
import *
17 from twitter
.oauth
import OAuth
, read_token_file
18 from twitter
.oauth_dance
import oauth_dance
19 from twitter
.util
import printNicely
20 from dateutil
import parser
29 def draw(t
, keyword
=None):
36 screen_name
= t
['user']['screen_name']
37 name
= t
['user']['name']
38 created_at
= t
['created_at']
39 date
= parser
.parse(created_at
)
40 time
= date
.strftime('%Y/%m/%d %H:%M:%S')
42 res
= db
.tweet_query(tid
)
45 res
= db
.tweet_query(tid
)
46 rid
= res
[0].rainbow_id
49 user
= cycle_color(name
) + grey(' ' + '@' + screen_name
+ ' ')
50 meta
= grey('[' + time
+ '] [id=' + str(rid
) + ']')
53 tweet
= map(lambda x
: grey(x
) if x
== 'RT' else x
, tweet
)
54 # Highlight screen_name
55 tweet
= map(lambda x
: cycle_color(x
) if x
[0] == '@' else x
, tweet
)
57 tweet
= map(lambda x
: cyan(x
) if x
[0:7] == 'http://' else x
, tweet
)
58 # Highlight search keyword
61 lambda x
: on_yellow(x
) if
62 ''.join(c
for c
in x
if c
.isalnum()).lower() == keyword
.lower()
66 tweet
= ' '.join(tweet
)
69 line1
= u
"{u:>{uw}}:".format(
73 line2
= u
"{c:>{cw}}".format(
85 def parse_arguments():
89 parser
= argparse
.ArgumentParser(description
=__doc__
or "")
93 help='Timeout for the stream (seconds).')
96 '--heartbeat-timeout',
97 help='Set heartbeat timeout.',
103 help='Set stream to non-blocking.')
107 help='Search the stream for specific text.')
108 return parser
.parse_args()
113 Authenticate with Twitter OAuth
115 # When using rainbow stream you must authorize.
116 twitter_credential
= os
.environ
.get(
120 '')) + os
.sep
+ '.rainbow_oauth'
121 if not os
.path
.exists(twitter_credential
):
122 oauth_dance("Rainbow Stream",
126 oauth_token
, oauth_token_secret
= read_token_file(twitter_credential
)
134 def get_decorated_name():
136 Beginning of every line
138 t
= Twitter(auth
=authen())
139 name
= '@' + t
.statuses
.user_timeline()[-1]['user']['screen_name']
140 g
['decorated_name'] = grey('[') + grey(name
) + grey(']: ')
147 t
= Twitter(auth
=authen())
148 count
= HOME_TWEET_NUM
149 if g
['stuff'].isdigit():
151 for tweet
in reversed(t
.statuses
.home_timeline(count
=count
)):
159 t
= Twitter(auth
=authen())
160 user
= g
['stuff'].split()[0]
163 count
= int(g
['stuff'].split()[1])
165 count
= HOME_TWEET_NUM
166 for tweet
in reversed(t
.statuses
.user_timeline(count
=count
, screen_name
=user
[1:])):
169 print(red('A name should begin with a \'@\''))
170 sys
.stdout
.write(g
['decorated_name'])
177 t
= Twitter(auth
=authen())
178 t
.statuses
.update(status
=g
['stuff'])
185 t
= Twitter(auth
=authen())
187 id = int(g
['stuff'].split()[0])
188 tid
= db
.rainbow_query(id)[0].tweet_id
189 user
= t
.statuses
.show(id=tid
)['user']['screen_name']
190 status
= ' '.join(g
['stuff'].split()[1:])
191 status
= '@' + user
+ ' ' + status
.decode('utf-8')
192 t
.statuses
.update(status
=status
, in_reply_to_status_id
=tid
)
194 print(red('Sorry I can\'t understand.'))
195 sys
.stdout
.write(g
['decorated_name'])
202 t
= Twitter(auth
=authen())
204 id = int(g
['stuff'].split()[0])
205 tid
= db
.rainbow_query(id)[0].tweet_id
206 t
.statuses
.destroy(id=tid
)
207 print(green('Okay it\'s gone.'))
209 print(red('Sorry I can\'t delete this tweet for you.'))
210 sys
.stdout
.write(g
['decorated_name'])
217 t
= Twitter(auth
=authen())
218 h
, w
= os
.popen('stty size', 'r').read().split()
219 if g
['stuff'][0] == '#':
220 rel
= t
.search
.tweets(q
=g
['stuff'])['statuses']
221 printNicely(grey('*' * int(w
) + '\n'))
222 print('Newest', SEARCH_MAX_RECORD
, 'tweet: \n')
224 draw(t
=rel
[i
], keyword
=g
['stuff'].strip())
225 printNicely(grey('*' * int(w
) + '\n'))
227 print(red('A keyword should be a hashtag (like \'#AKB48\')'))
228 sys
.stdout
.write(g
['decorated_name'])
233 List of friend (following)
235 t
= Twitter(auth
=authen())
236 g
['friends'] = t
.friends
.ids()['ids']
237 for i
in g
['friends']:
238 screen_name
= t
.users
.lookup(user_id
=i
)[0]['screen_name']
239 user
= cycle_color('@' + screen_name
)
248 t
= Twitter(auth
=authen())
249 g
['followers'] = t
.followers
.ids()['ids']
250 for i
in g
['followers']:
251 screen_name
= t
.users
.lookup(user_id
=i
)[0]['screen_name']
252 user
= cycle_color('@' + screen_name
)
262 Hi boss! I'm ready to serve you right now!
263 ----------------------------------------------------
264 "home" will show your timeline. "home 7" will print 7 tweet.
265 "view @bob" will show your friend @bob's home.
266 "t oops" will tweet "oops" immediately.
267 "rep 12345 oops" will reply "oops" to tweet with id "12345".
268 "del 12345" will delete tweet with id "12345".
269 "s #AKB48" will search for "AKB48" and return 5 newest tweet.
270 "fr" will list out your following people.
271 "fl" will list out your followers.
272 "h" or "help" will print this help once again.
273 "c" will clear the terminal.
275 ----------------------------------------------------
276 Have fun and hang tight!
279 sys
.stdout
.write(g
['decorated_name'])
293 os
.kill(g
['stream_pid'], signal
.SIGKILL
)
314 }.get(cmd
, lambda: sys
.stdout
.write(g
['decorated_name']))
319 Listen to user's input
321 for line
in iter(stdin
.readline
, ''):
323 cmd
= line
.split()[0]
326 # Save cmd to global variable and call process
327 g
['stuff'] = ' '.join(line
.split()[1:])
336 args
= parse_arguments()
340 # These arguments are optional:
342 timeout
=args
.timeout
,
343 block
=not args
.no_block
,
344 heartbeat_timeout
=args
.heartbeat_timeout
)
348 if args
.track_keywords
:
349 query_args
['track'] = args
.track_keywords
352 stream
= TwitterStream(
354 domain
='userstream.twitter.com',
356 tweet_iter
= stream
.user(**query_args
)
358 # Iterate over the sample stream.
359 for tweet
in tweet_iter
:
361 printNicely("-- None --")
362 elif tweet
is Timeout
:
363 printNicely("-- Timeout --")
364 elif tweet
is HeartbeatTimeout
:
365 printNicely("-- Heartbeat Timeout --")
366 elif tweet
is Hangup
:
367 printNicely("-- Hangup --")
368 elif tweet
.get('text'):
378 p
= Process(target
=stream
)
380 g
['stream_pid'] = p
.pid