fix docs
[rainbowstream.git] / rainbowstream / rainbow.py
CommitLineData
91476ec3
O
1"""
2Colorful user's timeline stream
3"""
78b81730 4from multiprocessing import Process
78b81730 5
b2b933a9 6import os
7import os.path
8import sys
9import signal
10import argparse
11import time
991c30af 12import requests
80b70d60 13import webbrowser
1f2f6159 14import json
91476ec3 15
91476ec3 16from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup
54277114 17from twitter.api import *
91476ec3 18from twitter.oauth import OAuth, read_token_file
8c840a83 19from twitter.oauth_dance import oauth_dance
91476ec3 20from twitter.util import printNicely
91476ec3 21
7500d90b 22from .draw import *
2a6238f5
O
23from .colors import *
24from .config import *
777c52d4 25from .consumer import *
94a5f62e 26from .interactive import *
18cab06a 27from .db import *
991c30af 28from .c_image import *
c3bab4ef 29from .py3patch import *
30
2a6238f5 31
f405a7d0 32g = {}
18cab06a 33db = RainbowDB()
94a5f62e 34cmdset = [
42fde775 35 'switch',
4592d231 36 'trend',
94a5f62e 37 'home',
38 'view',
305ce127 39 'mentions',
94a5f62e 40 't',
41 'rt',
80b70d60 42 'quote',
1f24a05a 43 'allrt',
7e4ccbf3 44 'fav',
94a5f62e 45 'rep',
46 'del',
7e4ccbf3 47 'ufav',
94a5f62e 48 's',
305ce127 49 'mes',
f5677fb1 50 'show',
80b70d60 51 'open',
0f6e4daf 52 'ls',
305ce127 53 'inbox',
54 'sent',
55 'trash',
e2b81717 56 'whois',
94a5f62e 57 'fl',
f5677fb1 58 'ufl',
5b2c4faf 59 'mute',
60 'unmute',
61 'muting',
305ce127 62 'block',
63 'unblock',
64 'report',
2d341029 65 'list',
813a5d80 66 'cal',
632c6fa5 67 'theme',
94a5f62e 68 'h',
69 'c',
70 'q'
71]
22be990e 72
c075e6dc 73
91476ec3
O
74def parse_arguments():
75 """
76 Parse the arguments
77 """
91476ec3 78 parser = argparse.ArgumentParser(description=__doc__ or "")
2a6238f5
O
79 parser.add_argument(
80 '-to',
81 '--timeout',
82 help='Timeout for the stream (seconds).')
83 parser.add_argument(
84 '-ht',
85 '--heartbeat-timeout',
86 help='Set heartbeat timeout.',
87 default=90)
88 parser.add_argument(
89 '-nb',
90 '--no-block',
91 action='store_true',
92 help='Set stream to non-blocking.')
93 parser.add_argument(
94 '-tt',
95 '--track-keywords',
96 help='Search the stream for specific text.')
d51b4107
O
97 parser.add_argument(
98 '-fil',
99 '--filter',
100 help='Filter specific screen_name.')
101 parser.add_argument(
102 '-ig',
103 '--ignore',
104 help='Ignore specific screen_name.')
88af38d8 105 parser.add_argument(
c1fa7c94
O
106 '-iot',
107 '--image-on-term',
108 action='store_true',
109 help='Display all image on terminal.')
91476ec3
O
110 return parser.parse_args()
111
112
54277114
O
113def authen():
114 """
7b674cef 115 Authenticate with Twitter OAuth
54277114 116 """
8c840a83 117 # When using rainbow stream you must authorize.
2a6238f5
O
118 twitter_credential = os.environ.get(
119 'HOME',
120 os.environ.get(
121 'USERPROFILE',
122 '')) + os.sep + '.rainbow_oauth'
8c840a83
O
123 if not os.path.exists(twitter_credential):
124 oauth_dance("Rainbow Stream",
125 CONSUMER_KEY,
126 CONSUMER_SECRET,
127 twitter_credential)
128 oauth_token, oauth_token_secret = read_token_file(twitter_credential)
54277114 129 return OAuth(
2a6238f5
O
130 oauth_token,
131 oauth_token_secret,
132 CONSUMER_KEY,
133 CONSUMER_SECRET)
91476ec3 134
54277114
O
135
136def get_decorated_name():
137 """
138 Beginning of every line
139 """
140 t = Twitter(auth=authen())
c5ff542b 141 name = '@' + t.account.verify_credentials()['screen_name']
42fde775 142 g['original_name'] = name[1:]
c075e6dc 143 g['decorated_name'] = color_func(c['DECORATED_NAME'])('[' + name + ']: ')
54277114 144
422dd385 145 files = os.listdir(os.path.dirname(__file__) + '/colorset')
c075e6dc 146 themes = [f.split('.')[0] for f in files if f.split('.')[-1] == 'json']
632c6fa5 147 g['themes'] = themes
1f2f6159 148 db.theme_store(c['THEME'])
632c6fa5 149
f405a7d0 150
42fde775 151def switch():
152 """
153 Switch stream
154 """
155 try:
156 target = g['stuff'].split()[0]
157
d51b4107
O
158 # Filter and ignore
159 args = parse_arguments()
7e4ccbf3 160 try:
d51b4107
O
161 if g['stuff'].split()[-1] == '-f':
162 only = raw_input('Only nicks: ')
163 ignore = raw_input('Ignore nicks: ')
7e4ccbf3 164 args.filter = filter(None, only.split(','))
165 args.ignore = filter(None, ignore.split(','))
d51b4107 166 elif g['stuff'].split()[-1] == '-d':
632c6fa5
O
167 args.filter = c['ONLY_LIST']
168 args.ignore = c['IGNORE_LIST']
d51b4107
O
169 except:
170 printNicely(red('Sorry, wrong format.'))
171 return
172
42fde775 173 # Public stream
174 if target == 'public':
175 keyword = g['stuff'].split()[1]
176 if keyword[0] == '#':
177 keyword = keyword[1:]
42fde775 178 # Kill old process
179 os.kill(g['stream_pid'], signal.SIGKILL)
42fde775 180 args.track_keywords = keyword
42fde775 181 # Start new process
182 p = Process(
d51b4107 183 target=stream,
42fde775 184 args=(
632c6fa5 185 c['PUBLIC_DOMAIN'],
42fde775 186 args))
187 p.start()
188 g['stream_pid'] = p.pid
189
190 # Personal stream
191 elif target == 'mine':
42fde775 192 # Kill old process
193 os.kill(g['stream_pid'], signal.SIGKILL)
42fde775 194 # Start new process
195 p = Process(
196 target=stream,
197 args=(
632c6fa5 198 c['USER_DOMAIN'],
42fde775 199 args,
200 g['original_name']))
201 p.start()
202 g['stream_pid'] = p.pid
d51b4107 203 printNicely('')
d51b4107
O
204 if args.filter:
205 printNicely(cyan('Only: ' + str(args.filter)))
206 if args.ignore:
207 printNicely(red('Ignore: ' + str(args.ignore)))
208 printNicely('')
42fde775 209 except:
210 printNicely(red('Sorry I can\'t understand.'))
42fde775 211
212
4592d231 213def trend():
214 """
215 Trend
216 """
217 t = Twitter(auth=authen())
48a25fe8 218 # Get country and town
4592d231 219 try:
220 country = g['stuff'].split()[0]
221 except:
222 country = ''
48a25fe8 223 try:
224 town = g['stuff'].split()[1]
225 except:
226 town = ''
227
228 avail = t.trends.available()
229 # World wide
230 if not country:
231 trends = t.trends.place(_id=1)[0]['trends']
232 print_trends(trends)
233 else:
234 for location in avail:
235 # Search for country and Town
236 if town:
237 if location['countryCode'] == country \
238 and location['placeType']['name'] == 'Town' \
239 and location['name'] == town:
240 trends = t.trends.place(_id=location['woeid'])[0]['trends']
241 print_trends(trends)
242 # Search for country only
243 else:
244 if location['countryCode'] == country \
245 and location['placeType']['name'] == 'Country':
246 trends = t.trends.place(_id=location['woeid'])[0]['trends']
247 print_trends(trends)
4592d231 248
249
7b674cef 250def home():
251 """
252 Home
253 """
254 t = Twitter(auth=authen())
632c6fa5 255 num = c['HOME_TWEET_NUM']
7b674cef 256 if g['stuff'].isdigit():
305ce127 257 num = int(g['stuff'])
94a5f62e 258 for tweet in reversed(t.statuses.home_timeline(count=num)):
c1fa7c94 259 draw(t=tweet, iot=g['iot'])
94a5f62e 260 printNicely('')
7b674cef 261
262
263def view():
264 """
265 Friend view
266 """
267 t = Twitter(auth=authen())
268 user = g['stuff'].split()[0]
b8fbcb70 269 if user[0] == '@':
270 try:
94a5f62e 271 num = int(g['stuff'].split()[1])
b8fbcb70 272 except:
632c6fa5 273 num = c['HOME_TWEET_NUM']
94a5f62e 274 for tweet in reversed(t.statuses.user_timeline(count=num, screen_name=user[1:])):
c1fa7c94 275 draw(t=tweet, iot=g['iot'])
94a5f62e 276 printNicely('')
b8fbcb70 277 else:
c91f75f2 278 printNicely(red('A name should begin with a \'@\''))
7b674cef 279
280
305ce127 281def mentions():
282 """
283 Mentions timeline
284 """
285 t = Twitter(auth=authen())
632c6fa5 286 num = c['HOME_TWEET_NUM']
305ce127 287 if g['stuff'].isdigit():
288 num = int(g['stuff'])
289 for tweet in reversed(t.statuses.mentions_timeline(count=num)):
290 draw(t=tweet, iot=g['iot'])
291 printNicely('')
292
293
f405a7d0 294def tweet():
54277114 295 """
7b674cef 296 Tweet
54277114
O
297 """
298 t = Twitter(auth=authen())
f405a7d0 299 t.statuses.update(status=g['stuff'])
f405a7d0 300
b2b933a9 301
1ba4abfd
O
302def retweet():
303 """
304 ReTweet
305 """
306 t = Twitter(auth=authen())
307 try:
308 id = int(g['stuff'].split()[0])
1ba4abfd 309 except:
b8c1f42a
O
310 printNicely(red('Sorry I can\'t understand.'))
311 return
312 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
313 t.statuses.retweet(id=tid, include_entities=False, trim_user=True)
1ba4abfd
O
314
315
80b70d60
O
316def quote():
317 """
318 Quote a tweet
319 """
320 t = Twitter(auth=authen())
321 try:
322 id = int(g['stuff'].split()[0])
323 except:
324 printNicely(red('Sorry I can\'t understand.'))
325 return
326 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
327 tweet = t.statuses.show(id=tid)
328 screen_name = tweet['user']['screen_name']
329 text = tweet['text']
330 quote = '\"@' + screen_name + ': ' + text + '\"'
331 quote = quote.encode('utf8')
595fdb16
O
332 notice = light_magenta('Compose mode ')
333 notice += light_yellow('(Enter nothing will cancel the quote)')
334 notice += light_magenta(':')
335 printNicely(notice)
80b70d60
O
336 extra = raw_input(quote)
337 if extra:
422dd385 338 t.statuses.update(status=quote + extra)
80b70d60
O
339 else:
340 printNicely(light_magenta('No text added.'))
341
342
1f24a05a 343def allretweet():
344 """
345 List all retweet
346 """
347 t = Twitter(auth=authen())
348 # Get rainbow id
349 try:
350 id = int(g['stuff'].split()[0])
351 except:
352 printNicely(red('Sorry I can\'t understand.'))
353 return
354 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
355 # Get display num if exist
356 try:
357 num = int(g['stuff'].split()[1])
358 except:
632c6fa5 359 num = c['RETWEETS_SHOW_NUM']
1f24a05a 360 # Get result and display
d8e901a4 361 rt_ary = t.statuses.retweets(id=tid, count=num)
1f24a05a 362 if not rt_ary:
363 printNicely(magenta('This tweet has no retweet.'))
364 return
365 for tweet in reversed(rt_ary):
366 draw(t=tweet, iot=g['iot'])
367 printNicely('')
368
369
7e4ccbf3 370def favorite():
371 """
372 Favorite
373 """
374 t = Twitter(auth=authen())
375 try:
376 id = int(g['stuff'].split()[0])
7e4ccbf3 377 except:
b8c1f42a
O
378 printNicely(red('Sorry I can\'t understand.'))
379 return
380 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
381 t.favorites.create(_id=tid, include_entities=False)
382 printNicely(green('Favorited.'))
383 draw(t.statuses.show(id=tid), iot=g['iot'])
384 printNicely('')
7e4ccbf3 385
386
7b674cef 387def reply():
829cc2d8 388 """
7b674cef 389 Reply
829cc2d8
O
390 """
391 t = Twitter(auth=authen())
7b674cef 392 try:
393 id = int(g['stuff'].split()[0])
7b674cef 394 except:
c91f75f2 395 printNicely(red('Sorry I can\'t understand.'))
b8c1f42a
O
396 return
397 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
398 user = t.statuses.show(id=tid)['user']['screen_name']
399 status = ' '.join(g['stuff'].split()[1:])
400 status = '@' + user + ' ' + status.decode('utf-8')
401 t.statuses.update(status=status, in_reply_to_status_id=tid)
7b674cef 402
403
404def delete():
405 """
406 Delete
407 """
408 t = Twitter(auth=authen())
409 try:
305ce127 410 rid = int(g['stuff'].split()[0])
7b674cef 411 except:
305ce127 412 printNicely(red('Sorry I can\'t understand.'))
b8c1f42a
O
413 return
414 tid = db.rainbow_to_tweet_query(rid)[0].tweet_id
415 t.statuses.destroy(id=tid)
416 printNicely(green('Okay it\'s gone.'))
829cc2d8
O
417
418
7e4ccbf3 419def unfavorite():
420 """
421 Unfavorite
422 """
423 t = Twitter(auth=authen())
424 try:
425 id = int(g['stuff'].split()[0])
7e4ccbf3 426 except:
b8c1f42a
O
427 printNicely(red('Sorry I can\'t understand.'))
428 return
429 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
430 t.favorites.destroy(_id=tid)
431 printNicely(green('Okay it\'s unfavorited.'))
432 draw(t.statuses.show(id=tid), iot=g['iot'])
433 printNicely('')
7e4ccbf3 434
435
f405a7d0
O
436def search():
437 """
7b674cef 438 Search
f405a7d0
O
439 """
440 t = Twitter(auth=authen())
59262e95
O
441 g['stuff'] = g['stuff'].strip()
442 rel = t.search.tweets(q=g['stuff'])['statuses']
443 if rel:
444 printNicely('Newest tweets:')
445 for i in reversed(xrange(c['SEARCH_MAX_RECORD'])):
446 draw(t=rel[i],
447 iot=g['iot'],
448 keyword=g['stuff'])
449 printNicely('')
b8c1f42a 450 else:
59262e95 451 printNicely(magenta('I\'m afraid there is no result'))
b2b933a9 452
f405a7d0 453
305ce127 454def message():
455 """
456 Send a direct message
457 """
458 t = Twitter(auth=authen())
459 user = g['stuff'].split()[0]
b8c1f42a 460 if user[0].startswith('@'):
305ce127 461 try:
462 content = g['stuff'].split()[1]
305ce127 463 except:
464 printNicely(red('Sorry I can\'t understand.'))
b8c1f42a
O
465 t.direct_messages.new(
466 screen_name=user[1:],
467 text=content
468 )
469 printNicely(green('Message sent.'))
305ce127 470 else:
471 printNicely(red('A name should begin with a \'@\''))
472
473
f5677fb1 474def show():
843647ad 475 """
f5677fb1 476 Show image
843647ad
O
477 """
478 t = Twitter(auth=authen())
f5677fb1
O
479 try:
480 target = g['stuff'].split()[0]
481 if target != 'image':
482 return
483 id = int(g['stuff'].split()[1])
305ce127 484 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
f5677fb1
O
485 tweet = t.statuses.show(id=tid)
486 media = tweet['entities']['media']
487 for m in media:
488 res = requests.get(m['media_url'])
b3164e62 489 img = Image.open(BytesIO(res.content))
f5677fb1
O
490 img.show()
491 except:
492 printNicely(red('Sorry I can\'t show this image.'))
843647ad
O
493
494
80bb2040 495def urlopen():
80b70d60
O
496 """
497 Open url
498 """
499 t = Twitter(auth=authen())
500 try:
501 if not g['stuff'].isdigit():
502 return
503 tid = db.rainbow_to_tweet_query(g['stuff'])[0].tweet_id
504 tweet = t.statuses.show(id=tid)
422dd385
O
505 link_ary = [
506 u for u in tweet['text'].split() if u.startswith('http://')]
80b70d60
O
507 if not link_ary:
508 printNicely(light_magenta('No url here @.@!'))
509 return
510 for link in link_ary:
511 webbrowser.open(link)
512 except:
513 printNicely(red('Sorry I can\'t open url in this tweet.'))
514
515
2d341029 516def ls():
0f6e4daf 517 """
518 List friends for followers
519 """
520 t = Twitter(auth=authen())
e2b81717
O
521 # Get name
522 try:
523 name = g['stuff'].split()[1]
b8c1f42a 524 if name.startswith('@'):
e2b81717
O
525 name = name[1:]
526 else:
527 printNicely(red('A name should begin with a \'@\''))
528 raise Exception('Invalid name')
529 except:
530 name = g['original_name']
531 # Get list followers or friends
0f6e4daf 532 try:
533 target = g['stuff'].split()[0]
0f6e4daf 534 except:
535 printNicely(red('Omg some syntax is wrong.'))
b8c1f42a
O
536 # Init cursor
537 d = {'fl': 'followers', 'fr': 'friends'}
538 next_cursor = -1
539 rel = {}
540 # Cursor loop
541 while next_cursor != 0:
542 list = getattr(t, d[target]).list(
543 screen_name=name,
544 cursor=next_cursor,
545 skip_status=True,
546 include_entities=False,
547 )
548 for u in list['users']:
549 rel[u['name']] = '@' + u['screen_name']
550 next_cursor = list['next_cursor']
551 # Print out result
2d341029 552 printNicely('All: ' + str(len(rel)) + ' ' + d[target] + '.')
b8c1f42a 553 for name in rel:
2d341029 554 user = ' ' + cycle_color(name)
422dd385 555 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
b8c1f42a 556 printNicely(user)
0f6e4daf 557
558
305ce127 559def inbox():
560 """
561 Inbox direct messages
562 """
563 t = Twitter(auth=authen())
632c6fa5 564 num = c['MESSAGES_DISPLAY']
305ce127 565 rel = []
566 if g['stuff'].isdigit():
567 num = g['stuff']
568 cur_page = 1
569 # Max message per page is 20 so we have to loop
570 while num > 20:
571 rel = rel + t.direct_messages(
572 count=20,
573 page=cur_page,
574 include_entities=False,
575 skip_status=False
48a25fe8 576 )
305ce127 577 num -= 20
578 cur_page += 1
579 rel = rel + t.direct_messages(
580 count=num,
581 page=cur_page,
582 include_entities=False,
583 skip_status=False
48a25fe8 584 )
e2b81717 585 # Display
305ce127 586 printNicely('Inbox: newest ' + str(len(rel)) + ' messages.')
587 for m in reversed(rel):
588 print_message(m)
589 printNicely('')
590
e2b81717 591
305ce127 592def sent():
593 """
594 Sent direct messages
595 """
596 t = Twitter(auth=authen())
632c6fa5 597 num = c['MESSAGES_DISPLAY']
305ce127 598 rel = []
599 if g['stuff'].isdigit():
600 num = int(g['stuff'])
601 cur_page = 1
602 # Max message per page is 20 so we have to loop
603 while num > 20:
604 rel = rel + t.direct_messages.sent(
605 count=20,
606 page=cur_page,
607 include_entities=False,
608 skip_status=False
48a25fe8 609 )
305ce127 610 num -= 20
611 cur_page += 1
612 rel = rel + t.direct_messages.sent(
613 count=num,
614 page=cur_page,
615 include_entities=False,
616 skip_status=False
48a25fe8 617 )
e2b81717 618 # Display
305ce127 619 printNicely('Sent: newest ' + str(len(rel)) + ' messages.')
620 for m in reversed(rel):
621 print_message(m)
622 printNicely('')
e2b81717 623
305ce127 624
625def trash():
626 """
627 Remove message
628 """
629 t = Twitter(auth=authen())
630 try:
631 rid = int(g['stuff'].split()[0])
305ce127 632 except:
633 printNicely(red('Sorry I can\'t understand.'))
b8c1f42a
O
634 mid = db.rainbow_to_message_query(rid)[0].message_id
635 t.direct_messages.destroy(id=mid)
636 printNicely(green('Message deleted.'))
305ce127 637
638
e2b81717
O
639def whois():
640 """
641 Show profile of a specific user
642 """
643 t = Twitter(auth=authen())
644 screen_name = g['stuff'].split()[0]
b8c1f42a 645 if screen_name.startswith('@'):
e2b81717
O
646 try:
647 user = t.users.show(
648 screen_name=screen_name[1:],
649 include_entities=False)
7500d90b 650 show_profile(user, g['iot'])
e2b81717
O
651 except:
652 printNicely(red('Omg no user.'))
653 else:
b8c1f42a 654 printNicely(red('A name should begin with a \'@\''))
e2b81717
O
655
656
f5677fb1 657def follow():
843647ad 658 """
f5677fb1 659 Follow a user
843647ad
O
660 """
661 t = Twitter(auth=authen())
f5677fb1 662 screen_name = g['stuff'].split()[0]
b8c1f42a
O
663 if screen_name.startswith('@'):
664 t.friendships.create(screen_name=screen_name[1:], follow=True)
665 printNicely(green('You are following ' + screen_name + ' now!'))
f5677fb1 666 else:
b8c1f42a 667 printNicely(red('A name should begin with a \'@\''))
f5677fb1
O
668
669
670def unfollow():
671 """
672 Unfollow a user
673 """
674 t = Twitter(auth=authen())
675 screen_name = g['stuff'].split()[0]
b8c1f42a
O
676 if screen_name.startswith('@'):
677 t.friendships.destroy(
678 screen_name=screen_name[1:],
679 include_entities=False)
680 printNicely(green('Unfollow ' + screen_name + ' success!'))
f5677fb1 681 else:
b8c1f42a 682 printNicely(red('A name should begin with a \'@\''))
843647ad
O
683
684
5b2c4faf 685def mute():
686 """
687 Mute a user
688 """
689 t = Twitter(auth=authen())
690 try:
691 screen_name = g['stuff'].split()[0]
692 except:
693 printNicely(red('A name should be specified. '))
694 return
695 if screen_name.startswith('@'):
696 rel = t.mutes.users.create(screen_name=screen_name[1:])
697 if isinstance(rel, dict):
698 printNicely(green(screen_name + ' is muted.'))
699 else:
700 printNicely(red(rel))
701 else:
702 printNicely(red('A name should begin with a \'@\''))
703
704
705def unmute():
706 """
707 Unmute a user
708 """
709 t = Twitter(auth=authen())
710 try:
711 screen_name = g['stuff'].split()[0]
712 except:
713 printNicely(red('A name should be specified. '))
714 return
715 if screen_name.startswith('@'):
716 rel = t.mutes.users.destroy(screen_name=screen_name[1:])
717 if isinstance(rel, dict):
718 printNicely(green(screen_name + ' is unmuted.'))
719 else:
720 printNicely(red(rel))
721 else:
722 printNicely(red('A name should begin with a \'@\''))
723
724
725def muting():
726 """
727 List muting user
728 """
729 t = Twitter(auth=authen())
730 # Init cursor
5b2c4faf 731 next_cursor = -1
732 rel = {}
733 # Cursor loop
734 while next_cursor != 0:
735 list = t.mutes.users.list(
736 screen_name=g['original_name'],
737 cursor=next_cursor,
738 skip_status=True,
739 include_entities=False,
740 )
741 for u in list['users']:
742 rel[u['name']] = '@' + u['screen_name']
743 next_cursor = list['next_cursor']
744 # Print out result
745 printNicely('All: ' + str(len(rel)) + ' people.')
746 for name in rel:
2d341029 747 user = ' ' + cycle_color(name)
422dd385 748 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
5b2c4faf 749 printNicely(user)
750
751
305ce127 752def block():
753 """
754 Block a user
755 """
756 t = Twitter(auth=authen())
757 screen_name = g['stuff'].split()[0]
b8c1f42a
O
758 if screen_name.startswith('@'):
759 t.blocks.create(
5b2c4faf 760 screen_name=screen_name[1:],
761 include_entities=False,
762 skip_status=True)
b8c1f42a 763 printNicely(green('You blocked ' + screen_name + '.'))
305ce127 764 else:
b8c1f42a 765 printNicely(red('A name should begin with a \'@\''))
305ce127 766
767
768def unblock():
769 """
770 Unblock a user
771 """
772 t = Twitter(auth=authen())
773 screen_name = g['stuff'].split()[0]
b8c1f42a
O
774 if screen_name.startswith('@'):
775 t.blocks.destroy(
776 screen_name=screen_name[1:],
777 include_entities=False,
778 skip_status=True)
779 printNicely(green('Unblock ' + screen_name + ' success!'))
305ce127 780 else:
b8c1f42a 781 printNicely(red('A name should begin with a \'@\''))
305ce127 782
783
784def report():
785 """
786 Report a user as a spam account
787 """
788 t = Twitter(auth=authen())
789 screen_name = g['stuff'].split()[0]
b8c1f42a
O
790 if screen_name.startswith('@'):
791 t.users.report_spam(
792 screen_name=screen_name[1:])
793 printNicely(green('You reported ' + screen_name + '.'))
305ce127 794 else:
795 printNicely(red('Sorry I can\'t understand.'))
796
797
8b8566d1
O
798def get_slug():
799 """
800 Get Slug Decorator
801 """
802 # Get list name
803 list_name = raw_input(light_magenta('Give me the list\'s name: '))
804 # Get list name and owner
805 try:
806 owner, slug = list_name.split('/')
807 if slug.startswith('@'):
808 slug = slug[1:]
809 return owner, slug
810 except:
811 printNicely(light_magenta('List name should follow "@owner/list_name" format.'))
812 raise Exception('Wrong list name')
813
814
2d341029
O
815def show_lists(t):
816 """
422dd385 817 List list
2d341029
O
818 """
819 rel = t.lists.list(screen_name=g['original_name'])
820 if rel:
821 print_list(rel)
822 else:
823 printNicely(light_magenta('You belong to no lists :)'))
824
825
826def list_home(t):
827 """
828 List home
829 """
8b8566d1 830 owner, slug = get_slug()
2d341029 831 res = t.lists.statuses(
422dd385
O
832 slug=slug,
833 owner_screen_name=owner,
834 count=c['LIST_MAX'],
2d341029
O
835 include_entities=False)
836 for tweet in res:
837 draw(t=tweet)
838 printNicely('')
839
840
841def list_members(t):
842 """
843 List members
844 """
8b8566d1 845 owner, slug = get_slug()
422dd385 846 # Get members
2d341029
O
847 rel = {}
848 next_cursor = -1
422dd385 849 while next_cursor != 0:
2d341029 850 m = t.lists.members(
422dd385
O
851 slug=slug,
852 owner_screen_name=owner,
853 cursor=next_cursor,
2d341029
O
854 include_entities=False)
855 for u in m['users']:
856 rel[u['name']] = '@' + u['screen_name']
857 next_cursor = m['next_cursor']
858 printNicely('All: ' + str(len(rel)) + ' members.')
859 for name in rel:
860 user = ' ' + cycle_color(name)
422dd385 861 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
2d341029
O
862 printNicely(user)
863
864
865def list_subscribers(t):
866 """
867 List subscribers
868 """
8b8566d1 869 owner, slug = get_slug()
422dd385 870 # Get subscribers
2d341029
O
871 rel = {}
872 next_cursor = -1
422dd385 873 while next_cursor != 0:
2d341029 874 m = t.lists.subscribers(
422dd385
O
875 slug=slug,
876 owner_screen_name=owner,
877 cursor=next_cursor,
2d341029
O
878 include_entities=False)
879 for u in m['users']:
880 rel[u['name']] = '@' + u['screen_name']
881 next_cursor = m['next_cursor']
882 printNicely('All: ' + str(len(rel)) + ' subscribers.')
883 for name in rel:
884 user = ' ' + cycle_color(name)
422dd385 885 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
2d341029
O
886 printNicely(user)
887
888
422dd385
O
889def list_add(t):
890 """
891 Add specific user to a list
892 """
8b8566d1 893 owner, slug = get_slug()
422dd385
O
894 # Add
895 user_name = raw_input(light_magenta('Give me name of the newbie: '))
896 if user_name.startswith('@'):
897 user_name = user_name[1:]
898 try:
899 t.lists.members.create(
900 slug=slug,
901 owner_screen_name=owner,
902 screen_name=user_name)
903 printNicely(light_green('Added.'))
904 except:
905 printNicely(light_magenta('I\'m sorry we can not add him/her.'))
906
907
2d341029
O
908def list_remove(t):
909 """
910 Remove specific user from a list
911 """
8b8566d1 912 owner, slug = get_slug()
2d341029 913 # Remove
422dd385
O
914 user_name = raw_input(light_magenta('Give me name of the unlucky one: '))
915 if user_name.startswith('@'):
916 user_name = user_name[1:]
2d341029
O
917 try:
918 t.lists.members.destroy(
422dd385
O
919 slug=slug,
920 owner_screen_name=owner,
921 screen_name=user_name)
922 printNicely(light_green('Gone.'))
923 except:
924 printNicely(light_magenta('I\'m sorry we can not remove him/her.'))
925
926
927def list_subscribe(t):
928 """
929 Subscribe to a list
930 """
8b8566d1 931 owner, slug = get_slug()
422dd385
O
932 # Subscribe
933 try:
934 t.lists.subscribers.create(
935 slug=slug,
936 owner_screen_name=owner)
937 printNicely(light_green('Done.'))
938 except:
939 printNicely(
940 light_magenta('I\'m sorry you can not subscribe to this list.'))
941
942
943def list_unsubscribe(t):
944 """
945 Unsubscribe a list
946 """
8b8566d1 947 owner, slug = get_slug()
422dd385
O
948 # Subscribe
949 try:
950 t.lists.subscribers.destroy(
951 slug=slug,
952 owner_screen_name=owner)
953 printNicely(light_green('Done.'))
954 except:
955 printNicely(
956 light_magenta('I\'m sorry you can not unsubscribe to this list.'))
957
958
959def list_own(t):
960 """
961 List own
962 """
963 rel = []
964 next_cursor = -1
965 while next_cursor != 0:
966 res = t.lists.ownerships(
967 screen_name=g['original_name'],
968 cursor=next_cursor)
969 rel += res['lists']
970 next_cursor = res['next_cursor']
971 if rel:
972 print_list(rel)
973 else:
974 printNicely(light_magenta('You own no lists :)'))
975
976
977def list_new(t):
978 """
979 Create a new list
980 """
981 name = raw_input(light_magenta('New list\'s name: '))
982 mode = raw_input(light_magenta('New list\'s mode (public/private): '))
983 description = raw_input(light_magenta('New list\'s description: '))
984 try:
985 t.lists.create(
986 name=name,
987 mode=mode,
988 description=description)
989 printNicely(light_green(name + ' list is created.'))
990 except:
991 printNicely(red('Oops something is wrong with Twitter :('))
992
993
994def list_update(t):
995 """
996 Update a list
997 """
998 slug = raw_input(light_magenta('Your list that you want to update: '))
999 name = raw_input(light_magenta('Update name (leave blank to unchange): '))
1000 mode = raw_input(light_magenta('Update mode (public/private): '))
1001 description = raw_input(light_magenta('Update description: '))
1002 try:
1003 if name:
1004 t.lists.update(
1005 slug='-'.join(slug.split()),
1006 owner_screen_name=g['original_name'],
1007 name=name,
1008 mode=mode,
1009 description=description)
1010 else:
1011 t.lists.update(
1012 slug=slug,
1013 owner_screen_name=g['original_name'],
1014 mode=mode,
1015 description=description)
1016 printNicely(light_green(slug + ' list is updated.'))
3c85d8fc 1017 except:
422dd385
O
1018 printNicely(red('Oops something is wrong with Twitter :('))
1019
1020
1021def list_delete(t):
1022 """
1023 Delete a list
1024 """
1025 slug = raw_input(light_magenta('Your list that you want to update: '))
1026 try:
1027 t.lists.destroy(
1028 slug='-'.join(slug.split()),
1029 owner_screen_name=g['original_name'])
1030 printNicely(light_green(slug + ' list is deleted.'))
2d341029 1031 except:
422dd385 1032 printNicely(red('Oops something is wrong with Twitter :('))
2d341029
O
1033
1034
1035def list():
1036 """
1037 Twitter's list
1038 """
1039 t = Twitter(auth=authen())
1040 # List all lists or base on action
1041 try:
1042 g['list_action'] = g['stuff'].split()[0]
1043 except:
1044 show_lists(t)
1045 return
422dd385 1046 # Sub-function
2d341029
O
1047 action_ary = {
1048 'home': list_home,
1049 'all_mem': list_members,
1050 'all_sub': list_subscribers,
422dd385 1051 'add': list_add,
2d341029 1052 'rm': list_remove,
422dd385
O
1053 'sub': list_subscribe,
1054 'unsub': list_unsubscribe,
1055 'own': list_own,
1056 'new': list_new,
1057 'update': list_update,
1058 'del': list_delete,
2d341029
O
1059 }
1060 try:
1061 return action_ary[g['list_action']](t)
3c85d8fc 1062 except:
8b8566d1 1063 printNicely(red('Please try again.'))
2d341029
O
1064
1065
813a5d80 1066def cal():
1067 """
1068 Unix's command `cal`
1069 """
1070 # Format
1071 rel = os.popen('cal').read().split('\n')
1072 month = rel.pop(0)
813a5d80 1073 date = rel.pop(0)
2a0cabee 1074 show_calendar(month, date, rel)
813a5d80 1075
1076
632c6fa5
O
1077def theme():
1078 """
1079 List and change theme
1080 """
1081 if not g['stuff']:
1082 # List themes
1083 for theme in g['themes']:
1f2f6159
O
1084 line = light_magenta(theme)
1085 if c['THEME'] == theme:
422dd385 1086 line = ' ' * 2 + light_yellow('* ') + line
ddb1e615 1087 else:
422dd385 1088 line = ' ' * 4 + line
632c6fa5 1089 printNicely(line)
1c8a5082 1090 elif g['stuff'] == 'current_as_default':
1f2f6159
O
1091 # Set as default
1092 def fixup(adict, k, v):
1093 for key in adict.keys():
1094 if key == k:
1095 adict[key] = v
1096 elif type(adict[key]) is dict:
1097 fixup(adict[key], k, v)
1098 # Modify
1099 path = os.environ.get(
1100 'HOME',
1101 os.environ.get(
1102 'USERPROFILE',
1103 '')) + os.sep + '.rainbow_config.json'
1104 data = load_config(rainbow_config)
1105 fixup(data, 'THEME', c['THEME'])
1106 # Save
1107 with open(path, 'w') as out:
1108 json.dump(data, out, indent = 4)
2a488171 1109 os.system('chmod 777 ' + path)
1c8a5082 1110 printNicely(light_green('Okay it will be applied from next time :)'))
632c6fa5
O
1111 else:
1112 # Change theme
c075e6dc
O
1113 try:
1114 # Load new config
bb03272e 1115 if g['stuff'] != 'custom':
422dd385
O
1116 new_config = os.path.dirname(
1117 __file__) + '/colorset/' + g['stuff'] + '.json'
bb03272e
VNM
1118 else:
1119 new_config = os.environ.get(
422dd385 1120 'HOME', os.environ.get(
bb03272e
VNM
1121 'USERPROFILE',
1122 '')) + os.sep + '.rainbow_config.json'
632c6fa5 1123 new_config = load_config(new_config)
9e3418f1 1124 if new_config:
a5301bc0
VNM
1125 for nc in new_config:
1126 c[nc] = new_config[nc]
77c9b04e 1127 # Update db and reset colors
ddb1e615 1128 db.theme_update(g['stuff'])
1f2f6159 1129 c['THEME'] = g['stuff']
59262e95 1130 start_cycle()
c075e6dc
O
1131 g['decorated_name'] = color_func(
1132 c['DECORATED_NAME'])(
1133 '[@' + g['original_name'] + ']: ')
632c6fa5 1134 printNicely(green('Theme changed.'))
c075e6dc 1135 except:
1f2f6159 1136 printNicely(red('No such theme exists.'))
632c6fa5
O
1137
1138
2d341029 1139def help_discover():
f405a7d0 1140 """
2d341029 1141 Discover the world
f405a7d0 1142 """
7e4ccbf3 1143 s = ' ' * 2
1f24a05a 1144 # Discover the world
2d341029 1145 usage = '\n'
8bc30efd 1146 usage += s + grey(u'\u266A' + ' Discover the world \n')
c075e6dc
O
1147 usage += s * 2 + light_green('trend') + ' will show global trending topics. ' + \
1148 'You can try ' + light_green('trend US') + ' or ' + \
1149 light_green('trend JP Tokyo') + '.\n'
1150 usage += s * 2 + light_green('home') + ' will show your timeline. ' + \
1151 light_green('home 7') + ' will show 7 tweets.\n'
1152 usage += s * 2 + light_green('mentions') + ' will show mentions timeline. ' + \
1153 light_green('mentions 7') + ' will show 7 mention tweets.\n'
1154 usage += s * 2 + light_green('whois @mdo') + ' will show profile of ' + \
8bc30efd 1155 magenta('@mdo') + '.\n'
c075e6dc 1156 usage += s * 2 + light_green('view @mdo') + \
8bc30efd 1157 ' will show ' + magenta('@mdo') + '\'s home.\n'
03e08f86
O
1158 usage += s * 2 + light_green('s AKB48') + ' will search for "' + \
1159 light_yellow('AKB48') + '" and return 5 newest tweet. ' + \
1160 'Search can be performed with or without hashtag.\n'
2d341029
O
1161 printNicely(usage)
1162
8bc30efd 1163
2d341029
O
1164def help_tweets():
1165 """
1166 Tweets
1167 """
1168 s = ' ' * 2
1f24a05a 1169 # Tweet
2d341029 1170 usage = '\n'
8bc30efd 1171 usage += s + grey(u'\u266A' + ' Tweets \n')
c075e6dc
O
1172 usage += s * 2 + light_green('t oops ') + \
1173 'will tweet "' + light_yellow('oops') + '" immediately.\n'
7e4ccbf3 1174 usage += s * 2 + \
c075e6dc
O
1175 light_green('rt 12 ') + ' will retweet to tweet with ' + \
1176 light_yellow('[id=12]') + '.\n'
80b70d60
O
1177 usage += s * 2 + \
1178 light_green('quote 12 ') + ' will quote the tweet with ' + \
1179 light_yellow('[id=12]') + '. If no extra text is added, ' + \
1180 'the quote will be canceled.\n'
1f24a05a 1181 usage += s * 2 + \
c075e6dc
O
1182 light_green('allrt 12 20 ') + ' will list 20 newest retweet of the tweet with ' + \
1183 light_yellow('[id=12]') + '.\n'
1184 usage += s * 2 + light_green('rep 12 oops') + ' will reply "' + \
1185 light_yellow('oops') + '" to tweet with ' + \
1186 light_yellow('[id=12]') + '.\n'
7e4ccbf3 1187 usage += s * 2 + \
c075e6dc
O
1188 light_green('fav 12 ') + ' will favorite the tweet with ' + \
1189 light_yellow('[id=12]') + '.\n'
7e4ccbf3 1190 usage += s * 2 + \
c075e6dc
O
1191 light_green('ufav 12 ') + ' will unfavorite tweet with ' + \
1192 light_yellow('[id=12]') + '.\n'
8bc30efd 1193 usage += s * 2 + \
c075e6dc
O
1194 light_green('del 12 ') + ' will delete tweet with ' + \
1195 light_yellow('[id=12]') + '.\n'
1196 usage += s * 2 + light_green('show image 12') + ' will show image in tweet with ' + \
1197 light_yellow('[id=12]') + ' in your OS\'s image viewer.\n'
80b70d60
O
1198 usage += s * 2 + light_green('open 12') + ' will open url in tweet with ' + \
1199 light_yellow('[id=12]') + ' in your OS\'s default browser.\n'
2d341029 1200 printNicely(usage)
8bc30efd 1201
2d341029
O
1202
1203def help_messages():
1204 """
1205 Messages
1206 """
1207 s = ' ' * 2
5b2c4faf 1208 # Direct message
2d341029 1209 usage = '\n'
8bc30efd 1210 usage += s + grey(u'\u266A' + ' Direct messages \n')
c075e6dc
O
1211 usage += s * 2 + light_green('inbox') + ' will show inbox messages. ' + \
1212 light_green('inbox 7') + ' will show newest 7 messages.\n'
1213 usage += s * 2 + light_green('sent') + ' will show sent messages. ' + \
1214 light_green('sent 7') + ' will show newest 7 messages.\n'
1215 usage += s * 2 + light_green('mes @dtvd88 hi') + ' will send a "hi" messege to ' + \
8bc30efd 1216 magenta('@dtvd88') + '.\n'
c075e6dc
O
1217 usage += s * 2 + light_green('trash 5') + ' will remove message with ' + \
1218 light_yellow('[message_id=5]') + '.\n'
2d341029 1219 printNicely(usage)
8bc30efd 1220
2d341029
O
1221
1222def help_friends_and_followers():
1223 """
1224 Friends and Followers
1225 """
1226 s = ' ' * 2
8bc30efd 1227 # Follower and following
2d341029 1228 usage = '\n'
cdccb0d6 1229 usage += s + grey(u'\u266A' + ' Friends and followers \n')
8bc30efd 1230 usage += s * 2 + \
c075e6dc 1231 light_green('ls fl') + \
8bc30efd 1232 ' will list all followers (people who are following you).\n'
1233 usage += s * 2 + \
c075e6dc 1234 light_green('ls fr') + \
8bc30efd 1235 ' will list all friends (people who you are following).\n'
c075e6dc 1236 usage += s * 2 + light_green('fl @dtvd88') + ' will follow ' + \
305ce127 1237 magenta('@dtvd88') + '.\n'
c075e6dc 1238 usage += s * 2 + light_green('ufl @dtvd88') + ' will unfollow ' + \
305ce127 1239 magenta('@dtvd88') + '.\n'
c075e6dc 1240 usage += s * 2 + light_green('mute @dtvd88') + ' will mute ' + \
5b2c4faf 1241 magenta('@dtvd88') + '.\n'
c075e6dc 1242 usage += s * 2 + light_green('unmute @dtvd88') + ' will unmute ' + \
5b2c4faf 1243 magenta('@dtvd88') + '.\n'
c075e6dc
O
1244 usage += s * 2 + light_green('muting') + ' will list muting users.\n'
1245 usage += s * 2 + light_green('block @dtvd88') + ' will block ' + \
305ce127 1246 magenta('@dtvd88') + '.\n'
c075e6dc 1247 usage += s * 2 + light_green('unblock @dtvd88') + ' will unblock ' + \
305ce127 1248 magenta('@dtvd88') + '.\n'
c075e6dc 1249 usage += s * 2 + light_green('report @dtvd88') + ' will report ' + \
305ce127 1250 magenta('@dtvd88') + ' as a spam account.\n'
2d341029
O
1251 printNicely(usage)
1252
1253
1254def help_list():
1255 """
1256 Lists
1257 """
1258 s = ' ' * 2
1259 # Twitter list
1260 usage = '\n'
1261 usage += s + grey(u'\u266A' + ' Twitter list\n')
1262 usage += s * 2 + light_green('list') + \
1263 ' will show all lists you are belong to.\n'
1264 usage += s * 2 + light_green('list home') + \
bef33491 1265 ' will show timeline of list. You will be asked for list\'s name.\n'
a65bd34c 1266 usage += s * 2 + light_green('list all_mem') + \
2d341029 1267 ' will show list\'s all members.\n'
a65bd34c 1268 usage += s * 2 + light_green('list all_sub') + \
2d341029 1269 ' will show list\'s all subscribers.\n'
422dd385
O
1270 usage += s * 2 + light_green('list add') + \
1271 ' will add specific person to a list owned by you.' + \
1272 ' You will be asked for list\'s name and person\'s name.\n'
2d341029
O
1273 usage += s * 2 + light_green('list rm') + \
1274 ' will remove specific person from a list owned by you.' + \
1275 ' You will be asked for list\'s name and person\'s name.\n'
422dd385
O
1276 usage += s * 2 + light_green('list sub') + \
1277 ' will subscribe you to a specific list.\n'
1278 usage += s * 2 + light_green('list unsub') + \
1279 ' will unsubscribe you from a specific list.\n'
1280 usage += s * 2 + light_green('list own') + \
1281 ' will show all list owned by you.\n'
1282 usage += s * 2 + light_green('list new') + \
1283 ' will create a new list.\n'
1284 usage += s * 2 + light_green('list update') + \
1285 ' will update a list owned by you.\n'
1286 usage += s * 2 + light_green('list del') + \
1287 ' will delete a list owned by you.\n'
2d341029 1288 printNicely(usage)
8bc30efd 1289
2d341029
O
1290
1291def help_stream():
1292 """
1293 Stream switch
1294 """
1295 s = ' ' * 2
8bc30efd 1296 # Switch
2d341029 1297 usage = '\n'
8bc30efd 1298 usage += s + grey(u'\u266A' + ' Switching streams \n')
c075e6dc 1299 usage += s * 2 + light_green('switch public #AKB') + \
48a25fe8 1300 ' will switch to public stream and follow "' + \
c075e6dc
O
1301 light_yellow('AKB') + '" keyword.\n'
1302 usage += s * 2 + light_green('switch mine') + \
48a25fe8 1303 ' will switch to your personal stream.\n'
c075e6dc 1304 usage += s * 2 + light_green('switch mine -f ') + \
48a25fe8 1305 ' will prompt to enter the filter.\n'
c075e6dc 1306 usage += s * 3 + light_yellow('Only nicks') + \
48a25fe8 1307 ' filter will decide nicks will be INCLUDE ONLY.\n'
c075e6dc 1308 usage += s * 3 + light_yellow('Ignore nicks') + \
48a25fe8 1309 ' filter will decide nicks will be EXCLUDE.\n'
c075e6dc 1310 usage += s * 2 + light_green('switch mine -d') + \
48a25fe8 1311 ' will use the config\'s ONLY_LIST and IGNORE_LIST.\n'
2d341029
O
1312 printNicely(usage)
1313
1314
1315def help():
1316 """
1317 Help
1318 """
1319 s = ' ' * 2
1320 h, w = os.popen('stty size', 'r').read().split()
1321
1322 # Start
1323 usage = '\n'
1324 usage += s + 'Hi boss! I\'m ready to serve you right now!\n'
1325 usage += s + '-' * (int(w) - 4) + '\n'
1326 usage += s + 'You are ' + \
1327 light_yellow('already') + ' on your personal stream.\n'
1328 usage += s + 'Any update from Twitter will show up ' + \
1329 light_yellow('immediately') + '.\n'
1330 usage += s + 'In addtion, following commands are available right now:\n'
1331
1332 # Twitter help section
1333 usage += '\n'
1334 usage += s + grey(u'\u266A' + ' Twitter help\n')
1335 usage += s * 2 + light_green('h discover') + \
1336 ' will show help for discover commands.\n'
1337 usage += s * 2 + light_green('h tweets') + \
1338 ' will show help for tweets commands.\n'
1339 usage += s * 2 + light_green('h messages') + \
1340 ' will show help for messages commands.\n'
1341 usage += s * 2 + light_green('h friends_and_followers') + \
1342 ' will show help for friends and followers commands.\n'
1343 usage += s * 2 + light_green('h list') + \
1344 ' will show help for list commands.\n'
1345 usage += s * 2 + light_green('h stream') + \
1346 ' will show help for stream commands.\n'
48a25fe8 1347
1f24a05a 1348 # Smart shell
1349 usage += '\n'
1350 usage += s + grey(u'\u266A' + ' Smart shell\n')
c075e6dc 1351 usage += s * 2 + light_green('111111 * 9 / 7') + ' or any math expression ' + \
1f24a05a 1352 'will be evaluate by Python interpreter.\n'
c075e6dc 1353 usage += s * 2 + 'Even ' + light_green('cal') + ' will show the calendar' + \
1f24a05a 1354 ' for current month.\n'
1355
1356 # Screening
1357 usage += '\n'
1358 usage += s + grey(u'\u266A' + ' Screening \n')
c075e6dc
O
1359 usage += s * 2 + light_green('theme') + ' will list available theme.' + \
1360 light_green('theme monokai') + ' will apply ' + light_yellow('monokai') + \
632c6fa5 1361 ' theme immediately.\n'
c075e6dc
O
1362 usage += s * 2 + light_green('h') + ' will show this help again.\n'
1363 usage += s * 2 + light_green('c') + ' will clear the screen.\n'
1364 usage += s * 2 + light_green('q') + ' will quit.\n'
1f24a05a 1365
8bc30efd 1366 # End
1367 usage += '\n'
7e4ccbf3 1368 usage += s + '-' * (int(w) - 4) + '\n'
8bc30efd 1369 usage += s + 'Have fun and hang tight! \n'
2d341029
O
1370
1371 # Show help
1372 d = {
422dd385
O
1373 'discover': help_discover,
1374 'tweets': help_tweets,
1375 'messages': help_messages,
1376 'friends_and_followers': help_friends_and_followers,
1377 'list': help_list,
1378 'stream': help_stream,
2d341029
O
1379 }
1380 if g['stuff']:
1381 d[g['stuff'].strip()]()
1382 else:
1383 printNicely(usage)
f405a7d0
O
1384
1385
843647ad 1386def clear():
f405a7d0 1387 """
7b674cef 1388 Clear screen
f405a7d0 1389 """
843647ad 1390 os.system('clear')
f405a7d0
O
1391
1392
843647ad 1393def quit():
b8dda704
O
1394 """
1395 Exit all
1396 """
f5677fb1 1397 save_history()
8e633322 1398 os.system('rm -rf rainbow.db')
843647ad
O
1399 os.kill(g['stream_pid'], signal.SIGKILL)
1400 sys.exit()
b8dda704
O
1401
1402
94a5f62e 1403def reset():
f405a7d0 1404 """
94a5f62e 1405 Reset prefix of line
f405a7d0 1406 """
c91f75f2 1407 if g['reset']:
e3885f55 1408 printNicely(magenta('Need tips ? Type "h" and hit Enter key!'))
c91f75f2 1409 g['reset'] = False
d0a726d6 1410 try:
2a0cabee
O
1411 printNicely(str(eval(g['cmd'])))
1412 except Exception:
d0a726d6 1413 pass
54277114
O
1414
1415
94a5f62e 1416def process(cmd):
54277114 1417 """
94a5f62e 1418 Process switch
54277114 1419 """
94a5f62e 1420 return dict(zip(
1421 cmdset,
b2b933a9 1422 [
42fde775 1423 switch,
4592d231 1424 trend,
b2b933a9 1425 home,
1426 view,
305ce127 1427 mentions,
b2b933a9 1428 tweet,
1429 retweet,
80b70d60 1430 quote,
1f24a05a 1431 allretweet,
7e4ccbf3 1432 favorite,
b2b933a9 1433 reply,
1434 delete,
7e4ccbf3 1435 unfavorite,
b2b933a9 1436 search,
305ce127 1437 message,
f5677fb1 1438 show,
80bb2040 1439 urlopen,
2d341029 1440 ls,
305ce127 1441 inbox,
1442 sent,
1443 trash,
e2b81717 1444 whois,
f5677fb1
O
1445 follow,
1446 unfollow,
5b2c4faf 1447 mute,
1448 unmute,
1449 muting,
305ce127 1450 block,
1451 unblock,
1452 report,
2d341029 1453 list,
813a5d80 1454 cal,
632c6fa5 1455 theme,
b2b933a9 1456 help,
1457 clear,
1458 quit
1459 ]
94a5f62e 1460 )).get(cmd, reset)
1461
1462
1463def listen():
42fde775 1464 """
1465 Listen to user's input
1466 """
d51b4107
O
1467 d = dict(zip(
1468 cmdset,
1469 [
affcb149 1470 ['public', 'mine'], # switch
4592d231 1471 [], # trend
7e4ccbf3 1472 [], # home
1473 ['@'], # view
305ce127 1474 [], # mentions
7e4ccbf3 1475 [], # tweet
1476 [], # retweet
80b70d60 1477 [], # quote
1f24a05a 1478 [], # allretweet
f5677fb1 1479 [], # favorite
7e4ccbf3 1480 [], # reply
1481 [], # delete
f5677fb1 1482 [], # unfavorite
7e4ccbf3 1483 ['#'], # search
305ce127 1484 ['@'], # message
f5677fb1 1485 ['image'], # show image
80b70d60 1486 [''], # open url
305ce127 1487 ['fl', 'fr'], # list
1488 [], # inbox
1489 [], # sent
1490 [], # trash
e2b81717 1491 ['@'], # whois
affcb149
O
1492 ['@'], # follow
1493 ['@'], # unfollow
5b2c4faf 1494 ['@'], # mute
1495 ['@'], # unmute
1496 ['@'], # muting
305ce127 1497 ['@'], # block
1498 ['@'], # unblock
1499 ['@'], # report
422dd385
O
1500 [
1501 'home',
1502 'all_mem',
1503 'all_sub',
1504 'add',
1505 'rm',
1506 'sub',
1507 'unsub',
1508 'own',
1509 'new',
1510 'update',
1511 'del'
1512 ], # list
813a5d80 1513 [], # cal
1c8a5082 1514 g['themes'] + ['current_as_default'], # theme
422dd385
O
1515 [
1516 'discover',
1517 'tweets',
1518 'messages',
1519 'friends_and_followers',
1520 'list',
1521 'stream'
1522 ], # help
7e4ccbf3 1523 [], # clear
1524 [], # quit
d51b4107 1525 ]
7e4ccbf3 1526 ))
d51b4107 1527 init_interactive_shell(d)
f5677fb1 1528 read_history()
819569e8 1529 reset()
b2b933a9 1530 while True:
1dd312f5
O
1531 if g['prefix']:
1532 line = raw_input(g['decorated_name'])
1533 else:
1534 line = raw_input()
843647ad
O
1535 try:
1536 cmd = line.split()[0]
1537 except:
1538 cmd = ''
d0a726d6 1539 g['cmd'] = cmd
f405a7d0 1540 # Save cmd to global variable and call process
b8c1f42a
O
1541 try:
1542 g['stuff'] = ' '.join(line.split()[1:])
1543 process(cmd)()
2d341029 1544 except Exception:
b8c1f42a
O
1545 printNicely(red('OMG something is wrong with Twitter right now.'))
1546 # Not redisplay prefix
7e4ccbf3 1547 if cmd in ['switch', 't', 'rt', 'rep']:
1dd312f5
O
1548 g['prefix'] = False
1549 else:
1550 g['prefix'] = True
54277114
O
1551
1552
42fde775 1553def stream(domain, args, name='Rainbow Stream'):
54277114 1554 """
f405a7d0 1555 Track the stream
54277114 1556 """
d51b4107 1557
54277114 1558 # The Logo
42fde775 1559 art_dict = {
632c6fa5
O
1560 c['USER_DOMAIN']: name,
1561 c['PUBLIC_DOMAIN']: args.track_keywords,
1f2f6159 1562 c['SITE_DOMAIN']: name,
42fde775 1563 }
687567eb 1564 if c['ASCII_ART']:
c075e6dc 1565 ascii_art(art_dict[domain])
d51b4107 1566
91476ec3
O
1567 # These arguments are optional:
1568 stream_args = dict(
1569 timeout=args.timeout,
1570 block=not args.no_block,
1571 heartbeat_timeout=args.heartbeat_timeout)
1572
1573 # Track keyword
1574 query_args = dict()
1575 if args.track_keywords:
1576 query_args['track'] = args.track_keywords
1577
1578 # Get stream
2a6238f5 1579 stream = TwitterStream(
22be990e 1580 auth=authen(),
42fde775 1581 domain=domain,
2a6238f5 1582 **stream_args)
91476ec3 1583
2a0cabee
O
1584 try:
1585 if domain == c['USER_DOMAIN']:
1586 tweet_iter = stream.user(**query_args)
1587 elif domain == c['SITE_DOMAIN']:
1588 tweet_iter = stream.site(**query_args)
42fde775 1589 else:
2a0cabee
O
1590 if args.track_keywords:
1591 tweet_iter = stream.statuses.filter(**query_args)
1592 else:
1593 tweet_iter = stream.statuses.sample()
42fde775 1594
2a0cabee 1595 # Iterate over the stream.
72c02928
VNM
1596 for tweet in tweet_iter:
1597 if tweet is None:
1598 printNicely("-- None --")
1599 elif tweet is Timeout:
1600 printNicely("-- Timeout --")
1601 elif tweet is HeartbeatTimeout:
1602 printNicely("-- Heartbeat Timeout --")
1603 elif tweet is Hangup:
1604 printNicely("-- Hangup --")
1605 elif tweet.get('text'):
1606 draw(
1607 t=tweet,
1608 iot=args.image_on_term,
1609 keyword=args.track_keywords,
1610 fil=args.filter,
1611 ig=args.ignore,
1612 )
2a0cabee
O
1613 except TwitterHTTPError:
1614 printNicely('')
c075e6dc 1615 printNicely(
2a0cabee 1616 magenta("We have maximum connection problem with twitter'stream API right now :("))
54277114
O
1617
1618
1619def fly():
1620 """
1621 Main function
1622 """
42fde775 1623 # Spawn stream process
1624 args = parse_arguments()
2a0cabee
O
1625 try:
1626 get_decorated_name()
1627
1628 except TwitterHTTPError:
1629 printNicely('')
1630 printNicely(
2e1241c7 1631 magenta("Something wrong with Twitter Oauth right now :("))
1632 printNicely(
1633 magenta("Please delete ~/.rainbow_oauth and try again."))
2a0cabee
O
1634 save_history()
1635 os.system('rm -rf rainbow.db')
1636 sys.exit()
1637
c075e6dc
O
1638 p = Process(
1639 target=stream,
1640 args=(
422dd385 1641 c['USER_DOMAIN'],
c075e6dc
O
1642 args,
1643 g['original_name']))
42fde775 1644 p.start()
1645
1646 # Start listen process
819569e8 1647 time.sleep(0.5)
c91f75f2 1648 g['reset'] = True
1dd312f5 1649 g['prefix'] = True
f405a7d0 1650 g['stream_pid'] = p.pid
c1fa7c94 1651 g['iot'] = args.image_on_term
0f6e4daf 1652 listen()