added support for "open" follow https:// links
[rainbowstream.git] / rainbowstream / rainbow.py
index 1058b038f244ce6d755a884d53cdf2060a2929d6..5542ca7ba6947184fd0af8183471095df9f94d02 100644 (file)
@@ -1,6 +1,3 @@
-"""
-Colorful user's timeline stream
-"""
 import os
 import os.path
 import sys
@@ -120,21 +117,25 @@ def init(args):
     signal.signal(signal.SIGINT, ctrl_c_handler)
     # Get name
     t = Twitter(auth=authen())
-    name = '@' + t.account.verify_credentials()['screen_name']
+    credential = t.account.verify_credentials()
+    screen_name = '@' + credential['screen_name']
+    name = credential['name']
     if not get_config('PREFIX'):
-        set_config('PREFIX', name)
-    g['original_name'] = name[1:]
+        set_config('PREFIX', screen_name)
+    c['original_name'] = g['original_name'] = screen_name[1:]
+    g['full_name'] = name
     g['decorated_name'] = lambda x: color_func(
         c['DECORATED_NAME'])('[' + x + ']: ')
     # Theme init
     files = os.listdir(os.path.dirname(__file__) + '/colorset')
     themes = [f.split('.')[0] for f in files if f.split('.')[-1] == 'json']
     g['themes'] = themes
+    g['pause'] = False
+    g['message_threads'] = {}
     # Startup cmd
     g['cmd'] = ''
     # Semaphore init
     c['lock'] = False
-    c['pause'] = False
     # Init tweet dict and message dict
     c['tweet_dict'] = []
     c['message_dict'] = []
@@ -462,6 +463,8 @@ def urlopen():
         tweet = t.statuses.show(id=tid)
         link_ary = [
             u for u in tweet['text'].split() if u.startswith('http://')]
+        link_ary.extend([
+            u for u in tweet['text'].split() if u.startswith('https://')])
         if not link_ary:
             printNicely(light_magenta('No url here @.@!'))
             return
@@ -473,17 +476,17 @@ def urlopen():
 
 def inbox():
     """
-    Inbox direct messages
+    Inbox threads
     """
     t = Twitter(auth=authen())
     num = c['MESSAGES_DISPLAY']
-    rel = []
     if g['stuff'].isdigit():
         num = g['stuff']
+    # Get inbox messages
     cur_page = 1
-    # Max message per page is 20 so we have to loop
+    inbox = []
     while num > 20:
-        rel = rel + t.direct_messages(
+        inbox = inbox + t.direct_messages(
             count=20,
             page=cur_page,
             include_entities=False,
@@ -491,32 +494,20 @@ def inbox():
         )
         num -= 20
         cur_page += 1
-    rel = rel + t.direct_messages(
+    inbox = inbox + t.direct_messages(
         count=num,
         page=cur_page,
         include_entities=False,
         skip_status=False
     )
-    # Display
-    printNicely('Inbox: newest ' + str(len(rel)) + ' messages.')
-    for m in reversed(rel):
-        print_message(m)
-    printNicely('')
-
-
-def sent():
-    """
-    Sent direct messages
-    """
-    t = Twitter(auth=authen())
+    # Get sent messages
     num = c['MESSAGES_DISPLAY']
-    rel = []
     if g['stuff'].isdigit():
-        num = int(g['stuff'])
+        num = g['stuff']
     cur_page = 1
-    # Max message per page is 20 so we have to loop
+    sent = []
     while num > 20:
-        rel = rel + t.direct_messages.sent(
+        sent = sent + t.direct_messages.sent(
             count=20,
             page=cur_page,
             include_entities=False,
@@ -524,17 +515,44 @@ def sent():
         )
         num -= 20
         cur_page += 1
-    rel = rel + t.direct_messages.sent(
+    sent = sent + t.direct_messages.sent(
         count=num,
         page=cur_page,
         include_entities=False,
         skip_status=False
     )
-    # Display
-    printNicely('Sent: newest ' + str(len(rel)) + ' messages.')
-    for m in reversed(rel):
-        print_message(m)
-    printNicely('')
+
+    d = {}
+    uniq_inbox = list(set(
+        [(m['sender_screen_name'], m['sender']['name']) for m in inbox]
+    ))
+    uniq_sent = list(set(
+        [(m['recipient_screen_name'], m['recipient']['name']) for m in sent]
+    ))
+    for partner in uniq_inbox:
+        inbox_ary = [m for m in inbox if m['sender_screen_name'] == partner[0]]
+        sent_ary = [
+            m for m in sent if m['recipient_screen_name'] == partner[0]]
+        d[partner] = inbox_ary + sent_ary
+    for partner in uniq_sent:
+        if partner not in d:
+            d[partner] = [
+                m for m in sent if m['recipient_screen_name'] == partner[0]]
+    g['message_threads'] = print_threads(d)
+
+
+def thread():
+    """
+    View a thread of message
+    """
+    try:
+        thread_id = int(g['stuff'])
+        print_thread(
+            g['message_threads'][thread_id],
+            g['original_name'],
+            g['full_name'])
+    except Exception:
+        printNicely(red('No such thread.'))
 
 
 def message():
@@ -542,19 +560,19 @@ def message():
     Send a direct message
     """
     t = Twitter(auth=authen())
-    user = g['stuff'].split()[0]
-    if user[0].startswith('@'):
-        try:
-            content = g['stuff'].split()[1]
-        except:
-            printNicely(red('Sorry I can\'t understand.'))
-        t.direct_messages.new(
-            screen_name=user[1:],
-            text=content
-        )
-        printNicely(green('Message sent.'))
-    else:
-        printNicely(red('A name should begin with a \'@\''))
+    try:
+        user = g['stuff'].split()[0]
+        if user[0].startswith('@'):
+            content = ' '.join(g['stuff'].split()[1:])
+            t.direct_messages.new(
+                screen_name=user[1:],
+                text=content
+            )
+            printNicely(green('Message sent.'))
+        else:
+            printNicely(red('A name should begin with a \'@\''))
+    except:
+        printNicely(red('Sorry I can\'t understand.'))
 
 
 def trash():
@@ -1260,8 +1278,8 @@ def help_messages():
     usage += s + grey(u'\u266A' + ' Direct messages \n')
     usage += s * 2 + light_green('inbox') + ' will show inbox messages. ' + \
         light_green('inbox 7') + ' will show newest 7 messages.\n'
-    usage += s * 2 + light_green('sent') + ' will show sent messages. ' + \
-        light_green('sent 7') + ' will show newest 7 messages.\n'
+    usage += s * 2 + light_green('thread 2') + ' will show full thread with ' + \
+        light_yellow('[thread_id=2]') + '.\n'
     usage += s * 2 + light_green('mes @dtvd88 hi') + ' will send a "hi" messege to ' + \
         magenta('@dtvd88') + '.\n'
     usage += s * 2 + light_green('trash 5') + ' will remove message with ' + \
@@ -1453,7 +1471,7 @@ def pause():
     """
     Pause stream display
     """
-    c['pause'] = True
+    g['pause'] = True
     printNicely(green('Stream is paused'))
 
 
@@ -1461,7 +1479,7 @@ def replay():
     """
     Replay stream
     """
-    c['pause'] = False
+    g['pause'] = False
     printNicely(green('Stream is running back now'))
 
 
@@ -1523,7 +1541,7 @@ cmdset = [
     'open',
     'ls',
     'inbox',
-    'sent',
+    'thread',
     'trash',
     'whois',
     'fl',
@@ -1567,7 +1585,7 @@ funcset = [
     urlopen,
     ls,
     inbox,
-    sent,
+    thread,
     trash,
     whois,
     follow,
@@ -1624,7 +1642,7 @@ def listen():
             [''],  # open url
             ['fl', 'fr'],  # list
             [],  # inbox
-            [],  # sent
+            [i for i in g['message_threads']],  # sent
             [],  # trash
             ['@'],  # whois
             ['@'],  # follow
@@ -1669,19 +1687,19 @@ def listen():
     read_history()
     reset()
     while True:
-        # raw_input
-        if g['prefix']:
-            line = raw_input(g['decorated_name'](c['PREFIX']))
-        else:
-            line = raw_input()
-        # Save cmd to compare with readline buffer
-        g['cmd'] = line.strip()
-        # Get short cmd to pass to handle function
-        try:
-            cmd = line.split()[0]
-        except:
-            cmd = ''
         try:
+            # raw_input
+            if g['prefix']:
+                line = raw_input(g['decorated_name'](c['PREFIX']))
+            else:
+                line = raw_input()
+            # Save cmd to compare with readline buffer
+            g['cmd'] = line.strip()
+            # Get short cmd to pass to handle function
+            try:
+                cmd = line.split()[0]
+            except:
+                cmd = ''
             # Lock the semaphore
             c['lock'] = True
             # Save cmd to global variable and call process
@@ -1695,6 +1713,8 @@ def listen():
                 g['prefix'] = True
             # Release the semaphore lock
             c['lock'] = False
+        except EOFError:
+            printNicely('')
         except Exception:
             printNicely(red('OMG something is wrong with Twitter right now.'))
 
@@ -1761,11 +1781,16 @@ def stream(domain, args, name='Rainbow Stream'):
             elif tweet is Hangup:
                 printNicely("-- Hangup --")
             elif tweet.get('text'):
+                # Check the semaphore pause and lock (stream process only)
+                if g['pause']:
+                    continue
+                while c['lock']:
+                    time.sleep(0.5)
+                # Draw the tweet
                 draw(
                     t=tweet,
                     keyword=args.track_keywords,
                     humanize=False,
-                    check_semaphore=True,
                     fil=args.filter,
                     ig=args.ignore,
                 )
@@ -1783,7 +1808,12 @@ def stream(domain, args, name='Rainbow Stream'):
                     sys.stdout.write(g['decorated_name'](c['PREFIX']))
                     sys.stdout.flush()
             elif tweet.get('direct_message'):
-                print_message(tweet['direct_message'], check_semaphore=True)
+                # Check the semaphore pause and lock (stream process only)
+                if g['pause']:
+                    continue
+                while c['lock']:
+                    time.sleep(0.5)
+                print_message(tweet['direct_message'])
     except TwitterHTTPError:
         printNicely('')
         printNicely(