X-Git-Url: https://vcs.fsf.org/?p=rainbowstream.git;a=blobdiff_plain;f=rainbowstream%2Frainbow.py;h=9a30b47db5b8241f92dc69939c8f064b5c6810c2;hp=84b89ffcf6a8f3988bef4c0c72257dbf98641297;hb=c0440e50b791a7408a79bbe94f0d2e8b170024d6;hpb=b8dda7041add749421f08c022e04023b6a939a29;ds=sidebyside diff --git a/rainbowstream/rainbow.py b/rainbowstream/rainbow.py index 84b89ff..9a30b47 100644 --- a/rainbowstream/rainbow.py +++ b/rainbowstream/rainbow.py @@ -5,7 +5,11 @@ Colorful user's timeline stream from __future__ import print_function from multiprocessing import Process -import os, os.path, argparse, sys, time, signal +import os +import os.path +import argparse +import sys +import signal from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup from twitter.api import * @@ -16,14 +20,17 @@ from dateutil import parser from .colors import * from .config import * +from .db import * g = {} +db = RainbowDB() -def draw(t,keyword=None): +def draw(t, keyword=None): """ Draw the rainbow """ # Retrieve tweet + tid = t['id'] text = t['text'] screen_name = t['user']['screen_name'] name = t['user']['name'] @@ -31,9 +38,15 @@ def draw(t,keyword=None): date = parser.parse(created_at) time = date.strftime('%Y/%m/%d %H:%M:%S') + res = db.tweet_query(tid) + if not res: + db.store(tid) + res = db.tweet_query(tid) + rid = res[0].rainbow_id + # Format info user = cycle_color(name) + grey(' ' + '@' + screen_name + ' ') - clock = grey('[' + time + ']') + meta = grey('[' + time + '] [id=' + str(rid) + ']') tweet = text.split() # Highlight RT tweet = map(lambda x: grey(x) if x == 'RT' else x, tweet) @@ -42,7 +55,13 @@ def draw(t,keyword=None): # Highlight link tweet = map(lambda x: cyan(x) if x[0:7] == 'http://' else x, tweet) # Highlight search keyword - tweet = map(lambda x: on_yellow(x) if ''.join(c for c in x if c.isalnum()).lower() == keyword.lower() else x, tweet) + if keyword: + tweet = map( + lambda x: on_yellow(x) if + ''.join(c for c in x if c.isalnum()).lower() == keyword.lower() + else x, + tweet + ) tweet = ' '.join(tweet) # Draw rainbow @@ -51,25 +70,22 @@ def draw(t,keyword=None): uw=len(user) + 2, ) line2 = u"{c:>{cw}}".format( - c=clock, - cw=len(clock) + 2, + c=meta, + cw=len(meta) + 2, ) line3 = ' ' + tweet - line4 = '\n' printNicely(line1) printNicely(line2) printNicely(line3) - printNicely(line4) + printNicely('') def parse_arguments(): """ Parse the arguments """ - parser = argparse.ArgumentParser(description=__doc__ or "") - parser.add_argument( '-to', '--timeout', @@ -93,7 +109,7 @@ def parse_arguments(): def authen(): """ - authenticate with Twitter OAuth + Authenticate with Twitter OAuth """ # When using rainbow stream you must authorize. twitter_credential = os.environ.get( @@ -123,73 +139,193 @@ def get_decorated_name(): g['decorated_name'] = grey('[') + grey(name) + grey(']: ') +def home(): + """ + Home + """ + t = Twitter(auth=authen()) + count = HOME_TWEET_NUM + if g['stuff'].isdigit(): + count = g['stuff'] + for tweet in reversed(t.statuses.home_timeline(count=count)): + draw(t=tweet) + + +def view(): + """ + Friend view + """ + t = Twitter(auth=authen()) + user = g['stuff'].split()[0] + if user[0] == '@': + try: + count = int(g['stuff'].split()[1]) + except: + count = HOME_TWEET_NUM + for tweet in reversed(t.statuses.user_timeline(count=count, screen_name=user[1:])): + draw(t=tweet) + else: + print(red('A name should begin with a \'@\'')) + sys.stdout.write(g['decorated_name']) + + def tweet(): """ - Authen and tweet + Tweet """ t = Twitter(auth=authen()) t.statuses.update(status=g['stuff']) +def retweet(): + """ + ReTweet + """ + t = Twitter(auth=authen()) + try: + id = int(g['stuff'].split()[0]) + tid = db.rainbow_query(id)[0].tweet_id + t.statuses.retweet(id=tid,include_entities=False,trim_user=True) + except: + print(red('Sorry I can\'t retweet for you.')) + sys.stdout.write(g['decorated_name']) + + +def reply(): + """ + Reply + """ + t = Twitter(auth=authen()) + try: + id = int(g['stuff'].split()[0]) + tid = db.rainbow_query(id)[0].tweet_id + user = t.statuses.show(id=tid)['user']['screen_name'] + status = ' '.join(g['stuff'].split()[1:]) + status = '@' + user + ' ' + status.decode('utf-8') + t.statuses.update(status=status, in_reply_to_status_id=tid) + except: + print(red('Sorry I can\'t understand.')) + sys.stdout.write(g['decorated_name']) + + +def delete(): + """ + Delete + """ + t = Twitter(auth=authen()) + try: + id = int(g['stuff'].split()[0]) + tid = db.rainbow_query(id)[0].tweet_id + t.statuses.destroy(id=tid) + print(green('Okay it\'s gone.')) + except: + print(red('Sorry I can\'t delete this tweet for you.')) + sys.stdout.write(g['decorated_name']) + + def search(): """ - Authen and search + Search + """ + t = Twitter(auth=authen()) + h, w = os.popen('stty size', 'r').read().split() + if g['stuff'][0] == '#': + rel = t.search.tweets(q=g['stuff'])['statuses'] + printNicely(grey('*' * int(w) + '\n')) + print('Newest', SEARCH_MAX_RECORD, 'tweet: \n') + for i in xrange(5): + draw(t=rel[i], keyword=g['stuff'].strip()) + printNicely(grey('*' * int(w) + '\n')) + else: + print(red('A keyword should be a hashtag (like \'#AKB48\')')) + sys.stdout.write(g['decorated_name']) + + +def friend(): + """ + List of friend (following) """ t = Twitter(auth=authen()) - rel = t.search.tweets(q='#' + g['stuff'])['statuses'] - printNicely(grey('**************************************************************************************\n')) - print('Newest',SEARCH_MAX_RECORD, 'tweet: \n') - for i in xrange(5): - draw(t=rel[i],keyword=g['stuff'].strip()) - printNicely(grey('**************************************************************************************\n')) + g['friends'] = t.friends.ids()['ids'] + for i in g['friends']: + screen_name = t.users.lookup(user_id=i)[0]['screen_name'] + user = cycle_color('@' + screen_name) + print(user, end=' ') + print('\n') + + +def follower(): + """ + List of follower + """ + t = Twitter(auth=authen()) + g['followers'] = t.followers.ids()['ids'] + for i in g['followers']: + screen_name = t.users.lookup(user_id=i)[0]['screen_name'] + user = cycle_color('@' + screen_name) + print(user, end=' ') + print('\n') def help(): """ - Print help + Help """ usage = ''' Hi boss! I'm ready to serve you right now! ---------------------------------------------------- - "!" at the beginning will start to tweet immediately - "/" at the beginning will search for 5 newest tweet - "?" or "h" will print this help once again - "c" will clear the terminal - "q" will exit + "home" will show your timeline. "home 7" will print 7 tweet. + "view @bob" will show your friend @bob's home. + "t oops" will tweet "oops" immediately. + "rt 12345" will retweet to tweet with id "12345". + "rep 12345 oops" will reply "oops" to tweet with id "12345". + "del 12345" will delete tweet with id "12345". + "s #AKB48" will search for "AKB48" and return 5 newest tweet. + "fr" will list out your following people. + "fl" will list out your followers. + "h" will print this help once again. + "c" will clear the terminal. + "q" will exit. ---------------------------------------------------- - Hvae fun and hang tight! + Have fun and hang tight! ''' printNicely(usage) sys.stdout.write(g['decorated_name']) -def quit(): +def clear(): """ - Exit all + Clear screen """ - os.kill(g['stream_pid'], signal.SIGKILL) - sys.exit() + os.system('clear') -def clear(): +def quit(): """ Exit all """ - os.system('clear') + os.kill(g['stream_pid'], signal.SIGKILL) + sys.exit() -def process(line): +def process(cmd): """ - Process switch by start of line + Process switch """ return { - '!' : tweet, - '/' : search, - '?' : help, - 'h' : help, - 'c' : clear, - 'q' : quit, - }.get(line[0],lambda: sys.stdout.write(g['decorated_name'])) + 'home' : home, + 'view' : view, + 't' : tweet, + 'rt' : retweet, + 'rep' : reply, + 'del' : delete, + 's' : search, + 'fr' : friend, + 'fl' : follower, + 'h' : help, + 'c' : clear, + 'q' : quit, + }.get(cmd, lambda: sys.stdout.write(g['decorated_name'])) def listen(stdin): @@ -197,9 +333,13 @@ def listen(stdin): Listen to user's input """ for line in iter(stdin.readline, ''): + try: + cmd = line.split()[0] + except: + cmd = '' # Save cmd to global variable and call process - g['stuff'] = line[1:] - process(line)() + g['stuff'] = ' '.join(line.split()[1:]) + process(cmd)() stdin.close() @@ -224,8 +364,8 @@ def stream(): # Get stream stream = TwitterStream( - auth = authen(), - domain = 'userstream.twitter.com', + auth=authen(), + domain=DOMAIN, **stream_args) tweet_iter = stream.user(**query_args) @@ -248,8 +388,8 @@ def fly(): Main function """ get_decorated_name() - p = Process(target = stream) + + p = Process(target=stream) p.start() g['stream_pid'] = p.pid listen(sys.stdin) -