re saerch keyword without hashtag
[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'
c075e6dc
O
1158 usage += s * 2 + light_green('s #AKB48') + ' will search for "' + \
1159 light_yellow('AKB48') + '" and return 5 newest tweet.\n'
2d341029
O
1160 printNicely(usage)
1161
8bc30efd 1162
2d341029
O
1163def help_tweets():
1164 """
1165 Tweets
1166 """
1167 s = ' ' * 2
1f24a05a 1168 # Tweet
2d341029 1169 usage = '\n'
8bc30efd 1170 usage += s + grey(u'\u266A' + ' Tweets \n')
c075e6dc
O
1171 usage += s * 2 + light_green('t oops ') + \
1172 'will tweet "' + light_yellow('oops') + '" immediately.\n'
7e4ccbf3 1173 usage += s * 2 + \
c075e6dc
O
1174 light_green('rt 12 ') + ' will retweet to tweet with ' + \
1175 light_yellow('[id=12]') + '.\n'
80b70d60
O
1176 usage += s * 2 + \
1177 light_green('quote 12 ') + ' will quote the tweet with ' + \
1178 light_yellow('[id=12]') + '. If no extra text is added, ' + \
1179 'the quote will be canceled.\n'
1f24a05a 1180 usage += s * 2 + \
c075e6dc
O
1181 light_green('allrt 12 20 ') + ' will list 20 newest retweet of the tweet with ' + \
1182 light_yellow('[id=12]') + '.\n'
1183 usage += s * 2 + light_green('rep 12 oops') + ' will reply "' + \
1184 light_yellow('oops') + '" to tweet with ' + \
1185 light_yellow('[id=12]') + '.\n'
7e4ccbf3 1186 usage += s * 2 + \
c075e6dc
O
1187 light_green('fav 12 ') + ' will favorite the tweet with ' + \
1188 light_yellow('[id=12]') + '.\n'
7e4ccbf3 1189 usage += s * 2 + \
c075e6dc
O
1190 light_green('ufav 12 ') + ' will unfavorite tweet with ' + \
1191 light_yellow('[id=12]') + '.\n'
8bc30efd 1192 usage += s * 2 + \
c075e6dc
O
1193 light_green('del 12 ') + ' will delete tweet with ' + \
1194 light_yellow('[id=12]') + '.\n'
1195 usage += s * 2 + light_green('show image 12') + ' will show image in tweet with ' + \
1196 light_yellow('[id=12]') + ' in your OS\'s image viewer.\n'
80b70d60
O
1197 usage += s * 2 + light_green('open 12') + ' will open url in tweet with ' + \
1198 light_yellow('[id=12]') + ' in your OS\'s default browser.\n'
2d341029 1199 printNicely(usage)
8bc30efd 1200
2d341029
O
1201
1202def help_messages():
1203 """
1204 Messages
1205 """
1206 s = ' ' * 2
5b2c4faf 1207 # Direct message
2d341029 1208 usage = '\n'
8bc30efd 1209 usage += s + grey(u'\u266A' + ' Direct messages \n')
c075e6dc
O
1210 usage += s * 2 + light_green('inbox') + ' will show inbox messages. ' + \
1211 light_green('inbox 7') + ' will show newest 7 messages.\n'
1212 usage += s * 2 + light_green('sent') + ' will show sent messages. ' + \
1213 light_green('sent 7') + ' will show newest 7 messages.\n'
1214 usage += s * 2 + light_green('mes @dtvd88 hi') + ' will send a "hi" messege to ' + \
8bc30efd 1215 magenta('@dtvd88') + '.\n'
c075e6dc
O
1216 usage += s * 2 + light_green('trash 5') + ' will remove message with ' + \
1217 light_yellow('[message_id=5]') + '.\n'
2d341029 1218 printNicely(usage)
8bc30efd 1219
2d341029
O
1220
1221def help_friends_and_followers():
1222 """
1223 Friends and Followers
1224 """
1225 s = ' ' * 2
8bc30efd 1226 # Follower and following
2d341029 1227 usage = '\n'
cdccb0d6 1228 usage += s + grey(u'\u266A' + ' Friends and followers \n')
8bc30efd 1229 usage += s * 2 + \
c075e6dc 1230 light_green('ls fl') + \
8bc30efd 1231 ' will list all followers (people who are following you).\n'
1232 usage += s * 2 + \
c075e6dc 1233 light_green('ls fr') + \
8bc30efd 1234 ' will list all friends (people who you are following).\n'
c075e6dc 1235 usage += s * 2 + light_green('fl @dtvd88') + ' will follow ' + \
305ce127 1236 magenta('@dtvd88') + '.\n'
c075e6dc 1237 usage += s * 2 + light_green('ufl @dtvd88') + ' will unfollow ' + \
305ce127 1238 magenta('@dtvd88') + '.\n'
c075e6dc 1239 usage += s * 2 + light_green('mute @dtvd88') + ' will mute ' + \
5b2c4faf 1240 magenta('@dtvd88') + '.\n'
c075e6dc 1241 usage += s * 2 + light_green('unmute @dtvd88') + ' will unmute ' + \
5b2c4faf 1242 magenta('@dtvd88') + '.\n'
c075e6dc
O
1243 usage += s * 2 + light_green('muting') + ' will list muting users.\n'
1244 usage += s * 2 + light_green('block @dtvd88') + ' will block ' + \
305ce127 1245 magenta('@dtvd88') + '.\n'
c075e6dc 1246 usage += s * 2 + light_green('unblock @dtvd88') + ' will unblock ' + \
305ce127 1247 magenta('@dtvd88') + '.\n'
c075e6dc 1248 usage += s * 2 + light_green('report @dtvd88') + ' will report ' + \
305ce127 1249 magenta('@dtvd88') + ' as a spam account.\n'
2d341029
O
1250 printNicely(usage)
1251
1252
1253def help_list():
1254 """
1255 Lists
1256 """
1257 s = ' ' * 2
1258 # Twitter list
1259 usage = '\n'
1260 usage += s + grey(u'\u266A' + ' Twitter list\n')
1261 usage += s * 2 + light_green('list') + \
1262 ' will show all lists you are belong to.\n'
1263 usage += s * 2 + light_green('list home') + \
bef33491 1264 ' will show timeline of list. You will be asked for list\'s name.\n'
a65bd34c 1265 usage += s * 2 + light_green('list all_mem') + \
2d341029 1266 ' will show list\'s all members.\n'
a65bd34c 1267 usage += s * 2 + light_green('list all_sub') + \
2d341029 1268 ' will show list\'s all subscribers.\n'
422dd385
O
1269 usage += s * 2 + light_green('list add') + \
1270 ' will add specific person to a list owned by you.' + \
1271 ' You will be asked for list\'s name and person\'s name.\n'
2d341029
O
1272 usage += s * 2 + light_green('list rm') + \
1273 ' will remove specific person from a list owned by you.' + \
1274 ' You will be asked for list\'s name and person\'s name.\n'
422dd385
O
1275 usage += s * 2 + light_green('list sub') + \
1276 ' will subscribe you to a specific list.\n'
1277 usage += s * 2 + light_green('list unsub') + \
1278 ' will unsubscribe you from a specific list.\n'
1279 usage += s * 2 + light_green('list own') + \
1280 ' will show all list owned by you.\n'
1281 usage += s * 2 + light_green('list new') + \
1282 ' will create a new list.\n'
1283 usage += s * 2 + light_green('list update') + \
1284 ' will update a list owned by you.\n'
1285 usage += s * 2 + light_green('list del') + \
1286 ' will delete a list owned by you.\n'
2d341029 1287 printNicely(usage)
8bc30efd 1288
2d341029
O
1289
1290def help_stream():
1291 """
1292 Stream switch
1293 """
1294 s = ' ' * 2
8bc30efd 1295 # Switch
2d341029 1296 usage = '\n'
8bc30efd 1297 usage += s + grey(u'\u266A' + ' Switching streams \n')
c075e6dc 1298 usage += s * 2 + light_green('switch public #AKB') + \
48a25fe8 1299 ' will switch to public stream and follow "' + \
c075e6dc
O
1300 light_yellow('AKB') + '" keyword.\n'
1301 usage += s * 2 + light_green('switch mine') + \
48a25fe8 1302 ' will switch to your personal stream.\n'
c075e6dc 1303 usage += s * 2 + light_green('switch mine -f ') + \
48a25fe8 1304 ' will prompt to enter the filter.\n'
c075e6dc 1305 usage += s * 3 + light_yellow('Only nicks') + \
48a25fe8 1306 ' filter will decide nicks will be INCLUDE ONLY.\n'
c075e6dc 1307 usage += s * 3 + light_yellow('Ignore nicks') + \
48a25fe8 1308 ' filter will decide nicks will be EXCLUDE.\n'
c075e6dc 1309 usage += s * 2 + light_green('switch mine -d') + \
48a25fe8 1310 ' will use the config\'s ONLY_LIST and IGNORE_LIST.\n'
2d341029
O
1311 printNicely(usage)
1312
1313
1314def help():
1315 """
1316 Help
1317 """
1318 s = ' ' * 2
1319 h, w = os.popen('stty size', 'r').read().split()
1320
1321 # Start
1322 usage = '\n'
1323 usage += s + 'Hi boss! I\'m ready to serve you right now!\n'
1324 usage += s + '-' * (int(w) - 4) + '\n'
1325 usage += s + 'You are ' + \
1326 light_yellow('already') + ' on your personal stream.\n'
1327 usage += s + 'Any update from Twitter will show up ' + \
1328 light_yellow('immediately') + '.\n'
1329 usage += s + 'In addtion, following commands are available right now:\n'
1330
1331 # Twitter help section
1332 usage += '\n'
1333 usage += s + grey(u'\u266A' + ' Twitter help\n')
1334 usage += s * 2 + light_green('h discover') + \
1335 ' will show help for discover commands.\n'
1336 usage += s * 2 + light_green('h tweets') + \
1337 ' will show help for tweets commands.\n'
1338 usage += s * 2 + light_green('h messages') + \
1339 ' will show help for messages commands.\n'
1340 usage += s * 2 + light_green('h friends_and_followers') + \
1341 ' will show help for friends and followers commands.\n'
1342 usage += s * 2 + light_green('h list') + \
1343 ' will show help for list commands.\n'
1344 usage += s * 2 + light_green('h stream') + \
1345 ' will show help for stream commands.\n'
48a25fe8 1346
1f24a05a 1347 # Smart shell
1348 usage += '\n'
1349 usage += s + grey(u'\u266A' + ' Smart shell\n')
c075e6dc 1350 usage += s * 2 + light_green('111111 * 9 / 7') + ' or any math expression ' + \
1f24a05a 1351 'will be evaluate by Python interpreter.\n'
c075e6dc 1352 usage += s * 2 + 'Even ' + light_green('cal') + ' will show the calendar' + \
1f24a05a 1353 ' for current month.\n'
1354
1355 # Screening
1356 usage += '\n'
1357 usage += s + grey(u'\u266A' + ' Screening \n')
c075e6dc
O
1358 usage += s * 2 + light_green('theme') + ' will list available theme.' + \
1359 light_green('theme monokai') + ' will apply ' + light_yellow('monokai') + \
632c6fa5 1360 ' theme immediately.\n'
c075e6dc
O
1361 usage += s * 2 + light_green('h') + ' will show this help again.\n'
1362 usage += s * 2 + light_green('c') + ' will clear the screen.\n'
1363 usage += s * 2 + light_green('q') + ' will quit.\n'
1f24a05a 1364
8bc30efd 1365 # End
1366 usage += '\n'
7e4ccbf3 1367 usage += s + '-' * (int(w) - 4) + '\n'
8bc30efd 1368 usage += s + 'Have fun and hang tight! \n'
2d341029
O
1369
1370 # Show help
1371 d = {
422dd385
O
1372 'discover': help_discover,
1373 'tweets': help_tweets,
1374 'messages': help_messages,
1375 'friends_and_followers': help_friends_and_followers,
1376 'list': help_list,
1377 'stream': help_stream,
2d341029
O
1378 }
1379 if g['stuff']:
1380 d[g['stuff'].strip()]()
1381 else:
1382 printNicely(usage)
f405a7d0
O
1383
1384
843647ad 1385def clear():
f405a7d0 1386 """
7b674cef 1387 Clear screen
f405a7d0 1388 """
843647ad 1389 os.system('clear')
f405a7d0
O
1390
1391
843647ad 1392def quit():
b8dda704
O
1393 """
1394 Exit all
1395 """
f5677fb1 1396 save_history()
8e633322 1397 os.system('rm -rf rainbow.db')
843647ad
O
1398 os.kill(g['stream_pid'], signal.SIGKILL)
1399 sys.exit()
b8dda704
O
1400
1401
94a5f62e 1402def reset():
f405a7d0 1403 """
94a5f62e 1404 Reset prefix of line
f405a7d0 1405 """
c91f75f2 1406 if g['reset']:
e3885f55 1407 printNicely(magenta('Need tips ? Type "h" and hit Enter key!'))
c91f75f2 1408 g['reset'] = False
d0a726d6 1409 try:
2a0cabee
O
1410 printNicely(str(eval(g['cmd'])))
1411 except Exception:
d0a726d6 1412 pass
54277114
O
1413
1414
94a5f62e 1415def process(cmd):
54277114 1416 """
94a5f62e 1417 Process switch
54277114 1418 """
94a5f62e 1419 return dict(zip(
1420 cmdset,
b2b933a9 1421 [
42fde775 1422 switch,
4592d231 1423 trend,
b2b933a9 1424 home,
1425 view,
305ce127 1426 mentions,
b2b933a9 1427 tweet,
1428 retweet,
80b70d60 1429 quote,
1f24a05a 1430 allretweet,
7e4ccbf3 1431 favorite,
b2b933a9 1432 reply,
1433 delete,
7e4ccbf3 1434 unfavorite,
b2b933a9 1435 search,
305ce127 1436 message,
f5677fb1 1437 show,
80bb2040 1438 urlopen,
2d341029 1439 ls,
305ce127 1440 inbox,
1441 sent,
1442 trash,
e2b81717 1443 whois,
f5677fb1
O
1444 follow,
1445 unfollow,
5b2c4faf 1446 mute,
1447 unmute,
1448 muting,
305ce127 1449 block,
1450 unblock,
1451 report,
2d341029 1452 list,
813a5d80 1453 cal,
632c6fa5 1454 theme,
b2b933a9 1455 help,
1456 clear,
1457 quit
1458 ]
94a5f62e 1459 )).get(cmd, reset)
1460
1461
1462def listen():
42fde775 1463 """
1464 Listen to user's input
1465 """
d51b4107
O
1466 d = dict(zip(
1467 cmdset,
1468 [
affcb149 1469 ['public', 'mine'], # switch
4592d231 1470 [], # trend
7e4ccbf3 1471 [], # home
1472 ['@'], # view
305ce127 1473 [], # mentions
7e4ccbf3 1474 [], # tweet
1475 [], # retweet
80b70d60 1476 [], # quote
1f24a05a 1477 [], # allretweet
f5677fb1 1478 [], # favorite
7e4ccbf3 1479 [], # reply
1480 [], # delete
f5677fb1 1481 [], # unfavorite
7e4ccbf3 1482 ['#'], # search
305ce127 1483 ['@'], # message
f5677fb1 1484 ['image'], # show image
80b70d60 1485 [''], # open url
305ce127 1486 ['fl', 'fr'], # list
1487 [], # inbox
1488 [], # sent
1489 [], # trash
e2b81717 1490 ['@'], # whois
affcb149
O
1491 ['@'], # follow
1492 ['@'], # unfollow
5b2c4faf 1493 ['@'], # mute
1494 ['@'], # unmute
1495 ['@'], # muting
305ce127 1496 ['@'], # block
1497 ['@'], # unblock
1498 ['@'], # report
422dd385
O
1499 [
1500 'home',
1501 'all_mem',
1502 'all_sub',
1503 'add',
1504 'rm',
1505 'sub',
1506 'unsub',
1507 'own',
1508 'new',
1509 'update',
1510 'del'
1511 ], # list
813a5d80 1512 [], # cal
1c8a5082 1513 g['themes'] + ['current_as_default'], # theme
422dd385
O
1514 [
1515 'discover',
1516 'tweets',
1517 'messages',
1518 'friends_and_followers',
1519 'list',
1520 'stream'
1521 ], # help
7e4ccbf3 1522 [], # clear
1523 [], # quit
d51b4107 1524 ]
7e4ccbf3 1525 ))
d51b4107 1526 init_interactive_shell(d)
f5677fb1 1527 read_history()
819569e8 1528 reset()
b2b933a9 1529 while True:
1dd312f5
O
1530 if g['prefix']:
1531 line = raw_input(g['decorated_name'])
1532 else:
1533 line = raw_input()
843647ad
O
1534 try:
1535 cmd = line.split()[0]
1536 except:
1537 cmd = ''
d0a726d6 1538 g['cmd'] = cmd
f405a7d0 1539 # Save cmd to global variable and call process
b8c1f42a
O
1540 try:
1541 g['stuff'] = ' '.join(line.split()[1:])
1542 process(cmd)()
2d341029 1543 except Exception:
b8c1f42a
O
1544 printNicely(red('OMG something is wrong with Twitter right now.'))
1545 # Not redisplay prefix
7e4ccbf3 1546 if cmd in ['switch', 't', 'rt', 'rep']:
1dd312f5
O
1547 g['prefix'] = False
1548 else:
1549 g['prefix'] = True
54277114
O
1550
1551
42fde775 1552def stream(domain, args, name='Rainbow Stream'):
54277114 1553 """
f405a7d0 1554 Track the stream
54277114 1555 """
d51b4107 1556
54277114 1557 # The Logo
42fde775 1558 art_dict = {
632c6fa5
O
1559 c['USER_DOMAIN']: name,
1560 c['PUBLIC_DOMAIN']: args.track_keywords,
1f2f6159 1561 c['SITE_DOMAIN']: name,
42fde775 1562 }
687567eb 1563 if c['ASCII_ART']:
c075e6dc 1564 ascii_art(art_dict[domain])
d51b4107 1565
91476ec3
O
1566 # These arguments are optional:
1567 stream_args = dict(
1568 timeout=args.timeout,
1569 block=not args.no_block,
1570 heartbeat_timeout=args.heartbeat_timeout)
1571
1572 # Track keyword
1573 query_args = dict()
1574 if args.track_keywords:
1575 query_args['track'] = args.track_keywords
1576
1577 # Get stream
2a6238f5 1578 stream = TwitterStream(
22be990e 1579 auth=authen(),
42fde775 1580 domain=domain,
2a6238f5 1581 **stream_args)
91476ec3 1582
2a0cabee
O
1583 try:
1584 if domain == c['USER_DOMAIN']:
1585 tweet_iter = stream.user(**query_args)
1586 elif domain == c['SITE_DOMAIN']:
1587 tweet_iter = stream.site(**query_args)
42fde775 1588 else:
2a0cabee
O
1589 if args.track_keywords:
1590 tweet_iter = stream.statuses.filter(**query_args)
1591 else:
1592 tweet_iter = stream.statuses.sample()
42fde775 1593
2a0cabee 1594 # Iterate over the stream.
72c02928
VNM
1595 for tweet in tweet_iter:
1596 if tweet is None:
1597 printNicely("-- None --")
1598 elif tweet is Timeout:
1599 printNicely("-- Timeout --")
1600 elif tweet is HeartbeatTimeout:
1601 printNicely("-- Heartbeat Timeout --")
1602 elif tweet is Hangup:
1603 printNicely("-- Hangup --")
1604 elif tweet.get('text'):
1605 draw(
1606 t=tweet,
1607 iot=args.image_on_term,
1608 keyword=args.track_keywords,
1609 fil=args.filter,
1610 ig=args.ignore,
1611 )
2a0cabee
O
1612 except TwitterHTTPError:
1613 printNicely('')
c075e6dc 1614 printNicely(
2a0cabee 1615 magenta("We have maximum connection problem with twitter'stream API right now :("))
54277114
O
1616
1617
1618def fly():
1619 """
1620 Main function
1621 """
42fde775 1622 # Spawn stream process
1623 args = parse_arguments()
2a0cabee
O
1624 try:
1625 get_decorated_name()
1626
1627 except TwitterHTTPError:
1628 printNicely('')
1629 printNicely(
2e1241c7 1630 magenta("Something wrong with Twitter Oauth right now :("))
1631 printNicely(
1632 magenta("Please delete ~/.rainbow_oauth and try again."))
2a0cabee
O
1633 save_history()
1634 os.system('rm -rf rainbow.db')
1635 sys.exit()
1636
c075e6dc
O
1637 p = Process(
1638 target=stream,
1639 args=(
422dd385 1640 c['USER_DOMAIN'],
c075e6dc
O
1641 args,
1642 g['original_name']))
42fde775 1643 p.start()
1644
1645 # Start listen process
819569e8 1646 time.sleep(0.5)
c91f75f2 1647 g['reset'] = True
1dd312f5 1648 g['prefix'] = True
f405a7d0 1649 g['stream_pid'] = p.pid
c1fa7c94 1650 g['iot'] = args.image_on_term
0f6e4daf 1651 listen()