check config and little refactoring
[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())
b8c1f42a
O
441 if g['stuff'].startswith('#'):
442 rel = t.search.tweets(q=g['stuff'])['statuses']
5b2c4faf 443 if rel:
b8c1f42a 444 printNicely('Newest tweets:')
632c6fa5 445 for i in reversed(xrange(c['SEARCH_MAX_RECORD'])):
b8c1f42a
O
446 draw(t=rel[i],
447 iot=g['iot'],
448 keyword=g['stuff'].strip()[1:])
449 printNicely('')
94a5f62e 450 else:
b8c1f42a
O
451 printNicely(magenta('I\'m afraid there is no result'))
452 else:
453 printNicely(red('A keyword should be a hashtag (like \'#AKB48\')'))
b2b933a9 454
f405a7d0 455
305ce127 456def message():
457 """
458 Send a direct message
459 """
460 t = Twitter(auth=authen())
461 user = g['stuff'].split()[0]
b8c1f42a 462 if user[0].startswith('@'):
305ce127 463 try:
464 content = g['stuff'].split()[1]
305ce127 465 except:
466 printNicely(red('Sorry I can\'t understand.'))
b8c1f42a
O
467 t.direct_messages.new(
468 screen_name=user[1:],
469 text=content
470 )
471 printNicely(green('Message sent.'))
305ce127 472 else:
473 printNicely(red('A name should begin with a \'@\''))
474
475
f5677fb1 476def show():
843647ad 477 """
f5677fb1 478 Show image
843647ad
O
479 """
480 t = Twitter(auth=authen())
f5677fb1
O
481 try:
482 target = g['stuff'].split()[0]
483 if target != 'image':
484 return
485 id = int(g['stuff'].split()[1])
305ce127 486 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
f5677fb1
O
487 tweet = t.statuses.show(id=tid)
488 media = tweet['entities']['media']
489 for m in media:
490 res = requests.get(m['media_url'])
b3164e62 491 img = Image.open(BytesIO(res.content))
f5677fb1
O
492 img.show()
493 except:
494 printNicely(red('Sorry I can\'t show this image.'))
843647ad
O
495
496
80bb2040 497def urlopen():
80b70d60
O
498 """
499 Open url
500 """
501 t = Twitter(auth=authen())
502 try:
503 if not g['stuff'].isdigit():
504 return
505 tid = db.rainbow_to_tweet_query(g['stuff'])[0].tweet_id
506 tweet = t.statuses.show(id=tid)
422dd385
O
507 link_ary = [
508 u for u in tweet['text'].split() if u.startswith('http://')]
80b70d60
O
509 if not link_ary:
510 printNicely(light_magenta('No url here @.@!'))
511 return
512 for link in link_ary:
513 webbrowser.open(link)
514 except:
515 printNicely(red('Sorry I can\'t open url in this tweet.'))
516
517
2d341029 518def ls():
0f6e4daf 519 """
520 List friends for followers
521 """
522 t = Twitter(auth=authen())
e2b81717
O
523 # Get name
524 try:
525 name = g['stuff'].split()[1]
b8c1f42a 526 if name.startswith('@'):
e2b81717
O
527 name = name[1:]
528 else:
529 printNicely(red('A name should begin with a \'@\''))
530 raise Exception('Invalid name')
531 except:
532 name = g['original_name']
533 # Get list followers or friends
0f6e4daf 534 try:
535 target = g['stuff'].split()[0]
0f6e4daf 536 except:
537 printNicely(red('Omg some syntax is wrong.'))
b8c1f42a
O
538 # Init cursor
539 d = {'fl': 'followers', 'fr': 'friends'}
540 next_cursor = -1
541 rel = {}
542 # Cursor loop
543 while next_cursor != 0:
544 list = getattr(t, d[target]).list(
545 screen_name=name,
546 cursor=next_cursor,
547 skip_status=True,
548 include_entities=False,
549 )
550 for u in list['users']:
551 rel[u['name']] = '@' + u['screen_name']
552 next_cursor = list['next_cursor']
553 # Print out result
2d341029 554 printNicely('All: ' + str(len(rel)) + ' ' + d[target] + '.')
b8c1f42a 555 for name in rel:
2d341029 556 user = ' ' + cycle_color(name)
422dd385 557 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
b8c1f42a 558 printNicely(user)
0f6e4daf 559
560
305ce127 561def inbox():
562 """
563 Inbox direct messages
564 """
565 t = Twitter(auth=authen())
632c6fa5 566 num = c['MESSAGES_DISPLAY']
305ce127 567 rel = []
568 if g['stuff'].isdigit():
569 num = g['stuff']
570 cur_page = 1
571 # Max message per page is 20 so we have to loop
572 while num > 20:
573 rel = rel + t.direct_messages(
574 count=20,
575 page=cur_page,
576 include_entities=False,
577 skip_status=False
48a25fe8 578 )
305ce127 579 num -= 20
580 cur_page += 1
581 rel = rel + t.direct_messages(
582 count=num,
583 page=cur_page,
584 include_entities=False,
585 skip_status=False
48a25fe8 586 )
e2b81717 587 # Display
305ce127 588 printNicely('Inbox: newest ' + str(len(rel)) + ' messages.')
589 for m in reversed(rel):
590 print_message(m)
591 printNicely('')
592
e2b81717 593
305ce127 594def sent():
595 """
596 Sent direct messages
597 """
598 t = Twitter(auth=authen())
632c6fa5 599 num = c['MESSAGES_DISPLAY']
305ce127 600 rel = []
601 if g['stuff'].isdigit():
602 num = int(g['stuff'])
603 cur_page = 1
604 # Max message per page is 20 so we have to loop
605 while num > 20:
606 rel = rel + t.direct_messages.sent(
607 count=20,
608 page=cur_page,
609 include_entities=False,
610 skip_status=False
48a25fe8 611 )
305ce127 612 num -= 20
613 cur_page += 1
614 rel = rel + t.direct_messages.sent(
615 count=num,
616 page=cur_page,
617 include_entities=False,
618 skip_status=False
48a25fe8 619 )
e2b81717 620 # Display
305ce127 621 printNicely('Sent: newest ' + str(len(rel)) + ' messages.')
622 for m in reversed(rel):
623 print_message(m)
624 printNicely('')
e2b81717 625
305ce127 626
627def trash():
628 """
629 Remove message
630 """
631 t = Twitter(auth=authen())
632 try:
633 rid = int(g['stuff'].split()[0])
305ce127 634 except:
635 printNicely(red('Sorry I can\'t understand.'))
b8c1f42a
O
636 mid = db.rainbow_to_message_query(rid)[0].message_id
637 t.direct_messages.destroy(id=mid)
638 printNicely(green('Message deleted.'))
305ce127 639
640
e2b81717
O
641def whois():
642 """
643 Show profile of a specific user
644 """
645 t = Twitter(auth=authen())
646 screen_name = g['stuff'].split()[0]
b8c1f42a 647 if screen_name.startswith('@'):
e2b81717
O
648 try:
649 user = t.users.show(
650 screen_name=screen_name[1:],
651 include_entities=False)
7500d90b 652 show_profile(user, g['iot'])
e2b81717
O
653 except:
654 printNicely(red('Omg no user.'))
655 else:
b8c1f42a 656 printNicely(red('A name should begin with a \'@\''))
e2b81717
O
657
658
f5677fb1 659def follow():
843647ad 660 """
f5677fb1 661 Follow a user
843647ad
O
662 """
663 t = Twitter(auth=authen())
f5677fb1 664 screen_name = g['stuff'].split()[0]
b8c1f42a
O
665 if screen_name.startswith('@'):
666 t.friendships.create(screen_name=screen_name[1:], follow=True)
667 printNicely(green('You are following ' + screen_name + ' now!'))
f5677fb1 668 else:
b8c1f42a 669 printNicely(red('A name should begin with a \'@\''))
f5677fb1
O
670
671
672def unfollow():
673 """
674 Unfollow a user
675 """
676 t = Twitter(auth=authen())
677 screen_name = g['stuff'].split()[0]
b8c1f42a
O
678 if screen_name.startswith('@'):
679 t.friendships.destroy(
680 screen_name=screen_name[1:],
681 include_entities=False)
682 printNicely(green('Unfollow ' + screen_name + ' success!'))
f5677fb1 683 else:
b8c1f42a 684 printNicely(red('A name should begin with a \'@\''))
843647ad
O
685
686
5b2c4faf 687def mute():
688 """
689 Mute a user
690 """
691 t = Twitter(auth=authen())
692 try:
693 screen_name = g['stuff'].split()[0]
694 except:
695 printNicely(red('A name should be specified. '))
696 return
697 if screen_name.startswith('@'):
698 rel = t.mutes.users.create(screen_name=screen_name[1:])
699 if isinstance(rel, dict):
700 printNicely(green(screen_name + ' is muted.'))
701 else:
702 printNicely(red(rel))
703 else:
704 printNicely(red('A name should begin with a \'@\''))
705
706
707def unmute():
708 """
709 Unmute a user
710 """
711 t = Twitter(auth=authen())
712 try:
713 screen_name = g['stuff'].split()[0]
714 except:
715 printNicely(red('A name should be specified. '))
716 return
717 if screen_name.startswith('@'):
718 rel = t.mutes.users.destroy(screen_name=screen_name[1:])
719 if isinstance(rel, dict):
720 printNicely(green(screen_name + ' is unmuted.'))
721 else:
722 printNicely(red(rel))
723 else:
724 printNicely(red('A name should begin with a \'@\''))
725
726
727def muting():
728 """
729 List muting user
730 """
731 t = Twitter(auth=authen())
732 # Init cursor
5b2c4faf 733 next_cursor = -1
734 rel = {}
735 # Cursor loop
736 while next_cursor != 0:
737 list = t.mutes.users.list(
738 screen_name=g['original_name'],
739 cursor=next_cursor,
740 skip_status=True,
741 include_entities=False,
742 )
743 for u in list['users']:
744 rel[u['name']] = '@' + u['screen_name']
745 next_cursor = list['next_cursor']
746 # Print out result
747 printNicely('All: ' + str(len(rel)) + ' people.')
748 for name in rel:
2d341029 749 user = ' ' + cycle_color(name)
422dd385 750 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
5b2c4faf 751 printNicely(user)
752
753
305ce127 754def block():
755 """
756 Block a user
757 """
758 t = Twitter(auth=authen())
759 screen_name = g['stuff'].split()[0]
b8c1f42a
O
760 if screen_name.startswith('@'):
761 t.blocks.create(
5b2c4faf 762 screen_name=screen_name[1:],
763 include_entities=False,
764 skip_status=True)
b8c1f42a 765 printNicely(green('You blocked ' + screen_name + '.'))
305ce127 766 else:
b8c1f42a 767 printNicely(red('A name should begin with a \'@\''))
305ce127 768
769
770def unblock():
771 """
772 Unblock a user
773 """
774 t = Twitter(auth=authen())
775 screen_name = g['stuff'].split()[0]
b8c1f42a
O
776 if screen_name.startswith('@'):
777 t.blocks.destroy(
778 screen_name=screen_name[1:],
779 include_entities=False,
780 skip_status=True)
781 printNicely(green('Unblock ' + screen_name + ' success!'))
305ce127 782 else:
b8c1f42a 783 printNicely(red('A name should begin with a \'@\''))
305ce127 784
785
786def report():
787 """
788 Report a user as a spam account
789 """
790 t = Twitter(auth=authen())
791 screen_name = g['stuff'].split()[0]
b8c1f42a
O
792 if screen_name.startswith('@'):
793 t.users.report_spam(
794 screen_name=screen_name[1:])
795 printNicely(green('You reported ' + screen_name + '.'))
305ce127 796 else:
797 printNicely(red('Sorry I can\'t understand.'))
798
799
8b8566d1
O
800def get_slug():
801 """
802 Get Slug Decorator
803 """
804 # Get list name
805 list_name = raw_input(light_magenta('Give me the list\'s name: '))
806 # Get list name and owner
807 try:
808 owner, slug = list_name.split('/')
809 if slug.startswith('@'):
810 slug = slug[1:]
811 return owner, slug
812 except:
813 printNicely(light_magenta('List name should follow "@owner/list_name" format.'))
814 raise Exception('Wrong list name')
815
816
2d341029
O
817def show_lists(t):
818 """
422dd385 819 List list
2d341029
O
820 """
821 rel = t.lists.list(screen_name=g['original_name'])
822 if rel:
823 print_list(rel)
824 else:
825 printNicely(light_magenta('You belong to no lists :)'))
826
827
828def list_home(t):
829 """
830 List home
831 """
8b8566d1 832 owner, slug = get_slug()
2d341029 833 res = t.lists.statuses(
422dd385
O
834 slug=slug,
835 owner_screen_name=owner,
836 count=c['LIST_MAX'],
2d341029
O
837 include_entities=False)
838 for tweet in res:
839 draw(t=tweet)
840 printNicely('')
841
842
843def list_members(t):
844 """
845 List members
846 """
8b8566d1 847 owner, slug = get_slug()
422dd385 848 # Get members
2d341029
O
849 rel = {}
850 next_cursor = -1
422dd385 851 while next_cursor != 0:
2d341029 852 m = t.lists.members(
422dd385
O
853 slug=slug,
854 owner_screen_name=owner,
855 cursor=next_cursor,
2d341029
O
856 include_entities=False)
857 for u in m['users']:
858 rel[u['name']] = '@' + u['screen_name']
859 next_cursor = m['next_cursor']
860 printNicely('All: ' + str(len(rel)) + ' members.')
861 for name in rel:
862 user = ' ' + cycle_color(name)
422dd385 863 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
2d341029
O
864 printNicely(user)
865
866
867def list_subscribers(t):
868 """
869 List subscribers
870 """
8b8566d1 871 owner, slug = get_slug()
422dd385 872 # Get subscribers
2d341029
O
873 rel = {}
874 next_cursor = -1
422dd385 875 while next_cursor != 0:
2d341029 876 m = t.lists.subscribers(
422dd385
O
877 slug=slug,
878 owner_screen_name=owner,
879 cursor=next_cursor,
2d341029
O
880 include_entities=False)
881 for u in m['users']:
882 rel[u['name']] = '@' + u['screen_name']
883 next_cursor = m['next_cursor']
884 printNicely('All: ' + str(len(rel)) + ' subscribers.')
885 for name in rel:
886 user = ' ' + cycle_color(name)
422dd385 887 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
2d341029
O
888 printNicely(user)
889
890
422dd385
O
891def list_add(t):
892 """
893 Add specific user to a list
894 """
8b8566d1 895 owner, slug = get_slug()
422dd385
O
896 # Add
897 user_name = raw_input(light_magenta('Give me name of the newbie: '))
898 if user_name.startswith('@'):
899 user_name = user_name[1:]
900 try:
901 t.lists.members.create(
902 slug=slug,
903 owner_screen_name=owner,
904 screen_name=user_name)
905 printNicely(light_green('Added.'))
906 except:
907 printNicely(light_magenta('I\'m sorry we can not add him/her.'))
908
909
2d341029
O
910def list_remove(t):
911 """
912 Remove specific user from a list
913 """
8b8566d1 914 owner, slug = get_slug()
2d341029 915 # Remove
422dd385
O
916 user_name = raw_input(light_magenta('Give me name of the unlucky one: '))
917 if user_name.startswith('@'):
918 user_name = user_name[1:]
2d341029
O
919 try:
920 t.lists.members.destroy(
422dd385
O
921 slug=slug,
922 owner_screen_name=owner,
923 screen_name=user_name)
924 printNicely(light_green('Gone.'))
925 except:
926 printNicely(light_magenta('I\'m sorry we can not remove him/her.'))
927
928
929def list_subscribe(t):
930 """
931 Subscribe to a list
932 """
8b8566d1 933 owner, slug = get_slug()
422dd385
O
934 # Subscribe
935 try:
936 t.lists.subscribers.create(
937 slug=slug,
938 owner_screen_name=owner)
939 printNicely(light_green('Done.'))
940 except:
941 printNicely(
942 light_magenta('I\'m sorry you can not subscribe to this list.'))
943
944
945def list_unsubscribe(t):
946 """
947 Unsubscribe a list
948 """
8b8566d1 949 owner, slug = get_slug()
422dd385
O
950 # Subscribe
951 try:
952 t.lists.subscribers.destroy(
953 slug=slug,
954 owner_screen_name=owner)
955 printNicely(light_green('Done.'))
956 except:
957 printNicely(
958 light_magenta('I\'m sorry you can not unsubscribe to this list.'))
959
960
961def list_own(t):
962 """
963 List own
964 """
965 rel = []
966 next_cursor = -1
967 while next_cursor != 0:
968 res = t.lists.ownerships(
969 screen_name=g['original_name'],
970 cursor=next_cursor)
971 rel += res['lists']
972 next_cursor = res['next_cursor']
973 if rel:
974 print_list(rel)
975 else:
976 printNicely(light_magenta('You own no lists :)'))
977
978
979def list_new(t):
980 """
981 Create a new list
982 """
983 name = raw_input(light_magenta('New list\'s name: '))
984 mode = raw_input(light_magenta('New list\'s mode (public/private): '))
985 description = raw_input(light_magenta('New list\'s description: '))
986 try:
987 t.lists.create(
988 name=name,
989 mode=mode,
990 description=description)
991 printNicely(light_green(name + ' list is created.'))
992 except:
993 printNicely(red('Oops something is wrong with Twitter :('))
994
995
996def list_update(t):
997 """
998 Update a list
999 """
1000 slug = raw_input(light_magenta('Your list that you want to update: '))
1001 name = raw_input(light_magenta('Update name (leave blank to unchange): '))
1002 mode = raw_input(light_magenta('Update mode (public/private): '))
1003 description = raw_input(light_magenta('Update description: '))
1004 try:
1005 if name:
1006 t.lists.update(
1007 slug='-'.join(slug.split()),
1008 owner_screen_name=g['original_name'],
1009 name=name,
1010 mode=mode,
1011 description=description)
1012 else:
1013 t.lists.update(
1014 slug=slug,
1015 owner_screen_name=g['original_name'],
1016 mode=mode,
1017 description=description)
1018 printNicely(light_green(slug + ' list is updated.'))
3c85d8fc 1019 except:
422dd385
O
1020 printNicely(red('Oops something is wrong with Twitter :('))
1021
1022
1023def list_delete(t):
1024 """
1025 Delete a list
1026 """
1027 slug = raw_input(light_magenta('Your list that you want to update: '))
1028 try:
1029 t.lists.destroy(
1030 slug='-'.join(slug.split()),
1031 owner_screen_name=g['original_name'])
1032 printNicely(light_green(slug + ' list is deleted.'))
2d341029 1033 except:
422dd385 1034 printNicely(red('Oops something is wrong with Twitter :('))
2d341029
O
1035
1036
1037def list():
1038 """
1039 Twitter's list
1040 """
1041 t = Twitter(auth=authen())
1042 # List all lists or base on action
1043 try:
1044 g['list_action'] = g['stuff'].split()[0]
1045 except:
1046 show_lists(t)
1047 return
422dd385 1048 # Sub-function
2d341029
O
1049 action_ary = {
1050 'home': list_home,
1051 'all_mem': list_members,
1052 'all_sub': list_subscribers,
422dd385 1053 'add': list_add,
2d341029 1054 'rm': list_remove,
422dd385
O
1055 'sub': list_subscribe,
1056 'unsub': list_unsubscribe,
1057 'own': list_own,
1058 'new': list_new,
1059 'update': list_update,
1060 'del': list_delete,
2d341029
O
1061 }
1062 try:
1063 return action_ary[g['list_action']](t)
3c85d8fc 1064 except:
8b8566d1 1065 printNicely(red('Please try again.'))
2d341029
O
1066
1067
813a5d80 1068def cal():
1069 """
1070 Unix's command `cal`
1071 """
1072 # Format
1073 rel = os.popen('cal').read().split('\n')
1074 month = rel.pop(0)
813a5d80 1075 date = rel.pop(0)
2a0cabee 1076 show_calendar(month, date, rel)
813a5d80 1077
1078
632c6fa5
O
1079def theme():
1080 """
1081 List and change theme
1082 """
1083 if not g['stuff']:
1084 # List themes
1085 for theme in g['themes']:
1f2f6159
O
1086 line = light_magenta(theme)
1087 if c['THEME'] == theme:
422dd385 1088 line = ' ' * 2 + light_yellow('* ') + line
ddb1e615 1089 else:
422dd385 1090 line = ' ' * 4 + line
632c6fa5 1091 printNicely(line)
1c8a5082 1092 elif g['stuff'] == 'current_as_default':
1f2f6159
O
1093 # Set as default
1094 def fixup(adict, k, v):
1095 for key in adict.keys():
1096 if key == k:
1097 adict[key] = v
1098 elif type(adict[key]) is dict:
1099 fixup(adict[key], k, v)
1100 # Modify
1101 path = os.environ.get(
1102 'HOME',
1103 os.environ.get(
1104 'USERPROFILE',
1105 '')) + os.sep + '.rainbow_config.json'
1106 data = load_config(rainbow_config)
1107 fixup(data, 'THEME', c['THEME'])
1108 # Save
1109 with open(path, 'w') as out:
1110 json.dump(data, out, indent = 4)
2a488171 1111 os.system('chmod 777 ' + path)
1c8a5082 1112 printNicely(light_green('Okay it will be applied from next time :)'))
632c6fa5
O
1113 else:
1114 # Change theme
c075e6dc
O
1115 try:
1116 # Load new config
bb03272e 1117 if g['stuff'] != 'custom':
422dd385
O
1118 new_config = os.path.dirname(
1119 __file__) + '/colorset/' + g['stuff'] + '.json'
bb03272e
VNM
1120 else:
1121 new_config = os.environ.get(
422dd385 1122 'HOME', os.environ.get(
bb03272e
VNM
1123 'USERPROFILE',
1124 '')) + os.sep + '.rainbow_config.json'
632c6fa5 1125 new_config = load_config(new_config)
9e3418f1 1126 if new_config:
a5301bc0
VNM
1127 for nc in new_config:
1128 c[nc] = new_config[nc]
77c9b04e 1129 # Update db and reset colors
ddb1e615 1130 db.theme_update(g['stuff'])
1f2f6159 1131 c['THEME'] = g['stuff']
e43ebfa6 1132 reset_cycle()
c075e6dc
O
1133 g['decorated_name'] = color_func(
1134 c['DECORATED_NAME'])(
1135 '[@' + g['original_name'] + ']: ')
632c6fa5 1136 printNicely(green('Theme changed.'))
c075e6dc 1137 except:
1f2f6159 1138 printNicely(red('No such theme exists.'))
632c6fa5
O
1139
1140
2d341029 1141def help_discover():
f405a7d0 1142 """
2d341029 1143 Discover the world
f405a7d0 1144 """
7e4ccbf3 1145 s = ' ' * 2
1f24a05a 1146 # Discover the world
2d341029 1147 usage = '\n'
8bc30efd 1148 usage += s + grey(u'\u266A' + ' Discover the world \n')
c075e6dc
O
1149 usage += s * 2 + light_green('trend') + ' will show global trending topics. ' + \
1150 'You can try ' + light_green('trend US') + ' or ' + \
1151 light_green('trend JP Tokyo') + '.\n'
1152 usage += s * 2 + light_green('home') + ' will show your timeline. ' + \
1153 light_green('home 7') + ' will show 7 tweets.\n'
1154 usage += s * 2 + light_green('mentions') + ' will show mentions timeline. ' + \
1155 light_green('mentions 7') + ' will show 7 mention tweets.\n'
1156 usage += s * 2 + light_green('whois @mdo') + ' will show profile of ' + \
8bc30efd 1157 magenta('@mdo') + '.\n'
c075e6dc 1158 usage += s * 2 + light_green('view @mdo') + \
8bc30efd 1159 ' will show ' + magenta('@mdo') + '\'s home.\n'
c075e6dc
O
1160 usage += s * 2 + light_green('s #AKB48') + ' will search for "' + \
1161 light_yellow('AKB48') + '" and return 5 newest tweet.\n'
2d341029
O
1162 printNicely(usage)
1163
8bc30efd 1164
2d341029
O
1165def help_tweets():
1166 """
1167 Tweets
1168 """
1169 s = ' ' * 2
1f24a05a 1170 # Tweet
2d341029 1171 usage = '\n'
8bc30efd 1172 usage += s + grey(u'\u266A' + ' Tweets \n')
c075e6dc
O
1173 usage += s * 2 + light_green('t oops ') + \
1174 'will tweet "' + light_yellow('oops') + '" immediately.\n'
7e4ccbf3 1175 usage += s * 2 + \
c075e6dc
O
1176 light_green('rt 12 ') + ' will retweet to tweet with ' + \
1177 light_yellow('[id=12]') + '.\n'
1f24a05a 1178 usage += s * 2 + \
80b70d60
O
1179 light_green('quote 12 ') + ' will quote the tweet with ' + \
1180 light_yellow('[id=12]') + '. If no extra text is added, ' + \
1181 'the quote will be canceled.\n'
1182 usage += s * 2 + \
c075e6dc
O
1183 light_green('allrt 12 20 ') + ' will list 20 newest retweet of the tweet with ' + \
1184 light_yellow('[id=12]') + '.\n'
1185 usage += s * 2 + light_green('rep 12 oops') + ' will reply "' + \
1186 light_yellow('oops') + '" to tweet with ' + \
1187 light_yellow('[id=12]') + '.\n'
7e4ccbf3 1188 usage += s * 2 + \
c075e6dc
O
1189 light_green('fav 12 ') + ' will favorite the tweet with ' + \
1190 light_yellow('[id=12]') + '.\n'
7e4ccbf3 1191 usage += s * 2 + \
c075e6dc
O
1192 light_green('ufav 12 ') + ' will unfavorite tweet with ' + \
1193 light_yellow('[id=12]') + '.\n'
8bc30efd 1194 usage += s * 2 + \
c075e6dc
O
1195 light_green('del 12 ') + ' will delete tweet with ' + \
1196 light_yellow('[id=12]') + '.\n'
1197 usage += s * 2 + light_green('show image 12') + ' will show image in tweet with ' + \
1198 light_yellow('[id=12]') + ' in your OS\'s image viewer.\n'
80b70d60
O
1199 usage += s * 2 + light_green('open 12') + ' will open url in tweet with ' + \
1200 light_yellow('[id=12]') + ' in your OS\'s default browser.\n'
2d341029 1201 printNicely(usage)
8bc30efd 1202
2d341029
O
1203
1204def help_messages():
1205 """
1206 Messages
1207 """
1208 s = ' ' * 2
5b2c4faf 1209 # Direct message
2d341029 1210 usage = '\n'
8bc30efd 1211 usage += s + grey(u'\u266A' + ' Direct messages \n')
c075e6dc
O
1212 usage += s * 2 + light_green('inbox') + ' will show inbox messages. ' + \
1213 light_green('inbox 7') + ' will show newest 7 messages.\n'
1214 usage += s * 2 + light_green('sent') + ' will show sent messages. ' + \
1215 light_green('sent 7') + ' will show newest 7 messages.\n'
1216 usage += s * 2 + light_green('mes @dtvd88 hi') + ' will send a "hi" messege to ' + \
8bc30efd 1217 magenta('@dtvd88') + '.\n'
c075e6dc
O
1218 usage += s * 2 + light_green('trash 5') + ' will remove message with ' + \
1219 light_yellow('[message_id=5]') + '.\n'
2d341029 1220 printNicely(usage)
8bc30efd 1221
2d341029
O
1222
1223def help_friends_and_followers():
1224 """
1225 Friends and Followers
1226 """
1227 s = ' ' * 2
8bc30efd 1228 # Follower and following
2d341029 1229 usage = '\n'
cdccb0d6 1230 usage += s + grey(u'\u266A' + ' Friends and followers \n')
8bc30efd 1231 usage += s * 2 + \
c075e6dc 1232 light_green('ls fl') + \
8bc30efd 1233 ' will list all followers (people who are following you).\n'
1234 usage += s * 2 + \
c075e6dc 1235 light_green('ls fr') + \
8bc30efd 1236 ' will list all friends (people who you are following).\n'
c075e6dc 1237 usage += s * 2 + light_green('fl @dtvd88') + ' will follow ' + \
305ce127 1238 magenta('@dtvd88') + '.\n'
c075e6dc 1239 usage += s * 2 + light_green('ufl @dtvd88') + ' will unfollow ' + \
305ce127 1240 magenta('@dtvd88') + '.\n'
c075e6dc 1241 usage += s * 2 + light_green('mute @dtvd88') + ' will mute ' + \
5b2c4faf 1242 magenta('@dtvd88') + '.\n'
c075e6dc 1243 usage += s * 2 + light_green('unmute @dtvd88') + ' will unmute ' + \
5b2c4faf 1244 magenta('@dtvd88') + '.\n'
c075e6dc
O
1245 usage += s * 2 + light_green('muting') + ' will list muting users.\n'
1246 usage += s * 2 + light_green('block @dtvd88') + ' will block ' + \
305ce127 1247 magenta('@dtvd88') + '.\n'
c075e6dc 1248 usage += s * 2 + light_green('unblock @dtvd88') + ' will unblock ' + \
305ce127 1249 magenta('@dtvd88') + '.\n'
c075e6dc 1250 usage += s * 2 + light_green('report @dtvd88') + ' will report ' + \
305ce127 1251 magenta('@dtvd88') + ' as a spam account.\n'
2d341029
O
1252 printNicely(usage)
1253
1254
1255def help_list():
1256 """
1257 Lists
1258 """
1259 s = ' ' * 2
1260 # Twitter list
1261 usage = '\n'
1262 usage += s + grey(u'\u266A' + ' Twitter list\n')
1263 usage += s * 2 + light_green('list') + \
1264 ' will show all lists you are belong to.\n'
1265 usage += s * 2 + light_green('list home') + \
bef33491 1266 ' will show timeline of list. You will be asked for list\'s name.\n'
a65bd34c 1267 usage += s * 2 + light_green('list all_mem') + \
2d341029 1268 ' will show list\'s all members.\n'
a65bd34c 1269 usage += s * 2 + light_green('list all_sub') + \
2d341029 1270 ' will show list\'s all subscribers.\n'
422dd385
O
1271 usage += s * 2 + light_green('list add') + \
1272 ' will add specific person to a list owned by you.' + \
1273 ' You will be asked for list\'s name and person\'s name.\n'
2d341029
O
1274 usage += s * 2 + light_green('list rm') + \
1275 ' will remove specific person from a list owned by you.' + \
1276 ' You will be asked for list\'s name and person\'s name.\n'
422dd385
O
1277 usage += s * 2 + light_green('list sub') + \
1278 ' will subscribe you to a specific list.\n'
1279 usage += s * 2 + light_green('list unsub') + \
1280 ' will unsubscribe you from a specific list.\n'
1281 usage += s * 2 + light_green('list own') + \
1282 ' will show all list owned by you.\n'
1283 usage += s * 2 + light_green('list new') + \
1284 ' will create a new list.\n'
1285 usage += s * 2 + light_green('list update') + \
1286 ' will update a list owned by you.\n'
1287 usage += s * 2 + light_green('list del') + \
1288 ' will delete a list owned by you.\n'
2d341029 1289 printNicely(usage)
8bc30efd 1290
2d341029
O
1291
1292def help_stream():
1293 """
1294 Stream switch
1295 """
1296 s = ' ' * 2
8bc30efd 1297 # Switch
2d341029 1298 usage = '\n'
8bc30efd 1299 usage += s + grey(u'\u266A' + ' Switching streams \n')
c075e6dc 1300 usage += s * 2 + light_green('switch public #AKB') + \
48a25fe8 1301 ' will switch to public stream and follow "' + \
c075e6dc
O
1302 light_yellow('AKB') + '" keyword.\n'
1303 usage += s * 2 + light_green('switch mine') + \
48a25fe8 1304 ' will switch to your personal stream.\n'
c075e6dc 1305 usage += s * 2 + light_green('switch mine -f ') + \
48a25fe8 1306 ' will prompt to enter the filter.\n'
c075e6dc 1307 usage += s * 3 + light_yellow('Only nicks') + \
48a25fe8 1308 ' filter will decide nicks will be INCLUDE ONLY.\n'
c075e6dc 1309 usage += s * 3 + light_yellow('Ignore nicks') + \
48a25fe8 1310 ' filter will decide nicks will be EXCLUDE.\n'
c075e6dc 1311 usage += s * 2 + light_green('switch mine -d') + \
48a25fe8 1312 ' will use the config\'s ONLY_LIST and IGNORE_LIST.\n'
2d341029
O
1313 printNicely(usage)
1314
1315
1316def help():
1317 """
1318 Help
1319 """
1320 s = ' ' * 2
1321 h, w = os.popen('stty size', 'r').read().split()
1322
1323 # Start
1324 usage = '\n'
1325 usage += s + 'Hi boss! I\'m ready to serve you right now!\n'
1326 usage += s + '-' * (int(w) - 4) + '\n'
1327 usage += s + 'You are ' + \
1328 light_yellow('already') + ' on your personal stream.\n'
1329 usage += s + 'Any update from Twitter will show up ' + \
1330 light_yellow('immediately') + '.\n'
1331 usage += s + 'In addtion, following commands are available right now:\n'
1332
1333 # Twitter help section
1334 usage += '\n'
1335 usage += s + grey(u'\u266A' + ' Twitter help\n')
1336 usage += s * 2 + light_green('h discover') + \
1337 ' will show help for discover commands.\n'
1338 usage += s * 2 + light_green('h tweets') + \
1339 ' will show help for tweets commands.\n'
1340 usage += s * 2 + light_green('h messages') + \
1341 ' will show help for messages commands.\n'
1342 usage += s * 2 + light_green('h friends_and_followers') + \
1343 ' will show help for friends and followers commands.\n'
1344 usage += s * 2 + light_green('h list') + \
1345 ' will show help for list commands.\n'
1346 usage += s * 2 + light_green('h stream') + \
1347 ' will show help for stream commands.\n'
48a25fe8 1348
1f24a05a 1349 # Smart shell
1350 usage += '\n'
1351 usage += s + grey(u'\u266A' + ' Smart shell\n')
c075e6dc 1352 usage += s * 2 + light_green('111111 * 9 / 7') + ' or any math expression ' + \
1f24a05a 1353 'will be evaluate by Python interpreter.\n'
c075e6dc 1354 usage += s * 2 + 'Even ' + light_green('cal') + ' will show the calendar' + \
1f24a05a 1355 ' for current month.\n'
1356
1357 # Screening
1358 usage += '\n'
1359 usage += s + grey(u'\u266A' + ' Screening \n')
c075e6dc
O
1360 usage += s * 2 + light_green('theme') + ' will list available theme.' + \
1361 light_green('theme monokai') + ' will apply ' + light_yellow('monokai') + \
632c6fa5 1362 ' theme immediately.\n'
c075e6dc
O
1363 usage += s * 2 + light_green('h') + ' will show this help again.\n'
1364 usage += s * 2 + light_green('c') + ' will clear the screen.\n'
1365 usage += s * 2 + light_green('q') + ' will quit.\n'
1f24a05a 1366
8bc30efd 1367 # End
1368 usage += '\n'
7e4ccbf3 1369 usage += s + '-' * (int(w) - 4) + '\n'
8bc30efd 1370 usage += s + 'Have fun and hang tight! \n'
2d341029
O
1371
1372 # Show help
1373 d = {
422dd385
O
1374 'discover': help_discover,
1375 'tweets': help_tweets,
1376 'messages': help_messages,
1377 'friends_and_followers': help_friends_and_followers,
1378 'list': help_list,
1379 'stream': help_stream,
2d341029
O
1380 }
1381 if g['stuff']:
1382 d[g['stuff'].strip()]()
1383 else:
1384 printNicely(usage)
f405a7d0
O
1385
1386
843647ad 1387def clear():
f405a7d0 1388 """
7b674cef 1389 Clear screen
f405a7d0 1390 """
843647ad 1391 os.system('clear')
f405a7d0
O
1392
1393
843647ad 1394def quit():
b8dda704
O
1395 """
1396 Exit all
1397 """
f5677fb1 1398 save_history()
8e633322 1399 os.system('rm -rf rainbow.db')
843647ad
O
1400 os.kill(g['stream_pid'], signal.SIGKILL)
1401 sys.exit()
b8dda704
O
1402
1403
94a5f62e 1404def reset():
f405a7d0 1405 """
94a5f62e 1406 Reset prefix of line
f405a7d0 1407 """
c91f75f2 1408 if g['reset']:
e3885f55 1409 printNicely(magenta('Need tips ? Type "h" and hit Enter key!'))
c91f75f2 1410 g['reset'] = False
d0a726d6 1411 try:
2a0cabee
O
1412 printNicely(str(eval(g['cmd'])))
1413 except Exception:
d0a726d6 1414 pass
54277114
O
1415
1416
94a5f62e 1417def process(cmd):
54277114 1418 """
94a5f62e 1419 Process switch
54277114 1420 """
94a5f62e 1421 return dict(zip(
1422 cmdset,
b2b933a9 1423 [
42fde775 1424 switch,
4592d231 1425 trend,
b2b933a9 1426 home,
1427 view,
305ce127 1428 mentions,
b2b933a9 1429 tweet,
1430 retweet,
80b70d60 1431 quote,
1f24a05a 1432 allretweet,
7e4ccbf3 1433 favorite,
b2b933a9 1434 reply,
1435 delete,
7e4ccbf3 1436 unfavorite,
b2b933a9 1437 search,
305ce127 1438 message,
f5677fb1 1439 show,
80bb2040 1440 urlopen,
2d341029 1441 ls,
305ce127 1442 inbox,
1443 sent,
1444 trash,
e2b81717 1445 whois,
f5677fb1
O
1446 follow,
1447 unfollow,
5b2c4faf 1448 mute,
1449 unmute,
1450 muting,
305ce127 1451 block,
1452 unblock,
1453 report,
2d341029 1454 list,
813a5d80 1455 cal,
632c6fa5 1456 theme,
b2b933a9 1457 help,
1458 clear,
1459 quit
1460 ]
94a5f62e 1461 )).get(cmd, reset)
1462
1463
1464def listen():
42fde775 1465 """
1466 Listen to user's input
1467 """
d51b4107
O
1468 d = dict(zip(
1469 cmdset,
1470 [
affcb149 1471 ['public', 'mine'], # switch
4592d231 1472 [], # trend
7e4ccbf3 1473 [], # home
1474 ['@'], # view
305ce127 1475 [], # mentions
7e4ccbf3 1476 [], # tweet
1477 [], # retweet
80b70d60 1478 [], # quote
1f24a05a 1479 [], # allretweet
f5677fb1 1480 [], # favorite
7e4ccbf3 1481 [], # reply
1482 [], # delete
f5677fb1 1483 [], # unfavorite
7e4ccbf3 1484 ['#'], # search
305ce127 1485 ['@'], # message
f5677fb1 1486 ['image'], # show image
80b70d60 1487 [''], # open url
305ce127 1488 ['fl', 'fr'], # list
1489 [], # inbox
1490 [], # sent
1491 [], # trash
e2b81717 1492 ['@'], # whois
affcb149
O
1493 ['@'], # follow
1494 ['@'], # unfollow
5b2c4faf 1495 ['@'], # mute
1496 ['@'], # unmute
1497 ['@'], # muting
305ce127 1498 ['@'], # block
1499 ['@'], # unblock
1500 ['@'], # report
422dd385
O
1501 [
1502 'home',
1503 'all_mem',
1504 'all_sub',
1505 'add',
1506 'rm',
1507 'sub',
1508 'unsub',
1509 'own',
1510 'new',
1511 'update',
1512 'del'
1513 ], # list
813a5d80 1514 [], # cal
1c8a5082 1515 g['themes'] + ['current_as_default'], # theme
422dd385
O
1516 [
1517 'discover',
1518 'tweets',
1519 'messages',
1520 'friends_and_followers',
1521 'list',
1522 'stream'
1523 ], # help
7e4ccbf3 1524 [], # clear
1525 [], # quit
d51b4107 1526 ]
7e4ccbf3 1527 ))
d51b4107 1528 init_interactive_shell(d)
f5677fb1 1529 read_history()
819569e8 1530 reset()
b2b933a9 1531 while True:
1dd312f5
O
1532 if g['prefix']:
1533 line = raw_input(g['decorated_name'])
1534 else:
1535 line = raw_input()
843647ad
O
1536 try:
1537 cmd = line.split()[0]
1538 except:
1539 cmd = ''
d0a726d6 1540 g['cmd'] = cmd
f405a7d0 1541 # Save cmd to global variable and call process
b8c1f42a
O
1542 try:
1543 g['stuff'] = ' '.join(line.split()[1:])
1544 process(cmd)()
2d341029 1545 except Exception:
b8c1f42a
O
1546 printNicely(red('OMG something is wrong with Twitter right now.'))
1547 # Not redisplay prefix
7e4ccbf3 1548 if cmd in ['switch', 't', 'rt', 'rep']:
1dd312f5
O
1549 g['prefix'] = False
1550 else:
1551 g['prefix'] = True
54277114
O
1552
1553
42fde775 1554def stream(domain, args, name='Rainbow Stream'):
54277114 1555 """
f405a7d0 1556 Track the stream
54277114 1557 """
d51b4107 1558
54277114 1559 # The Logo
42fde775 1560 art_dict = {
632c6fa5
O
1561 c['USER_DOMAIN']: name,
1562 c['PUBLIC_DOMAIN']: args.track_keywords,
1f2f6159 1563 c['SITE_DOMAIN']: name,
42fde775 1564 }
687567eb 1565 if c['ASCII_ART']:
c075e6dc 1566 ascii_art(art_dict[domain])
d51b4107 1567
91476ec3
O
1568 # These arguments are optional:
1569 stream_args = dict(
1570 timeout=args.timeout,
1571 block=not args.no_block,
1572 heartbeat_timeout=args.heartbeat_timeout)
1573
1574 # Track keyword
1575 query_args = dict()
1576 if args.track_keywords:
1577 query_args['track'] = args.track_keywords
1578
1579 # Get stream
2a6238f5 1580 stream = TwitterStream(
22be990e 1581 auth=authen(),
42fde775 1582 domain=domain,
2a6238f5 1583 **stream_args)
91476ec3 1584
2a0cabee
O
1585 try:
1586 if domain == c['USER_DOMAIN']:
1587 tweet_iter = stream.user(**query_args)
1588 elif domain == c['SITE_DOMAIN']:
1589 tweet_iter = stream.site(**query_args)
42fde775 1590 else:
2a0cabee
O
1591 if args.track_keywords:
1592 tweet_iter = stream.statuses.filter(**query_args)
1593 else:
1594 tweet_iter = stream.statuses.sample()
42fde775 1595
2a0cabee 1596 # Iterate over the stream.
72c02928
VNM
1597 for tweet in tweet_iter:
1598 if tweet is None:
1599 printNicely("-- None --")
1600 elif tweet is Timeout:
1601 printNicely("-- Timeout --")
1602 elif tweet is HeartbeatTimeout:
1603 printNicely("-- Heartbeat Timeout --")
1604 elif tweet is Hangup:
1605 printNicely("-- Hangup --")
1606 elif tweet.get('text'):
1607 draw(
1608 t=tweet,
1609 iot=args.image_on_term,
1610 keyword=args.track_keywords,
1611 fil=args.filter,
1612 ig=args.ignore,
1613 )
2a0cabee
O
1614 except TwitterHTTPError:
1615 printNicely('')
c075e6dc 1616 printNicely(
2a0cabee 1617 magenta("We have maximum connection problem with twitter'stream API right now :("))
54277114
O
1618
1619
1620def fly():
1621 """
1622 Main function
1623 """
42fde775 1624 # Spawn stream process
1625 args = parse_arguments()
2a0cabee
O
1626 try:
1627 get_decorated_name()
1628
1629 except TwitterHTTPError:
1630 printNicely('')
1631 printNicely(
2e1241c7 1632 magenta("Something wrong with Twitter Oauth right now :("))
1633 printNicely(
1634 magenta("Please delete ~/.rainbow_oauth and try again."))
2a0cabee
O
1635 save_history()
1636 os.system('rm -rf rainbow.db')
1637 sys.exit()
1638
c075e6dc
O
1639 p = Process(
1640 target=stream,
1641 args=(
422dd385 1642 c['USER_DOMAIN'],
c075e6dc
O
1643 args,
1644 g['original_name']))
42fde775 1645 p.start()
1646
1647 # Start listen process
819569e8 1648 time.sleep(0.5)
c91f75f2 1649 g['reset'] = True
1dd312f5 1650 g['prefix'] = True
f405a7d0 1651 g['stream_pid'] = p.pid
c1fa7c94 1652 g['iot'] = args.image_on_term
0f6e4daf 1653 listen()