mirror of
https://github.com/SinTan1729/TvTimeToTrakt.git
synced 2024-12-25 21:08:37 -06:00
Don't prompt for authentication if Oauth token is still valid
This commit is contained in:
parent
7af14f2f8f
commit
5c3bda15b7
1 changed files with 41 additions and 24 deletions
|
@ -1,23 +1,24 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import trakt.core
|
import trakt.core
|
||||||
from trakt import init
|
|
||||||
from tinydb import Query, TinyDB
|
from tinydb import Query, TinyDB
|
||||||
|
from trakt import init
|
||||||
from trakt.tv import TVShow
|
from trakt.tv import TVShow
|
||||||
|
|
||||||
# Setup logger
|
# Setup logger
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
format='%(asctime)s %(levelname)s :: %(message)s',
|
format="%(asctime)s [%(levelname)7s] :: %(message)s",
|
||||||
level=logging.INFO,
|
level=logging.INFO,
|
||||||
datefmt='%Y-%m-%d %H:%M:%S'
|
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.
|
||||||
|
@ -34,6 +35,17 @@ class Expando(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def isAuthenticated():
|
||||||
|
with open(f"{Path.home()}/.pytrakt.json") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
daysBeforeExpiration = (
|
||||||
|
datetime.fromtimestamp(data["OAUTH_EXPIRES_AT"]) - datetime.now()
|
||||||
|
).days
|
||||||
|
if daysBeforeExpiration < 1:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def getConfiguration():
|
def getConfiguration():
|
||||||
configEx = Expando()
|
configEx = Expando()
|
||||||
|
|
||||||
|
@ -64,7 +76,8 @@ def getFollowedShowsPath():
|
||||||
|
|
||||||
|
|
||||||
def initTraktAuth():
|
def initTraktAuth():
|
||||||
return True
|
if isAuthenticated():
|
||||||
|
return True
|
||||||
# Set the method of authentication
|
# Set the method of authentication
|
||||||
trakt.core.AUTH_METHOD = trakt.core.OAUTH_AUTH
|
trakt.core.AUTH_METHOD = trakt.core.OAUTH_AUTH
|
||||||
return init(
|
return init(
|
||||||
|
@ -93,7 +106,7 @@ def getYearFromTitle(title):
|
||||||
ex.titleWithoutYear = titleValue
|
ex.titleWithoutYear = titleValue
|
||||||
ex.yearValue = int(yearValue)
|
ex.yearValue = int(yearValue)
|
||||||
return ex
|
return ex
|
||||||
except:
|
except Exception:
|
||||||
# If the above failed, then the title doesn't include a year
|
# If the above failed, then the title doesn't include a year
|
||||||
# so return the object as is.
|
# so return the object as is.
|
||||||
ex.titleWithoutYear = title
|
ex.titleWithoutYear = title
|
||||||
|
@ -160,7 +173,7 @@ def getShowByName(name, seasonNo, episodeNo):
|
||||||
if checkTitleNameMatch(name, show.title):
|
if checkTitleNameMatch(name, show.title):
|
||||||
# If the title included the year of broadcast, then we can be more picky in the results
|
# If the title included the year of broadcast, then we can be more picky in the results
|
||||||
# to look for a show with a broadcast year that matches
|
# to look for a show with a broadcast year that matches
|
||||||
if doesTitleIncludeYear == True:
|
if doesTitleIncludeYear:
|
||||||
# If the show title is a 1:1 match, with the same broadcast year, then bingo!
|
# If the show title is a 1:1 match, with the same broadcast year, then bingo!
|
||||||
if (name == show.title) and (show.year == titleObj.yearValue):
|
if (name == show.title) and (show.year == titleObj.yearValue):
|
||||||
# Clear previous results, and only use this one
|
# Clear previous results, and only use this one
|
||||||
|
@ -206,7 +219,7 @@ def getShowByName(name, seasonNo, episodeNo):
|
||||||
skipShow = firstMatch.get("SkipShow")
|
skipShow = firstMatch.get("SkipShow")
|
||||||
# If the user did not skip, but provided an index selection, get the
|
# If the user did not skip, but provided an index selection, get the
|
||||||
# matching show
|
# matching show
|
||||||
if skipShow == False:
|
if not skipShow:
|
||||||
return showsWithSameName[firstMatchSelectedIndex]
|
return showsWithSameName[firstMatchSelectedIndex]
|
||||||
# Otherwise, return None, which will trigger the script to skip
|
# Otherwise, return None, which will trigger the script to skip
|
||||||
# and move onto the next show
|
# and move onto the next show
|
||||||
|
@ -231,7 +244,7 @@ def getShowByName(name, seasonNo, episodeNo):
|
||||||
try:
|
try:
|
||||||
# Get the user's selection, either a numerical input, or a string 'SKIP' value
|
# Get the user's selection, either a numerical input, or a string 'SKIP' value
|
||||||
indexSelected = input(
|
indexSelected = input(
|
||||||
f"Please make a selection from above (or enter SKIP):"
|
"Please make a selection from above (or enter SKIP):"
|
||||||
)
|
)
|
||||||
|
|
||||||
if indexSelected != "SKIP":
|
if indexSelected != "SKIP":
|
||||||
|
@ -246,7 +259,7 @@ def getShowByName(name, seasonNo, episodeNo):
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
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 Exception:
|
||||||
logging.error(
|
logging.error(
|
||||||
f"Sorry! Please select a value between 0 to {len(showsWithSameName)}"
|
f"Sorry! Please select a value between 0 to {len(showsWithSameName)}"
|
||||||
)
|
)
|
||||||
|
@ -361,7 +374,7 @@ def processWatchedShows():
|
||||||
# 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:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"WARNING: An error occurred 10 times in a row... skipping episode..."
|
"An error occurred 10 times in a row... skipping episode..."
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
try:
|
try:
|
||||||
|
@ -375,11 +388,11 @@ def processWatchedShows():
|
||||||
)
|
)
|
||||||
# If the method returned 'None', then this is an indication to skip the episode, and
|
# If the method returned 'None', then this is an indication to skip the episode, and
|
||||||
# move onto the next one
|
# move onto the next one
|
||||||
if traktShowObj == None:
|
if traktShowObj is None:
|
||||||
break
|
break
|
||||||
# Show the progress of the import on-screen
|
# Show the progress of the import on-screen
|
||||||
logging.info(
|
logging.info(
|
||||||
f"({rowsCount+1}/{rowsTotal}) Processing - '{tvShowName}' 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[
|
||||||
|
@ -399,21 +412,23 @@ 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:
|
||||||
tvShowSlug = traktShowObj.to_json()['shows'][0]['ids']['ids']['slug']
|
tvShowSlug = traktShowObj.to_json()["shows"][0]["ids"]["ids"][
|
||||||
|
"slug"
|
||||||
|
]
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"({rowsCount}/{rowsTotal}) WARNING: {tvShowName} Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo} does not exist in Trakt! (https://trakt.tv/shows/{tvShowSlug}/seasons/{tvShowSeasonNo}/episodes/{tvShowEpisodeNo})"
|
f"({rowsCount}/{rowsTotal}) - {tvShowName} Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo} does not exist in Trakt! (https://trakt.tv/shows/{tvShowSlug}/seasons/{tvShowSeasonNo}/episodes/{tvShowEpisodeNo})"
|
||||||
)
|
)
|
||||||
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:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"({rowsCount}/{rowsTotal}) WARNING: {tvShowName} Season {tvShowSeasonNo}, Episode {tvShowEpisodeNo} does not exist (search) in Trakt!"
|
f"({rowsCount}/{rowsTotal}) - {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:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
"WARNING: The program is running too quickly and has hit Trakt's API rate limit! Please increase the delay between "
|
"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."
|
||||||
)
|
)
|
||||||
|
@ -424,7 +439,7 @@ def processWatchedShows():
|
||||||
# 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:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"({rowsCount}/{rowsTotal}) WARNING: A JSON decode error occuring whilst processing {tvShowName} "
|
f"({rowsCount}/{rowsTotal}) - 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."
|
||||||
)
|
)
|
||||||
|
@ -440,7 +455,7 @@ def processWatchedShows():
|
||||||
# Skip the episode
|
# Skip the episode
|
||||||
else:
|
else:
|
||||||
logging.info(
|
logging.info(
|
||||||
f"({rowsCount}/{rowsTotal}) Already imported, skipping - '{tvShowName}' Season {tvShowSeasonNo} / Episode {tvShowEpisodeNo}."
|
f"({rowsCount}/{rowsTotal}) - Already imported, skipping '{tvShowName}' Season {tvShowSeasonNo} / Episode {tvShowEpisodeNo}."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,12 +463,12 @@ def start():
|
||||||
# Create the initial authentication with Trakt, before starting the process
|
# Create the initial authentication with Trakt, before starting the process
|
||||||
if initTraktAuth():
|
if initTraktAuth():
|
||||||
# Display a menu selection
|
# Display a menu selection
|
||||||
print(f">> What do you want to do?")
|
print(">> What do you want to do?")
|
||||||
print(f" 1) Import Watch History from TV Time")
|
print(" 1) Import Watch History from TV Time")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
menuSelection = input(f"Enter your menu selection: ")
|
menuSelection = input("Enter your menu selection: ")
|
||||||
menuSelection = 1 if not menuSelection else int(menuSelection)
|
menuSelection = 1 if not menuSelection else int(menuSelection)
|
||||||
break
|
break
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -466,7 +481,9 @@ def start():
|
||||||
else:
|
else:
|
||||||
logging.warning("Sorry - that's an unknown menu selection")
|
logging.warning("Sorry - that's an unknown menu selection")
|
||||||
else:
|
else:
|
||||||
logging.error("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__":
|
||||||
|
@ -483,5 +500,5 @@ if __name__ == "__main__":
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logging.error(
|
logging.error(
|
||||||
f"The 'config.json' file cannot be found - have you created it yet?"
|
"The 'config.json' file cannot be found - have you created it yet?"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue