diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..4e16e2fd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM python:2.7.9 + +RUN pip install rainbowstream +CMD rainbowstream diff --git a/docs/conf.py b/docs/conf.py index aad7d312..3c2d6aab 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,9 +48,9 @@ # built documents. # # The short X.Y version. -version = '1.2.7' +version = '1.3.0' # The full version, including alpha/beta/rc tags. -release = '1.2.7' +release = '1.3.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/rainbowstream/c_image.py b/rainbowstream/c_image.py index f0501502..a044e076 100644 --- a/rainbowstream/c_image.py +++ b/rainbowstream/c_image.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from PIL import Image from os.path import join, dirname, getmtime, exists, expanduser from .config import * @@ -24,11 +25,35 @@ def call_c(): rgb2short = call_c() -def pixel_print(ansicolor): +def pixel_print(pixel): """ Print a pixel with given Ansi color """ - sys.stdout.write('\033[48;5;%sm \033[0m' % (ansicolor)) + r, g, b = pixel[:3] + + if c['24BIT'] is True: + sys.stdout.write('\033[48;2;%d;%d;%dm \033[0m' + % (r, g, b)) + else: + ansicolor = rgb2short(r, g, b) + sys.stdout.write('\033[48;5;%sm \033[0m' % (ansicolor)) + + +def block_print(higher, lower): + """ + Print two pixels arranged above each other with Ansi color. + Abuses Unicode to print two pixels in the space of one terminal block. + """ + r0, g0, b0 = lower[:3] + r1, g1, b1 = higher[:3] + + if c['24BIT'] is True: + sys.stdout.write('\033[38;2;%d;%d;%dm\033[48;2;%d;%d;%dm▄\033[0m' + % (r1, g1, b1, r0, g0, b0)) + else: + i0 = rgb2short(r0, g0, b0) + i1 = rgb2short(r1, g1, b1) + sys.stdout.write('\033[38;5;%sm\033[48;5;%sm▄\033[0m' % (i1, i0)) def image_to_display(path, start=None, length=None): @@ -46,16 +71,16 @@ def image_to_display(path, start=None, length=None): i.load() width = min(w, length) height = int(float(h) * (float(width) / float(w))) - height //= 2 i = i.resize((width, height), Image.ANTIALIAS) height = min(height, c['IMAGE_MAX_HEIGHT']) - for y in xrange(height): + for real_y in xrange(height // 2): sys.stdout.write(' ' * start) for x in xrange(width): - p = i.getpixel((x, y)) - r, g, b = p[:3] - pixel_print(rgb2short(r, g, b)) + y = real_y * 2 + p0 = i.getpixel((x, y)) + p1 = i.getpixel((x, y + 1)) + block_print(p1, p0) sys.stdout.write('\n') diff --git a/rainbowstream/rainbow.py b/rainbowstream/rainbow.py index b65e62a8..8e9e22b6 100644 --- a/rainbowstream/rainbow.py +++ b/rainbowstream/rainbow.py @@ -47,7 +47,7 @@ def parse_arguments(): parser.add_argument( '-s', '--stream', - default="mine", + default="mine", help='Default stream after program start. (Default: mine)') parser.add_argument( '-to', @@ -70,6 +70,11 @@ def parse_arguments(): '--image-on-term', action='store_true', help='Display all image on terminal.') + parser.add_argument( + '-24', + '--color-24bit', + action='store_true', + help='Display images using 24bit color codes.') parser.add_argument( '-ph', '--proxy-host', @@ -208,7 +213,8 @@ def upgrade_center(): url = 'https://raw.githubusercontent.com/DTVD/rainbowstream/master/setup.py' readme = requests.get(url).text latest = readme.split('version = \'')[1].split('\'')[0] - if current != latest: + g['using_latest'] = current == latest + if not g['using_latest']: notice = light_magenta('RainbowStream latest version is ') notice += light_green(latest) notice += light_magenta(' while your current version is ') @@ -220,7 +226,7 @@ def upgrade_center(): notice = light_yellow('You are running latest version (') notice += light_green(current) notice += light_yellow(')') - printNicely(notice) + notice += '\n' except: pass @@ -266,6 +272,8 @@ def init(args): # Image on term c['IMAGE_ON_TERM'] = args.image_on_term set_config('IMAGE_ON_TERM', str(c['IMAGE_ON_TERM'])) + # Use 24 bit color + c['24BIT'] = args.color_24bit # Check type of ONLY_LIST and IGNORE_LIST if not isinstance(c['ONLY_LIST'], list): printNicely(red('ONLY_LIST is not a valid list value.')) @@ -725,14 +733,14 @@ def urlopen(): return tid = c['tweet_dict'][int(g['stuff'])] tweet = t.statuses.show(id=tid) - link_prefix = ('http://', 'https://') - link_ary = [u for u in tweet['text'].split() - if u.startswith(link_prefix)] - if not link_ary: + urls = tweet['entities']['urls'] + if not urls: printNicely(light_magenta('No url here @.@!')) return - for link in link_ary: - webbrowser.open(link) + else: + for url in urls: + expanded_url = url['expanded_url'] + webbrowser.open(expanded_url) except: debug_option() printNicely(red('Sorry I can\'t open url in this tweet.')) @@ -2028,6 +2036,7 @@ def listen(): c['lock'] = True # Save cmd to global variable and call process g['stuff'] = ' '.join(line.split()[1:]) + # Check tweet length # Process the command process(cmd)() # Not re-display @@ -2039,9 +2048,11 @@ def listen(): c['lock'] = False except EOFError: printNicely('') + except TwitterHTTPError as e: + detail_twitter_error(e) except Exception: debug_option() - printNicely(red('OMG something is wrong with Twitter right now.')) + printNicely(red('OMG something is wrong with Twitter API right now.')) def reconn_notice(): @@ -2296,7 +2307,7 @@ def fly(): # Spawn stream thread target = args.stream.split()[0] - if target == 'mine' : + if target == 'mine': spawn_personal_stream(args) else: try: diff --git a/setup.py b/setup.py index 99b932f9..1d4e49ec 100644 --- a/setup.py +++ b/setup.py @@ -3,13 +3,13 @@ import os.path # Bumped version -version = '1.2.7' +version = '1.3.0' # Require install_requires = [ "python-dateutil", "arrow", - "requests", + "requests==2.5.3", "pyfiglet", "twitter", "Pillow",