Delete unused Error
[rainbowstream.git] / rainbowstream / rainbow.py
index fe14401..53fcd63 100644 (file)
@@ -42,6 +42,11 @@ def parse_arguments():
     """
     parser = argparse.ArgumentParser(description=__doc__ or "")
     parser.add_argument(
+        '-s',
+        '--stream',
+             default="mine",
+        help='Default stream after program start. (Default: mine)')
+    parser.add_argument(
         '-to',
         '--timeout',
         help='Timeout for the stream (seconds).')
@@ -99,7 +104,7 @@ def proxy_connect(args):
                 int(args.proxy_port))
         else:
             printNicely(
-                magenta("Sorry, wrong proxy type specified! Aborting..."))
+                magenta('Sorry, wrong proxy type specified! Aborting...'))
             sys.exit()
         socket.socket = socks.socksocket
 
@@ -115,7 +120,7 @@ def authen():
             'USERPROFILE',
             '')) + os.sep + '.rainbow_oauth'
     if not os.path.exists(twitter_credential):
-        oauth_dance("Rainbow Stream",
+        oauth_dance('Rainbow Stream',
                     CONSUMER_KEY,
                     CONSUMER_SECRET,
                     twitter_credential)
@@ -167,10 +172,10 @@ def upgrade_center():
     Check latest and notify to upgrade
     """
     try:
-        current = pkg_resources.get_distribution("rainbowstream").version
+        current = pkg_resources.get_distribution('rainbowstream').version
         url = 'https://raw.githubusercontent.com/DTVD/rainbowstream/master/setup.py'
         readme = requests.get(url).text
-        latest = readme.split("version = \'")[1].split("\'")[0]
+        latest = readme.split('version = \'')[1].split('\'')[0]
         if current != latest:
             notice = light_magenta('RainbowStream latest version is ')
             notice += light_green(latest)
@@ -202,8 +207,6 @@ def init(args):
     credential = t.account.verify_credentials()
     screen_name = '@' + credential['screen_name']
     name = credential['name']
-    if not get_config('PREFIX'):
-        set_config('PREFIX', screen_name)
     c['original_name'] = g['original_name'] = screen_name[1:]
     g['listname'] = g['keyword'] = ''
     g['PREFIX'] = u2str(emojize(format_prefix()))
@@ -321,7 +324,11 @@ def whois():
     Show profile of a specific user
     """
     t = Twitter(auth=authen())
-    screen_name = g['stuff'].split()[0]
+    try:
+        screen_name = g['stuff'].split()[0]
+    except:
+        printNicely(red('Sorry I can\'t understand.'))
+        return
     if screen_name.startswith('@'):
         try:
             user = t.users.show(
@@ -340,7 +347,11 @@ def view():
     Friend view
     """
     t = Twitter(auth=authen())
-    user = g['stuff'].split()[0]
+    try:
+        user = g['stuff'].split()[0]
+    except:
+        printNicely(red('Sorry I can\'t understand.'))
+        return
     if user[0] == '@':
         try:
             num = int(g['stuff'].split()[1])
@@ -361,6 +372,9 @@ def search():
     t = Twitter(auth=authen())
     # Setup query
     query = g['stuff'].strip()
+    if not query:
+        printNicely(red('Sorry I can\'t understand.'))
+        return
     type = c['SEARCH_TYPE']
     if type not in ['mixed', 'recent', 'popular']:
         type = 'mixed'
@@ -503,6 +517,29 @@ def reply():
     t.statuses.update(status=status, in_reply_to_status_id=tid)
 
 
+def reply_all():
+    """
+    Reply to all
+    """
+    t = Twitter(auth=authen())
+    try:
+        id = int(g['stuff'].split()[0])
+    except:
+        printNicely(red('Sorry I can\'t understand.'))
+        return
+    tid = c['tweet_dict'][id]
+    original_tweet = t.statuses.show(id=tid)
+    text = original_tweet['text']
+    nick_ary = [original_tweet['user']['screen_name']]
+    for user in list(original_tweet['entities']['user_mentions']):
+        if user['screen_name'] not in nick_ary \
+                and user['screen_name'] != g['original_name']:
+            nick_ary.append(user['screen_name'])
+    status = ' '.join(g['stuff'].split()[1:])
+    status = ' '.join(['@' + nick for nick in nick_ary]) + ' ' + str2u(status)
+    t.statuses.update(status=status, in_reply_to_status_id=tid)
+
+
 def favorite():
     """
     Favorite
@@ -756,6 +793,7 @@ def ls():
         target = g['stuff'].split()[0]
     except:
         printNicely(red('Omg some syntax is wrong.'))
+        return
     # Init cursor
     d = {'fl': 'followers', 'fr': 'friends'}
     next_cursor = -1
@@ -937,6 +975,22 @@ def get_slug():
         raise Exception('Wrong list name')
 
 
+def check_slug(list_name):
+    """
+    Check slug
+    """
+    # Get list name and owner
+    try:
+        owner, slug = list_name.split('/')
+        if slug.startswith('@'):
+            slug = slug[1:]
+        return owner, slug
+    except:
+        printNicely(
+            light_magenta('List name should follow "@owner/list_name" format.'))
+        raise Exception('Wrong list name')
+
+
 def show_lists(t):
     """
     List list
@@ -1235,89 +1289,19 @@ def switch():
         except:
             printNicely(red('Sorry, wrong format.'))
             return
-        # Public stream
-        if target == 'public':
-            keyword = g['stuff'].split()[1]
-            if keyword[0] == '#':
-                keyword = keyword[1:]
-            # Kill old thread
-            g['stream_stop'] = True
-            args.track_keywords = keyword
-            # Set the variable to tracked keyword
-            # and reset the listname
-            g['keyword'] = keyword
-            g['listname'] = ''
-            # Reset prefix
-            g['PREFIX'] = u2str(emojize(format_prefix(keyword = g['keyword'])))
-            # Start new thread
-            th = threading.Thread(
-                target=stream,
-                args=(
-                    c['PUBLIC_DOMAIN'],
-                    args))
-            th.daemon = True
-            th.start()
-        # Personal stream
-        elif target == 'mine':
-            # Kill old thread
-            g['stream_stop'] = True
-            # Reset the tracked keyword and listname
-            g['keyword'] = g['listname'] = ''
-            # Reset prefix
-            g['PREFIX'] = u2str(emojize(format_prefix()))
-            # Start new thread
-            th = threading.Thread(
-                target=stream,
-                args=(
-                    c['USER_DOMAIN'],
-                    args,
-                    g['original_name']))
-            th.daemon = True
-            th.start()
-        # Stream base on list
-        elif target == 'list':
-            owner, slug = get_slug()
-            # Force python 2 not redraw readline buffer
-            listname = '/'.join([owner, slug])
-            # Set the listname variable 
-            # and reset tracked keyword
-            g['listname'] = listname
-            g['keyword'] = ''
-            g['PREFIX'] = g['cmd'] = u2str(emojize(format_prefix(listname = g['listname'])))
-            printNicely(light_yellow('getting list members ...'))
-            # Get members
-            t = Twitter(auth=authen())
-            members = []
-            next_cursor = -1
-            while next_cursor != 0:
-                m = t.lists.members(
-                    slug=slug,
-                    owner_screen_name=owner,
-                    cursor=next_cursor,
-                    include_entities=False)
-                for u in m['users']:
-                    members.append('@' + u['screen_name'])
-                next_cursor = m['next_cursor']
-            printNicely(light_yellow('... done.'))
-            # Build thread filter array
-            args.filter = members
-            # Kill old thread
-            g['stream_stop'] = True
-            # Start new thread
-            th = threading.Thread(
-                target=stream,
-                args=(
-                    c['USER_DOMAIN'],
-                    args,
-                    slug))
-            th.daemon = True
-            th.start()
-        printNicely('')
-        if args.filter:
-            printNicely(cyan('Include: ' + str(len(args.filter)) + ' people.'))
-        if args.ignore:
-            printNicely(red('Ignore: ' + str(len(args.ignore)) + ' people.'))
-        printNicely('')
+        # Kill old thread
+        g['stream_stop'] = True
+        try: 
+            stuff = g['stuff'].split()[1]
+        except:
+            stuff = None
+        # Spawn new thread
+        spawn_dict = {
+            'public': spawn_public_stream,
+            'list': spawn_list_stream,
+            'mine': spawn_personal_stream,
+        }
+        spawn_dict.get(target)(args, stuff)
     except:
         debug_option()
         printNicely(red('Sorry I can\'t understand.'))
@@ -1420,7 +1404,10 @@ def config():
                 g['decorated_name'] = lambda x: color_func(
                     c['DECORATED_NAME'])('[' + x + ']: ')
             elif key == 'PREFIX':
-                g['PREFIX'] = u2str(emojize(format_prefix(listname = g['listname'], keyword = g['keyword'])))
+                g['PREFIX'] = u2str(emojize(format_prefix(
+                    listname=g['listname'],
+                    keyword=g['keyword']
+                )))
             reload_config()
             printNicely(green('Updated successfully.'))
         except:
@@ -1480,7 +1467,10 @@ def help_tweets():
     usage += s * 2 + light_green('conversation 12') + ' will show the chain of ' + \
         'replies prior to the tweet with ' + light_yellow('[id=12]') + '.\n'
     usage += s * 2 + light_green('rep 12 oops') + ' will reply "' + \
-        light_yellow('oops') + '" to tweet with ' + \
+        light_yellow('oops') + '" to the owner of the tweet with ' + \
+        light_yellow('[id=12]') + '.\n'
+    usage += s * 2 + light_green('repall 12 oops') + ' will reply "' + \
+        light_yellow('oops') + '" to all people in the tweet with ' + \
         light_yellow('[id=12]') + '.\n'
     usage += s * 2 + \
         light_green('fav 12 ') + ' will favorite the tweet with ' + \
@@ -1768,6 +1758,7 @@ cmdset = [
     'conversation',
     'fav',
     'rep',
+    'repall',
     'del',
     'ufav',
     'share',
@@ -1815,6 +1806,7 @@ funcset = [
     conversation,
     favorite,
     reply,
+    reply_all,
     delete,
     unfavorite,
     share,
@@ -1875,6 +1867,7 @@ def listen():
             [],  # conversation
             [],  # favorite
             [],  # reply
+            [],  # reply_all
             [],  # delete
             [],  # unfavorite
             [],  # url
@@ -1968,12 +1961,12 @@ def reconn_notice():
     """
     Notice when Hangup or 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.")
+    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'](g['PREFIX']))
     sys.stdout.flush()
@@ -1986,11 +1979,11 @@ def stream(domain, args, name='Rainbow Stream'):
     # The Logo
     art_dict = {
         c['USER_DOMAIN']: name,
-        c['PUBLIC_DOMAIN']: args.track_keywords,
+        c['PUBLIC_DOMAIN']: args.track_keywords or 'Global',
         c['SITE_DOMAIN']: name,
     }
     if c['ASCII_ART']:
-        ascii_art(art_dict[domain])
+        ascii_art(art_dict.get(domain, name))
     # These arguments are optional:
     stream_args = dict(
         timeout=0.5,  # To check g['stream_stop'] after each 0.5 s
@@ -2021,7 +2014,7 @@ def stream(domain, args, name='Rainbow Stream'):
         last_tweet_time = time.time()
         for tweet in tweet_iter:
             if tweet is None:
-                printNicely("-- None --")
+                printNicely('-- None --')
             elif tweet is Timeout:
                 # Because the stream check for each 0.3s
                 # so we shouldn't output anything here
@@ -2029,12 +2022,12 @@ def stream(domain, args, name='Rainbow Stream'):
                     StreamLock.release()
                     break
             elif tweet is HeartbeatTimeout:
-                printNicely("-- Heartbeat Timeout --")
+                printNicely('-- Heartbeat Timeout --')
                 reconn_notice()
                 StreamLock.release()
                 break
             elif tweet is Hangup:
-                printNicely("-- Hangup --")
+                printNicely('-- Hangup --')
                 reconn_notice()
                 StreamLock.release()
                 break
@@ -2082,10 +2075,110 @@ def stream(domain, args, name='Rainbow Stream'):
     except TwitterHTTPError as e:
         printNicely('')
         printNicely(
-            magenta("We have connection problem with twitter'stream API right now :("))
+            magenta('We have connection problem with twitter stream API right now :('))
         detail_twitter_error(e)
         sys.stdout.write(g['decorated_name'](g['PREFIX']))
         sys.stdout.flush()
+    except (URLError):
+        printNicely(
+            magenta('There seems to be a connection problem.'))
+        save_history()
+        sys.exit()
+
+
+def spawn_public_stream(args, keyword=None):
+    """
+    Spawn a new public stream
+    """
+    # Only set keyword if specified
+    if keyword:
+        if keyword[0] == '#':
+            keyword = keyword[1:]
+        args.track_keywords = keyword
+        g['keyword'] = keyword
+    else:
+        g['keyword'] = 'Global'
+    g['PREFIX'] = u2str(emojize(format_prefix(keyword=g['keyword'])))
+    g['listname'] = ''
+    # Start new thread
+    th = threading.Thread(
+        target=stream,
+        args=(
+            c['PUBLIC_DOMAIN'],
+            args))
+    th.daemon = True
+    th.start()
+
+
+def spawn_list_stream(args, stuff=None):
+    """
+    Spawn a new list stream
+    """
+    try:
+        owner, slug = check_slug(stuff)
+    except:
+        owner, slug = get_slug()
+
+    # Force python 2 not redraw readline buffer
+    listname = '/'.join([owner, slug])
+    # Set the listname variable
+    # and reset tracked keyword
+    g['listname'] = listname
+    g['keyword'] = ''
+    g['PREFIX'] = g['cmd'] = u2str(emojize(format_prefix(
+        listname=g['listname']
+    )))
+    printNicely(light_yellow('getting list members ...'))
+    # Get members
+    t = Twitter(auth=authen())
+    members = []
+    next_cursor = -1
+    while next_cursor != 0:
+        m = t.lists.members(
+            slug=slug,
+            owner_screen_name=owner,
+            cursor=next_cursor,
+            include_entities=False)
+        for u in m['users']:
+            members.append('@' + u['screen_name'])
+        next_cursor = m['next_cursor']
+    printNicely(light_yellow('... done.'))
+    # Build thread filter array
+    args.filter = members
+    # Start new thread
+    th = threading.Thread(
+        target=stream,
+        args=(
+            c['USER_DOMAIN'],
+            args,
+            slug))
+    th.daemon = True
+    th.start()
+    printNicely('')
+    if args.filter:
+        printNicely(cyan('Include: ' + str(len(args.filter)) + ' people.'))
+    if args.ignore:
+        printNicely(red('Ignore: ' + str(len(args.ignore)) + ' people.'))
+    printNicely('')
+
+
+def spawn_personal_stream(args, stuff=None):
+    """
+    Spawn a new personal stream
+    """
+    # Reset the tracked keyword and listname
+    g['keyword'] = g['listname'] = ''
+    # Reset prefix
+    g['PREFIX'] = u2str(emojize(format_prefix()))
+    # Start new thread
+    th = threading.Thread(
+        target=stream,
+        args=(
+            c['USER_DOMAIN'],
+            args,
+            g['original_name']))
+    th.daemon = True
+    th.start()
 
 
 def fly():
@@ -2101,28 +2194,34 @@ def fly():
     except TwitterHTTPError as e:
         printNicely('')
         printNicely(
-            magenta("We have connection problem with twitter'REST API right now :("))
+            magenta('We have connection problem with twitter REST API right now :('))
         detail_twitter_error(e)
         save_history()
         sys.exit()
     # Proxy connection problem
     except (socks.ProxyConnectionError, URLError):
         printNicely(
-            magenta("There seems to be a connection problem."))
+            magenta('There seems to be a connection problem.'))
         printNicely(
-            magenta("You might want to check your proxy settings (host, port and type)!"))
+            magenta('You might want to check your proxy settings (host, port and type)!'))
         save_history()
         sys.exit()
 
     # Spawn stream thread
-    th = threading.Thread(
-        target=stream,
-        args=(
-            c['USER_DOMAIN'],
-            args,
-            g['original_name']))
-    th.daemon = True
-    th.start()
+    target = args.stream.split()[0]
+    if target == 'mine' :
+        spawn_personal_stream(args)
+    else:
+        try:
+            stuff = args.stream.split()[1]
+        except:
+            stuff = None
+        spawn_dict = {
+            'public': spawn_public_stream,
+            'list': spawn_list_stream,
+        }
+        spawn_dict.get(target)(args, stuff)
+
     # Start listen process
     time.sleep(0.5)
     g['reset'] = True