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