From 632c6fa515fe36cf88ef2bf39378464bd24701d8 Mon Sep 17 00:00:00 2001 From: Orakaro Date: Thu, 3 Jul 2014 00:56:05 +0900 Subject: [PATCH] change theme base on config --- rainbowstream/c_image.py | 4 +- rainbowstream/colors.py | 11 ++--- rainbowstream/colorset/default.json | 6 ++- rainbowstream/colorset/monokai.json | 59 ++++++++++++++++++++++++ rainbowstream/config.py | 17 ++++--- rainbowstream/draw.py | 43 +++++++++--------- rainbowstream/interactive.py | 6 +-- rainbowstream/rainbow.py | 69 ++++++++++++++++++++--------- setup.py | 2 +- 9 files changed, 153 insertions(+), 64 deletions(-) create mode 100644 rainbowstream/colorset/monokai.json diff --git a/rainbowstream/c_image.py b/rainbowstream/c_image.py index bc2112e..7b33489 100644 --- a/rainbowstream/c_image.py +++ b/rainbowstream/c_image.py @@ -27,7 +27,7 @@ def pixel_print(ansicolor): def image_to_display(path,start=None,length=None): rows, columns = os.popen('stty size', 'r').read().split() if not start: - start = IMAGE_SHIFT + start = c['IMAGE_SHIFT'] if not length: length = int(columns) - 2 * start i = Image.open(path) @@ -38,7 +38,7 @@ def image_to_display(path,start=None,length=None): height = int(float(h) * (float(width) / float(w))) height //= 2 i = i.resize((width, height), Image.ANTIALIAS) - height = min(height, IMAGE_MAX_HEIGHT) + height = min(height, c['IMAGE_MAX_HEIGHT']) for y in xrange(height): print ' ' * start, diff --git a/rainbowstream/colors.py b/rainbowstream/colors.py index e221e7f..bcf48ed 100644 --- a/rainbowstream/colors.py +++ b/rainbowstream/colors.py @@ -2,6 +2,7 @@ import random import itertools from functools import wraps from pyfiglet import figlet_format +from .config import * def basic_color(code): @@ -60,14 +61,8 @@ on_light_magenta = basic_color('105') on_light_cyan = basic_color('106') on_white = basic_color('107') -colors_shuffle = [ - grey, - light_red, - light_green, - light_yellow, - light_blue, - light_magenta, - light_cyan] +colors_shuffle = [locals()[i.encode('utf8')] if not i.startswith('RGB_') else RGB(int(i[4:])) for i in c['CYCLE_COLOR']] + background_shuffle = [ on_grey, on_light_red, diff --git a/rainbowstream/colorset/default.json b/rainbowstream/colorset/default.json index 7c42226..fea5e81 100644 --- a/rainbowstream/colorset/default.json +++ b/rainbowstream/colorset/default.json @@ -40,8 +40,12 @@ * light_magenta * light_cyan * white - + and 256 colors from RGB_0 to RGB_255 + Color code can be reference at + http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html */ + + "CYCLE_COLOR" :["light_red","light_green","light_yellow","light_blue","light_magenta","light_cyan"], "TWEET" : { "nick" : "grey", "clock" : "grey", diff --git a/rainbowstream/colorset/monokai.json b/rainbowstream/colorset/monokai.json new file mode 100644 index 0000000..4130427 --- /dev/null +++ b/rainbowstream/colorset/monokai.json @@ -0,0 +1,59 @@ +{ + /* Color config + There are 16 basic colors supported : + * default + * black + * red + * green + * yellow + * blue + * magenta + * cyan + * grey + * light_red + * light_green + * light_yellow + * light_blue + * light_magenta + * light_cyan + * white + and 256 colors from RGB_0 to RGB_255 + Color code can be reference at + http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html + */ + + "CYCLE_COLOR" :["RGB_198","RGB_57","RGB_166","RGB_50","RGB_179","RGB_74","RGB_112"], + "TWEET" : { + "nick" : "RGB_198", + "clock" : "RGB_57", + "id" : "RGB_166", + "favourite" : "RGB_50", + "rt" : "RGB_179", + "link" : "RGB_74", + "keyword" : "on_light_green" + }, + + "MESSAGE" : { + "sender" : "RGB_198", + "recipient" : "RGB_112", + "to" : "RGB_50", + "clock" : "RGB_57", + "id" : "RGB_166" + }, + + "PROFILE" : { + "statuses_count" : "RGB_112", + "friends_count" : "RGB_198", + "followers_count" : "RGB_57", + "nick" : "RGB_198", + "profile_image_url" : "RGB_74", + "description" : "RGB_166", + "location" : "RGB_112", + "url" : "RGB_74", + "clock" : "RGB_57" + }, + + "TREND" : { + "url": "RGB_74" + } +} \ No newline at end of file diff --git a/rainbowstream/config.py b/rainbowstream/config.py index de49969..3f61553 100644 --- a/rainbowstream/config.py +++ b/rainbowstream/config.py @@ -2,7 +2,6 @@ import json import re import os import os.path -from twitter.util import printNicely # Regular expression for comments comment_re = re.compile( @@ -21,14 +20,18 @@ def load_config(filepath): while match: content = content[:match.start()] + content[match.end():] match = comment_re.search(content) - data = json.loads(content) - for d in data: - globals()[d] = data[d] + return json.loads(content) except: pass -# Load colorset +# Load default colorset +c = {} default_config = 'rainbowstream/colorset/default.json' +data = load_config(default_config) +for d in data: + c[d] = data[d] +# Load user's colorset rainbow_config = os.environ.get('HOME', os.environ.get('USERPROFILE','')) + os.sep + '.rainbow_config.json' -load_config(default_config) -load_config(rainbow_config) +data = load_config(rainbow_config) +for d in data: + c[d] = data[d] diff --git a/rainbowstream/draw.py b/rainbowstream/draw.py index b0d5478..b35649c 100644 --- a/rainbowstream/draw.py +++ b/rainbowstream/draw.py @@ -20,6 +20,7 @@ def color_func(func_name): """ Call color function base on name """ + print globals()['TWEET'] pure = func_name.encode('utf8') if pure.startswith('RGB_') and pure[4:].isdigit(): return RGB(int(pure[4:])) @@ -78,10 +79,10 @@ def draw(t, iot=False, keyword=None, fil=[], ig=[]): rid = res[0].rainbow_id # Format info - user = cycle_color(name) + color_func(TWEET['nick'])(' ' + screen_name + ' ') - meta = color_func(TWEET['clock'])('[' + clock + '] ') + color_func(TWEET['id'])('[id=' + str(rid) + '] ') + user = cycle_color(name) + color_func(c['TWEET']['nick'])(' ' + screen_name + ' ') + meta = color_func(c['TWEET']['clock'])('[' + clock + '] ') + color_func(c['TWEET']['id'])('[id=' + str(rid) + '] ') if favorited: - meta = meta + color_func(TWEET['favorite'])(u'\u2605') + meta = meta + color_func(c['TWEET']['favorite'])(u'\u2605') tweet = text.split() # Replace url if expanded_url: @@ -90,15 +91,15 @@ def draw(t, iot=False, keyword=None, fil=[], ig=[]): lambda x: expanded_url[index] if x == url[index] else x, tweet) # Highlight RT - tweet = map(lambda x: color_func(TWEET['rt'])(x) if x == 'RT' else x, tweet) + tweet = map(lambda x: color_func(c['TWEET']['rt'])(x) if x == 'RT' else x, tweet) # Highlight screen_name tweet = map(lambda x: cycle_color(x) if x[0] == '@' else x, tweet) # Highlight link - tweet = map(lambda x: color_func(TWEET['link'])(x) if x[0:4] == 'http' else x, tweet) + tweet = map(lambda x: color_func(c['TWEET']['link'])(x) if x[0:4] == 'http' else x, tweet) # Highlight search keyword if keyword: tweet = map( - lambda x: color_func(TWEET['keyword'])(x) if + lambda x: color_func(c['TWEET']['keyword'])(x) if ''.join(c for c in x if c.isalnum()).lower() == keyword.lower() else x, tweet @@ -151,10 +152,10 @@ def print_message(m): rid = res[0].rainbow_id # Draw - sender = cycle_color(sender_name) + color_func(MESSAGE['sender'])(' ' + sender_screen_name + ' ') - recipient = cycle_color(recipient_name) + color_func(MESSAGE['recipient'])(' ' + recipient_screen_name + ' ') - user = sender + color_func(MESSAGE['to'])(' >>> ') + recipient - meta = color_func(MESSAGE['clock'])('[' + clock + ']') + color_func(MESSAGE['id'])(' [message_id=' + str(rid) + '] ') + sender = cycle_color(sender_name) + color_func(c['MESSAGE']['sender'])(' ' + sender_screen_name + ' ') + recipient = cycle_color(recipient_name) + color_func(c['MESSAGE']['recipient'])(' ' + recipient_screen_name + ' ') + user = sender + color_func(c['MESSAGE']['to'])(' >>> ') + recipient + meta = color_func(c['MESSAGE']['clock'])('[' + clock + ']') + color_func(c['MESSAGE']['id'])(' [message_id=' + str(rid) + '] ') text = ''.join(map(lambda x: x + ' ' if x == '\n' else x, text)) line1 = u"{u:>{uw}}:".format( @@ -191,21 +192,21 @@ def show_profile(u, iot=False): followers_count = u['followers_count'] # Create content - statuses_count = color_func(PROFILE['statuses_count'])(str(statuses_count) + ' tweets') - friends_count = color_func(PROFILE['friends_count'])(str(friends_count) + ' following') - followers_count = color_func(PROFILE['followers_count'])(str(followers_count) + ' followers') + statuses_count = color_func(c['PROFILE']['statuses_count'])(str(statuses_count) + ' tweets') + friends_count = color_func(c['PROFILE']['friends_count'])(str(friends_count) + ' following') + followers_count = color_func(c['PROFILE']['followers_count'])(str(followers_count) + ' followers') count = statuses_count + ' ' + friends_count + ' ' + followers_count - user = cycle_color(name) + color_func(PROFILE['nick'])(' @' + screen_name + ' : ') + count - profile_image_raw_url = 'Profile photo: ' + color_func(PROFILE['profile_image_url'])(profile_image_url) + user = cycle_color(name) + color_func(c['PROFILE']['nick'])(' @' + screen_name + ' : ') + count + profile_image_raw_url = 'Profile photo: ' + color_func(c['PROFILE']['profile_image_url'])(profile_image_url) description = ''.join( map(lambda x: x + ' ' * 4 if x == '\n' else x, description)) - description = color_func(PROFILE['description'])(description) - location = 'Location : ' + color_func(PROFILE['location'])(location) - url = 'URL : ' + (color_func(PROFILE['url'])(url) if url else '') + description = color_func(c['PROFILE']['description'])(description) + location = 'Location : ' + color_func(c['PROFILE']['location'])(location) + url = 'URL : ' + (color_func(c['PROFILE']['url'])(url) if url else '') date = parser.parse(created_at) date = date - datetime.timedelta(seconds=time.timezone) clock = date.strftime('%Y/%m/%d %H:%M:%S') - clock = 'Join at ' + color_func(PROFILE['clock'])(clock) + clock = 'Join at ' + color_func(c['PROFILE']['clock'])(clock) # Format line1 = u"{u:>{uw}}".format( @@ -250,10 +251,10 @@ def print_trends(trends): """ Display topics """ - for topic in trends[:TREND_MAX]: + for topic in trends[:c['TREND_MAX']]: name = topic['name'] url = topic['url'] - line = cycle_color(name) + ': ' + TREND['url'](url) + line = cycle_color(name) + ': ' + color_func(TREND['url'])(url) printNicely(line) printNicely('') diff --git a/rainbowstream/interactive.py b/rainbowstream/interactive.py index 98b9c21..afbbc05 100644 --- a/rainbowstream/interactive.py +++ b/rainbowstream/interactive.py @@ -68,15 +68,15 @@ def read_history(): """ Read history file """ - if os.path.isfile(HISTORY_FILENAME): - readline.read_history_file(HISTORY_FILENAME) + if os.path.isfile(c['HISTORY_FILENAME']): + readline.read_history_file(c['HISTORY_FILENAME']) def save_history(): """ Save history to file """ - readline.write_history_file(HISTORY_FILENAME) + readline.write_history_file(c['HISTORY_FILENAME']) def init_interactive_shell(d): diff --git a/rainbowstream/rainbow.py b/rainbowstream/rainbow.py index e6488f0..f31fa23 100644 --- a/rainbowstream/rainbow.py +++ b/rainbowstream/rainbow.py @@ -2,7 +2,6 @@ Colorful user's timeline stream """ from multiprocessing import Process -from dateutil import parser import os import os.path @@ -10,7 +9,6 @@ import sys import signal import argparse import time -import datetime import requests from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup @@ -60,6 +58,7 @@ cmdset = [ 'unblock', 'report', 'cal', + 'theme', 'h', 'c', 'q' @@ -136,6 +135,10 @@ def get_decorated_name(): g['original_name'] = name[1:] g['decorated_name'] = grey('[') + grey(name) + grey(']: ') + files = os.listdir('rainbowstream/colorset') + themes = [f.split('.')[0] for f in files if f.split('.')[-1]=='json'] + g['themes'] = themes + def switch(): """ @@ -153,8 +156,8 @@ def switch(): args.filter = filter(None, only.split(',')) args.ignore = filter(None, ignore.split(',')) elif g['stuff'].split()[-1] == '-d': - args.filter = ONLY_LIST - args.ignore = IGNORE_LIST + args.filter = c['ONLY_LIST'] + args.ignore = c['IGNORE_LIST'] except: printNicely(red('Sorry, wrong format.')) return @@ -171,7 +174,7 @@ def switch(): p = Process( target=stream, args=( - PUBLIC_DOMAIN, + c['PUBLIC_DOMAIN'], args)) p.start() g['stream_pid'] = p.pid @@ -184,7 +187,7 @@ def switch(): p = Process( target=stream, args=( - USER_DOMAIN, + c['USER_DOMAIN'], args, g['original_name'])) p.start() @@ -242,7 +245,7 @@ def home(): Home """ t = Twitter(auth=authen()) - num = HOME_TWEET_NUM + num = c['HOME_TWEET_NUM'] if g['stuff'].isdigit(): num = int(g['stuff']) for tweet in reversed(t.statuses.home_timeline(count=num)): @@ -260,7 +263,7 @@ def view(): try: num = int(g['stuff'].split()[1]) except: - num = HOME_TWEET_NUM + num = c['HOME_TWEET_NUM'] for tweet in reversed(t.statuses.user_timeline(count=num, screen_name=user[1:])): draw(t=tweet, iot=g['iot']) printNicely('') @@ -273,7 +276,7 @@ def mentions(): Mentions timeline """ t = Twitter(auth=authen()) - num = HOME_TWEET_NUM + num = c['HOME_TWEET_NUM'] if g['stuff'].isdigit(): num = int(g['stuff']) for tweet in reversed(t.statuses.mentions_timeline(count=num)): @@ -319,7 +322,7 @@ def allretweet(): try: num = int(g['stuff'].split()[1]) except: - num = RETWEETS_SHOW_NUM + num = c['RETWEETS_SHOW_NUM'] # Get result and display rt_ary = t.statuses.retweets(id=tid, count=num) if not rt_ary: @@ -405,7 +408,7 @@ def search(): rel = t.search.tweets(q=g['stuff'])['statuses'] if rel: printNicely('Newest tweets:') - for i in reversed(xrange(SEARCH_MAX_RECORD)): + for i in reversed(xrange(c['SEARCH_MAX_RECORD'])): draw(t=rel[i], iot=g['iot'], keyword=g['stuff'].strip()[1:]) @@ -504,7 +507,7 @@ def inbox(): Inbox direct messages """ t = Twitter(auth=authen()) - num = MESSAGES_DISPLAY + num = c['MESSAGES_DISPLAY'] rel = [] if g['stuff'].isdigit(): num = g['stuff'] @@ -537,7 +540,7 @@ def sent(): Sent direct messages """ t = Twitter(auth=authen()) - num = MESSAGES_DISPLAY + num = c['MESSAGES_DISPLAY'] rel = [] if g['stuff'].isdigit(): num = int(g['stuff']) @@ -671,7 +674,6 @@ def muting(): """ t = Twitter(auth=authen()) # Init cursor - d = {'fl': 'followers', 'fr': 'friends'} next_cursor = -1 rel = {} # Cursor loop @@ -758,6 +760,27 @@ def cal(): printNicely(' '.join(ary)) +def theme(): + """ + List and change theme + """ + if not g['stuff']: + # List themes + for theme in g['themes']: + line = ' '*2 + magenta('* ' + theme) + printNicely(line) + else: + # Change theme + try : + new_config = 'rainbowstream/colorset/' + g['stuff'] + '.json' + new_config = load_config(new_config) + for nc in new_config: + c[nc] = new_config[nc] + printNicely(green('Theme changed.')) + except : + printNicely(red('Sorry, config file is broken!')) + + def help(): """ Help @@ -869,7 +892,6 @@ def help(): ' filter will decide nicks will be EXCLUDE.\n' usage += s * 2 + green('switch mine -d') + \ ' will use the config\'s ONLY_LIST and IGNORE_LIST.\n' - usage += s * 3 + '(see ' + grey('rainbowstream/config.py') + ').\n' # Smart shell usage += '\n' @@ -882,6 +904,9 @@ def help(): # Screening usage += '\n' usage += s + grey(u'\u266A' + ' Screening \n') + usage += s * 2 + green('theme') + ' will list available theme.' + \ + green('theme monokai') + ' will apply '+ yellow('monokai') + \ + ' theme immediately.\n' usage += s * 2 + green('h') + ' will show this help again.\n' usage += s * 2 + green('c') + ' will clear the screen.\n' usage += s * 2 + green('q') + ' will quit.\n' @@ -959,6 +984,7 @@ def process(cmd): unblock, report, cal, + theme, help, clear, quit @@ -1002,6 +1028,7 @@ def listen(): ['@'], # unblock ['@'], # report [], # cal + g['themes'], # theme [], # help [], # clear [], # quit @@ -1040,9 +1067,9 @@ def stream(domain, args, name='Rainbow Stream'): # The Logo art_dict = { - USER_DOMAIN: name, - PUBLIC_DOMAIN: args.track_keywords, - SITE_DOMAIN: 'Site Stream', + c['USER_DOMAIN']: name, + c['PUBLIC_DOMAIN']: args.track_keywords, + c['SITE_DOMAIN']: 'Site Stream', } ascii_art(art_dict[domain]) @@ -1063,9 +1090,9 @@ def stream(domain, args, name='Rainbow Stream'): domain=domain, **stream_args) - if domain == USER_DOMAIN: + if domain == c['USER_DOMAIN']: tweet_iter = stream.user(**query_args) - elif domain == SITE_DOMAIN: + elif domain == c['SITE_DOMAIN']: tweet_iter = stream.site(**query_args) else: if args.track_keywords: @@ -1104,7 +1131,7 @@ def fly(): # Spawn stream process args = parse_arguments() get_decorated_name() - p = Process(target=stream, args=(USER_DOMAIN, args, g['original_name'])) + p = Process(target=stream, args=(c['USER_DOMAIN'], args, g['original_name'])) p.start() # Start listen process diff --git a/setup.py b/setup.py index b4f59a0..57d3685 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '0.1.1' +version = '0.1.2' install_requires = [ "SQLAlchemy", -- 2.25.1