Merge pull request #258 from jimdoescode/alternate_oauth
authororakaro.targaryen <orakaro@users.noreply.github.com>
Tue, 26 Nov 2019 14:11:20 +0000 (23:11 +0900)
committerGitHub <noreply@github.com>
Tue, 26 Nov 2019 14:11:20 +0000 (23:11 +0900)
Allow specifying the location of oauth files

1  2 
rainbowstream/rainbow.py

diff --combined rainbowstream/rainbow.py
@@@ -89,6 -89,16 +89,16 @@@ def parse_arguments()
          '--proxy-type',
          default='SOCKS5',
          help='Proxy type (HTTP, SOCKS4, SOCKS5; Default: SOCKS5).')
+     parser.add_argument(
+         '-ta',
+         '--twitter-auth',
+         default=os.environ.get('HOME', os.environ.get('USERPROFILE', '')) + os.sep + '.rainbow_oauth',
+         help='Specify which OAuth profile to use for twitter. Default: ~/.rainbow_oauth.')
+     parser.add_argument(
+         '-pa',
+         '--pocket-auth',
+         default=os.environ.get('HOME', os.environ.get('USERPROFILE', '')) + os.sep + '.rainbow_pckt_oauth',
+         help='Specify which OAuth profile to use for pocket. Default: ~/.rainbow_pckt_oauth.')
      return parser.parse_args()
  
  
@@@ -122,11 -132,7 +132,7 @@@ def authen()
      Authenticate with Twitter OAuth
      """
      # When using rainbow stream you must authorize.
-     twitter_credential = os.environ.get(
-         'HOME',
-         os.environ.get(
-             'USERPROFILE',
-             '')) + os.sep + '.rainbow_oauth'
+     twitter_credential = g['twitter_oauth_path']
      if not os.path.exists(twitter_credential):
          oauth_dance('Rainbow Stream',
                      CONSUMER_KEY,
@@@ -144,12 -150,7 +150,7 @@@ def pckt_authen()
      """
      Authenticate with Pocket OAuth
      """
-     pocket_credential = os.environ.get(
-          'HOME',
-         os.environ.get(
-             'USERPROFILE',
-             '')) + os.sep + '.rainbow_pckt_oauth'
+     pocket_credential = g['pocket_oauth_path']
      if not os.path.exists(pocket_credential):
          request_token = Pocket.get_request_token(consumer_key=PCKT_CONSUMER_KEY)
          auth_url = Pocket.get_auth_url(code=request_token, redirect_uri="/")
@@@ -238,6 -239,9 +239,9 @@@ def init(args)
      # Handle Ctrl C
      ctrl_c_handler = lambda signum, frame: quit()
      signal.signal(signal.SIGINT, ctrl_c_handler)
+     # Set OAuth file path (needs to happen before authen is called)
+     g['twitter_oauth_path'] = args.twitter_auth
+     g['pocket_oauth_path'] = args.pocket_auth
      # Upgrade notify
      upgrade_center()
      # Get name
      credential = t.account.verify_credentials()
      screen_name = '@' + credential['screen_name']
      name = credential['name']
 +    g['id_str'] = credential['id_str']
      c['original_name'] = g['original_name'] = screen_name[1:]
      g['listname'] = g['keyword'] = ''
      g['PREFIX'] = u2str(emojize(format_prefix()))
@@@ -323,27 -326,6 +327,27 @@@ def trend()
                      print_trends(trends)
  
  
 +def poll():
 +    """
 +    Fetch stream based on since_id
 +    """
 +    t = Twitter(auth=authen())
 +
 +    num = c['HOME_TWEET_NUM']
 +    kwargs = {'count': num}
 +
 +    if 'since_id' in g:
 +        kwargs['since_id'] = g['since_id']
 +
 +    kwargs = add_tweetmode_parameter(kwargs)
 +    result = t.statuses.home_timeline(**kwargs)
 +    if result:
 +        g['since_id'] = result[0]['id']
 +    for tweet in reversed(result):
 +        draw(t=tweet)
 +    if result:
 +        printNicely('')
 +
  def home():
      """
      Home
@@@ -476,7 -458,7 +480,7 @@@ def search()
      # Return results
      if rel:
          printNicely('Newest tweets:')
 -        for i in reversed(xrange(count)):
 +        for i in reversed(xrange(min(len(rel), count))):
              draw(t=rel[i], keyword=query)
          printNicely('')
      else:
@@@ -818,36 -800,52 +822,36 @@@ def inbox()
      num = c['MESSAGES_DISPLAY']
      if g['stuff'].isdigit():
          num = g['stuff']
 +
 +    def inboxFilter(message):
 +        return message['message_create']['sender_id'] == g['id_str']
 +    def sentFilter(message):
 +        return message['message_create']['target']['recipient_id'] == g['id_str']
 +
 +    def map_message(message):
 +        message_create = message['message_create']
 +        sender = t.users.show(id=int(message_create['sender_id']),include_entities=False)
 +        recipient = t.users.show(id=int(message_create['target']['recipient_id']),include_entities=False)
 +        message['sender_screen_name'] = sender['screen_name']
 +        message['sender_name'] = sender['name']
 +        message['recipient_screen_name'] = recipient['screen_name']
 +        message['recipient_name'] = recipient['name']
 +        message['text'] = message['message_create']['message_data']['text']
 +        message['created_at'] = message['created_timestamp']
 +        return message
 +
      # Get inbox messages
 -    cur_page = 1
 -    inbox = []
 -    while num > 20:
 -        inbox = inbox + t.direct_messages(
 -            count=20,
 -            page=cur_page,
 -            include_entities=False,
 -            skip_status=False
 -        )
 -        num -= 20
 -        cur_page += 1
 -    inbox = inbox + t.direct_messages(
 -        count=num,
 -        page=cur_page,
 -        include_entities=False,
 -        skip_status=False
 -    )
 -    # Get sent messages
 -    num = c['MESSAGES_DISPLAY']
 -    if g['stuff'].isdigit():
 -        num = g['stuff']
 -    cur_page = 1
 -    sent = []
 -    while num > 20:
 -        sent = sent + t.direct_messages.sent(
 -            count=20,
 -            page=cur_page,
 -            include_entities=False,
 -            skip_status=False
 -        )
 -        num -= 20
 -        cur_page += 1
 -    sent = sent + t.direct_messages.sent(
 -        count=num,
 -        page=cur_page,
 -        include_entities=False,
 -        skip_status=False
 -    )
 +    messages = t.direct_messages.events.list()['events']
 +    messages = list(map(map_message, messages))
 +    inbox = list(filter(inboxFilter, messages))
 +    sent = list(filter(sentFilter, messages))
  
      d = {}
      uniq_inbox = list(set(
 -        [(m['sender_screen_name'], m['sender']['name']) for m in inbox]
 +        [(m['sender_screen_name'], m['sender_name']) for m in inbox]
      ))
      uniq_sent = list(set(
 -        [(m['recipient_screen_name'], m['recipient']['name']) for m in sent]
 +        [(m['recipient_screen_name'], m['recipient_name']) for m in sent]
      ))
      for partner in uniq_inbox:
          inbox_ary = [m for m in inbox if m['sender_screen_name'] == partner[0]]
@@@ -1494,7 -1492,7 +1498,7 @@@ def theme()
              # Redefine decorated_name
              g['decorated_name'] = lambda x: color_func(
                  c['DECORATED_NAME'])(
 -                '[' + x + ']: ')
 +                '[' + x + ']: ', rl=True)
              printNicely(green('Theme changed.'))
          except:
              printNicely(red('No such theme exists.'))
@@@ -1557,7 -1555,7 +1561,7 @@@ def config()
              if key == 'THEME':
                  c['THEME'] = reload_theme(value, c['THEME'])
                  g['decorated_name'] = lambda x: color_func(
 -                    c['DECORATED_NAME'])('[' + x + ']: ')
 +                    c['DECORATED_NAME'])('[' + x + ']: ', rl=True)
              elif key == 'PREFIX':
                  g['PREFIX'] = u2str(emojize(format_prefix(
                      listname=g['listname'],
@@@ -2162,11 -2160,98 +2166,11 @@@ def stream(domain, args, name='Rainbow 
      query_args = dict()
      if args.track_keywords:
          query_args['track'] = args.track_keywords
 -    # Get stream
 -    stream = TwitterStream(
 -        auth=authen(),
 -        domain=domain,
 -        **stream_args)
 -    try:
 -        if domain == c['USER_DOMAIN']:
 -            tweet_iter = stream.user(**query_args)
 -        elif domain == c['SITE_DOMAIN']:
 -            tweet_iter = stream.site(**query_args)
 -        else:
 -            if args.track_keywords:
 -                tweet_iter = stream.statuses.filter(**query_args)
 -            else:
 -                tweet_iter = stream.statuses.sample()
 -        # 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 --')
 -            elif tweet is Timeout:
 -                # Because the stream check for each 0.3s
 -                # so we shouldn't output anything here
 -                if(g['stream_stop']):
 -                    StreamLock.release()
 -                    break
 -            elif tweet is HeartbeatTimeout:
 -                printNicely('-- Heartbeat Timeout --')
 -                reconn_notice()
 -                StreamLock.release()
 -                break
 -            elif tweet is Hangup:
 -                printNicely('-- Hangup --')
 -                reconn_notice()
 -                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
 -                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']:
 -                    continue
 -                while c['lock']:
 -                    time.sleep(0.5)
 -                print_message(tweet['direct_message'])
 -            elif tweet.get('event'):
 -                c['events'].append(tweet)
 -                print_event(tweet)
 -    except TwitterHTTPError as e:
 -        printNicely('')
 -        printNicely(
 -            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):
 -        printNicely(
 -            magenta('There seems to be a connection problem.'))
 -        save_history()
 -        sys.exit()
  
 +    polling_time = 90
 +    while True:
 +        time.sleep(polling_time)
 +        poll()
  
  def spawn_public_stream(args, keyword=None):
      """