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