Skip to content

Commit

Permalink
Merge pull request #75 from RileyXX/fix-for-trakt-auth-requests-and-i…
Browse files Browse the repository at this point in the history
…mprovements-for-handling-credentials

Fix for some Trakt auth requests failing occasionally + other minor improvements
  • Loading branch information
RileyXX authored Nov 9, 2023
2 parents 277088c + c48db51 commit 589eff2
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 41 deletions.
63 changes: 40 additions & 23 deletions IMDBTraktSyncer/authTrakt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@
def make_trakt_request(url, headers=None, params=None, payload=None, max_retries=5):
retry_delay = 1 # seconds between retries
retry_attempts = 0

if headers is None:
headers = {
'Content-Type': 'application/json',
}

while retry_attempts < max_retries:
response = None
try:
response = requests.post(url, headers=headers, json=payload)
if payload is None:
if params:
response = requests.get(url, headers=headers, params=params)
else:
response = requests.get(url, headers=headers)
else:
response = requests.post(url, headers=headers, json=payload)

if response.status_code in [200, 201, 204]:
return response # Request succeeded, return response
Expand All @@ -23,16 +34,20 @@ def make_trakt_request(url, headers=None, params=None, payload=None, max_retries
retry_delay *= 2 # Exponential backoff for retries
else:
# Handle other status codes as needed
error_message = get_trakt_message(response.status_code)
print(f"Request failed with status code {response.status_code}: {error_message}")
status_message = get_trakt_message(response.status_code)
error_message = f"Request failed with status code {response.status_code}: {status_message}"
print(f" - {error_message}")
EL.logger.error(f"{error_message}. URL: {url}")
return None

except requests.exceptions.RequestException as e:
print(f"Request failed with exception: {e}")
error_message = f"Request failed with exception: {e}"
print(f" - {error_message}")
EL.logger.error(error_message, exc_info=True)
return None

error_message = "Max retry attempts reached with Trakt API, request failed."
print(f"{error_message}")
print(f" - {error_message}")
EL.logger.error(error_message)
return None

Expand Down Expand Up @@ -82,12 +97,14 @@ def authenticate(client_id, client_secret, refresh_token=None):
'grant_type': 'refresh_token'
}

response = requests.post('https://api.trakt.tv/oauth/token', json=data)
# Use make_trakt_request for the POST request
response = make_trakt_request('https://api.trakt.tv/oauth/token', payload=data)

json_data = response.json()
ACCESS_TOKEN = json_data['access_token']
REFRESH_TOKEN = json_data['refresh_token']
return ACCESS_TOKEN, REFRESH_TOKEN
if response:
json_data = response.json()
ACCESS_TOKEN = json_data['access_token']
REFRESH_TOKEN = json_data['refresh_token']
return ACCESS_TOKEN, REFRESH_TOKEN

else:
# Set up the authorization endpoint URL
Expand All @@ -109,9 +126,6 @@ def authenticate(client_id, client_secret, refresh_token=None):
authorization_code = input('Please enter the authorization code from the URL: ')

# Set up the access token request
headers = {
'Content-Type': 'application/json'
}
data = {
'code': authorization_code,
'client_id': CLIENT_ID,
Expand All @@ -120,16 +134,19 @@ def authenticate(client_id, client_secret, refresh_token=None):
'grant_type': 'authorization_code'
}

# Make the request to get the access token
response = requests.post('https://api.trakt.tv/oauth/token', json=data)
# Use make_trakt_request for the POST request
response = make_trakt_request('https://api.trakt.tv/oauth/token', payload=data)

if response:
# Parse the JSON response from the API
json_data = response.json()

# Parse the JSON response from the API
json_data = response.json()
# Extract the access token from the response
ACCESS_TOKEN = json_data['access_token']

# Extract the access token from the response
ACCESS_TOKEN = json_data['access_token']

# Extract the refresh token from the response
REFRESH_TOKEN = json_data['refresh_token']
# Extract the refresh token from the response
REFRESH_TOKEN = json_data['refresh_token']

return ACCESS_TOKEN, REFRESH_TOKEN
return ACCESS_TOKEN, REFRESH_TOKEN

return None
44 changes: 27 additions & 17 deletions IMDBTraktSyncer/verifyCredentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ def prompt_get_credentials():
# Define the file path
here = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(here, 'credentials.txt')

default_values = {
"trakt_client_id": "empty",
"trakt_client_secret": "empty",
"trakt_access_token": "empty",
"trakt_refresh_token": "empty",
"imdb_username": "empty",
"imdb_password": "empty"
}

# Check if the file exists
if not os.path.isfile(file_path) or os.path.getsize(file_path) == 0:
# If the file does not exist or is empty, create it with default values
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(default_values, f)

# Old version support (v1.0.6 and below). Convert old credentials.txt format to json
if os.path.isfile(file_path):
Expand All @@ -26,23 +41,18 @@ def prompt_get_credentials():
json.dump(values, txt_file)
print("Warning: You are using a depreciated credentials.txt file.\nConversion successful: credentials.txt file converted to the new JSON format.")

# Check if the file exists
if not os.path.isfile(file_path):
# If the file does not exist, create it with default values
default_values = {
"trakt_client_id": "empty",
"trakt_client_secret": "empty",
"trakt_access_token": "empty",
"trakt_refresh_token": "empty",
"imdb_username": "empty",
"imdb_password": "empty"
}
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(default_values, f)

# Load the values from the file
# Load the values from the file or initialize with default values
with open(file_path, 'r', encoding='utf-8') as f:
values = json.load(f)
try:
values = json.load(f)
except json.decoder.JSONDecodeError:
# Handle the case where the file is empty or not a valid JSON
values = default_values

# Check if any default values are missing and add them if necessary
for key, default_value in default_values.items():
if key not in values:
values[key] = default_value

# Check if any of the values are "empty" and prompt the user to enter them
for key in values.keys():
Expand Down Expand Up @@ -230,7 +240,7 @@ def prompt_sync_reviews():

while True:
# Prompt the user for input
print("Ratings are synced by default. Please note: comments synced to IMDB will use \"My Review\" as the title field.")
print("Please note: comments synced to IMDB will use \"My Review\" as the title field.")
print("Do you want to sync comments? (y/n)")
user_input = input("Enter your choice: ")

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
with codecs.open(os.path.join(here, "README.md"), 'r', encoding="utf-8") as fh:
long_description = "\n" + fh.read()

VERSION = '1.8.2'
VERSION = '1.8.3'
DESCRIPTION = 'A python script that syncs user watchlist, ratings and comments for Movies, TV Shows and Episodes both ways between Trakt and IMDB.'

# Setting up
Expand Down

0 comments on commit 589eff2

Please sign in to comment.