add various tweet api
[rainbowstream.git] / rainbowstream / rainbow.py
CommitLineData
91476ec3
O
1"""
2Colorful user's timeline stream
3"""
78b81730
O
4from multiprocessing import Process
5from dateutil import parser
6
b2b933a9 7import os
8import os.path
9import sys
10import signal
11import argparse
12import time
13import datetime
991c30af 14import requests
91476ec3 15
91476ec3 16from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup
54277114 17from twitter.api import *
91476ec3 18from twitter.oauth import OAuth, read_token_file
8c840a83 19from twitter.oauth_dance import oauth_dance
91476ec3 20from twitter.util import printNicely
991c30af 21from StringIO import StringIO
91476ec3 22
2a6238f5
O
23from .colors import *
24from .config import *
777c52d4 25from .consumer import *
94a5f62e 26from .interactive import *
18cab06a 27from .db import *
991c30af 28from .c_image import *
2a6238f5 29
f405a7d0 30g = {}
18cab06a 31db = RainbowDB()
94a5f62e 32cmdset = [
42fde775 33 'switch',
94a5f62e 34 'home',
35 'view',
305ce127 36 'mentions',
94a5f62e 37 't',
38 'rt',
7e4ccbf3 39 'fav',
94a5f62e 40 'rep',
41 'del',
7e4ccbf3 42 'ufav',
94a5f62e 43 's',
305ce127 44 'mes',
f5677fb1 45 'show',
0f6e4daf 46 'ls',
305ce127 47 'inbox',
48 'sent',
49 'trash',
94a5f62e 50 'fl',
f5677fb1 51 'ufl',
305ce127 52 'block',
53 'unblock',
54 'report',
94a5f62e 55 'h',
56 'c',
57 'q'
58]
22be990e 59
b2b933a9 60
c1fa7c94 61def draw(t, iot=False, keyword=None, fil=[], ig=[]):
91476ec3
O
62 """
63 Draw the rainbow
64 """
d51b4107 65
91476ec3 66 # Retrieve tweet
829cc2d8 67 tid = t['id']
91476ec3
O
68 text = t['text']
69 screen_name = t['user']['screen_name']
70 name = t['user']['name']
71 created_at = t['created_at']
7e4ccbf3 72 favorited = t['favorited']
91476ec3 73 date = parser.parse(created_at)
e20af1c3 74 date = date - datetime.timedelta(seconds=time.timezone)
75 clock = date.strftime('%Y/%m/%d %H:%M:%S')
91476ec3 76
991c30af
O
77 # Get expanded url
78 try:
79 expanded_url = []
80 url = []
81 urls = t['entities']['urls']
82 for u in urls:
83 expanded_url.append(u['expanded_url'])
84 url.append(u['url'])
85 except:
86 expanded_url = None
87 url = None
88
89 # Get media
90 try:
91 media_url = []
92 media = t['entities']['media']
93 for m in media:
f5677fb1 94 media_url.append(m['media_url'])
991c30af
O
95 except:
96 media_url = None
97
d51b4107
O
98 # Filter and ignore
99 screen_name = '@' + screen_name
100 if fil and screen_name not in fil:
101 return
102 if ig and screen_name in ig:
103 return
104
305ce127 105 # Get rainbow id
106 res = db.tweet_to_rainbow_query(tid)
18cab06a 107 if not res:
305ce127 108 db.tweet_store(tid)
109 res = db.tweet_to_rainbow_query(tid)
18cab06a
O
110 rid = res[0].rainbow_id
111
91476ec3 112 # Format info
d51b4107 113 user = cycle_color(name) + grey(' ' + screen_name + ' ')
7e4ccbf3 114 meta = grey('[' + clock + '] [id=' + str(rid) + '] ')
115 if favorited:
116 meta = meta + green(u'\u2605')
8c840a83 117 tweet = text.split()
991c30af
O
118 # Replace url
119 if expanded_url:
120 for index in range(len(expanded_url)):
121 tweet = map(
122 lambda x: expanded_url[index] if x == url[index] else x,
123 tweet)
b8dda704 124 # Highlight RT
2a6238f5 125 tweet = map(lambda x: grey(x) if x == 'RT' else x, tweet)
b8dda704 126 # Highlight screen_name
2a6238f5 127 tweet = map(lambda x: cycle_color(x) if x[0] == '@' else x, tweet)
b8dda704 128 # Highlight link
2a6238f5 129 tweet = map(lambda x: cyan(x) if x[0:7] == 'http://' else x, tweet)
b8dda704 130 # Highlight search keyword
7a431249 131 if keyword:
22be990e 132 tweet = map(
133 lambda x: on_yellow(x) if
134 ''.join(c for c in x if c.isalnum()).lower() == keyword.lower()
135 else x,
136 tweet
137 )
991c30af 138 # Recreate tweet
8c840a83 139 tweet = ' '.join(tweet)
91476ec3
O
140
141 # Draw rainbow
06773ffe 142 line1 = u"{u:>{uw}}:".format(
2a6238f5
O
143 u=user,
144 uw=len(user) + 2,
91476ec3 145 )
06773ffe 146 line2 = u"{c:>{cw}}".format(
829cc2d8
O
147 c=meta,
148 cw=len(meta) + 2,
06773ffe
O
149 )
150 line3 = ' ' + tweet
91476ec3 151
94a5f62e 152 printNicely('')
f405a7d0
O
153 printNicely(line1)
154 printNicely(line2)
155 printNicely(line3)
91476ec3 156
991c30af 157 # Display Image
c1fa7c94 158 if iot and media_url:
f5677fb1
O
159 for mu in media_url:
160 response = requests.get(mu)
161 image_to_display(StringIO(response.content))
991c30af 162
91476ec3 163
305ce127 164def print_message(m):
165 """
166 Print direct message
167 """
168 screen_name = '@' + m['sender_screen_name']
169 name = m['sender']['name']
170 text = m['text']
171 mid = m['id']
172 date = parser.parse(m['created_at'])
173 date = date - datetime.timedelta(seconds=time.timezone)
174 clock = date.strftime('%Y/%m/%d %H:%M:%S')
175
176 # Get rainbow id
177 res = db.message_to_rainbow_query(mid)
178 if not res:
179 db.message_store(mid)
180 res = db.message_to_rainbow_query(mid)
181 rid = res[0].rainbow_id
182
183 user = cycle_color(name) + grey(' ' + screen_name + ' ')
184 meta = grey('[' + clock + '] [message_id=' + str(rid) + '] ')
185 text = ''.join(map(lambda x: x+' ' if x=='\n' else x,text))
186
187 line1 = u"{u:>{uw}}:".format(
188 u=user,
189 uw=len(user) + 2,
190 )
191 line2 = u"{c:>{cw}}".format(
192 c=meta,
193 cw=len(meta) + 2,
194 )
195
196 line3 = ' ' + text
197
198 printNicely('')
199 printNicely(line1)
200 printNicely(line2)
201 printNicely(line3)
202
203
91476ec3
O
204def parse_arguments():
205 """
206 Parse the arguments
207 """
91476ec3 208 parser = argparse.ArgumentParser(description=__doc__ or "")
2a6238f5
O
209 parser.add_argument(
210 '-to',
211 '--timeout',
212 help='Timeout for the stream (seconds).')
213 parser.add_argument(
214 '-ht',
215 '--heartbeat-timeout',
216 help='Set heartbeat timeout.',
217 default=90)
218 parser.add_argument(
219 '-nb',
220 '--no-block',
221 action='store_true',
222 help='Set stream to non-blocking.')
223 parser.add_argument(
224 '-tt',
225 '--track-keywords',
226 help='Search the stream for specific text.')
d51b4107
O
227 parser.add_argument(
228 '-fil',
229 '--filter',
230 help='Filter specific screen_name.')
231 parser.add_argument(
232 '-ig',
233 '--ignore',
234 help='Ignore specific screen_name.')
88af38d8 235 parser.add_argument(
c1fa7c94
O
236 '-iot',
237 '--image-on-term',
238 action='store_true',
239 help='Display all image on terminal.')
91476ec3
O
240 return parser.parse_args()
241
242
54277114
O
243def authen():
244 """
7b674cef 245 Authenticate with Twitter OAuth
54277114 246 """
8c840a83 247 # When using rainbow stream you must authorize.
2a6238f5
O
248 twitter_credential = os.environ.get(
249 'HOME',
250 os.environ.get(
251 'USERPROFILE',
252 '')) + os.sep + '.rainbow_oauth'
8c840a83
O
253 if not os.path.exists(twitter_credential):
254 oauth_dance("Rainbow Stream",
255 CONSUMER_KEY,
256 CONSUMER_SECRET,
257 twitter_credential)
258 oauth_token, oauth_token_secret = read_token_file(twitter_credential)
54277114 259 return OAuth(
2a6238f5
O
260 oauth_token,
261 oauth_token_secret,
262 CONSUMER_KEY,
263 CONSUMER_SECRET)
91476ec3 264
54277114
O
265
266def get_decorated_name():
267 """
268 Beginning of every line
269 """
270 t = Twitter(auth=authen())
c5ff542b 271 name = '@' + t.account.verify_credentials()['screen_name']
42fde775 272 g['original_name'] = name[1:]
f405a7d0 273 g['decorated_name'] = grey('[') + grey(name) + grey(']: ')
54277114 274
f405a7d0 275
42fde775 276def switch():
277 """
278 Switch stream
279 """
280 try:
281 target = g['stuff'].split()[0]
282
d51b4107
O
283 # Filter and ignore
284 args = parse_arguments()
7e4ccbf3 285 try:
d51b4107
O
286 if g['stuff'].split()[-1] == '-f':
287 only = raw_input('Only nicks: ')
288 ignore = raw_input('Ignore nicks: ')
7e4ccbf3 289 args.filter = filter(None, only.split(','))
290 args.ignore = filter(None, ignore.split(','))
d51b4107
O
291 elif g['stuff'].split()[-1] == '-d':
292 args.filter = ONLY_LIST
293 args.ignore = IGNORE_LIST
294 except:
295 printNicely(red('Sorry, wrong format.'))
296 return
297
42fde775 298 # Public stream
299 if target == 'public':
300 keyword = g['stuff'].split()[1]
301 if keyword[0] == '#':
302 keyword = keyword[1:]
42fde775 303 # Kill old process
304 os.kill(g['stream_pid'], signal.SIGKILL)
42fde775 305 args.track_keywords = keyword
42fde775 306 # Start new process
307 p = Process(
d51b4107 308 target=stream,
42fde775 309 args=(
d51b4107 310 PUBLIC_DOMAIN,
42fde775 311 args))
312 p.start()
313 g['stream_pid'] = p.pid
314
315 # Personal stream
316 elif target == 'mine':
42fde775 317 # Kill old process
318 os.kill(g['stream_pid'], signal.SIGKILL)
42fde775 319 # Start new process
320 p = Process(
321 target=stream,
322 args=(
323 USER_DOMAIN,
324 args,
325 g['original_name']))
326 p.start()
327 g['stream_pid'] = p.pid
d51b4107 328 printNicely('')
1551a7d3 329 printNicely(green('Stream switched.'))
d51b4107
O
330 if args.filter:
331 printNicely(cyan('Only: ' + str(args.filter)))
332 if args.ignore:
333 printNicely(red('Ignore: ' + str(args.ignore)))
334 printNicely('')
42fde775 335 except:
336 printNicely(red('Sorry I can\'t understand.'))
42fde775 337
338
7b674cef 339def home():
340 """
341 Home
342 """
343 t = Twitter(auth=authen())
94a5f62e 344 num = HOME_TWEET_NUM
7b674cef 345 if g['stuff'].isdigit():
305ce127 346 num = int(g['stuff'])
94a5f62e 347 for tweet in reversed(t.statuses.home_timeline(count=num)):
c1fa7c94 348 draw(t=tweet, iot=g['iot'])
94a5f62e 349 printNicely('')
7b674cef 350
351
352def view():
353 """
354 Friend view
355 """
356 t = Twitter(auth=authen())
357 user = g['stuff'].split()[0]
b8fbcb70 358 if user[0] == '@':
359 try:
94a5f62e 360 num = int(g['stuff'].split()[1])
b8fbcb70 361 except:
94a5f62e 362 num = HOME_TWEET_NUM
363 for tweet in reversed(t.statuses.user_timeline(count=num, screen_name=user[1:])):
c1fa7c94 364 draw(t=tweet, iot=g['iot'])
94a5f62e 365 printNicely('')
b8fbcb70 366 else:
c91f75f2 367 printNicely(red('A name should begin with a \'@\''))
7b674cef 368
369
305ce127 370def mentions():
371 """
372 Mentions timeline
373 """
374 t = Twitter(auth=authen())
375 num = HOME_TWEET_NUM
376 if g['stuff'].isdigit():
377 num = int(g['stuff'])
378 for tweet in reversed(t.statuses.mentions_timeline(count=num)):
379 draw(t=tweet, iot=g['iot'])
380 printNicely('')
381
382
f405a7d0 383def tweet():
54277114 384 """
7b674cef 385 Tweet
54277114
O
386 """
387 t = Twitter(auth=authen())
f405a7d0 388 t.statuses.update(status=g['stuff'])
f405a7d0 389
b2b933a9 390
1ba4abfd
O
391def retweet():
392 """
393 ReTweet
394 """
395 t = Twitter(auth=authen())
396 try:
397 id = int(g['stuff'].split()[0])
305ce127 398 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
b2b933a9 399 t.statuses.retweet(id=tid, include_entities=False, trim_user=True)
1ba4abfd 400 except:
c91f75f2 401 printNicely(red('Sorry I can\'t retweet for you.'))
1ba4abfd
O
402
403
7e4ccbf3 404def favorite():
405 """
406 Favorite
407 """
408 t = Twitter(auth=authen())
409 try:
410 id = int(g['stuff'].split()[0])
305ce127 411 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
7e4ccbf3 412 t.favorites.create(_id=tid, include_entities=False)
413 printNicely(green('Favorited.'))
c1fa7c94 414 draw(t.statuses.show(id=tid), iot=g['iot'])
7e4ccbf3 415 except:
416 printNicely(red('Omg some syntax is wrong.'))
417
418
7b674cef 419def reply():
829cc2d8 420 """
7b674cef 421 Reply
829cc2d8
O
422 """
423 t = Twitter(auth=authen())
7b674cef 424 try:
425 id = int(g['stuff'].split()[0])
305ce127 426 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
18cab06a 427 user = t.statuses.show(id=tid)['user']['screen_name']
7b674cef 428 status = ' '.join(g['stuff'].split()[1:])
429 status = '@' + user + ' ' + status.decode('utf-8')
18cab06a 430 t.statuses.update(status=status, in_reply_to_status_id=tid)
7b674cef 431 except:
c91f75f2 432 printNicely(red('Sorry I can\'t understand.'))
7b674cef 433
434
435def delete():
436 """
437 Delete
438 """
439 t = Twitter(auth=authen())
440 try:
305ce127 441 rid = int(g['stuff'].split()[0])
442 tid = db.rainbow_to_tweet_query(rid)[0].tweet_id
18cab06a 443 t.statuses.destroy(id=tid)
c91f75f2 444 printNicely(green('Okay it\'s gone.'))
7b674cef 445 except:
305ce127 446 printNicely(red('Sorry I can\'t understand.'))
829cc2d8
O
447
448
7e4ccbf3 449def unfavorite():
450 """
451 Unfavorite
452 """
453 t = Twitter(auth=authen())
454 try:
455 id = int(g['stuff'].split()[0])
305ce127 456 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
7e4ccbf3 457 t.favorites.destroy(_id=tid)
458 printNicely(green('Okay it\'s unfavorited.'))
c1fa7c94 459 draw(t.statuses.show(id=tid), iot=g['iot'])
7e4ccbf3 460 except:
461 printNicely(red('Sorry I can\'t unfavorite this tweet for you.'))
462
463
f405a7d0
O
464def search():
465 """
7b674cef 466 Search
f405a7d0
O
467 """
468 t = Twitter(auth=authen())
94a5f62e 469 try:
470 if g['stuff'][0] == '#':
471 rel = t.search.tweets(q=g['stuff'])['statuses']
c91f75f2 472 if len(rel):
473 printNicely('Newest tweets:')
474 for i in reversed(xrange(SEARCH_MAX_RECORD)):
88af38d8 475 draw(t=rel[i],
0f6e4daf 476 iot=g['iot'],
477 keyword=g['stuff'].strip()[1:])
c91f75f2 478 printNicely('')
479 else:
480 printNicely(magenta('I\'m afraid there is no result'))
94a5f62e 481 else:
c91f75f2 482 printNicely(red('A keyword should be a hashtag (like \'#AKB48\')'))
94a5f62e 483 except:
c91f75f2 484 printNicely(red('Sorry I can\'t understand.'))
b2b933a9 485
f405a7d0 486
305ce127 487def message():
488 """
489 Send a direct message
490 """
491 t = Twitter(auth=authen())
492 user = g['stuff'].split()[0]
493 if user[0] == '@':
494 try:
495 content = g['stuff'].split()[1]
496 t.direct_messages.new(
497 screen_name=user[1:],
498 text=content
499 )
500 printNicely(green('Message sent.'))
501 except:
502 printNicely(red('Sorry I can\'t understand.'))
503 else:
504 printNicely(red('A name should begin with a \'@\''))
505
506
f5677fb1 507def show():
843647ad 508 """
f5677fb1 509 Show image
843647ad
O
510 """
511 t = Twitter(auth=authen())
f5677fb1
O
512 try:
513 target = g['stuff'].split()[0]
514 if target != 'image':
515 return
516 id = int(g['stuff'].split()[1])
305ce127 517 tid = db.rainbow_to_tweet_query(id)[0].tweet_id
f5677fb1
O
518 tweet = t.statuses.show(id=tid)
519 media = tweet['entities']['media']
520 for m in media:
521 res = requests.get(m['media_url'])
522 img = Image.open(StringIO(res.content))
523 img.show()
524 except:
525 printNicely(red('Sorry I can\'t show this image.'))
843647ad
O
526
527
0f6e4daf 528def list():
529 """
530 List friends for followers
531 """
532 t = Twitter(auth=authen())
533 try:
534 target = g['stuff'].split()[0]
535 d = {'fl': 'followers', 'fr': 'friends'}
536 next_cursor = -1
537 rel = {}
538 # Cursor loop
539 while next_cursor != 0:
305ce127 540 list = getattr(t, d[target]).list(
541 screen_name=g['original_name'],
542 cursor=next_cursor,
543 skip_status=True,
544 include_entities=False,
545 )
0f6e4daf 546 for u in list['users']:
547 rel[u['name']] = '@' + u['screen_name']
548 next_cursor = list['next_cursor']
549 # Print out result
550 printNicely('All: ' + str(len(rel)) + ' people.')
551 for name in rel:
552 user = ' ' + cycle_color(name) + grey(' ' + rel[name] + ' ')
553 printNicely(user)
554 except:
555 printNicely(red('Omg some syntax is wrong.'))
556
557
305ce127 558def inbox():
559 """
560 Inbox direct messages
561 """
562 t = Twitter(auth=authen())
563 num = MESSAGES_DISPLAY
564 rel = []
565 if g['stuff'].isdigit():
566 num = g['stuff']
567 cur_page = 1
568 # Max message per page is 20 so we have to loop
569 while num > 20:
570 rel = rel + t.direct_messages(
571 count=20,
572 page=cur_page,
573 include_entities=False,
574 skip_status=False
575 )
576 num -= 20
577 cur_page += 1
578 rel = rel + t.direct_messages(
579 count=num,
580 page=cur_page,
581 include_entities=False,
582 skip_status=False
583 )
584 # Display
585 printNicely('Inbox: newest ' + str(len(rel)) + ' messages.')
586 for m in reversed(rel):
587 print_message(m)
588 printNicely('')
589
590
591def sent():
592 """
593 Sent direct messages
594 """
595 t = Twitter(auth=authen())
596 num = MESSAGES_DISPLAY
597 rel = []
598 if g['stuff'].isdigit():
599 num = int(g['stuff'])
600 cur_page = 1
601 # Max message per page is 20 so we have to loop
602 while num > 20:
603 rel = rel + t.direct_messages.sent(
604 count=20,
605 page=cur_page,
606 include_entities=False,
607 skip_status=False
608 )
609 num -= 20
610 cur_page += 1
611 rel = rel + t.direct_messages.sent(
612 count=num,
613 page=cur_page,
614 include_entities=False,
615 skip_status=False
616 )
617 # Display
618 printNicely('Sent: newest ' + str(len(rel)) + ' messages.')
619 for m in reversed(rel):
620 print_message(m)
621 printNicely('')
622
623
624def trash():
625 """
626 Remove message
627 """
628 t = Twitter(auth=authen())
629 try:
630 rid = int(g['stuff'].split()[0])
631 mid = db.rainbow_to_message_query(rid)[0].message_id
632 t.direct_messages.destroy(id=mid)
633 printNicely(green('Message deleted.'))
634 except:
635 printNicely(red('Sorry I can\'t understand.'))
636
637
f5677fb1 638def follow():
843647ad 639 """
f5677fb1 640 Follow a user
843647ad
O
641 """
642 t = Twitter(auth=authen())
f5677fb1
O
643 screen_name = g['stuff'].split()[0]
644 if screen_name[0] == '@':
0f6e4daf 645 try:
646 t.friendships.create(screen_name=screen_name[1:], follow=True)
f5677fb1
O
647 printNicely(green('You are following ' + screen_name + ' now!'))
648 except:
649 printNicely(red('Sorry can not follow at this time.'))
650 else:
651 printNicely(red('Sorry I can\'t understand.'))
652
653
654def unfollow():
655 """
656 Unfollow a user
657 """
658 t = Twitter(auth=authen())
659 screen_name = g['stuff'].split()[0]
660 if screen_name[0] == '@':
0f6e4daf 661 try:
662 t.friendships.destroy(
305ce127 663 screen_name=screen_name[1:],
0f6e4daf 664 include_entities=False)
f5677fb1
O
665 printNicely(green('Unfollow ' + screen_name + ' success!'))
666 except:
667 printNicely(red('Sorry can not unfollow at this time.'))
668 else:
669 printNicely(red('Sorry I can\'t understand.'))
843647ad
O
670
671
305ce127 672def block():
673 """
674 Block a user
675 """
676 t = Twitter(auth=authen())
677 screen_name = g['stuff'].split()[0]
678 if screen_name[0] == '@':
679 try:
680 t.blocks.create(
681 screen_name=screen_name[1:],
682 include_entities=False,
683 skip_status=True)
684 printNicely(green('You blocked ' + screen_name + '.'))
685 except:
686 printNicely(red('Sorry something went wrong.'))
687 else:
688 printNicely(red('Sorry I can\'t understand.'))
689
690
691def unblock():
692 """
693 Unblock a user
694 """
695 t = Twitter(auth=authen())
696 screen_name = g['stuff'].split()[0]
697 if screen_name[0] == '@':
698 try:
699 t.blocks.destroy(
700 screen_name=screen_name[1:],
701 include_entities=False,
702 skip_status=True)
703 printNicely(green('Unblock ' + screen_name + ' success!'))
704 except:
705 printNicely(red('Sorry something went wrong.'))
706 else:
707 printNicely(red('Sorry I can\'t understand.'))
708
709
710def report():
711 """
712 Report a user as a spam account
713 """
714 t = Twitter(auth=authen())
715 screen_name = g['stuff'].split()[0]
716 if screen_name[0] == '@':
717 try:
718 t.users.report_spam(
719 screen_name=screen_name[1:])
720 printNicely(green('You reported ' + screen_name + '.'))
721 except:
722 printNicely(red('Sorry something went wrong.'))
723 else:
724 printNicely(red('Sorry I can\'t understand.'))
725
726
f405a7d0
O
727def help():
728 """
7b674cef 729 Help
f405a7d0 730 """
7e4ccbf3 731 s = ' ' * 2
732 h, w = os.popen('stty size', 'r').read().split()
e3885f55
O
733
734 usage = '\n'
735 usage += s + 'Hi boss! I\'m ready to serve you right now!\n'
7e4ccbf3 736 usage += s + '-' * (int(w) - 4) + '\n'
737
738 usage += s + 'You are ' + yellow('already') + ' on your personal stream.\n'
739 usage += s * 2 + green('switch public #AKB') + \
740 ' will switch to public stream and follow "' + \
741 yellow('AKB') + '" keyword.\n'
742 usage += s * 2 + green('switch mine') + \
743 ' will switch to your personal stream.\n'
744 usage += s * 2 + green('switch mine -f ') + \
745 ' will prompt to enter the filter.\n'
746 usage += s * 3 + yellow('Only nicks') + \
747 ' filter will decide nicks will be INCLUDE ONLY.\n'
748 usage += s * 3 + yellow('Ignore nicks') + \
749 ' filter will decide nicks will be EXCLUDE.\n'
750 usage += s * 2 + green('switch mine -d') + \
751 ' will use the config\'s ONLY_LIST and IGNORE_LIST.\n'
752 usage += s * 3 + '(see ' + grey('rainbowstream/config.py') + ').\n'
e3885f55
O
753
754 usage += s + 'For more action: \n'
7e4ccbf3 755 usage += s * 2 + green('home') + ' will show your timeline. ' + \
305ce127 756 green('home 7') + ' will show 7 tweets.\n'
7e4ccbf3 757 usage += s * 2 + green('view @mdo') + \
305ce127 758 ' will show ' + magenta('@mdo') + '\'s home.\n'
759 usage += s * 2 + green('mentions') + ' will show mentions timeline. ' + \
760 green('mentions 7') + ' will show 7 mentions tweets.\n'
7e4ccbf3 761 usage += s * 2 + green('t oops ') + \
762 'will tweet "' + yellow('oops') + '" immediately.\n'
763 usage += s * 2 + \
764 green('rt 12 ') + ' will retweet to tweet with ' + \
765 yellow('[id=12]') + '.\n'
766 usage += s * 2 + \
767 green('fav 12 ') + ' will favorite the tweet with ' + \
768 yellow('[id=12]') + '.\n'
769 usage += s * 2 + green('rep 12 oops') + ' will reply "' + \
770 yellow('oops') + '" to tweet with ' + yellow('[id=12]') + '.\n'
771 usage += s * 2 + \
772 green('del 12 ') + ' will delete tweet with ' + \
773 yellow('[id=12]') + '.\n'
774 usage += s * 2 + \
775 green('ufav 12 ') + ' will unfavorite tweet with ' + \
776 yellow('[id=12]') + '.\n'
777 usage += s * 2 + green('s #AKB48') + ' will search for "' + \
778 yellow('AKB48') + '" and return 5 newest tweet.\n'
305ce127 779 usage += s * 2 + green('mes @dtvd88 hi') + ' will send a "hi" messege to ' + \
780 magenta('@dtvd88') + '.\n'
a99b7b04
O
781 usage += s * 2 + green('show image 12') + ' will show image in tweet with ' + \
782 yellow('[id=12]') + ' in your OS\'s image viewer.\n'
0f6e4daf 783 usage += s * 2 + \
784 green('ls fl') + \
b5f92888 785 ' will list all followers (people who are following you).\n'
0f6e4daf 786 usage += s * 2 + \
787 green('ls fr') + \
788 ' will list all friends (people who you are following).\n'
305ce127 789 usage += s * 2 + green('inbox') + ' will show inbox messages. ' + \
790 green('inbox 7') + ' will show newest 7 messages.\n'
791 usage += s * 2 + green('sent') + ' will show sent messages. ' + \
792 green('sent 7') + ' will show newest 7 messages.\n'
793 usage += s * 2 + green('trash 5') + ' will remove message with ' + \
794 yellow('[message_id=5]') + '.\n'
f5677fb1 795 usage += s * 2 + green('fl @dtvd88') + ' will follow ' + \
305ce127 796 magenta('@dtvd88') + '.\n'
f5677fb1 797 usage += s * 2 + green('ufl @dtvd88') + ' will unfollow ' + \
305ce127 798 magenta('@dtvd88') + '.\n'
799 usage += s * 2 + green('block @dtvd88') + ' will block ' + \
800 magenta('@dtvd88') + '.\n'
801 usage += s * 2 + green('unblock @dtvd88') + ' will unblock ' + \
802 magenta('@dtvd88') + '.\n'
803 usage += s * 2 + green('report @dtvd88') + ' will report ' + \
804 magenta('@dtvd88') + ' as a spam account.\n'
7e4ccbf3 805 usage += s * 2 + green('h') + ' will show this help again.\n'
806 usage += s * 2 + green('c') + ' will clear the screen.\n'
807 usage += s * 2 + green('q') + ' will quit.\n'
808
809 usage += s + '-' * (int(w) - 4) + '\n'
e3885f55 810 usage += s + 'Have fun and hang tight!\n'
f405a7d0 811 printNicely(usage)
f405a7d0
O
812
813
843647ad 814def clear():
f405a7d0 815 """
7b674cef 816 Clear screen
f405a7d0 817 """
843647ad 818 os.system('clear')
f405a7d0
O
819
820
843647ad 821def quit():
b8dda704
O
822 """
823 Exit all
824 """
f5677fb1 825 save_history()
8e633322 826 os.system('rm -rf rainbow.db')
843647ad
O
827 os.kill(g['stream_pid'], signal.SIGKILL)
828 sys.exit()
b8dda704
O
829
830
94a5f62e 831def reset():
f405a7d0 832 """
94a5f62e 833 Reset prefix of line
f405a7d0 834 """
c91f75f2 835 if g['reset']:
e3885f55 836 printNicely(magenta('Need tips ? Type "h" and hit Enter key!'))
c91f75f2 837 g['reset'] = False
54277114
O
838
839
94a5f62e 840def process(cmd):
54277114 841 """
94a5f62e 842 Process switch
54277114 843 """
94a5f62e 844 return dict(zip(
845 cmdset,
b2b933a9 846 [
42fde775 847 switch,
b2b933a9 848 home,
849 view,
305ce127 850 mentions,
b2b933a9 851 tweet,
852 retweet,
7e4ccbf3 853 favorite,
b2b933a9 854 reply,
855 delete,
7e4ccbf3 856 unfavorite,
b2b933a9 857 search,
305ce127 858 message,
f5677fb1 859 show,
0f6e4daf 860 list,
305ce127 861 inbox,
862 sent,
863 trash,
f5677fb1
O
864 follow,
865 unfollow,
305ce127 866 block,
867 unblock,
868 report,
b2b933a9 869 help,
870 clear,
871 quit
872 ]
94a5f62e 873 )).get(cmd, reset)
874
875
876def listen():
42fde775 877 """
878 Listen to user's input
879 """
d51b4107
O
880 d = dict(zip(
881 cmdset,
882 [
affcb149 883 ['public', 'mine'], # switch
7e4ccbf3 884 [], # home
885 ['@'], # view
305ce127 886 [], # mentions
7e4ccbf3 887 [], # tweet
888 [], # retweet
f5677fb1 889 [], # favorite
7e4ccbf3 890 [], # reply
891 [], # delete
f5677fb1 892 [], # unfavorite
7e4ccbf3 893 ['#'], # search
305ce127 894 ['@'], # message
f5677fb1 895 ['image'], # show image
305ce127 896 ['fl', 'fr'], # list
897 [], # inbox
898 [], # sent
899 [], # trash
affcb149
O
900 ['@'], # follow
901 ['@'], # unfollow
305ce127 902 ['@'], # block
903 ['@'], # unblock
904 ['@'], # report
7e4ccbf3 905 [], # help
906 [], # clear
907 [], # quit
d51b4107 908 ]
7e4ccbf3 909 ))
d51b4107 910 init_interactive_shell(d)
f5677fb1 911 read_history()
819569e8 912 reset()
b2b933a9 913 while True:
1dd312f5
O
914 if g['prefix']:
915 line = raw_input(g['decorated_name'])
916 else:
917 line = raw_input()
843647ad
O
918 try:
919 cmd = line.split()[0]
920 except:
921 cmd = ''
f405a7d0 922 # Save cmd to global variable and call process
843647ad
O
923 g['stuff'] = ' '.join(line.split()[1:])
924 process(cmd)()
7e4ccbf3 925 if cmd in ['switch', 't', 'rt', 'rep']:
1dd312f5
O
926 g['prefix'] = False
927 else:
928 g['prefix'] = True
54277114
O
929
930
42fde775 931def stream(domain, args, name='Rainbow Stream'):
54277114 932 """
f405a7d0 933 Track the stream
54277114 934 """
d51b4107 935
54277114 936 # The Logo
42fde775 937 art_dict = {
938 USER_DOMAIN: name,
939 PUBLIC_DOMAIN: args.track_keywords,
940 SITE_DOMAIN: 'Site Stream',
941 }
942 ascii_art(art_dict[domain])
d51b4107 943
91476ec3
O
944 # These arguments are optional:
945 stream_args = dict(
946 timeout=args.timeout,
947 block=not args.no_block,
948 heartbeat_timeout=args.heartbeat_timeout)
949
950 # Track keyword
951 query_args = dict()
952 if args.track_keywords:
953 query_args['track'] = args.track_keywords
954
955 # Get stream
2a6238f5 956 stream = TwitterStream(
22be990e 957 auth=authen(),
42fde775 958 domain=domain,
2a6238f5 959 **stream_args)
91476ec3 960
42fde775 961 if domain == USER_DOMAIN:
962 tweet_iter = stream.user(**query_args)
963 elif domain == SITE_DOMAIN:
964 tweet_iter = stream.site(**query_args)
965 else:
966 if args.track_keywords:
967 tweet_iter = stream.statuses.filter(**query_args)
968 else:
969 tweet_iter = stream.statuses.sample()
970
971 # Iterate over the stream.
91476ec3
O
972 for tweet in tweet_iter:
973 if tweet is None:
974 printNicely("-- None --")
975 elif tweet is Timeout:
976 printNicely("-- Timeout --")
977 elif tweet is HeartbeatTimeout:
978 printNicely("-- Heartbeat Timeout --")
979 elif tweet is Hangup:
980 printNicely("-- Hangup --")
981 elif tweet.get('text'):
7e4ccbf3 982 draw(
983 t=tweet,
c1fa7c94 984 iot=args.image_on_term,
7e4ccbf3 985 keyword=args.track_keywords,
986 fil=args.filter,
88af38d8 987 ig=args.ignore,
0f6e4daf 988 )
54277114
O
989
990
991def fly():
992 """
993 Main function
994 """
42fde775 995 # Spawn stream process
996 args = parse_arguments()
54277114 997 get_decorated_name()
42fde775 998 p = Process(target=stream, args=(USER_DOMAIN, args, g['original_name']))
999 p.start()
1000
1001 # Start listen process
819569e8 1002 time.sleep(0.5)
c91f75f2 1003 g['reset'] = True
1dd312f5 1004 g['prefix'] = True
f405a7d0 1005 g['stream_pid'] = p.pid
c1fa7c94 1006 g['iot'] = args.image_on_term
0f6e4daf 1007 listen()