Merge pull request #40 from bartj3/fix/typo
[rainbowstream.git] / rainbowstream / rainbow.py
index 95461788e9961cce9375639fe623f30a04132e7a..dfbfb3b7ac3d559e7ad5a76bc92e88a1504c4197 100644 (file)
@@ -31,49 +31,6 @@ g = {}
 # Lock for streams
 StreamLock = threading.Lock()
 
-# Commands
-cmdset = [
-    'switch',
-    'trend',
-    'home',
-    'view',
-    'mentions',
-    't',
-    'rt',
-    'quote',
-    'allrt',
-    'fav',
-    'rep',
-    'del',
-    'ufav',
-    's',
-    'mes',
-    'show',
-    'open',
-    'ls',
-    'inbox',
-    'sent',
-    'trash',
-    'whois',
-    'fl',
-    'ufl',
-    'mute',
-    'unmute',
-    'muting',
-    'block',
-    'unblock',
-    'report',
-    'list',
-    'cal',
-    'config',
-    'theme',
-    'h',
-    'p',
-    'r',
-    'c',
-    'q'
-]
-
 
 def parse_arguments():
     """
@@ -84,16 +41,6 @@ def parse_arguments():
         '-to',
         '--timeout',
         help='Timeout for the stream (seconds).')
-    parser.add_argument(
-        '-ht',
-        '--heartbeat-timeout',
-        help='Set heartbeat timeout.',
-        default=90)
-    parser.add_argument(
-        '-nb',
-        '--no-block',
-        action='store_true',
-        help='Set stream to non-blocking.')
     parser.add_argument(
         '-tt',
         '--track-keywords',
@@ -178,14 +125,13 @@ def init(args):
         set_config('PREFIX', name)
     g['original_name'] = name[1:]
     g['decorated_name'] = lambda x: color_func(
-        c['DECORATED_NAME'])(
-        '[' + x + ']: ')
+        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
     # Startup cmd
-    g['previous_cmd'] = ''
+    g['cmd'] = ''
     # Semaphore init
     c['lock'] = False
     c['pause'] = False
@@ -194,6 +140,7 @@ def init(args):
     c['message_dict'] = []
     # Image on term
     c['IMAGE_ON_TERM'] = args.image_on_term
+    set_config('IMAGE_ON_TERM', str(c['IMAGE_ON_TERM']))
     # Mute dict
     c['IGNORE_LIST'] += build_mute_dict()
 
@@ -365,6 +312,7 @@ def quote():
     """
     Quote a tweet
     """
+    # Get tweet
     t = Twitter(auth=authen())
     try:
         id = int(g['stuff'].split()[0])
@@ -373,17 +321,16 @@ def quote():
         return
     tid = c['tweet_dict'][id]
     tweet = t.statuses.show(id=tid)
-    screen_name = tweet['user']['screen_name']
-    text = tweet['text']
-    quote = '\"@' + screen_name + ': ' + text + '\"'
-    quote = quote.encode('utf8')
-    notice = light_magenta('Compose mode ')
-    notice += light_yellow('(Enter nothing will cancel the quote)')
-    notice += light_magenta(':')
-    printNicely(notice)
-    extra = raw_input(quote)
-    if extra:
-        t.statuses.update(status=quote + extra)
+    # Get formater
+    formater = format_quote(tweet)
+    if not formater:
+        return
+    # Get comment
+    prefix = light_magenta('Compose your ') + light_green('#comment: ')
+    comment = raw_input(prefix)
+    if comment:
+        quote = comment.join(formater.split('#comment'))
+        t.statuses.update(status=quote)
     else:
         printNicely(light_magenta('No text added.'))
 
@@ -445,7 +392,7 @@ def reply():
     tid = c['tweet_dict'][id]
     user = t.statuses.show(id=tid)['user']['screen_name']
     status = ' '.join(g['stuff'].split()[1:])
-    status = '@' + user + ' ' + status.decode('utf-8')
+    status = '@' + user + ' ' + str2u(status)
     t.statuses.update(status=status, in_reply_to_status_id=tid)
 
 
@@ -744,7 +691,7 @@ def mute():
             rel = t.mutes.users.create(screen_name=screen_name[1:])
             if isinstance(rel, dict):
                 printNicely(green(screen_name + ' is muted.'))
-                c['IGNORE_LIST'] += [screen_name.decode('utf8')]
+                c['IGNORE_LIST'] += [unc(screen_name)]
                 c['IGNORE_LIST'] = list(set(c['IGNORE_LIST']))
             else:
                 printNicely(red(rel))
@@ -1151,17 +1098,16 @@ def config():
             value = get_default_config(key)
             line = ' ' * 2 + green(key) + ': ' + light_magenta(value)
             printNicely(line)
-        except:
-            printNicely(
-                light_magenta('This config key does not exist in default.'))
+        except Exception as e:
+            printNicely(red(e))
     # Delete specific config key in config file
     elif len(g['stuff'].split()) == 2 and g['stuff'].split()[-1] == 'drop':
         key = g['stuff'].split()[0]
         try:
             delete_config(key)
             printNicely(green('Config key is dropped.'))
-        except:
-            printNicely(red('No such config key.'))
+        except Exception as e:
+            printNicely(red(e))
     # Set specific config
     elif len(g['stuff'].split()) == 3 and g['stuff'].split()[1] == '=':
         key = g['stuff'].split()[0]
@@ -1175,13 +1121,11 @@ def config():
             if key == 'THEME':
                 c['THEME'] = reload_theme(value, c['THEME'])
                 g['decorated_name'] = lambda x: color_func(
-                    c['DECORATED_NAME'])(
-                    '[' + x + ']: ')
+                    c['DECORATED_NAME'])('[' + x + ']: ')
+            reload_config()
             printNicely(green('Updated successfully.'))
-        except:
-            printNicely(light_magenta('Not valid value.'))
-            return
-        reload_config()
+        except Exception as e:
+            printNicely(red(e))
     else:
         printNicely(light_magenta('Sorry I can\'s understand.'))
 
@@ -1403,7 +1347,7 @@ def help():
         light_yellow('already') + ' on your personal stream.\n'
     usage += s + 'Any update from Twitter will show up ' + \
         light_yellow('immediately') + '.\n'
-    usage += s + 'In addtion, following commands are available right now:\n'
+    usage += s + 'In addition, following commands are available right now:\n'
     # Twitter help section
     usage += '\n'
     usage += s + grey(u'\u266A' + ' Twitter help\n')
@@ -1516,6 +1460,10 @@ def reset():
     Reset prefix of line
     """
     if g['reset']:
+        if c.get('USER_JSON_ERROR'):
+            printNicely(red('Your ~/.rainbow_config.json is messed up:'))
+            printNicely(red('>>> ' + c['USER_JSON_ERROR']))
+            printNicely('')
         printNicely(magenta('Need tips ? Type "h" and hit Enter key!'))
     g['reset'] = False
     try:
@@ -1524,54 +1472,98 @@ def reset():
         pass
 
 
+# Command set
+cmdset = [
+    'switch',
+    'trend',
+    'home',
+    'view',
+    'mentions',
+    't',
+    'rt',
+    'quote',
+    'allrt',
+    'fav',
+    'rep',
+    'del',
+    'ufav',
+    's',
+    'mes',
+    'show',
+    'open',
+    'ls',
+    'inbox',
+    'sent',
+    'trash',
+    'whois',
+    'fl',
+    'ufl',
+    'mute',
+    'unmute',
+    'muting',
+    'block',
+    'unblock',
+    'report',
+    'list',
+    'cal',
+    'config',
+    'theme',
+    'h',
+    'p',
+    'r',
+    'c',
+    'q'
+]
+
+# Handle function set
+funcset = [
+    switch,
+    trend,
+    home,
+    view,
+    mentions,
+    tweet,
+    retweet,
+    quote,
+    allretweet,
+    favorite,
+    reply,
+    delete,
+    unfavorite,
+    search,
+    message,
+    show,
+    urlopen,
+    ls,
+    inbox,
+    sent,
+    trash,
+    whois,
+    follow,
+    unfollow,
+    mute,
+    unmute,
+    muting,
+    block,
+    unblock,
+    report,
+    twitterlist,
+    cal,
+    config,
+    theme,
+    help,
+    pause,
+    replay,
+    clear,
+    quit
+]
+
+
 def process(cmd):
     """
     Process switch
     """
-    return dict(zip(
-        cmdset,
-        [
-            switch,
-            trend,
-            home,
-            view,
-            mentions,
-            tweet,
-            retweet,
-            quote,
-            allretweet,
-            favorite,
-            reply,
-            delete,
-            unfavorite,
-            search,
-            message,
-            show,
-            urlopen,
-            ls,
-            inbox,
-            sent,
-            trash,
-            whois,
-            follow,
-            unfollow,
-            mute,
-            unmute,
-            muting,
-            block,
-            unblock,
-            report,
-            twitterlist,
-            cal,
-            config,
-            theme,
-            help,
-            pause,
-            replay,
-            clear,
-            quit
-        ]
-    )).get(cmd, reset)
+    return dict(zip(cmdset, funcset)).get(cmd, reset)
 
 
 def listen():
@@ -1650,13 +1642,13 @@ def listen():
             line = raw_input(g['decorated_name'](c['PREFIX']))
         else:
             line = raw_input()
-        # Save previous cmd in order to compare with readline buffer
-        g['previous_cmd'] = line.strip()
+        # 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 = ''
-        g['cmd'] = cmd
         try:
             # Lock the semaphore
             c['lock'] = True
@@ -1690,8 +1682,8 @@ def stream(domain, args, name='Rainbow Stream'):
     # These arguments are optional:
     stream_args = dict(
         timeout=0.5,  # To check g['stream_stop'] after each 0.5 s
-        block=not args.no_block,
-        heartbeat_timeout=args.heartbeat_timeout)
+        block=True,
+        heartbeat_timeout=c['HEARTBEAT_TIMEOUT'] * 60)
     # Track keyword
     query_args = dict()
     if args.track_keywords:
@@ -1723,6 +1715,17 @@ def stream(domain, args, name='Rainbow Stream'):
                     break
             elif tweet is HeartbeatTimeout:
                 printNicely("-- Heartbeat Timeout --")
+                guide = light_magenta("You can use ") + \
+                    light_green("switch") + \
+                    light_magenta(" command to return to your stream.\n")
+                guide += light_magenta("Type ") + \
+                    light_green("h stream") + \
+                    light_magenta(" for more details.")
+                printNicely(guide)
+                sys.stdout.write(g['decorated_name'](c['PREFIX']))
+                sys.stdout.flush()
+                StreamLock.release()
+                break
             elif tweet is Hangup:
                 printNicely("-- Hangup --")
             elif tweet.get('text'):
@@ -1739,9 +1742,9 @@ def stream(domain, args, name='Rainbow Stream'):
                 # after completely delete a word after typing it,
                 # somehow readline buffer still contains
                 # the 1st character of that word
-                if current_buffer and g['previous_cmd'] != current_buffer:
+                if current_buffer and g['cmd'] != current_buffer:
                     sys.stdout.write(
-                        g['decorated_name'](c['PREFIX']) + current_buffer)
+                        g['decorated_name'](c['PREFIX']) + str2u(current_buffer))
                     sys.stdout.flush()
                 elif not c['HIDE_PROMPT']:
                     sys.stdout.write(g['decorated_name'](c['PREFIX']))