upgrade center
[rainbowstream.git] / rainbowstream / rainbow.py
index 4b346828ef144e72934114ad587e39b7a4643c96..9c88fc82eed1a69c59a83314a4508244a30d858e 100644 (file)
@@ -7,6 +7,8 @@ import time
 import threading
 import requests
 import webbrowser
+import traceback
+import pkg_resources
 
 from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup
 from twitter.api import *
@@ -21,6 +23,7 @@ from .consumer import *
 from .interactive import *
 from .c_image import *
 from .py3patch import *
+from .emoji import *
 
 # Global values
 g = {}
@@ -108,6 +111,34 @@ def build_mute_dict(dict_data=False):
         return screen_name_list
 
 
+def debug_option():
+    """
+    Save traceback when run in debug mode
+    """
+    if g['debug']:
+        g['traceback'].append(traceback.format_exc())
+
+
+def upgrade_center():
+    """
+    Check latest and notify to upgrade
+    """
+    try:
+        current = pkg_resources.get_distribution("rainbowstream").version 
+        url = 'https://raw.githubusercontent.com/DTVD/rainbowstream/master/setup.py'
+        readme = requests.get(url).content 
+        latest = readme.split("version = \'")[1].split("\'")[0]
+        if current != latest:
+            notice =  light_magenta('RainbowStream latest version is ') 
+            notice += light_green(latest)
+            notice += light_magenta(' while your current version is ')
+            notice += light_yellow(current) + '\n'
+            notice += light_magenta('You should upgrade with "pip install -U rainbowstream".')
+            printNicely(notice)
+    except:
+        pass
+
+
 def init(args):
     """
     Init function
@@ -115,6 +146,8 @@ def init(args):
     # Handle Ctrl C
     ctrl_c_handler = lambda signum, frame: quit()
     signal.signal(signal.SIGINT, ctrl_c_handler)
+    # Upgrade notify
+    upgrade_center()
     # Get name
     t = Twitter(auth=authen())
     credential = t.account.verify_credentials()
@@ -122,6 +155,8 @@ def init(args):
     name = credential['name']
     if not get_config('PREFIX'):
         set_config('PREFIX', screen_name)
+    c['PREFIX'] = emojize(c['PREFIX'])
+    g['PREFIX'] = u2str(c['PREFIX'])
     c['original_name'] = g['original_name'] = screen_name[1:]
     g['full_name'] = name
     g['decorated_name'] = lambda x: color_func(
@@ -132,8 +167,15 @@ def init(args):
     g['themes'] = themes
     g['pause'] = False
     g['message_threads'] = {}
+    # Events
+    g['events'] = []
     # Startup cmd
     g['cmd'] = ''
+    # Debug option default = True
+    g['debug'] = True
+    g['traceback'] = []
+    # Retweet of mine events
+    c['events'] = []
     # Semaphore init
     c['lock'] = False
     # Init tweet dict and message dict
@@ -195,6 +237,19 @@ def home():
     printNicely('')
 
 
+def notification():
+    """
+    Show notifications
+    """
+    g['events'] = g['events'] + c['events']
+    if g['events']:
+        for e in g['events']:
+            print_event(e)
+        printNicely('')
+    else:
+        printNicely(magenta('Nothing at this time.'))
+
+
 def mentions():
     """
     Mentions timeline
@@ -221,7 +276,8 @@ def whois():
                 include_entities=False)
             show_profile(user)
         except:
-            printNicely(red('Omg no user.'))
+            debug_option()
+            printNicely(red('No user.'))
     else:
         printNicely(red('A name should begin with a \'@\''))
 
@@ -249,13 +305,24 @@ def search():
     Search
     """
     t = Twitter(auth=authen())
-    g['stuff'] = g['stuff'].strip()
-    rel = t.search.tweets(q=g['stuff'])['statuses']
+    # Setup query
+    query = g['stuff'].strip()
+    type = c['SEARCH_TYPE']
+    if type not in ['mixed', 'recent', 'popular']:
+        type = 'mixed'
+    max_record = c['SEARCH_MAX_RECORD']
+    count = min(max_record, 100)
+    # Perform search
+    rel = t.search.tweets(
+        q=query,
+        type=type,
+        count=count
+    )['statuses']
+    # Return results
     if rel:
         printNicely('Newest tweets:')
-        for i in reversed(xrange(c['SEARCH_MAX_RECORD'])):
-            draw(t=rel[i],
-                 keyword=g['stuff'])
+        for i in reversed(xrange(count)):
+            draw(t=rel[i], keyword=query)
         printNicely('')
     else:
         printNicely(magenta('I\'m afraid there is no result'))
@@ -448,6 +515,7 @@ def show():
             img = Image.open(BytesIO(res.content))
             img.show()
     except:
+        debug_option()
         printNicely(red('Sorry I can\'t show this image.'))
 
 
@@ -461,14 +529,16 @@ def urlopen():
             return
         tid = c['tweet_dict'][int(g['stuff'])]
         tweet = t.statuses.show(id=tid)
-        link_ary = [
-            u for u in tweet['text'].split() if u.startswith('http://')]
+        link_prefix = ('http://', 'https://')
+        link_ary = [u for u in tweet['text'].split()
+                    if u.startswith(link_prefix)]
         if not link_ary:
             printNicely(light_magenta('No url here @.@!'))
             return
         for link in link_ary:
             webbrowser.open(link)
     except:
+        debug_option()
         printNicely(red('Sorry I can\'t open url in this tweet.'))
 
 
@@ -550,6 +620,7 @@ def thread():
             g['original_name'],
             g['full_name'])
     except Exception:
+        debug_option()
         printNicely(red('No such thread.'))
 
 
@@ -570,6 +641,7 @@ def message():
         else:
             printNicely(red('A name should begin with a \'@\''))
     except:
+        debug_option()
         printNicely(red('Sorry I can\'t understand.'))
 
 
@@ -678,6 +750,7 @@ def mute():
             else:
                 printNicely(red(rel))
         except:
+            debug_option()
             printNicely(red('Something is wrong, can not mute now :('))
     else:
         printNicely(red('A name should begin with a \'@\''))
@@ -876,6 +949,7 @@ def list_add(t):
             screen_name=user_name)
         printNicely(green('Added.'))
     except:
+        debug_option()
         printNicely(light_magenta('I\'m sorry we can not add him/her.'))
 
 
@@ -895,6 +969,7 @@ def list_remove(t):
             screen_name=user_name)
         printNicely(green('Gone.'))
     except:
+        debug_option()
         printNicely(light_magenta('I\'m sorry we can not remove him/her.'))
 
 
@@ -910,6 +985,7 @@ def list_subscribe(t):
             owner_screen_name=owner)
         printNicely(green('Done.'))
     except:
+        debug_option()
         printNicely(
             light_magenta('I\'m sorry you can not subscribe to this list.'))
 
@@ -926,6 +1002,7 @@ def list_unsubscribe(t):
             owner_screen_name=owner)
         printNicely(green('Done.'))
     except:
+        debug_option()
         printNicely(
             light_magenta('I\'m sorry you can not unsubscribe to this list.'))
 
@@ -962,6 +1039,7 @@ def list_new(t):
             description=description)
         printNicely(green(name + ' list is created.'))
     except:
+        debug_option()
         printNicely(red('Oops something is wrong with Twitter :('))
 
 
@@ -989,6 +1067,7 @@ def list_update(t):
                 description=description)
         printNicely(green(slug + ' list is updated.'))
     except:
+        debug_option()
         printNicely(red('Oops something is wrong with Twitter :('))
 
 
@@ -1003,6 +1082,7 @@ def list_delete(t):
             owner_screen_name=g['original_name'])
         printNicely(green(slug + ' list is deleted.'))
     except:
+        debug_option()
         printNicely(red('Oops something is wrong with Twitter :('))
 
 
@@ -1213,6 +1293,8 @@ def help_discover():
         light_green('trend JP Tokyo') + '.\n'
     usage += s * 2 + light_green('home') + ' will show your timeline. ' + \
         light_green('home 7') + ' will show 7 tweets.\n'
+    usage += s * 2 + \
+        light_green('notification') + ' will show your recent notification.\n'
     usage += s * 2 + light_green('mentions') + ' will show mentions timeline. ' + \
         light_green('mentions 7') + ' will show 7 mention tweets.\n'
     usage += s * 2 + light_green('whois @mdo') + ' will show profile  of ' + \
@@ -1522,6 +1604,7 @@ cmdset = [
     'switch',
     'trend',
     'home',
+    'notification',
     'view',
     'mentions',
     't',
@@ -1566,6 +1649,7 @@ funcset = [
     switch,
     trend,
     home,
+    notification,
     view,
     mentions,
     tweet,
@@ -1623,6 +1707,7 @@ def listen():
             ['public', 'mine'],  # switch
             [],  # trend
             [],  # home
+            [],  # notification
             ['@'],  # view
             [],  # mentions
             [],  # tweet
@@ -1688,7 +1773,8 @@ def listen():
         try:
             # raw_input
             if g['prefix']:
-                line = raw_input(g['decorated_name'](c['PREFIX']))
+                # Only use PREFIX as a string with raw_input
+                line = raw_input(g['decorated_name'](g['PREFIX']))
             else:
                 line = raw_input()
             # Save cmd to compare with readline buffer
@@ -1714,6 +1800,7 @@ def listen():
         except EOFError:
             printNicely('')
         except Exception:
+            debug_option()
             printNicely(red('OMG something is wrong with Twitter right now.'))
 
 
@@ -1812,6 +1899,9 @@ def stream(domain, args, name='Rainbow Stream'):
                 while c['lock']:
                     time.sleep(0.5)
                 print_message(tweet['direct_message'])
+            elif tweet.get('event'):
+                g['events'].append(tweet)
+                print_event(tweet)
     except TwitterHTTPError:
         printNicely('')
         printNicely(