from .c_image import *
from .py3patch import *
from .emoji import *
+from .util import *
# Global values
g = {}
Parse the 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',
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
'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)
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)
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
credential = t.account.verify_credentials()
screen_name = '@' + credential['screen_name']
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)
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']
+ owner = '@' + original_tweet['user']['screen_name']
+ nick_ary = ['@' + re.sub('[\W_]', '', w)
+ for w in text.split() if w.startswith('@')] + [owner]
+ status = ' '.join(g['stuff'].split()[1:])
+ status = ' '.join(nick_ary) + ' ' + str2u(status)
+ t.statuses.update(status=status, in_reply_to_status_id=tid)
+
+
def favorite():
"""
Favorite
light_magenta('List name should follow "@owner/list_name" format.'))
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):
"""
# 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(c['PREFIX']))
+ g['PREFIX'] = u2str(emojize(format_prefix(keyword=g['keyword'])))
# Start new thread
th = threading.Thread(
target=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(c['PREFIX']))
+ g['PREFIX'] = u2str(emojize(format_prefix()))
# Start new thread
th = threading.Thread(
target=stream,
th.start()
# Stream base on list
elif target == 'list':
- owner, slug = get_slug()
+ try:
+ owner, slug = check_slug(g['stuff'].split()[1])
+ except:
+ 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())
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:
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 ' + \
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'
'conversation',
'fav',
'rep',
+ 'repall',
'del',
'ufav',
'share',
'p',
'r',
'c',
- 'q'
+ 'v',
+ 'q',
]
# Handle function set
conversation,
favorite,
reply,
+ reply_all,
delete,
unfavorite,
share,
pause,
replay,
clear,
- quit
+ upgrade_center,
+ quit,
]
[], # conversation
[], # favorite
[], # reply
+ [], # reply_all
[], # delete
[], # unfavorite
[], # url
[], # pause
[], # reconnect
[], # clear
+ [], # version
[], # quit
]
))
"""
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'](c['PREFIX']))
+ sys.stdout.write(g['decorated_name'](g['PREFIX']))
sys.stdout.flush()
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
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
elif tweet.get('text'):
- if time.time() - last_tweet_time >= get_config("STREAM_DELAY"):
- last_tweet_time = time.time()
- # Check the semaphore pause and lock (stream process only)
- if g['pause']:
- continue
- while c['lock']:
- time.sleep(0.5)
- # Draw the tweet
- draw(
- t=tweet,
- keyword=args.track_keywords,
- humanize=False,
- fil=args.filter,
- ig=args.ignore,
- )
- # Current readline buffer
- current_buffer = readline.get_line_buffer().strip()
- # There is an unexpected behaviour in MacOSX readline + Python 2:
- # after completely delete a word after typing it,
- # somehow readline buffer still contains
- # 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))
- sys.stdout.flush()
- elif not c['HIDE_PROMPT']:
- sys.stdout.write(g['decorated_name'](c['PREFIX']))
- sys.stdout.flush()
+ # 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
+ while c['lock']:
+ time.sleep(0.5)
+ # Draw the tweet
+ draw(
+ t=tweet,
+ keyword=args.track_keywords,
+ humanize=False,
+ fil=args.filter,
+ ig=args.ignore,
+ )
+ # Current readline buffer
+ current_buffer = readline.get_line_buffer().strip()
+ # There is an unexpected behaviour in MacOSX readline + Python 2:
+ # after completely delete a word after typing it,
+ # somehow readline buffer still contains
+ # the 1st character of that word
+ if current_buffer and g['cmd'] != current_buffer:
+ sys.stdout.write(
+ g['decorated_name'](g['PREFIX']) + current_buffer)
+ sys.stdout.flush()
+ elif not c['HIDE_PROMPT']:
+ 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)
if g['pause']:
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()
+ except (URLError, ConnectionResetError):
+ printNicely(
+ magenta('There seems to be a connection problem.'))
+ save_history()
+ sys.exit()
def fly():
proxy_connect(args)
init(args)
# Twitter API connection problem
- except TwitterHTTPError:
+ 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."))
+ 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 == 'public':
+ try:
+ keyword = args.stream.split()[1]
+ if keyword[0] == '#':
+ keyword = keyword[1:]
+ args.track_keywords = keyword
+ # Set the variable to tracked keyword
+ g['keyword'] = keyword
+ # 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()
+ except:
+ printNicely(red('Public requires a keyword! Loading your personal stream.'))
+ # Start new thread
+ th = threading.Thread(
+ target=stream,
+ args=(
+ c['USER_DOMAIN'],
+ args,
+ g['original_name']))
+ th.daemon = True
+ th.start()
+ elif target == "list":
+ try:
+ owner, slug = check_slug(args.stream.split()[1])
+ # 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.'))
+ except:
+ printNicely(red('List requieres a correct name of a list! Loading your personal stream.'))
+ # Start new thread
+ th = threading.Thread(
+ target=stream,
+ args=(
+ c['USER_DOMAIN'],
+ args,
+ g['original_name']))
+ th.daemon = True
+ th.start()
+ elif target == "mine":
+ # Start new thread
+ th = threading.Thread(
+ target=stream,
+ args=(
+ c['USER_DOMAIN'],
+ args,
+ g['original_name']))
+ th.daemon = True
+ th.start()
+ else:
+ printNicely(red('Wrong -s/--stream argument given. Loading your personal stream.'))
+ # Start new thread
+ th = threading.Thread(
+ target=stream,
+ args=(
+ c['USER_DOMAIN'],
+ args,
+ g['original_name']))
+ th.daemon = True
+ th.start()
+
# Start listen process
time.sleep(0.5)
g['reset'] = True