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