Update README.md
[rainbowstream.git] / rainbowstream / rainbow.py
index 9016815066bbf6892fa08e3f5c003045d2f21e93..dc714e6f016db4f6c80008af60cdfd1e7a8d06cc 100644 (file)
@@ -1,28 +1,45 @@
 """
 Colorful user's timeline stream
 """
 """
 Colorful user's timeline stream
 """
-
 from __future__ import print_function
 from multiprocessing import Process
 from __future__ import print_function
 from multiprocessing import Process
+from dateutil import parser
 
 import os
 import os.path
 
 import os
 import os.path
-import argparse
 import sys
 import sys
-import time
 import signal
 import signal
+import argparse
+import time
+import datetime
 
 from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup
 from twitter.api import *
 from twitter.oauth import OAuth, read_token_file
 from twitter.oauth_dance import oauth_dance
 from twitter.util import printNicely
 
 from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup
 from twitter.api import *
 from twitter.oauth import OAuth, read_token_file
 from twitter.oauth_dance import oauth_dance
 from twitter.util import printNicely
-from dateutil import parser
 
 from .colors import *
 from .config import *
 
 from .colors import *
 from .config import *
+from .interactive import *
+from .db import *
 
 g = {}
 
 g = {}
+db = RainbowDB()
+cmdset = [
+    'home',
+    'view',
+    't',
+    'rt',
+    'rep',
+    'del',
+    's',
+    'fr',
+    'fl',
+    'h',
+    'c',
+    'q'
+]
 
 
 def draw(t, keyword=None):
 
 
 def draw(t, keyword=None):
@@ -36,11 +53,18 @@ def draw(t, keyword=None):
     name = t['user']['name']
     created_at = t['created_at']
     date = parser.parse(created_at)
     name = t['user']['name']
     created_at = t['created_at']
     date = parser.parse(created_at)
-    time = date.strftime('%Y/%m/%d %H:%M:%S')
+    date = date - datetime.timedelta(seconds=time.timezone)
+    clock = 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 + ' ')
 
     # Format info
     user = cycle_color(name) + grey(' ' + '@' + screen_name + ' ')
-    meta = grey('[' + time + '] [id=' + str(tid) + ']')
+    meta = grey('[' + clock + '] [id=' + str(rid) + ']')
     tweet = text.split()
     # Highlight RT
     tweet = map(lambda x: grey(x) if x == 'RT' else x, tweet)
     tweet = text.split()
     # Highlight RT
     tweet = map(lambda x: grey(x) if x == 'RT' else x, tweet)
@@ -69,10 +93,10 @@ def draw(t, keyword=None):
     )
     line3 = '  ' + tweet
 
     )
     line3 = '  ' + tweet
 
+    printNicely('')
     printNicely(line1)
     printNicely(line2)
     printNicely(line3)
     printNicely(line1)
     printNicely(line2)
     printNicely(line3)
-    printNicely('')
 
 
 def parse_arguments():
 
 
 def parse_arguments():
@@ -129,7 +153,7 @@ def get_decorated_name():
     Beginning of every line
     """
     t = Twitter(auth=authen())
     Beginning of every line
     """
     t = Twitter(auth=authen())
-    name = '@' + t.statuses.user_timeline()[-1]['user']['screen_name']
+    name = '@' + t.account.verify_credentials()['screen_name']
     g['decorated_name'] = grey('[') + grey(name) + grey(']: ')
 
 
     g['decorated_name'] = grey('[') + grey(name) + grey(']: ')
 
 
@@ -138,11 +162,12 @@ def home():
     Home
     """
     t = Twitter(auth=authen())
     Home
     """
     t = Twitter(auth=authen())
-    count = HOME_TWEET_NUM
+    num = HOME_TWEET_NUM
     if g['stuff'].isdigit():
     if g['stuff'].isdigit():
-        count = g['stuff']
-    for tweet in reversed(t.statuses.home_timeline(count=count)):
+        num = g['stuff']
+    for tweet in reversed(t.statuses.home_timeline(count=num)):
         draw(t=tweet)
         draw(t=tweet)
+    printNicely('')
 
 
 def view():
 
 
 def view():
@@ -151,12 +176,16 @@ def view():
     """
     t = Twitter(auth=authen())
     user = g['stuff'].split()[0]
     """
     t = Twitter(auth=authen())
     user = g['stuff'].split()[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)):
-        draw(t=tweet)
+    if user[0] == '@':
+        try:
+            num = int(g['stuff'].split()[1])
+        except:
+            num = HOME_TWEET_NUM
+        for tweet in reversed(t.statuses.user_timeline(count=num, screen_name=user[1:])):
+            draw(t=tweet)
+        printNicely('')
+    else:
+        print(red('A name should begin with a \'@\''))
 
 
 def tweet():
 
 
 def tweet():
@@ -165,6 +194,21 @@ def tweet():
     """
     t = Twitter(auth=authen())
     t.statuses.update(status=g['stuff'])
     """
     t = Twitter(auth=authen())
     t.statuses.update(status=g['stuff'])
+    g['prefix'] = False
+
+
+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.'))
+    g['prefix'] = False
 
 
 def reply():
 
 
 def reply():
@@ -174,12 +218,14 @@ def reply():
     t = Twitter(auth=authen())
     try:
         id = int(g['stuff'].split()[0])
     t = Twitter(auth=authen())
     try:
         id = int(g['stuff'].split()[0])
-        user = t.statuses.show(id=id)['user']['screen_name']
+        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')
         status = ' '.join(g['stuff'].split()[1:])
         status = '@' + user + ' ' + status.decode('utf-8')
-        t.statuses.update(status=status, in_reply_to_status_id=id)
+        t.statuses.update(status=status, in_reply_to_status_id=tid)
     except:
         print(red('Sorry I can\'t understand.'))
     except:
         print(red('Sorry I can\'t understand.'))
+    g['prefix'] = False
 
 
 def delete():
 
 
 def delete():
@@ -189,7 +235,8 @@ def delete():
     t = Twitter(auth=authen())
     try:
         id = int(g['stuff'].split()[0])
     t = Twitter(auth=authen())
     try:
         id = int(g['stuff'].split()[0])
-        t.statuses.destroy(id=id)
+        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.'))
         print(green('Okay it\'s gone.'))
     except:
         print(red('Sorry I can\'t delete this tweet for you.'))
@@ -200,14 +247,17 @@ def search():
     Search
     """
     t = Twitter(auth=authen())
     Search
     """
     t = Twitter(auth=authen())
-    rel = t.search.tweets(q='#' + g['stuff'])['statuses']
-    h, w = os.popen('stty size', 'r').read().split()
-
-    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'))
+    try:
+        if g['stuff'][0] == '#':
+            rel = t.search.tweets(q=g['stuff'])['statuses']
+            print('Newest', SEARCH_MAX_RECORD, 'tweet:')
+            for i in xrange(SEARCH_MAX_RECORD):
+                draw(t=rel[i], keyword=g['stuff'].strip()[1:])
+            printNicely('')
+        else:
+            print(red('A keyword should be a hashtag (like \'#AKB48\')'))
+    except:
+        print(red('Sorry I can\'t understand.'))
 
 
 def friend():
 
 
 def friend():
@@ -242,23 +292,23 @@ def help():
     """
     usage = '''
     Hi boss! I'm ready to serve you right now!
     """
     usage = '''
     Hi boss! I'm ready to serve you right now!
-    ----------------------------------------------------
-    "home" will show your timeline. "home 7" will print 7 tweet.
-    "view bob" will show your friend @bob's home.
+    -------------------------------------------------------------
+    "home" will show your timeline. "home 7" will show 7 tweet.
+    "view @bob" will show your friend @bob's home.
     "t oops" will tweet "oops" immediately.
     "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".
     "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.
+    "s #AKB48" will search for "AKB48" and return 5 newest tweet.
     "fr" will list out your following people.
     "fl" will list out your followers.
     "fr" will list out your following people.
     "fl" will list out your followers.
-    "h" or "help" will print this help once again.
+    "h" will show this help again.
     "c" will clear the terminal.
     "q" will exit.
     "c" will clear the terminal.
     "q" will exit.
-    ----------------------------------------------------
+    -------------------------------------------------------------
     Have fun and hang tight!
     '''
     printNicely(usage)
     Have fun and hang tight!
     '''
     printNicely(usage)
-    sys.stdout.write(g['decorated_name'])
 
 
 def clear():
 
 
 def clear():
@@ -272,35 +322,49 @@ def quit():
     """
     Exit all
     """
     """
     Exit all
     """
+    os.system('rm -rf rainbow.db')
     os.kill(g['stream_pid'], signal.SIGKILL)
     sys.exit()
 
 
     os.kill(g['stream_pid'], signal.SIGKILL)
     sys.exit()
 
 
-def process(cmd):
+def reset():
     """
     """
-    Process switch
+    Reset prefix of line
     """
     """
-    return {
-        'home': home,
-        'view': view,
-        't': tweet,
-        'rep': reply,
-        'del': delete,
-        's': search,
-        'fr': friend,
-        'fl': follower,
-        'h': help,
-        'help': help,
-        'c': clear,
-        'q': quit,
-    }.get(cmd, lambda: sys.stdout.write(g['decorated_name']))
+    g['prefix'] = True
 
 
 
 
-def listen(stdin):
+def process(cmd):
     """
     """
-    Listen to user's input
+    Process switch
     """
     """
-    for line in iter(stdin.readline, ''):
+    return dict(zip(
+        cmdset,
+        [
+            home,
+            view,
+            tweet,
+            retweet,
+            reply,
+            delete,
+            search,
+            friend,
+            follower,
+            help,
+            clear,
+            quit
+        ]
+    )).get(cmd, reset)
+
+
+def listen():
+    init_interactive_shell(cmdset)
+    first = True
+    while True:
+        if g['prefix'] and not first:
+            line = raw_input(g['decorated_name'])
+        else:
+            line = raw_input()
         try:
             cmd = line.split()[0]
         except:
         try:
             cmd = line.split()[0]
         except:
@@ -308,7 +372,7 @@ def listen(stdin):
         # Save cmd to global variable and call process
         g['stuff'] = ' '.join(line.split()[1:])
         process(cmd)()
         # Save cmd to global variable and call process
         g['stuff'] = ' '.join(line.split()[1:])
         process(cmd)()
-    stdin.close()
+        first = False
 
 
 def stream():
 
 
 def stream():
@@ -333,7 +397,7 @@ def stream():
     # Get stream
     stream = TwitterStream(
         auth=authen(),
     # Get stream
     stream = TwitterStream(
         auth=authen(),
-        domain='userstream.twitter.com',
+        domain=DOMAIN,
         **stream_args)
     tweet_iter = stream.user(**query_args)
 
         **stream_args)
     tweet_iter = stream.user(**query_args)
 
@@ -356,7 +420,8 @@ def fly():
     Main function
     """
     get_decorated_name()
     Main function
     """
     get_decorated_name()
+    g['prefix'] = True
     p = Process(target=stream)
     p.start()
     g['stream_pid'] = p.pid
     p = Process(target=stream)
     p.start()
     g['stream_pid'] = p.pid
-    listen(sys.stdin)
+    listen()