diff --git a/foodie_utils.py b/foodie_utils.py index 7ec2024..5b4d5d5 100644 --- a/foodie_utils.py +++ b/foodie_utils.py @@ -1201,6 +1201,17 @@ def check_author_rate_limit(author, max_tweets=17, tweet_window_seconds=86400): author_info = rate_limit_info[username] script_run_id = author_info.get('script_run_id', 0) + # Check if quota has reset based on previous reset time + reset = author_info.get('tweet_reset', current_time + tweet_window_seconds) + if current_time >= reset: + logger.info(f"Quota reset for {username}, restoring to {max_tweets} tweets") + author_info['tweet_remaining'] = max_tweets + author_info['tweet_reset'] = current_time + tweet_window_seconds + author_info['tweets_posted_in_run'] = 0 + author_info['script_run_id'] = check_author_rate_limit.script_run_id + rate_limit_info[username] = author_info + save_json_file(rate_limit_file, rate_limit_info) + # If script restarted or new author, post a test tweet to sync quota if script_run_id != check_author_rate_limit.script_run_id: logger.info(f"Script restart detected for {username}, posting test tweet to sync quota") @@ -1215,33 +1226,29 @@ def check_author_rate_limit(author, max_tweets=17, tweet_window_seconds=86400): remaining = max_tweets reset = current_time + tweet_window_seconds logger.warning(f"Test tweet failed for {username}, resetting quota to {max_tweets}") + else: + # Only update remaining if the API reset time is newer than the stored reset + if reset > author_info.get('tweet_reset', 0): + logger.info(f"Updating quota for {username} from API: {remaining} remaining, reset at {datetime.fromtimestamp(reset, tz=timezone.utc)}") + author_info['tweet_remaining'] = remaining + else: + logger.info(f"Retaining previous quota for {username}: {author_info['tweet_remaining']} remaining") + remaining = author_info['tweet_remaining'] + # Ensure reset is in the future if reset <= current_time: logger.warning(f"Reset time {reset} is in the past for {username}. Setting to 24 hours from now.") reset = current_time + tweet_window_seconds - # Update author info with synced quota - author_info = { - 'tweet_remaining': remaining, - 'tweet_reset': reset, - 'tweets_posted_in_run': 0, - 'script_run_id': check_author_rate_limit.script_run_id - } - rate_limit_info[username] = author_info - save_json_file(rate_limit_file, rate_limit_info) - - # Check if quota has reset - reset = author_info['tweet_reset'] - if current_time >= reset: - logger.info(f"Quota reset for {username}, restoring to {max_tweets} tweets") - remaining = max_tweets - reset = current_time + tweet_window_seconds - author_info['tweet_remaining'] = remaining + + # Update author info author_info['tweet_reset'] = reset author_info['tweets_posted_in_run'] = 0 + author_info['script_run_id'] = check_author_rate_limit.script_run_id rate_limit_info[username] = author_info save_json_file(rate_limit_file, rate_limit_info) - else: - remaining = author_info['tweet_remaining'] - author_info['tweets_posted_in_run'] + + # Calculate remaining tweets + remaining = author_info['tweet_remaining'] - author_info['tweets_posted_in_run'] can_post = remaining > 0 if not can_post: @@ -1309,6 +1316,7 @@ def get_x_rate_limit_status(author): try: response = requests.post(url, json=payload, auth=oauth) headers = response.headers + logger.debug(f"Rate limit headers for {username}: {headers}") # Extract app-level rate limit info from headers remaining_str = headers.get('x-rate-limit-remaining') @@ -1331,8 +1339,8 @@ def get_x_rate_limit_status(author): # Ensure reset is in the future current_time = int(time.time()) - if reset <= current_time: - logger.warning(f"Reset time {reset} is in the past for {username}. Setting to 24 hours from now.") + if reset <= current_time or reset > current_time + 2 * 86400: # Allow up to 48 hours + logger.warning(f"Invalid reset time {reset} for {username}. Setting to 24 hours from now.") reset = current_time + 86400 # 24 hours if response.status_code == 201: