c424e841e779c640b60a12c6364f80e62fa776ba
[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(light_magenta('List name should follow "@owner/list_name" format.'))
818 raise Exception('Wrong list name')
819
820
821 def show_lists(t):
822 """
823 List list
824 """
825 rel = t.lists.list(screen_name=g['original_name'])
826 if rel:
827 print_list(rel)
828 else:
829 printNicely(light_magenta('You belong to no lists :)'))
830
831
832 def list_home(t):
833 """
834 List home
835 """
836 owner, slug = get_slug()
837 res = t.lists.statuses(
838 slug=slug,
839 owner_screen_name=owner,
840 count=c['LIST_MAX'],
841 include_entities=False)
842 for tweet in res:
843 draw(t=tweet)
844 printNicely('')
845
846
847 def list_members(t):
848 """
849 List members
850 """
851 owner, slug = get_slug()
852 # Get members
853 rel = {}
854 next_cursor = -1
855 while next_cursor != 0:
856 m = t.lists.members(
857 slug=slug,
858 owner_screen_name=owner,
859 cursor=next_cursor,
860 include_entities=False)
861 for u in m['users']:
862 rel[u['name']] = '@' + u['screen_name']
863 next_cursor = m['next_cursor']
864 printNicely('All: ' + str(len(rel)) + ' members.')
865 for name in rel:
866 user = ' ' + cycle_color(name)
867 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
868 printNicely(user)
869
870
871 def list_subscribers(t):
872 """
873 List subscribers
874 """
875 owner, slug = get_slug()
876 # Get subscribers
877 rel = {}
878 next_cursor = -1
879 while next_cursor != 0:
880 m = t.lists.subscribers(
881 slug=slug,
882 owner_screen_name=owner,
883 cursor=next_cursor,
884 include_entities=False)
885 for u in m['users']:
886 rel[u['name']] = '@' + u['screen_name']
887 next_cursor = m['next_cursor']
888 printNicely('All: ' + str(len(rel)) + ' subscribers.')
889 for name in rel:
890 user = ' ' + cycle_color(name)
891 user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ')
892 printNicely(user)
893
894
895 def list_add(t):
896 """
897 Add specific user to a list
898 """
899 owner, slug = get_slug()
900 # Add
901 user_name = raw_input(light_magenta('Give me name of the newbie: '))
902 if user_name.startswith('@'):
903 user_name = user_name[1:]
904 try:
905 t.lists.members.create(
906 slug=slug,
907 owner_screen_name=owner,
908 screen_name=user_name)
909 printNicely(light_green('Added.'))
910 except:
911 printNicely(light_magenta('I\'m sorry we can not add him/her.'))
912
913
914 def list_remove(t):
915 """
916 Remove specific user from a list
917 """
918 owner, slug = get_slug()
919 # Remove
920 user_name = raw_input(light_magenta('Give me name of the unlucky one: '))
921 if user_name.startswith('@'):
922 user_name = user_name[1:]
923 try:
924 t.lists.members.destroy(
925 slug=slug,
926 owner_screen_name=owner,
927 screen_name=user_name)
928 printNicely(light_green('Gone.'))
929 except:
930 printNicely(light_magenta('I\'m sorry we can not remove him/her.'))
931
932
933 def list_subscribe(t):
934 """
935 Subscribe to a list
936 """
937 owner, slug = get_slug()
938 # Subscribe
939 try:
940 t.lists.subscribers.create(
941 slug=slug,
942 owner_screen_name=owner)
943 printNicely(light_green('Done.'))
944 except:
945 printNicely(
946 light_magenta('I\'m sorry you can not subscribe to this list.'))
947
948
949 def list_unsubscribe(t):
950 """
951 Unsubscribe a list
952 """
953 owner, slug = get_slug()
954 # Subscribe
955 try:
956 t.lists.subscribers.destroy(
957 slug=slug,
958 owner_screen_name=owner)
959 printNicely(light_green('Done.'))
960 except:
961 printNicely(
962 light_magenta('I\'m sorry you can not unsubscribe to this list.'))
963
964
965 def list_own(t):
966 """
967 List own
968 """
969 rel = []
970 next_cursor = -1
971 while next_cursor != 0:
972 res = t.lists.ownerships(
973 screen_name=g['original_name'],
974 cursor=next_cursor)
975 rel += res['lists']
976 next_cursor = res['next_cursor']
977 if rel:
978 print_list(rel)
979 else:
980 printNicely(light_magenta('You own no lists :)'))
981
982
983 def list_new(t):
984 """
985 Create a new list
986 """
987 name = raw_input(light_magenta('New list\'s name: '))
988 mode = raw_input(light_magenta('New list\'s mode (public/private): '))
989 description = raw_input(light_magenta('New list\'s description: '))
990 try:
991 t.lists.create(
992 name=name,
993 mode=mode,
994 description=description)
995 printNicely(light_green(name + ' list is created.'))
996 except:
997 printNicely(red('Oops something is wrong with Twitter :('))
998
999
1000 def list_update(t):
1001 """
1002 Update a list
1003 """
1004 slug = raw_input(light_magenta('Your list that you want to update: '))
1005 name = raw_input(light_magenta('Update name (leave blank to unchange): '))
1006 mode = raw_input(light_magenta('Update mode (public/private): '))
1007 description = raw_input(light_magenta('Update description: '))
1008 try:
1009 if name:
1010 t.lists.update(
1011 slug='-'.join(slug.split()),
1012 owner_screen_name=g['original_name'],
1013 name=name,
1014 mode=mode,
1015 description=description)
1016 else:
1017 t.lists.update(
1018 slug=slug,
1019 owner_screen_name=g['original_name'],
1020 mode=mode,
1021 description=description)
1022 printNicely(light_green(slug + ' list is updated.'))
1023 except:
1024 printNicely(red('Oops something is wrong with Twitter :('))
1025
1026
1027 def list_delete(t):
1028 """
1029 Delete a list
1030 """
1031 slug = raw_input(light_magenta('Your list that you want to update: '))
1032 try:
1033 t.lists.destroy(
1034 slug='-'.join(slug.split()),
1035 owner_screen_name=g['original_name'])
1036 printNicely(light_green(slug + ' list is deleted.'))
1037 except:
1038 printNicely(red('Oops something is wrong with Twitter :('))
1039
1040
1041 def list():
1042 """
1043 Twitter's list
1044 """
1045 t = Twitter(auth=authen())
1046 # List all lists or base on action
1047 try:
1048 g['list_action'] = g['stuff'].split()[0]
1049 except:
1050 show_lists(t)
1051 return
1052 # Sub-function
1053 action_ary = {
1054 'home': list_home,
1055 'all_mem': list_members,
1056 'all_sub': list_subscribers,
1057 'add': list_add,
1058 'rm': list_remove,
1059 'sub': list_subscribe,
1060 'unsub': list_unsubscribe,
1061 'own': list_own,
1062 'new': list_new,
1063 'update': list_update,
1064 'del': list_delete,
1065 }
1066 try:
1067 return action_ary[g['list_action']](t)
1068 except:
1069 printNicely(red('Please try again.'))
1070
1071
1072 def cal():
1073 """
1074 Unix's command `cal`
1075 """
1076 # Format
1077 rel = os.popen('cal').read().split('\n')
1078 month = rel.pop(0)
1079 date = rel.pop(0)
1080 show_calendar(month, date, rel)
1081
1082
1083 def config():
1084 """
1085 Browse and change config
1086 """
1087 all_config = get_all_config()
1088 g['stuff'] = g['stuff'].strip()
1089 # List all config
1090 if not g['stuff']:
1091 for k in all_config:
1092 line = ' '*2 + light_green(k) + ': ' + light_yellow(str(all_config[k]))
1093 printNicely(line)
1094 guide = 'Detailed explanation can be found at ' + \
1095 color_func(c['TWEET']['link'])('http://rainbowstream.readthedocs.org/en/latest/#config-explanation')
1096 printNicely(guide)
1097 # Print specific config
1098 elif len(g['stuff'].split()) == 1:
1099 if g['stuff'] in all_config:
1100 k = g['stuff']
1101 line = ' '*2 + light_green(k) + ': ' + light_yellow(str(all_config[k]))
1102 printNicely(line)
1103 else:
1104 printNicely(red('No config key like this.'))
1105 # Print specific config's default value
1106 elif len(g['stuff'].split()) == 2 and g['stuff'].split()[-1] == 'default':
1107 key = g['stuff'].split()[0]
1108 value = get_default_config(key)
1109 line = ' '*2 + light_green(key) + ': ' + light_magenta(value)
1110 printNicely(line)
1111 # Set specific config
1112 elif len(g['stuff'].split()) == 3 and g['stuff'].split()[1] == '=' :
1113 key = g['stuff'].split()[0]
1114 value = g['stuff'].split()[-1]
1115 try:
1116 set_config(key,value)
1117 printNicely(light_green('Updated successfully.'))
1118 except:
1119 printNicely(light_magenta('Not valid value.'))
1120 return
1121 reload_config()
1122 else:
1123 printNicely(light_magenta('Sorry I can\'s understand.'))
1124
1125
1126 def theme():
1127 """
1128 List and change theme
1129 """
1130 if not g['stuff']:
1131 # List themes
1132 for theme in g['themes']:
1133 line = light_magenta(theme)
1134 if c['THEME'] == theme:
1135 line = ' ' * 2 + light_yellow('* ') + line
1136 else:
1137 line = ' ' * 4 + line
1138 printNicely(line)
1139 elif g['stuff'] == 'current_as_default':
1140 # Set as default
1141 set_config('THEME',c['THEME'])
1142 printNicely(light_green('Okay it will be applied from next time :)'))
1143 else:
1144 # Change theme
1145 try:
1146 # Load new config
1147 if g['stuff'] != 'custom':
1148 new_config = os.path.dirname(
1149 __file__) + '/colorset/' + g['stuff'] + '.json'
1150 else:
1151 new_config = os.environ.get(
1152 'HOME', os.environ.get(
1153 'USERPROFILE',
1154 '')) + os.sep + '.rainbow_config.json'
1155 new_config = load_config(new_config)
1156 if new_config:
1157 for nc in new_config:
1158 c[nc] = new_config[nc]
1159 # Update db and reset colors
1160 db.theme_update(g['stuff'])
1161 c['THEME'] = g['stuff']
1162 start_cycle()
1163 g['decorated_name'] = color_func(
1164 c['DECORATED_NAME'])(
1165 '[@' + g['original_name'] + ']: ')
1166 printNicely(green('Theme changed.'))
1167 except:
1168 printNicely(red('No such theme exists.'))
1169
1170
1171 def help_discover():
1172 """
1173 Discover the world
1174 """
1175 s = ' ' * 2
1176 # Discover the world
1177 usage = '\n'
1178 usage += s + grey(u'\u266A' + ' Discover the world \n')
1179 usage += s * 2 + light_green('trend') + ' will show global trending topics. ' + \
1180 'You can try ' + light_green('trend US') + ' or ' + \
1181 light_green('trend JP Tokyo') + '.\n'
1182 usage += s * 2 + light_green('home') + ' will show your timeline. ' + \
1183 light_green('home 7') + ' will show 7 tweets.\n'
1184 usage += s * 2 + light_green('mentions') + ' will show mentions timeline. ' + \
1185 light_green('mentions 7') + ' will show 7 mention tweets.\n'
1186 usage += s * 2 + light_green('whois @mdo') + ' will show profile of ' + \
1187 magenta('@mdo') + '.\n'
1188 usage += s * 2 + light_green('view @mdo') + \
1189 ' will show ' + magenta('@mdo') + '\'s home.\n'
1190 usage += s * 2 + light_green('s AKB48') + ' will search for "' + \
1191 light_yellow('AKB48') + '" and return 5 newest tweet. ' + \
1192 'Search can be performed with or without hashtag.\n'
1193 printNicely(usage)
1194
1195
1196 def help_tweets():
1197 """
1198 Tweets
1199 """
1200 s = ' ' * 2
1201 # Tweet
1202 usage = '\n'
1203 usage += s + grey(u'\u266A' + ' Tweets \n')
1204 usage += s * 2 + light_green('t oops ') + \
1205 'will tweet "' + light_yellow('oops') + '" immediately.\n'
1206 usage += s * 2 + \
1207 light_green('rt 12 ') + ' will retweet to tweet with ' + \
1208 light_yellow('[id=12]') + '.\n'
1209 usage += s * 2 + \
1210 light_green('quote 12 ') + ' will quote the tweet with ' + \
1211 light_yellow('[id=12]') + '. If no extra text is added, ' + \
1212 'the quote will be canceled.\n'
1213 usage += s * 2 + \
1214 light_green('allrt 12 20 ') + ' will list 20 newest retweet of the tweet with ' + \
1215 light_yellow('[id=12]') + '.\n'
1216 usage += s * 2 + light_green('rep 12 oops') + ' will reply "' + \
1217 light_yellow('oops') + '" to tweet with ' + \
1218 light_yellow('[id=12]') + '.\n'
1219 usage += s * 2 + \
1220 light_green('fav 12 ') + ' will favorite the tweet with ' + \
1221 light_yellow('[id=12]') + '.\n'
1222 usage += s * 2 + \
1223 light_green('ufav 12 ') + ' will unfavorite tweet with ' + \
1224 light_yellow('[id=12]') + '.\n'
1225 usage += s * 2 + \
1226 light_green('del 12 ') + ' will delete tweet with ' + \
1227 light_yellow('[id=12]') + '.\n'
1228 usage += s * 2 + light_green('show image 12') + ' will show image in tweet with ' + \
1229 light_yellow('[id=12]') + ' in your OS\'s image viewer.\n'
1230 usage += s * 2 + light_green('open 12') + ' will open url in tweet with ' + \
1231 light_yellow('[id=12]') + ' in your OS\'s default browser.\n'
1232 printNicely(usage)
1233
1234
1235 def help_messages():
1236 """
1237 Messages
1238 """
1239 s = ' ' * 2
1240 # Direct message
1241 usage = '\n'
1242 usage += s + grey(u'\u266A' + ' Direct messages \n')
1243 usage += s * 2 + light_green('inbox') + ' will show inbox messages. ' + \
1244 light_green('inbox 7') + ' will show newest 7 messages.\n'
1245 usage += s * 2 + light_green('sent') + ' will show sent messages. ' + \
1246 light_green('sent 7') + ' will show newest 7 messages.\n'
1247 usage += s * 2 + light_green('mes @dtvd88 hi') + ' will send a "hi" messege to ' + \
1248 magenta('@dtvd88') + '.\n'
1249 usage += s * 2 + light_green('trash 5') + ' will remove message with ' + \
1250 light_yellow('[message_id=5]') + '.\n'
1251 printNicely(usage)
1252
1253
1254 def help_friends_and_followers():
1255 """
1256 Friends and Followers
1257 """
1258 s = ' ' * 2
1259 # Follower and following
1260 usage = '\n'
1261 usage += s + grey(u'\u266A' + ' Friends and followers \n')
1262 usage += s * 2 + \
1263 light_green('ls fl') + \
1264 ' will list all followers (people who are following you).\n'
1265 usage += s * 2 + \
1266 light_green('ls fr') + \
1267 ' will list all friends (people who you are following).\n'
1268 usage += s * 2 + light_green('fl @dtvd88') + ' will follow ' + \
1269 magenta('@dtvd88') + '.\n'
1270 usage += s * 2 + light_green('ufl @dtvd88') + ' will unfollow ' + \
1271 magenta('@dtvd88') + '.\n'
1272 usage += s * 2 + light_green('mute @dtvd88') + ' will mute ' + \
1273 magenta('@dtvd88') + '.\n'
1274 usage += s * 2 + light_green('unmute @dtvd88') + ' will unmute ' + \
1275 magenta('@dtvd88') + '.\n'
1276 usage += s * 2 + light_green('muting') + ' will list muting users.\n'
1277 usage += s * 2 + light_green('block @dtvd88') + ' will block ' + \
1278 magenta('@dtvd88') + '.\n'
1279 usage += s * 2 + light_green('unblock @dtvd88') + ' will unblock ' + \
1280 magenta('@dtvd88') + '.\n'
1281 usage += s * 2 + light_green('report @dtvd88') + ' will report ' + \
1282 magenta('@dtvd88') + ' as a spam account.\n'
1283 printNicely(usage)
1284
1285
1286 def help_list():
1287 """
1288 Lists
1289 """
1290 s = ' ' * 2
1291 # Twitter list
1292 usage = '\n'
1293 usage += s + grey(u'\u266A' + ' Twitter list\n')
1294 usage += s * 2 + light_green('list') + \
1295 ' will show all lists you are belong to.\n'
1296 usage += s * 2 + light_green('list home') + \
1297 ' will show timeline of list. You will be asked for list\'s name.\n'
1298 usage += s * 2 + light_green('list all_mem') + \
1299 ' will show list\'s all members.\n'
1300 usage += s * 2 + light_green('list all_sub') + \
1301 ' will show list\'s all subscribers.\n'
1302 usage += s * 2 + light_green('list add') + \
1303 ' will add specific person to a list owned by you.' + \
1304 ' You will be asked for list\'s name and person\'s name.\n'
1305 usage += s * 2 + light_green('list rm') + \
1306 ' will remove specific person from a list owned by you.' + \
1307 ' You will be asked for list\'s name and person\'s name.\n'
1308 usage += s * 2 + light_green('list sub') + \
1309 ' will subscribe you to a specific list.\n'
1310 usage += s * 2 + light_green('list unsub') + \
1311 ' will unsubscribe you from a specific list.\n'
1312 usage += s * 2 + light_green('list own') + \
1313 ' will show all list owned by you.\n'
1314 usage += s * 2 + light_green('list new') + \
1315 ' will create a new list.\n'
1316 usage += s * 2 + light_green('list update') + \
1317 ' will update a list owned by you.\n'
1318 usage += s * 2 + light_green('list del') + \
1319 ' will delete a list owned by you.\n'
1320 printNicely(usage)
1321
1322
1323 def help_stream():
1324 """
1325 Stream switch
1326 """
1327 s = ' ' * 2
1328 # Switch
1329 usage = '\n'
1330 usage += s + grey(u'\u266A' + ' Switching streams \n')
1331 usage += s * 2 + light_green('switch public #AKB') + \
1332 ' will switch to public stream and follow "' + \
1333 light_yellow('AKB') + '" keyword.\n'
1334 usage += s * 2 + light_green('switch mine') + \
1335 ' will switch to your personal stream.\n'
1336 usage += s * 2 + light_green('switch mine -f ') + \
1337 ' will prompt to enter the filter.\n'
1338 usage += s * 3 + light_yellow('Only nicks') + \
1339 ' filter will decide nicks will be INCLUDE ONLY.\n'
1340 usage += s * 3 + light_yellow('Ignore nicks') + \
1341 ' filter will decide nicks will be EXCLUDE.\n'
1342 usage += s * 2 + light_green('switch mine -d') + \
1343 ' will use the config\'s ONLY_LIST and IGNORE_LIST.\n'
1344 printNicely(usage)
1345
1346
1347 def help():
1348 """
1349 Help
1350 """
1351 s = ' ' * 2
1352 h, w = os.popen('stty size', 'r').read().split()
1353
1354 # Start
1355 usage = '\n'
1356 usage += s + 'Hi boss! I\'m ready to serve you right now!\n'
1357 usage += s + '-' * (int(w) - 4) + '\n'
1358 usage += s + 'You are ' + \
1359 light_yellow('already') + ' on your personal stream.\n'
1360 usage += s + 'Any update from Twitter will show up ' + \
1361 light_yellow('immediately') + '.\n'
1362 usage += s + 'In addtion, following commands are available right now:\n'
1363
1364 # Twitter help section
1365 usage += '\n'
1366 usage += s + grey(u'\u266A' + ' Twitter help\n')
1367 usage += s * 2 + light_green('h discover') + \
1368 ' will show help for discover commands.\n'
1369 usage += s * 2 + light_green('h tweets') + \
1370 ' will show help for tweets commands.\n'
1371 usage += s * 2 + light_green('h messages') + \
1372 ' will show help for messages commands.\n'
1373 usage += s * 2 + light_green('h friends_and_followers') + \
1374 ' will show help for friends and followers commands.\n'
1375 usage += s * 2 + light_green('h list') + \
1376 ' will show help for list commands.\n'
1377 usage += s * 2 + light_green('h stream') + \
1378 ' will show help for stream commands.\n'
1379
1380 # Smart shell
1381 usage += '\n'
1382 usage += s + grey(u'\u266A' + ' Smart shell\n')
1383 usage += s * 2 + light_green('111111 * 9 / 7') + ' or any math expression ' + \
1384 'will be evaluate by Python interpreter.\n'
1385 usage += s * 2 + 'Even ' + light_green('cal') + ' will show the calendar' + \
1386 ' for current month.\n'
1387
1388 # Config
1389 usage += '\n'
1390 usage += s + grey(u'\u266A' + ' Config \n')
1391 usage += s * 2 + light_green('theme') + ' will list available theme. ' + \
1392 light_green('theme monokai') + ' will apply ' + light_yellow('monokai') + \
1393 ' theme immediately.\n'
1394 usage += s * 2 + light_green('config') + ' will list all config.\n'
1395 usage += s * 3 + \
1396 light_green('config ASCII_ART') + ' will output current value of ' +\
1397 light_yellow('ASCII_ART') +' config key.\n'
1398 usage += s * 3 + \
1399 light_green('config ASCII_ART default') + ' will output default value of ' + \
1400 light_yellow('ASCII_ART') +' config key.\n'
1401 usage += s * 3 + \
1402 light_green('config ASCII_ART = False') + ' will set value of ' + \
1403 light_yellow('ASCII_ART') +' config key to ' + light_yellow('False') + '.\n'
1404
1405 # Screening
1406 usage += '\n'
1407 usage += s + grey(u'\u266A' + ' Screening \n')
1408 usage += s * 2 + light_green('h') + ' will show this help again.\n'
1409 usage += s * 2 + light_green('c') + ' will clear the screen.\n'
1410 usage += s * 2 + light_green('q') + ' will quit.\n'
1411
1412 # End
1413 usage += '\n'
1414 usage += s + '-' * (int(w) - 4) + '\n'
1415 usage += s + 'Have fun and hang tight! \n'
1416
1417 # Show help
1418 d = {
1419 'discover': help_discover,
1420 'tweets': help_tweets,
1421 'messages': help_messages,
1422 'friends_and_followers': help_friends_and_followers,
1423 'list': help_list,
1424 'stream': help_stream,
1425 }
1426 if g['stuff']:
1427 d[g['stuff'].strip()]()
1428 else:
1429 printNicely(usage)
1430
1431
1432 def clear():
1433 """
1434 Clear screen
1435 """
1436 os.system('clear')
1437
1438
1439 def quit():
1440 """
1441 Exit all
1442 """
1443 save_history()
1444 os.system('rm -rf rainbow.db')
1445 os.kill(g['stream_pid'], signal.SIGKILL)
1446 sys.exit()
1447
1448
1449 def reset():
1450 """
1451 Reset prefix of line
1452 """
1453 if g['reset']:
1454 printNicely(magenta('Need tips ? Type "h" and hit Enter key!'))
1455 g['reset'] = False
1456 try:
1457 printNicely(str(eval(g['cmd'])))
1458 except Exception:
1459 pass
1460
1461
1462 def process(cmd):
1463 """
1464 Process switch
1465 """
1466 return dict(zip(
1467 cmdset,
1468 [
1469 switch,
1470 trend,
1471 home,
1472 view,
1473 mentions,
1474 tweet,
1475 retweet,
1476 quote,
1477 allretweet,
1478 favorite,
1479 reply,
1480 delete,
1481 unfavorite,
1482 search,
1483 message,
1484 show,
1485 urlopen,
1486 ls,
1487 inbox,
1488 sent,
1489 trash,
1490 whois,
1491 follow,
1492 unfollow,
1493 mute,
1494 unmute,
1495 muting,
1496 block,
1497 unblock,
1498 report,
1499 list,
1500 cal,
1501 config,
1502 theme,
1503 help,
1504 clear,
1505 quit
1506 ]
1507 )).get(cmd, reset)
1508
1509
1510 def listen():
1511 """
1512 Listen to user's input
1513 """
1514 d = dict(zip(
1515 cmdset,
1516 [
1517 ['public', 'mine'], # switch
1518 [], # trend
1519 [], # home
1520 ['@'], # view
1521 [], # mentions
1522 [], # tweet
1523 [], # retweet
1524 [], # quote
1525 [], # allretweet
1526 [], # favorite
1527 [], # reply
1528 [], # delete
1529 [], # unfavorite
1530 ['#'], # search
1531 ['@'], # message
1532 ['image'], # show image
1533 [''], # open url
1534 ['fl', 'fr'], # list
1535 [], # inbox
1536 [], # sent
1537 [], # trash
1538 ['@'], # whois
1539 ['@'], # follow
1540 ['@'], # unfollow
1541 ['@'], # mute
1542 ['@'], # unmute
1543 ['@'], # muting
1544 ['@'], # block
1545 ['@'], # unblock
1546 ['@'], # report
1547 [
1548 'home',
1549 'all_mem',
1550 'all_sub',
1551 'add',
1552 'rm',
1553 'sub',
1554 'unsub',
1555 'own',
1556 'new',
1557 'update',
1558 'del'
1559 ], # list
1560 [], # cal
1561 [key for key in dict(get_all_config())], # config
1562 g['themes'] + ['current_as_default'], # theme
1563 [
1564 'discover',
1565 'tweets',
1566 'messages',
1567 'friends_and_followers',
1568 'list',
1569 'stream'
1570 ], # help
1571 [], # clear
1572 [], # quit
1573 ]
1574 ))
1575 init_interactive_shell(d)
1576 read_history()
1577 reset()
1578 while True:
1579 if g['prefix']:
1580 line = raw_input(g['decorated_name'])
1581 else:
1582 line = raw_input()
1583 try:
1584 cmd = line.split()[0]
1585 except:
1586 cmd = ''
1587 g['cmd'] = cmd
1588 try:
1589 # Lock the semaphore
1590 db.semaphore_update(True)
1591 # Save cmd to global variable and call process
1592 g['stuff'] = ' '.join(line.split()[1:])
1593 # Process the command
1594 process(cmd)()
1595 # Not re-display
1596 if cmd in ['switch', 't', 'rt', 'rep']:
1597 g['prefix'] = False
1598 else:
1599 g['prefix'] = True
1600 # Release the semaphore lock
1601 db.semaphore_update(False)
1602 except Exception:
1603 printNicely(red('OMG something is wrong with Twitter right now.'))
1604
1605
1606 def stream(domain, args, name='Rainbow Stream'):
1607 """
1608 Track the stream
1609 """
1610
1611 # The Logo
1612 art_dict = {
1613 c['USER_DOMAIN']: name,
1614 c['PUBLIC_DOMAIN']: args.track_keywords,
1615 c['SITE_DOMAIN']: name,
1616 }
1617 if c['ASCII_ART']:
1618 ascii_art(art_dict[domain])
1619
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
1632 stream = TwitterStream(
1633 auth=authen(),
1634 domain=domain,
1635 **stream_args)
1636
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)
1642 else:
1643 if args.track_keywords:
1644 tweet_iter = stream.statuses.filter(**query_args)
1645 else:
1646 tweet_iter = stream.statuses.sample()
1647
1648 # Iterate over the stream.
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 check_semaphore=True,
1664 fil=args.filter,
1665 ig=args.ignore,
1666 )
1667 except TwitterHTTPError:
1668 printNicely('')
1669 printNicely(
1670 magenta("We have maximum connection problem with twitter'stream API right now :("))
1671
1672
1673 def fly():
1674 """
1675 Main function
1676 """
1677 # Spawn stream process
1678 args = parse_arguments()
1679 try:
1680 get_decorated_name()
1681
1682 except TwitterHTTPError:
1683 printNicely('')
1684 printNicely(
1685 magenta("Something wrong with Twitter Oauth right now :("))
1686 printNicely(
1687 magenta("Please delete ~/.rainbow_oauth and try again."))
1688 save_history()
1689 os.system('rm -rf rainbow.db')
1690 sys.exit()
1691
1692 p = Process(
1693 target=stream,
1694 args=(
1695 c['USER_DOMAIN'],
1696 args,
1697 g['original_name']))
1698 p.start()
1699
1700 # Start listen process
1701 time.sleep(0.5)
1702 g['reset'] = True
1703 g['prefix'] = True
1704 g['stream_pid'] = p.pid
1705 g['iot'] = args.image_on_term
1706 listen()