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