]> jfr.im git - z_archive/twitter.git/blobdiff - twitter/follow.py
Fixed broken rate limiting error handling in archiver/follow.
[z_archive/twitter.git] / twitter / follow.py
index abc5fdabfe7a1b931e55202439f4ecdfc34c212c..8c763c16803e7aabcd23908d2eba03df4813dc58 100644 (file)
@@ -9,6 +9,7 @@ OPTIONS
  -r --followers        display followers of the given user (default)
  -g --following        display users the given user is following
  -a --api-rate         see your current API rate limit status
+ -i --ids              prepend user id to each line. useful to tracking renames
 
 AUTHENTICATION
     Authenticate to Twitter using OAuth to see following/followers of private
@@ -18,9 +19,16 @@ AUTHENTICATION
 
 from __future__ import print_function
 
-import os, sys, time, calendar, urllib2, httplib
+import os, sys, time, calendar
 from getopt import gnu_getopt as getopt, GetoptError
 
+try:
+    import urllib.request as urllib2
+    import http.client as httplib
+except ImportError:
+    import urllib2
+    import httplib
+
 # T-Follow (Twitter-Follow) application registered by @stalkr_
 CONSUMER_KEY='USRZQfvFFjB6UvZIN2Edww'
 CONSUMER_SECRET='AwGAaSzZa5r0TDL8RKCDtffnI9H9mooZUdOa95nw8'
@@ -31,10 +39,11 @@ from .oauth_dance import oauth_dance
 from .auth import NoAuth
 from .util import Fail, err
 
+
 def parse_args(args, options):
     """Parse arguments from command-line to set options."""
-    long_opts = ['help', 'oauth', 'followers', 'following', 'api-rate']
-    short_opts = "horga"
+    long_opts = ['help', 'oauth', 'followers', 'following', 'api-rate', 'ids']
+    short_opts = "horgai"
     opts, extra_args = getopt(args, short_opts, long_opts)
 
     for opt, arg in opts:
@@ -49,6 +58,8 @@ def parse_args(args, options):
             options['followers'] = False
         elif opt in ('-a', '--api-rate'):
             options['api-rate' ] = True
+        elif opt in ('-i', '--ids'):
+            options['show_id'] = True
 
     options['extra_args'] = extra_args
 
@@ -70,16 +81,16 @@ def lookup(twitter, user_ids):
             try:
                 portion = lookup_portion(twitter, user_ids[i:][:api_limit])
             except TwitterError as e:
-                if e.e.code == 400:
+                if e.e.code == 429:
                     err("Fail: %i API rate limit exceeded" % e.e.code)
-                    rate = twitter.account.rate_limit_status()
-                    reset = rate['reset_time_in_seconds']
+                    rls = twitter.application.rate_limit_status()
+                    reset = rls.rate_limit_reset
                     reset = time.asctime(time.localtime(reset))
-                    delay = int(rate['reset_time_in_seconds']
+                    delay = int(rls.rate_limit_reset
                                 - time.time()) + 5 # avoid race
-                    err("Hourly limit of %i requests reached, next reset on "
+                    err("Interval limit of %i requests reached, next reset on "
                         "%s: going to sleep for %i secs"
-                        % (rate['hourly_limit'], reset, delay))
+                        % (rls.rate_limit_limit, reset, delay))
                     fail.wait(delay)
                     continue
                 elif e.e.code == 502:
@@ -128,15 +139,15 @@ def follow(twitter, screen_name, followers=True):
                           % ("ers" if followers else "ing"))
                 err("Fail: %i Unauthorized (%s)" % (e.e.code, reason))
                 break
-            elif e.e.code == 400:
+            elif e.e.code == 429:
                 err("Fail: %i API rate limit exceeded" % e.e.code)
-                rate = twitter.account.rate_limit_status()
-                reset = rate['reset_time_in_seconds']
+                rls = twitter.application.rate_limit_status()
+                reset = rls.rate_limit_reset
                 reset = time.asctime(time.localtime(reset))
-                delay = int(rate['reset_time_in_seconds']
+                delay = int(rls.rate_limit_reset
                             - time.time()) + 5 # avoid race
-                err("Hourly limit of %i requests reached, next reset on %s: "
-                    "going to sleep for %i secs" % (rate['hourly_limit'],
+                err("Interval limit of %i requests reached, next reset on %s: "
+                    "going to sleep for %i secs" % (rls.rate_limit_limit,
                                                     reset, delay))
                 fail.wait(delay)
                 continue
@@ -169,18 +180,19 @@ def follow(twitter, screen_name, followers=True):
 
 def rate_limit_status(twitter):
     """Print current Twitter API rate limit status."""
-    r = twitter.account.rate_limit_status()
-    print("Remaining API requests: %i/%i (hourly limit)"
-          % (r['remaining_hits'], r['hourly_limit']))
+    rls = twitter.application.rate_limit_status()
+    print("Remaining API requests: %i/%i (interval limit)"
+          % (rls.rate_limit_remaining, rls.rate_limit_limit))
     print("Next reset in %is (%s)"
-          % (int(r['reset_time_in_seconds'] - time.time()),
-             time.asctime(time.localtime(r['reset_time_in_seconds']))))
+          % (int(rls.rate_limit_reset - time.time()),
+             time.asctime(time.localtime(rls.rate_limit_reset))))
 
 def main(args=sys.argv[1:]):
     options = {
         'oauth': False,
         'followers': True,
-        'api-rate': False
+        'api-rate': False,
+        'show_id': False
     }
     try:
         parse_args(args, options)
@@ -206,7 +218,7 @@ def main(args=sys.argv[1:]):
     else:
         auth = NoAuth()
 
-    twitter = Twitter(auth=auth, api_version='1', domain='api.twitter.com')
+    twitter = Twitter(auth=auth, api_version='1.1', domain='api.twitter.com')
 
     if options['api-rate']:
         rate_limit_status(twitter)
@@ -224,7 +236,17 @@ def main(args=sys.argv[1:]):
             raise SystemExit(1)
 
         for uid in user_ids:
-            print(users[uid].encode("utf-8"))
+            if options['show_id']:
+              try:
+                print(str(uid) + "\t" + users[uid].encode("utf-8"))
+              except KeyError:
+                pass
+
+            else:
+              try:
+                print(users[uid].encode("utf-8"))
+              except KeyError:
+                pass
 
         # print total on stderr to separate from user list on stdout
         if options['followers']: