Reduce rate-limit based on API reference; Configure python logging library

This commit is contained in:
Baptiste Roux 2022-02-19 12:34:54 +01:00
parent 8c58b78b8e
commit 3cd4d93d7f
No known key found for this signature in database
GPG key ID: F2D53AA58807C6B5

View file

@ -2,19 +2,27 @@
import csv import csv
import json import json
import os import os
import logging
import re import re
import sys import sys
import time import time
from datetime import datetime from datetime import datetime
import trakt.core import trakt.core
from trakt import init
from tinydb import Query, TinyDB from tinydb import Query, TinyDB
from trakt import Expando
from trakt.tv import TVShow from trakt.tv import TVShow
# Setup logger
logging.basicConfig(
format='%(asctime)s %(levelname)s :: %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S'
)
# Adjust this value to increase/decrease your requests between episodes. # Adjust this value to increase/decrease your requests between episodes.
# Make sure it's above 1 seconds to remain within the rate limit. # Make to remain within the rate limit: https://trakt.docs.apiary.io/#introduction/rate-limiting
DELAY_BETWEEN_EPISODES_IN_SECONDS = 5 DELAY_BETWEEN_EPISODES_IN_SECONDS = 0.75
# Create a database to keep track of completed processes # Create a database to keep track of completed processes
database = TinyDB("localStorage.json") database = TinyDB("localStorage.json")
@ -239,7 +247,7 @@ def getShowByName(name, seasonNo, episodeNo):
sys.exit("Cancel requested...") sys.exit("Cancel requested...")
# Otherwise, the user has entered an invalid value, warn the user to try again # Otherwise, the user has entered an invalid value, warn the user to try again
except: except:
print( logging.error(
f"Sorry! Please select a value between 0 to {len(showsWithSameName)}" f"Sorry! Please select a value between 0 to {len(showsWithSameName)}"
) )
@ -332,7 +340,6 @@ def processWatchedShows():
# Get the date which the show was marked 'watched' in TV Time # Get the date which the show was marked 'watched' in TV Time
tvShowDateWatched = row["updated_at"] tvShowDateWatched = row["updated_at"]
# Parse the watched date value into a Python type # Parse the watched date value into a Python type
print(tvShowDateWatched)
tvShowDateWatchedConverted = datetime.strptime( tvShowDateWatchedConverted = datetime.strptime(
tvShowDateWatched, "%Y-%m-%d %H:%M:%S" tvShowDateWatched, "%Y-%m-%d %H:%M:%S"
) )
@ -353,7 +360,7 @@ def processWatchedShows():
# If more than 10 errors occurred in one streak, whilst trying to import the episode # If more than 10 errors occurred in one streak, whilst trying to import the episode
# then give up, and move onto the next episode, but warn the user. # then give up, and move onto the next episode, but warn the user.
if errorStreak > 10: if errorStreak > 10:
print( logging.warning(
f"WARNING: An error occurred 10 times in a row... skipping episode..." f"WARNING: An error occurred 10 times in a row... skipping episode..."
) )
break break
@ -371,8 +378,8 @@ def processWatchedShows():
if traktShowObj == None: if traktShowObj == None:
break break
# Show the progress of the import on-screen # Show the progress of the import on-screen
print( logging.info(
f"({rowsCount+1}/{rowsTotal}) Processing Show {tvShowName} on Season {tvShowSeasonNo} - Episode {tvShowEpisodeNo}" f"({rowsCount+1}/{rowsTotal}) Processing - '{tvShowName}' Season {tvShowSeasonNo} / Episode {tvShowEpisodeNo}"
) )
# Get the season from the Trakt API # Get the season from the Trakt API
season = traktShowObj.seasons[ season = traktShowObj.seasons[
@ -392,19 +399,19 @@ def processWatchedShows():
# an incorrect Trakt show has been selected, with season/episodes which don't match TV Time. # an incorrect Trakt show has been selected, with season/episodes which don't match TV Time.
# It can also occur due to a bug in Trakt Py, whereby some seasons contain an empty array of episodes. # It can also occur due to a bug in Trakt Py, whereby some seasons contain an empty array of episodes.
except IndexError: except IndexError:
print( logging.warning(
f"({rowsCount}/{rowsTotal}) WARNING: {tvShowName} Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo} does not exist (season/episode index) in Trakt!" f"({rowsCount}/{rowsTotal}) WARNING: {tvShowName} Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo} does not exist (season/episode index) in Trakt!"
) )
break break
# Catch any errors which are raised because a show could not be found in Trakt # Catch any errors which are raised because a show could not be found in Trakt
except trakt.errors.NotFoundException: except trakt.errors.NotFoundException:
print( logging.warning(
f"({rowsCount}/{rowsTotal}) WARNING: {tvShowName} Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo} does not exist (search) in Trakt!" f"({rowsCount}/{rowsTotal}) WARNING: {tvShowName} Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo} does not exist (search) in Trakt!"
) )
break break
# Catch errors because of the program breaching the Trakt API rate limit # Catch errors because of the program breaching the Trakt API rate limit
except trakt.errors.RateLimitException: except trakt.errors.RateLimitException:
print( logging.warning(
"WARNING: The program is running too quickly and has hit Trakt's API rate limit! Please increase the delay between " "WARNING: The program is running too quickly and has hit Trakt's API rate limit! Please increase the delay between "
+ "episdoes via the variable 'DELAY_BETWEEN_EPISODES_IN_SECONDS'. The program will now wait 60 seconds before " + "episdoes via the variable 'DELAY_BETWEEN_EPISODES_IN_SECONDS'. The program will now wait 60 seconds before "
+ "trying again." + "trying again."
@ -415,7 +422,7 @@ def processWatchedShows():
errorStreak += 1 errorStreak += 1
# Catch a JSON decode error - this can be raised when the API server is down and produces a HTML page, instead of JSON # Catch a JSON decode error - this can be raised when the API server is down and produces a HTML page, instead of JSON
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
print( logging.warning(
f"({rowsCount}/{rowsTotal}) WARNING: A JSON decode error occuring whilst processing {tvShowName} " f"({rowsCount}/{rowsTotal}) WARNING: A JSON decode error occuring whilst processing {tvShowName} "
+ f"Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo}! This might occur when the server is down and has produced " + f"Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo}! This might occur when the server is down and has produced "
+ "a HTML document instead of JSON. The script will wait 60 seconds before trying again." + "a HTML document instead of JSON. The script will wait 60 seconds before trying again."
@ -431,8 +438,8 @@ def processWatchedShows():
sys.exit("Cancel requested...") sys.exit("Cancel requested...")
# Skip the episode # Skip the episode
else: else:
print( logging.info(
f"({rowsCount}/{rowsTotal}) Skipping '{tvShowName}' Season {tvShowSeasonNo} Episode {tvShowEpisodeNo}. It's already been imported." f"({rowsCount}/{rowsTotal}) Already imported, skipping - '{tvShowName}' Season {tvShowSeasonNo} / Episode {tvShowEpisodeNo}."
) )
@ -449,16 +456,16 @@ def start():
menuSelection = 1 if not menuSelection else int(menuSelection) menuSelection = 1 if not menuSelection else int(menuSelection)
break break
except ValueError: except ValueError:
print("Invalid input. Please enter a numerical number.") logging.warning("Invalid input. Please enter a numerical number.")
# Start the process which is required # Start the process which is required
if menuSelection == 1: if menuSelection == 1:
# Invoke the method which will import episodes which have been watched # Invoke the method which will import episodes which have been watched
# from TV Time into Trakt # from TV Time into Trakt
processWatchedShows() processWatchedShows()
else: else:
print("Sorry - that's an unknown menu selection") logging.warning("Sorry - that's an unknown menu selection")
else: else:
print("ERROR: Unable to complete authentication to Trakt - please try again.") logging.error("ERROR: Unable to complete authentication to Trakt - please try again.")
if __name__ == "__main__": if __name__ == "__main__":
@ -468,12 +475,12 @@ if __name__ == "__main__":
if os.path.isdir(config.GDPR_WORKSPACE_PATH): if os.path.isdir(config.GDPR_WORKSPACE_PATH):
start() start()
else: else:
print( logging.error(
"Oops! The TV Time GDPR folder '" "Oops! The TV Time GDPR folder '"
+ config.GDPR_WORKSPACE_PATH + config.GDPR_WORKSPACE_PATH
+ "' does not exist on the local system. Please check it, and try again." + "' does not exist on the local system. Please check it, and try again."
) )
else: else:
print( logging.error(
f"ERROR: The 'config.json' file cannot be found - have you created it yet?" f"The 'config.json' file cannot be found - have you created it yet?"
) )