5e240148f71e49d74f0980cde02548b07bea7de3
2 Colorful user's timeline stream
4 from multiprocessing
import Process
5 from dateutil
import parser
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
23 from .interactive
import *
45 def draw(t
, keyword
=None, fil
=[], ig
=[]):
53 screen_name
= t
['user']['screen_name']
54 name
= t
['user']['name']
55 created_at
= t
['created_at']
56 date
= parser
.parse(created_at
)
57 date
= date
- datetime
.timedelta(seconds
=time
.timezone
)
58 clock
= date
.strftime('%Y/%m/%d %H:%M:%S')
61 screen_name
= '@' + screen_name
62 if fil
and screen_name
not in fil
:
64 if ig
and screen_name
in ig
:
67 res
= db
.tweet_query(tid
)
70 res
= db
.tweet_query(tid
)
71 rid
= res
[0].rainbow_id
74 user
= cycle_color(name
) + grey(' ' + screen_name
+ ' ')
75 meta
= grey('[' + clock
+ '] [id=' + str(rid
) + ']')
78 tweet
= map(lambda x
: grey(x
) if x
== 'RT' else x
, tweet
)
79 # Highlight screen_name
80 tweet
= map(lambda x
: cycle_color(x
) if x
[0] == '@' else x
, tweet
)
82 tweet
= map(lambda x
: cyan(x
) if x
[0:7] == 'http://' else x
, tweet
)
83 # Highlight search keyword
86 lambda x
: on_yellow(x
) if
87 ''.join(c
for c
in x
if c
.isalnum()).lower() == keyword
.lower()
91 tweet
= ' '.join(tweet
)
94 line1
= u
"{u:>{uw}}:".format(
98 line2
= u
"{c:>{cw}}".format(
110 def parse_arguments():
114 parser
= argparse
.ArgumentParser(description
=__doc__
or "")
118 help='Timeout for the stream (seconds).')
121 '--heartbeat-timeout',
122 help='Set heartbeat timeout.',
128 help='Set stream to non-blocking.')
132 help='Search the stream for specific text.')
136 help='Filter specific screen_name.')
140 help='Ignore specific screen_name.')
141 return parser
.parse_args()
146 Authenticate with Twitter OAuth
148 # When using rainbow stream you must authorize.
149 twitter_credential
= os
.environ
.get(
153 '')) + os
.sep
+ '.rainbow_oauth'
154 if not os
.path
.exists(twitter_credential
):
155 oauth_dance("Rainbow Stream",
159 oauth_token
, oauth_token_secret
= read_token_file(twitter_credential
)
167 def get_decorated_name():
169 Beginning of every line
171 t
= Twitter(auth
=authen())
172 name
= '@' + t
.account
.verify_credentials()['screen_name']
173 g
['original_name'] = name
[1:]
174 g
['decorated_name'] = grey('[') + grey(name
) + grey(']: ')
182 target
= g
['stuff'].split()[0]
185 args
= parse_arguments()
187 if g
['stuff'].split()[-1] == '-f':
188 only
= raw_input('Only nicks: ')
189 ignore
= raw_input('Ignore nicks: ')
190 args
.filter = filter(None,only
.split(','))
191 args
.ignore
= filter(None,ignore
.split(','))
192 elif g
['stuff'].split()[-1] == '-d':
193 args
.filter = ONLY_LIST
194 args
.ignore
= IGNORE_LIST
196 printNicely(red('Sorry, wrong format.'))
200 if target
== 'public':
201 keyword
= g
['stuff'].split()[1]
202 if keyword
[0] == '#':
203 keyword
= keyword
[1:]
205 os
.kill(g
['stream_pid'], signal
.SIGKILL
)
206 args
.track_keywords
= keyword
214 g
['stream_pid'] = p
.pid
217 elif target
== 'mine':
219 os
.kill(g
['stream_pid'], signal
.SIGKILL
)
228 g
['stream_pid'] = p
.pid
230 printNicely(green('Stream switched.'))
232 printNicely(cyan('Only: ' + str(args
.filter)))
234 printNicely(red('Ignore: ' + str(args
.ignore
)))
237 printNicely(red('Sorry I can\'t understand.'))
244 t
= Twitter(auth
=authen())
246 if g
['stuff'].isdigit():
248 for tweet
in reversed(t
.statuses
.home_timeline(count
=num
)):
257 t
= Twitter(auth
=authen())
258 user
= g
['stuff'].split()[0]
261 num
= int(g
['stuff'].split()[1])
264 for tweet
in reversed(t
.statuses
.user_timeline(count
=num
, screen_name
=user
[1:])):
268 printNicely(red('A name should begin with a \'@\''))
275 t
= Twitter(auth
=authen())
276 t
.statuses
.update(status
=g
['stuff'])
283 t
= Twitter(auth
=authen())
285 id = int(g
['stuff'].split()[0])
286 tid
= db
.rainbow_query(id)[0].tweet_id
287 t
.statuses
.retweet(id=tid
, include_entities
=False, trim_user
=True)
289 printNicely(red('Sorry I can\'t retweet for you.'))
296 t
= Twitter(auth
=authen())
298 id = int(g
['stuff'].split()[0])
299 tid
= db
.rainbow_query(id)[0].tweet_id
300 user
= t
.statuses
.show(id=tid
)['user']['screen_name']
301 status
= ' '.join(g
['stuff'].split()[1:])
302 status
= '@' + user
+ ' ' + status
.decode('utf-8')
303 t
.statuses
.update(status
=status
, in_reply_to_status_id
=tid
)
305 printNicely(red('Sorry I can\'t understand.'))
312 t
= Twitter(auth
=authen())
314 id = int(g
['stuff'].split()[0])
315 tid
= db
.rainbow_query(id)[0].tweet_id
316 t
.statuses
.destroy(id=tid
)
317 printNicely(green('Okay it\'s gone.'))
319 printNicely(red('Sorry I can\'t delete this tweet for you.'))
326 t
= Twitter(auth
=authen())
328 if g
['stuff'][0] == '#':
329 rel
= t
.search
.tweets(q
=g
['stuff'])['statuses']
331 printNicely('Newest tweets:')
332 for i
in reversed(xrange(SEARCH_MAX_RECORD
)):
333 draw(t
=rel
[i
], keyword
=g
['stuff'].strip()[1:])
336 printNicely(magenta('I\'m afraid there is no result'))
338 printNicely(red('A keyword should be a hashtag (like \'#AKB48\')'))
340 printNicely(red('Sorry I can\'t understand.'))
345 List of friend (following)
347 t
= Twitter(auth
=authen())
348 g
['friends'] = t
.friends
.ids()['ids']
349 for i
in g
['friends']:
350 name
= t
.users
.lookup(user_id
=i
)[0]['name']
351 screen_name
= '@' + t
.users
.lookup(user_id
=i
)[0]['screen_name']
352 user
= cycle_color(name
) + grey(' ' + screen_name
+ ' ')
360 t
= Twitter(auth
=authen())
361 g
['followers'] = t
.followers
.ids()['ids']
362 for i
in g
['followers']:
363 name
= t
.users
.lookup(user_id
=i
)[0]['name']
364 screen_name
= '@' + t
.users
.lookup(user_id
=i
)[0]['screen_name']
365 user
= cycle_color(name
) + grey(' ' + screen_name
+ ' ')
374 Hi boss! I'm ready to serve you right now!
375 -------------------------------------------------------------
376 You are already on your personal stream:
377 "switch public #AKB" will switch to public stream and follow "AKB" keyword.
378 "switch mine" will switch back to your personal stream.
379 "switch mine -f" will prompt to enter the filter.
380 "Only nicks" filter will decide nicks will be INCLUDE ONLY.
381 "Ignore nicks" filter will decide nicks will be EXCLUDE.
382 "switch mine -d" will use the config's ONLY_LIST and IGNORE_LIST
383 (see rainbowstream/config.py).
385 "home" will show your timeline. "home 7" will show 7 tweet.
386 "view @bob" will show your friend @bob's home.
387 "t oops" will tweet "oops" immediately.
388 "rt 12345" will retweet to tweet with id "12345".
389 "rep 12345 oops" will reply "oops" to tweet with id "12345".
390 "del 12345" will delete tweet with id "12345".
391 "s #AKB48" will search for "AKB48" and return 5 newest tweet.
392 "fr" will list out your following people.
393 "fl" will list out your followers.
394 "h" will show this help again.
395 "c" will clear the terminal.
397 -------------------------------------------------------------
398 Have fun and hang tight!
414 os
.system('rm -rf rainbow.db')
415 os
.kill(g
['stream_pid'], signal
.SIGKILL
)
424 printNicely(green('Need tips ? Type "h" and hit Enter key!'))
454 Listen to user's input
459 ['public #','mine'], # switch
474 init_interactive_shell(d
)
478 line
= raw_input(g
['decorated_name'])
482 cmd
= line
.split()[0]
485 # Save cmd to global variable and call process
486 g
['stuff'] = ' '.join(line
.split()[1:])
488 if cmd
in ['switch','t','rt','rep']:
494 def stream(domain
, args
, name
='Rainbow Stream'):
502 PUBLIC_DOMAIN
: args
.track_keywords
,
503 SITE_DOMAIN
: 'Site Stream',
505 ascii_art(art_dict
[domain
])
507 # These arguments are optional:
509 timeout
=args
.timeout
,
510 block
=not args
.no_block
,
511 heartbeat_timeout
=args
.heartbeat_timeout
)
515 if args
.track_keywords
:
516 query_args
['track'] = args
.track_keywords
519 stream
= TwitterStream(
524 if domain
== USER_DOMAIN
:
525 tweet_iter
= stream
.user(**query_args
)
526 elif domain
== SITE_DOMAIN
:
527 tweet_iter
= stream
.site(**query_args
)
529 if args
.track_keywords
:
530 tweet_iter
= stream
.statuses
.filter(**query_args
)
532 tweet_iter
= stream
.statuses
.sample()
534 # Iterate over the stream.
535 for tweet
in tweet_iter
:
537 printNicely("-- None --")
538 elif tweet
is Timeout
:
539 printNicely("-- Timeout --")
540 elif tweet
is HeartbeatTimeout
:
541 printNicely("-- Heartbeat Timeout --")
542 elif tweet
is Hangup
:
543 printNicely("-- Hangup --")
544 elif tweet
.get('text'):
545 draw(t
=tweet
, keyword
=args
.track_keywords
, fil
=args
.filter, ig
=args
.ignore
)
552 # Spawn stream process
553 args
= parse_arguments()
555 p
= Process(target
=stream
, args
=(USER_DOMAIN
, args
, g
['original_name']))
558 # Start listen process
562 g
['stream_pid'] = p
.pid