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