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