From fd87ddac9e3f8c4f0a6e8b9aa0bf900262a99274 Mon Sep 17 00:00:00 2001 From: Orakaro Date: Sat, 23 Aug 2014 01:37:13 +0900 Subject: [PATCH] rearrange functions and add docs --- README.rst | 8 +- docs/conf.py | 4 +- docs/index.rst | 12 +- rainbowstream/colorset/config | 2 + rainbowstream/rainbow.py | 450 +++++++++++++++++----------------- setup.py | 2 +- 6 files changed, 242 insertions(+), 236 deletions(-) diff --git a/README.rst b/README.rst index ab9234a..3548034 100644 --- a/README.rst +++ b/README.rst @@ -50,7 +50,7 @@ Use `virtualenv`_ Troubleshooting ^^^^^^^^^^^^^^^ -If you use Linux, you might need to install some packages if you haven't already. +If you use Linux, you might need to install some packages if you haven't already. For debian-based distros, these can be installed with .. code:: bash @@ -95,9 +95,9 @@ You can try it with: rainbowstream -iot # Or rainbowstream --image-on-term -You also can change the config key ``IMAGE_ON_TERM`` to ``True`` inside the app -to enable above feature, -change ``IMAGE_SHIFT`` to set image's margin (relative to your terminal's width) +You also can change the config key ``IMAGE_ON_TERM`` to ``True`` inside the app +to enable above feature, +change ``IMAGE_SHIFT`` to set image's margin (relative to your terminal's width) or ``IMAGE_MAX_HEIGHT`` to control max height of every image. (see `config management`_ section). diff --git a/docs/conf.py b/docs/conf.py index 5ed636e..7b765b9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,9 +48,9 @@ copyright = u'2014, Vu Nhat Minh' # built documents. # # The short X.Y version. -version = '0.8.1' +version = '0.8.2' # The full version, including alpha/beta/rc tags. -release = '0.8.1' +release = '0.8.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/index.rst b/docs/index.rst index d32f510..56b97a5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -42,7 +42,7 @@ Use `virtualenv`_ Troubleshooting ^^^^^^^^^^^^^^^ -If you use Linux, you might need to install some packages if you haven't already. +If you use Linux, you might need to install some packages if you haven't already. For debian-based distros, these can be installed with .. code:: bash @@ -87,9 +87,9 @@ You can try it with: rainbowstream -iot # Or rainbowstream --image-on-term -You also can change the config key ``IMAGE_ON_TERM`` to ``True`` inside the app -to enable above feature, -change ``IMAGE_SHIFT`` to set image's margin (relative to your terminal's width) +You also can change the config key ``IMAGE_ON_TERM`` to ``True`` inside the app +to enable above feature, +change ``IMAGE_SHIFT`` to set image's margin (relative to your terminal's width) or ``IMAGE_MAX_HEIGHT`` to control max height of every image. (see `config management`_ section). @@ -143,6 +143,8 @@ Here is full list of supported command: - ``allrt 12 20`` will list 20 newest retweets of the tweet with *[id=12]*. If the number of retweets is not specified, 5 newest retweets will be listed instead. +- ``conversation 12`` will show the chain of replies prior to the tweet with *[id=12]*. + - ``rep 12 Really`` will reply *‘Really’* to the tweet with *[id=12]*. - ``fav 12`` will favorite the tweet with *[id=12]*. @@ -324,6 +326,8 @@ You can view or set a new value of every config key by ``config`` command (See * - ``RETWEETS_SHOW_NUM``: default tweets to display on 'allrt' command. +- ``CONVERSATION_MAX``: max tweet in a 'conversation' thread. + - ``QUOTE_FORMAT``: format when quote a tweet + ``#comment``: Your own comment about the tweet diff --git a/rainbowstream/colorset/config b/rainbowstream/colorset/config index 6845ed1..fe43317 100644 --- a/rainbowstream/colorset/config +++ b/rainbowstream/colorset/config @@ -17,6 +17,8 @@ "HOME_TWEET_NUM" : 5, // 'allrt': default number of retweets "RETWEETS_SHOW_NUM" : 5, + // 'conversation': max tweet in a thread + "CONVERSATION_MAX" : 30, // 'quote' format "QUOTE_FORMAT" : "#comment RT #owner: #tweet", // 'inbox','sent': default number of direct message diff --git a/rainbowstream/rainbow.py b/rainbowstream/rainbow.py index 9badc1e..1058b03 100644 --- a/rainbowstream/rainbow.py +++ b/rainbowstream/rainbow.py @@ -145,67 +145,6 @@ def init(args): c['IGNORE_LIST'] += build_mute_dict() -def switch(): - """ - Switch stream - """ - try: - target = g['stuff'].split()[0] - # Filter and ignore - args = parse_arguments() - try: - if g['stuff'].split()[-1] == '-f': - guide = 'To ignore an option, just hit Enter key.' - printNicely(light_magenta(guide)) - only = raw_input('Only nicks [Ex: @xxx,@yy]: ') - ignore = raw_input('Ignore nicks [Ex: @xxx,@yy]: ') - args.filter = filter(None, only.split(',')) - args.ignore = filter(None, ignore.split(',')) - elif g['stuff'].split()[-1] == '-d': - args.filter = c['ONLY_LIST'] - args.ignore = c['IGNORE_LIST'] - 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 - # 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 - # Start new thread - th = threading.Thread( - target=stream, - args=( - c['USER_DOMAIN'], - args, - g['original_name'])) - th.daemon = True - th.start() - printNicely('') - if args.filter: - printNicely(cyan('Only: ' + str(args.filter))) - if args.ignore: - printNicely(red('Ignore: ' + str(args.ignore))) - printNicely('') - except: - printNicely(red('Sorry I can\'t understand.')) - - def trend(): """ Trend @@ -255,6 +194,37 @@ def home(): printNicely('') +def mentions(): + """ + Mentions timeline + """ + t = Twitter(auth=authen()) + num = c['HOME_TWEET_NUM'] + if g['stuff'].isdigit(): + num = int(g['stuff']) + for tweet in reversed(t.statuses.mentions_timeline(count=num)): + draw(t=tweet) + printNicely('') + + +def whois(): + """ + Show profile of a specific user + """ + t = Twitter(auth=authen()) + screen_name = g['stuff'].split()[0] + if screen_name.startswith('@'): + try: + user = t.users.show( + screen_name=screen_name[1:], + include_entities=False) + show_profile(user) + except: + printNicely(red('Omg no user.')) + else: + printNicely(red('A name should begin with a \'@\'')) + + def view(): """ Friend view @@ -273,44 +243,21 @@ def view(): printNicely(red('A name should begin with a \'@\'')) -def mentions(): - """ - Mentions timeline - """ - t = Twitter(auth=authen()) - num = c['HOME_TWEET_NUM'] - if g['stuff'].isdigit(): - num = int(g['stuff']) - for tweet in reversed(t.statuses.mentions_timeline(count=num)): - draw(t=tweet) - printNicely('') - - -def conversation(): +def search(): """ - Conversation view + Search """ 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] - tweet = t.statuses.show(id=tid) - limit = 9 - thread_ref = [] - thread_ref.append (tweet) - prev_tid = tweet['in_reply_to_status_id'] - while prev_tid and limit: - limit -= 1 - tweet = t.statuses.show(id=prev_tid) - prev_tid = tweet['in_reply_to_status_id'] - thread_ref.append (tweet) - - for tweet in reversed(thread_ref): - draw(t=tweet) - printNicely('') + g['stuff'] = g['stuff'].strip() + rel = t.search.tweets(q=g['stuff'])['statuses'] + if rel: + printNicely('Newest tweets:') + for i in reversed(xrange(c['SEARCH_MAX_RECORD'])): + draw(t=rel[i], + keyword=g['stuff']) + printNicely('') + else: + printNicely(magenta('I\'m afraid there is no result')) def tweet(): @@ -389,9 +336,9 @@ def allretweet(): printNicely('') -def favorite(): +def conversation(): """ - Favorite + Conversation view """ t = Twitter(auth=authen()) try: @@ -400,9 +347,19 @@ def favorite(): printNicely(red('Sorry I can\'t understand.')) return tid = c['tweet_dict'][id] - t.favorites.create(_id=tid, include_entities=False) - printNicely(green('Favorited.')) - draw(t.statuses.show(id=tid)) + tweet = t.statuses.show(id=tid) + limit = c['CONVERSATION_MAX'] + thread_ref = [] + thread_ref.append(tweet) + prev_tid = tweet['in_reply_to_status_id'] + while prev_tid and limit: + limit -= 1 + tweet = t.statuses.show(id=prev_tid) + prev_tid = tweet['in_reply_to_status_id'] + thread_ref.append(tweet) + + for tweet in reversed(thread_ref): + draw(t=tweet) printNicely('') @@ -423,9 +380,9 @@ def reply(): t.statuses.update(status=status, in_reply_to_status_id=tid) -def delete(): +def favorite(): """ - Delete + Favorite """ t = Twitter(auth=authen()) try: @@ -434,8 +391,10 @@ def delete(): printNicely(red('Sorry I can\'t understand.')) return tid = c['tweet_dict'][id] - t.statuses.destroy(id=tid) - printNicely(green('Okay it\'s gone.')) + t.favorites.create(_id=tid, include_entities=False) + printNicely(green('Favorited.')) + draw(t.statuses.show(id=tid)) + printNicely('') def unfavorite(): @@ -455,41 +414,19 @@ def unfavorite(): printNicely('') -def search(): - """ - Search - """ - t = Twitter(auth=authen()) - g['stuff'] = g['stuff'].strip() - rel = t.search.tweets(q=g['stuff'])['statuses'] - if rel: - printNicely('Newest tweets:') - for i in reversed(xrange(c['SEARCH_MAX_RECORD'])): - draw(t=rel[i], - keyword=g['stuff']) - printNicely('') - else: - printNicely(magenta('I\'m afraid there is no result')) - - -def message(): +def delete(): """ - Send a direct message + Delete """ 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: + id = int(g['stuff'].split()[0]) + except: + printNicely(red('Sorry I can\'t understand.')) + return + tid = c['tweet_dict'][id] + t.statuses.destroy(id=tid) + printNicely(green('Okay it\'s gone.')) def show(): @@ -534,49 +471,6 @@ def urlopen(): printNicely(red('Sorry I can\'t open url in this tweet.')) -def ls(): - """ - List friends for followers - """ - t = Twitter(auth=authen()) - # Get name - try: - name = g['stuff'].split()[1] - if name.startswith('@'): - name = name[1:] - else: - printNicely(red('A name should begin with a \'@\'')) - raise Exception('Invalid name') - except: - name = g['original_name'] - # Get list followers or friends - try: - target = g['stuff'].split()[0] - except: - printNicely(red('Omg some syntax is wrong.')) - # Init cursor - d = {'fl': 'followers', 'fr': 'friends'} - next_cursor = -1 - rel = {} - # Cursor loop - while next_cursor != 0: - list = getattr(t, d[target]).list( - screen_name=name, - cursor=next_cursor, - skip_status=True, - include_entities=False, - ) - for u in list['users']: - rel[u['name']] = '@' + u['screen_name'] - next_cursor = list['next_cursor'] - # Print out result - printNicely('All: ' + str(len(rel)) + ' ' + d[target] + '.') - for name in rel: - user = ' ' + cycle_color(name) - user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ') - printNicely(user) - - def inbox(): """ Inbox direct messages @@ -643,6 +537,26 @@ def sent(): printNicely('') +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 \'@\'')) + + def trash(): """ Remove message @@ -657,22 +571,47 @@ def trash(): printNicely(green('Message deleted.')) -def whois(): +def ls(): """ - Show profile of a specific user + List friends for followers """ t = Twitter(auth=authen()) - screen_name = g['stuff'].split()[0] - if screen_name.startswith('@'): - try: - user = t.users.show( - screen_name=screen_name[1:], - include_entities=False) - show_profile(user) - except: - printNicely(red('Omg no user.')) - else: - printNicely(red('A name should begin with a \'@\'')) + # Get name + try: + name = g['stuff'].split()[1] + if name.startswith('@'): + name = name[1:] + else: + printNicely(red('A name should begin with a \'@\'')) + raise Exception('Invalid name') + except: + name = g['original_name'] + # Get list followers or friends + try: + target = g['stuff'].split()[0] + except: + printNicely(red('Omg some syntax is wrong.')) + # Init cursor + d = {'fl': 'followers', 'fr': 'friends'} + next_cursor = -1 + rel = {} + # Cursor loop + while next_cursor != 0: + list = getattr(t, d[target]).list( + screen_name=name, + cursor=next_cursor, + skip_status=True, + include_entities=False, + ) + for u in list['users']: + rel[u['name']] = '@' + u['screen_name'] + next_cursor = list['next_cursor'] + # Print out result + printNicely('All: ' + str(len(rel)) + ' ' + d[target] + '.') + for name in rel: + user = ' ' + cycle_color(name) + user += color_func(c['TWEET']['nick'])(' ' + rel[name] + ' ') + printNicely(user) def follow(): @@ -1082,6 +1021,67 @@ def twitterlist(): printNicely(red('Please try again.')) +def switch(): + """ + Switch stream + """ + try: + target = g['stuff'].split()[0] + # Filter and ignore + args = parse_arguments() + try: + if g['stuff'].split()[-1] == '-f': + guide = 'To ignore an option, just hit Enter key.' + printNicely(light_magenta(guide)) + only = raw_input('Only nicks [Ex: @xxx,@yy]: ') + ignore = raw_input('Ignore nicks [Ex: @xxx,@yy]: ') + args.filter = filter(None, only.split(',')) + args.ignore = filter(None, ignore.split(',')) + elif g['stuff'].split()[-1] == '-d': + args.filter = c['ONLY_LIST'] + args.ignore = c['IGNORE_LIST'] + 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 + # 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 + # Start new thread + th = threading.Thread( + target=stream, + args=( + c['USER_DOMAIN'], + args, + g['original_name'])) + th.daemon = True + th.start() + printNicely('') + if args.filter: + printNicely(cyan('Only: ' + str(args.filter))) + if args.ignore: + printNicely(red('Ignore: ' + str(args.ignore))) + printNicely('') + except: + printNicely(red('Sorry I can\'t understand.')) + + def cal(): """ Unix's command `cal` @@ -1093,6 +1093,33 @@ def cal(): show_calendar(month, date, rel) +def theme(): + """ + List and change theme + """ + if not g['stuff']: + # List themes + for theme in g['themes']: + line = light_magenta(theme) + if c['THEME'] == theme: + line = ' ' * 2 + light_yellow('* ') + line + else: + line = ' ' * 4 + line + printNicely(line) + else: + # Change theme + try: + # Load new theme + c['THEME'] = reload_theme(g['stuff'], c['THEME']) + # Redefine decorated_name + g['decorated_name'] = lambda x: color_func( + c['DECORATED_NAME'])( + '[' + x + ']: ') + printNicely(green('Theme changed.')) + except: + printNicely(red('No such theme exists.')) + + def config(): """ Browse and change config @@ -1157,33 +1184,6 @@ def config(): printNicely(light_magenta('Sorry I can\'s understand.')) -def theme(): - """ - List and change theme - """ - if not g['stuff']: - # List themes - for theme in g['themes']: - line = light_magenta(theme) - if c['THEME'] == theme: - line = ' ' * 2 + light_yellow('* ') + line - else: - line = ' ' * 4 + line - printNicely(line) - else: - # Change theme - try: - # Load new theme - c['THEME'] = reload_theme(g['stuff'], c['THEME']) - # Redefine decorated_name - g['decorated_name'] = lambda x: color_func( - c['DECORATED_NAME'])( - '[' + x + ']: ') - printNicely(green('Theme changed.')) - except: - printNicely(red('No such theme exists.')) - - def help_discover(): """ Discover the world @@ -1199,8 +1199,6 @@ def help_discover(): light_green('home 7') + ' will show 7 tweets.\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('conversation 12') + ' will show the chain of replies prior to the tweet with ' + \ - light_yellow('[id=12]') + '.\n' usage += s * 2 + light_green('whois @mdo') + ' will show profile of ' + \ magenta('@mdo') + '.\n' usage += s * 2 + light_green('view @mdo') + \ @@ -1231,6 +1229,8 @@ def help_tweets(): usage += s * 2 + \ light_green('allrt 12 20 ') + ' will list 20 newest retweet of the tweet with ' + \ light_yellow('[id=12]') + '.\n' + 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('[id=12]') + '.\n' @@ -1508,11 +1508,11 @@ cmdset = [ 'home', 'view', 'mentions', - 'conversation', 't', 'rt', 'quote', 'allrt', + 'conversation', 'fav', 'rep', 'del', @@ -1552,11 +1552,11 @@ funcset = [ home, view, mentions, - conversation, tweet, retweet, quote, allretweet, + conversation, favorite, reply, delete, @@ -1609,11 +1609,11 @@ def listen(): [], # home ['@'], # view [], # mentions - [], # conversation [], # tweet [], # retweet [], # quote [], # allretweet + [], # conversation [], # favorite [], # reply [], # delete diff --git a/setup.py b/setup.py index 55854d7..23e51f5 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import os import os.path # Bumped version -version = '0.8.1' +version = '0.8.2' # Require install_requires = [ -- 2.25.1