improve Extractor.wait()
- allow 'until' to be a datetime object - do "time calculations" with UTC timestamps - set a default 'reason'
This commit is contained in:
@@ -122,23 +122,33 @@ class Extractor():
|
|||||||
|
|
||||||
raise exception.HttpError(msg)
|
raise exception.HttpError(msg)
|
||||||
|
|
||||||
def wait(self, *, seconds=None, until=None, reason=None, adjust=1):
|
def wait(self, *, seconds=None, until=None, adjust=1.0,
|
||||||
now = datetime.datetime.now()
|
reason="rate limit reset"):
|
||||||
|
now = time.time()
|
||||||
|
|
||||||
if seconds:
|
if seconds:
|
||||||
seconds = float(seconds)
|
seconds = float(seconds)
|
||||||
until = now + datetime.timedelta(seconds=seconds)
|
until = now + seconds
|
||||||
elif until:
|
elif until:
|
||||||
until = datetime.datetime.fromtimestamp(float(until))
|
if isinstance(until, datetime.datetime):
|
||||||
seconds = (until - now).total_seconds()
|
# convert to UTC timestamp
|
||||||
|
epoch = datetime.datetime(1970, 1, 1)
|
||||||
|
until = (until - epoch) / datetime.timedelta(0, 1)
|
||||||
|
else:
|
||||||
|
until = float(until)
|
||||||
|
seconds = until - now
|
||||||
else:
|
else:
|
||||||
raise ValueError("Either 'seconds' or 'until' is required")
|
raise ValueError("Either 'seconds' or 'until' is required")
|
||||||
|
|
||||||
|
seconds += adjust
|
||||||
|
if seconds <= 0.0:
|
||||||
|
return
|
||||||
|
|
||||||
if reason:
|
if reason:
|
||||||
t = until.time()
|
t = datetime.datetime.fromtimestamp(until).time()
|
||||||
isotime = "{:02}:{:02}:{:02}".format(t.hour, t.minute, t.second)
|
isotime = "{:02}:{:02}:{:02}".format(t.hour, t.minute, t.second)
|
||||||
self.log.info("Waiting until %s for %s.", isotime, reason)
|
self.log.info("Waiting until %s for %s.", isotime, reason)
|
||||||
time.sleep(seconds + adjust)
|
time.sleep(seconds)
|
||||||
|
|
||||||
def _get_auth_info(self):
|
def _get_auth_info(self):
|
||||||
"""Return authentication information as (username, password) tuple"""
|
"""Return authentication information as (username, password) tuple"""
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ class DeviantartExtractor(Extractor):
|
|||||||
b"Request blocked." not in response.content:
|
b"Request blocked." not in response.content:
|
||||||
DeviantartExtractor._last_request = time.time()
|
DeviantartExtractor._last_request = time.time()
|
||||||
return response
|
return response
|
||||||
self.wait(seconds=180, reason="rate limit reset")
|
self.wait(seconds=180)
|
||||||
|
|
||||||
|
|
||||||
class DeviantartUserExtractor(DeviantartExtractor):
|
class DeviantartUserExtractor(DeviantartExtractor):
|
||||||
|
|||||||
@@ -313,8 +313,7 @@ class RedditAPI():
|
|||||||
|
|
||||||
remaining = response.headers.get("x-ratelimit-remaining")
|
remaining = response.headers.get("x-ratelimit-remaining")
|
||||||
if remaining and float(remaining) < 2:
|
if remaining and float(remaining) < 2:
|
||||||
reset = response.headers["x-ratelimit-reset"]
|
self.extractor.wait(seconds=response.headers["x-ratelimit-reset"])
|
||||||
self.extractor.wait(seconds=reset, reason="rate limit reset")
|
|
||||||
return self._call(endpoint, params)
|
return self._call(endpoint, params)
|
||||||
|
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ class TumblrAPI(oauth.OAuth1API):
|
|||||||
reset = response.headers.get("x-ratelimit-perhour-reset")
|
reset = response.headers.get("x-ratelimit-perhour-reset")
|
||||||
if reset:
|
if reset:
|
||||||
self.log.info("Hourly API rate limit exceeded")
|
self.log.info("Hourly API rate limit exceeded")
|
||||||
self.extractor.wait(seconds=reset, reason="rate limit reset")
|
self.extractor.wait(seconds=reset)
|
||||||
return self._call(blog, endpoint, params)
|
return self._call(blog, endpoint, params)
|
||||||
|
|
||||||
raise exception.StopExtraction(data)
|
raise exception.StopExtraction(data)
|
||||||
|
|||||||
@@ -224,8 +224,7 @@ class TwitterExtractor(Extractor):
|
|||||||
if response.status_code == 429 or \
|
if response.status_code == 429 or \
|
||||||
response.headers.get("x-rate-limit-remaining") == "0":
|
response.headers.get("x-rate-limit-remaining") == "0":
|
||||||
if self.logged_in:
|
if self.logged_in:
|
||||||
reset = response.headers.get("x-rate-limit-reset")
|
self.wait(until=response.headers.get("x-rate-limit-reset"))
|
||||||
self.wait(until=reset, reason="rate limit reset")
|
|
||||||
else:
|
else:
|
||||||
_guest_token.invalidate()
|
_guest_token.invalidate()
|
||||||
return self._video_from_tweet(tweet_id)
|
return self._video_from_tweet(tweet_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user