X-Git-Url: https://vcs.fsf.org/?p=rainbowstream.git;a=blobdiff_plain;f=rainbowstream%2Frainbow.py;h=fe144015df00367a566d8e0a1b5cc0abf4cd23b2;hp=bd421d24664cef082e715038b63dcd8fe41182b7;hb=1d01129e5baa3ef92e63e54480f5dffa57bf2890;hpb=75d81134270f456c6c353cfbc2d7e166aaefa506 diff --git a/rainbowstream/rainbow.py b/rainbowstream/rainbow.py index bd421d2..fe14401 100644 --- a/rainbowstream/rainbow.py +++ b/rainbowstream/rainbow.py @@ -9,7 +9,10 @@ import requests import webbrowser import traceback import pkg_resources +import socks +import socket +from io import BytesIO from twitter.stream import TwitterStream, Timeout, HeartbeatTimeout, Hangup from twitter.api import * from twitter.oauth import OAuth, read_token_file @@ -24,6 +27,7 @@ from .interactive import * from .c_image import * from .py3patch import * from .emoji import * +from .util import * # Global values g = {} @@ -58,9 +62,48 @@ def parse_arguments(): '--image-on-term', action='store_true', help='Display all image on terminal.') + parser.add_argument( + '-ph', + '--proxy-host', + help='Use HTTP/SOCKS proxy for network connections.') + parser.add_argument( + '-pp', + '--proxy-port', + default=8080, + help='HTTP/SOCKS proxy port (Default: 8080).') + parser.add_argument( + '-pt', + '--proxy-type', + default='SOCKS5', + help='Proxy type (HTTP, SOCKS4, SOCKS5; Default: SOCKS5).') return parser.parse_args() +def proxy_connect(args): + """ + Connect to specified proxy + """ + if args.proxy_host: + # Setup proxy by monkeypatching the standard lib + if args.proxy_type.lower() == "socks5" or not args.proxy_type: + socks.set_default_proxy( + socks.SOCKS5, args.proxy_host, + int(args.proxy_port)) + elif args.proxy_type.lower() == "http": + socks.set_default_proxy( + socks.HTTP, args.proxy_host, + int(args.proxy_port)) + elif args.proxy_type.lower() == "socks4": + socks.set_default_proxy( + socks.SOCKS4, args.proxy_host, + int(args.proxy_port)) + else: + printNicely( + magenta("Sorry, wrong proxy type specified! Aborting...")) + sys.exit() + socket.socket = socks.socksocket + + def authen(): """ Authenticate with Twitter OAuth @@ -136,6 +179,11 @@ def upgrade_center(): notice += light_magenta('You should upgrade with ') notice += light_green('pip install -U rainbowstream') printNicely(notice) + else: + notice = light_yellow('You are running latest version (') + notice += light_green(current) + notice += light_yellow(')') + printNicely(notice) except: pass @@ -156,9 +204,9 @@ def init(args): name = credential['name'] if not get_config('PREFIX'): set_config('PREFIX', screen_name) - c['PREFIX'] = emojize(c['PREFIX']) - g['PREFIX'] = u2str(c['PREFIX']) c['original_name'] = g['original_name'] = screen_name[1:] + g['listname'] = g['keyword'] = '' + g['PREFIX'] = u2str(emojize(format_prefix())) g['full_name'] = name g['decorated_name'] = lambda x: color_func( c['DECORATED_NAME'])('[' + x + ']: ', rl=True) @@ -1195,8 +1243,12 @@ def switch(): # Kill old thread g['stream_stop'] = True args.track_keywords = keyword - # Set prefix to origin name with public - g['PREFIX'] = '@' + g['original_name'] + '/public' + # 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, @@ -1209,8 +1261,10 @@ def switch(): elif target == 'mine': # Kill old thread g['stream_stop'] = True - # Set prefix to origin name - g['PREFIX'] = '@' + g['original_name'] + # 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, @@ -1224,7 +1278,12 @@ def switch(): elif target == 'list': owner, slug = get_slug() # Force python 2 not redraw readline buffer - g['PREFIX'] = g['cmd'] = '/'.join([owner, slug]) + 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()) @@ -1361,7 +1420,7 @@ def config(): g['decorated_name'] = lambda x: color_func( c['DECORATED_NAME'])('[' + x + ']: ') elif key == 'PREFIX': - g['PREFIX'] = u2str(emojize(c['PREFIX'])) + g['PREFIX'] = u2str(emojize(format_prefix(listname = g['listname'], keyword = g['keyword']))) reload_config() printNicely(green('Updated successfully.')) except: @@ -1618,6 +1677,7 @@ def help(): usage += s * 2 + light_green('p') + ' will pause the stream.\n' usage += s * 2 + light_green('r') + ' will unpause the stream.\n' usage += s * 2 + light_green('c') + ' will clear the screen.\n' + usage += s * 2 + light_green('v') + ' will show version info.\n' usage += s * 2 + light_green('q') + ' will quit.\n' # End usage += '\n' @@ -1736,7 +1796,8 @@ cmdset = [ 'p', 'r', 'c', - 'q' + 'v', + 'q', ] # Handle function set @@ -1782,7 +1843,8 @@ funcset = [ pause, replay, clear, - quit + upgrade_center, + quit, ] @@ -1860,6 +1922,7 @@ def listen(): [], # pause [], # reconnect [], # clear + [], # version [], # quit ] )) @@ -1912,7 +1975,7 @@ def reconn_notice(): light_green("h stream") + \ light_magenta(" for more details.") printNicely(guide) - sys.stdout.write(g['decorated_name'](c['PREFIX'])) + sys.stdout.write(g['decorated_name'](g['PREFIX'])) sys.stdout.flush() @@ -1955,6 +2018,7 @@ def stream(domain, args, name='Rainbow Stream'): # Block new stream until other one exits StreamLock.acquire() g['stream_stop'] = False + last_tweet_time = time.time() for tweet in tweet_iter: if tweet is None: printNicely("-- None --") @@ -1975,6 +2039,10 @@ def stream(domain, args, name='Rainbow Stream'): StreamLock.release() break elif tweet.get('text'): + # Slow down the stream by STREAM_DELAY config key + if time.time() - last_tweet_time < c['STREAM_DELAY']: + continue + last_tweet_time = time.time() # Check the semaphore pause and lock (stream process only) if g['pause']: continue @@ -1996,10 +2064,10 @@ def stream(domain, args, name='Rainbow Stream'): # the 1st character of that word if current_buffer and g['cmd'] != current_buffer: sys.stdout.write( - g['decorated_name'](c['PREFIX']) + str2u(current_buffer)) + g['decorated_name'](g['PREFIX']) + current_buffer) sys.stdout.flush() elif not c['HIDE_PROMPT']: - sys.stdout.write(g['decorated_name'](c['PREFIX'])) + sys.stdout.write(g['decorated_name'](g['PREFIX'])) sys.stdout.flush() elif tweet.get('direct_message'): # Check the semaphore pause and lock (stream process only) @@ -2011,10 +2079,13 @@ def stream(domain, args, name='Rainbow Stream'): elif tweet.get('event'): c['events'].append(tweet) print_event(tweet) - except TwitterHTTPError: + except TwitterHTTPError as e: printNicely('') printNicely( - magenta("We have maximum 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() def fly(): @@ -2024,14 +2095,25 @@ def fly(): # Initial args = parse_arguments() try: + proxy_connect(args) init(args) - except TwitterHTTPError: + # Twitter API connection problem + except TwitterHTTPError as e: printNicely('') printNicely( - magenta("We have connection problem with twitter'stream API right now :(")) - printNicely(magenta("Let's try again later.")) + 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.")) + printNicely( + 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,