add removal with sonarr/radarr
This commit is contained in:
parent
1da63a16a1
commit
130802c5c5
|
|
@ -1,7 +1,15 @@
|
|||
[TAUTULLI]
|
||||
SERVER_URL = https://tautulli.exemple.com/
|
||||
SERVER_URL = https://tautulli.exemple.com
|
||||
API_KEY = e18e33df8f7sdfae92d3a2344f2f60
|
||||
|
||||
[RADARR]
|
||||
SERVER_URL = https://radarr.exemple.com
|
||||
API_KEY = e1werwrdfae92d3a2344f2f60
|
||||
|
||||
[SONARR]
|
||||
SERVER_URL = https://sonarr.exemple.com
|
||||
API_KEY = e18e33df8f7sdfasdfaf2f60
|
||||
|
||||
[MEDIA_FILTER]
|
||||
; Section_id de la librairie film à nettoyer
|
||||
film_section_ids = [1,2]
|
||||
|
|
|
|||
146
plexwasher.py
146
plexwasher.py
|
|
@ -11,6 +11,7 @@ import sys
|
|||
import requests
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import re
|
||||
|
||||
class RequestError(Exception):
|
||||
pass
|
||||
|
|
@ -18,8 +19,12 @@ class RequestError(Exception):
|
|||
class ApplicationError(Exception):
|
||||
pass
|
||||
|
||||
SERVER_URL = ""
|
||||
API_KEY = ""
|
||||
TAUTULLI_SERVER_URL = ""
|
||||
TAUTULLI_API_KEY = ""
|
||||
SONARR_SERVER_URL = ""
|
||||
SONARR_API_KEY = ""
|
||||
RADARR_SERVER_URL = ""
|
||||
RADARR_API_KEY = ""
|
||||
FILM_SECTION_IDS = []
|
||||
DEADLINE_NEVER_WATCHED = ""
|
||||
DEADLINE_LAST_WATCHED = ""
|
||||
|
|
@ -35,8 +40,8 @@ def get_unwatched_rating_keys(sectionId):
|
|||
deadlineLastWacthed = datetime.now() - relativedelta(months=DEADLINE_LAST_WATCHED)
|
||||
|
||||
# Send http request to refresh the list and get the number of media to safeguard from infinite loop
|
||||
payload = {'apikey': API_KEY, 'cmd': 'get_library_media_info', 'section_id': sectionId, 'order_column': 'last_played', 'order_dir': 'asc','length': 1, 'start': 0, 'refresh ': 'true'}
|
||||
request = requests.get(SERVER_URL+"api/v2", params=payload)
|
||||
payload = {'apikey': TAUTULLI_API_KEY, 'cmd': 'get_library_media_info', 'section_id': sectionId, 'order_column': 'last_played', 'order_dir': 'asc','length': 1, 'start': 0, 'refresh ': 'true'}
|
||||
request = requests.get(TAUTULLI_SERVER_URL+"/api/v2", params=payload)
|
||||
response = json.loads(request.content)
|
||||
|
||||
if response["response"]['result'] == 'error':
|
||||
|
|
@ -49,8 +54,8 @@ def get_unwatched_rating_keys(sectionId):
|
|||
recentlyWatched = False
|
||||
|
||||
# Send http request to retrieve the next n=length items
|
||||
payload = {'apikey': API_KEY, 'cmd': 'get_library_media_info', 'section_id': sectionId, 'order_column': 'last_played', 'order_dir': 'asc', 'length': length, 'start': start}
|
||||
request = requests.get(SERVER_URL+"api/v2", params=payload)
|
||||
payload = {'apikey': TAUTULLI_API_KEY, 'cmd': 'get_library_media_info', 'section_id': sectionId, 'order_column': 'last_played', 'order_dir': 'asc', 'length': length, 'start': start}
|
||||
request = requests.get(TAUTULLI_SERVER_URL+"/api/v2", params=payload)
|
||||
response = json.loads(request.content)
|
||||
|
||||
if response["response"]['result'] == 'error':
|
||||
|
|
@ -88,8 +93,8 @@ def get_unwatched_rating_keys(sectionId):
|
|||
# Returns the path list of all the files composing the media
|
||||
def get_media_paths(rating_key):
|
||||
# Get the metadata of the media
|
||||
payload = {'apikey': API_KEY, 'cmd': 'get_metadata', 'rating_key': rating_key}
|
||||
request = requests.get(SERVER_URL+"api/v2", params=payload)
|
||||
payload = {'apikey': TAUTULLI_API_KEY, 'cmd': 'get_metadata', 'rating_key': rating_key}
|
||||
request = requests.get(TAUTULLI_SERVER_URL+"/api/v2", params=payload)
|
||||
response = json.loads(request.content)
|
||||
|
||||
if response["response"]['result'] == 'error':
|
||||
|
|
@ -103,8 +108,8 @@ def get_media_paths(rating_key):
|
|||
case "show" | "season":
|
||||
# If the media is a group of media we get the path of all its components
|
||||
# Getting the list of child
|
||||
payload = {'apikey': API_KEY, 'cmd': 'get_children_metadata', 'rating_key': rating_key}
|
||||
request = requests.get(SERVER_URL+"api/v2", params=payload)
|
||||
payload = {'apikey': TAUTULLI_API_KEY, 'cmd': 'get_children_metadata', 'rating_key': rating_key}
|
||||
request = requests.get(TAUTULLI_SERVER_URL+"/api/v2", params=payload)
|
||||
response = json.loads(request.content)
|
||||
|
||||
if response["response"]['result'] == 'error':
|
||||
|
|
@ -153,19 +158,101 @@ def get_and_store_files_to_remove():
|
|||
for path in pathToRemove:
|
||||
f.write(f"{path}\n")
|
||||
|
||||
def delete_from_radarr(movies, path):
|
||||
for movie in movies:
|
||||
if movie["path"] in path:
|
||||
# Send http request to delete movie
|
||||
payload = {'apikey': RADARR_API_KEY, 'deleteFiles': 'true'}
|
||||
request = requests.delete(RADARR_SERVER_URL+"/api/v3/movie/"+str(movie["id"]), params=payload)
|
||||
if request.status_code == 200:
|
||||
logger.debug("Successfully deleted {}".format(movie["title"]))
|
||||
return True
|
||||
logger.warning("recieved not 200 from raddar. : " + request.reason)
|
||||
|
||||
logger.debug("Failed to delete {} using raddar".format(movie["title"]))
|
||||
return False
|
||||
|
||||
def delete_from_sonarr(name, deletedSeries, series):
|
||||
if name in deletedSeries:
|
||||
logger.debug("Skipping deletion of {} as it has already been deleted".format(name))
|
||||
return True
|
||||
|
||||
for serie in series:
|
||||
if serie["title"] == name:
|
||||
# Send http request to delete serie
|
||||
payload = {'apikey': SONARR_API_KEY, 'deleteFiles': 'true'}
|
||||
request = requests.delete(SONARR_SERVER_URL+"/api/v3/series/"+str(serie["id"]), params=payload)
|
||||
if request.status_code == 200:
|
||||
deletedSeries.append(name)
|
||||
logger.debug("Successfully deleted {}".format(name))
|
||||
return True
|
||||
logger.warning("recieved not 200 from sonarr. : " + request.reason)
|
||||
|
||||
logger.debug("Failed to delete {} using sonarr".format(name))
|
||||
return False
|
||||
|
||||
|
||||
# Delete all files and empty parent folder listed in an input file
|
||||
def delete_files(inputFile):
|
||||
series =[]
|
||||
deletedSeries = []
|
||||
movies = []
|
||||
|
||||
# Send http request to get the list of series
|
||||
payload = {'apikey': SONARR_API_KEY}
|
||||
request = requests.get(SONARR_SERVER_URL+"/api/v3/series", params=payload)
|
||||
if request.status_code == 200:
|
||||
series = json.loads(request.content)
|
||||
else:
|
||||
logger.warning("Failed to retrieve list of series from sonarr. : " + request.reason)
|
||||
|
||||
# Send http request to get the list of movies
|
||||
payload = {'apikey': RADARR_API_KEY}
|
||||
request = requests.get(RADARR_SERVER_URL+"/api/v3/movie", params=payload)
|
||||
if request.status_code == 200:
|
||||
movies = json.loads(request.content)
|
||||
else:
|
||||
logger.warning("Failed to retrieve list of series from sonarr. : " + request.reason)
|
||||
|
||||
logger.info("Deleting all unwanted media files listed in \"{}\"".format(inputFile))
|
||||
with open(inputFile, 'r') as f:
|
||||
for path in f:
|
||||
path = path.strip()
|
||||
logger.debug("Deleting file: " + path)
|
||||
os.remove(path)
|
||||
parent = os.path.split(path)[0]
|
||||
dir = os.listdir(parent)
|
||||
if len(dir) == 0:
|
||||
logger.debug("Deleting empty folder: " + parent)
|
||||
|
||||
# try to delete a serie with sonarr
|
||||
try:
|
||||
match = re.search(r'/Plex/Series/([^/]+)/', path)
|
||||
if match:
|
||||
logger.debug("{} matched series path pattern for '{}'".format(path, match.group(1)))
|
||||
if delete_from_sonarr(match.group(1), deletedSeries, series):
|
||||
continue
|
||||
|
||||
except Exception as err:
|
||||
logger.warning("Error while trying to remove with sonarr: {}".format(err))
|
||||
|
||||
# try to delete a movie with radarr
|
||||
try:
|
||||
match = re.search(r'/Plex/Films/([^/]+)', path)
|
||||
if match:
|
||||
logger.debug("{} matched movies path pattern".format(path))
|
||||
if delete_from_radarr(movies, path):
|
||||
continue
|
||||
|
||||
except Exception as err:
|
||||
logger.warning("Error while trying to remove with radarr: {}".format(err))
|
||||
|
||||
# failed to delete with sonarr/radarr so we delete the file directly
|
||||
try:
|
||||
logger.debug("Failed to delete with sonarr/radarr. -> Deleting the file directly")
|
||||
os.remove(path)
|
||||
parent = os.path.split(path)[0]
|
||||
dir = os.listdir(parent)
|
||||
if len(dir) == 0:
|
||||
logger.debug("Deleting empty folder: " + parent)
|
||||
os.rmdir(parent)
|
||||
except Exception as err:
|
||||
logger.error("Error could not delete '{}' from local dir: {}".format(path, err))
|
||||
|
||||
|
||||
###### ----- main ----- ######
|
||||
|
|
@ -211,8 +298,18 @@ config_obj.read("config.ini")
|
|||
|
||||
# -- Read TAUTULLI section --
|
||||
serverParam = config_obj["TAUTULLI"]
|
||||
SERVER_URL = serverParam["server_url"]
|
||||
API_KEY = serverParam["api_key"]
|
||||
TAUTULLI_SERVER_URL = serverParam["server_url"]
|
||||
TAUTULLI_API_KEY = serverParam["api_key"]
|
||||
|
||||
# -- Read RADARR section --
|
||||
serverParam = config_obj["RADARR"]
|
||||
RADARR_SERVER_URL = serverParam["server_url"]
|
||||
RADARR_API_KEY = serverParam["api_key"]
|
||||
|
||||
# -- Read SONARR section --
|
||||
serverParam = config_obj["SONARR"]
|
||||
SONARR_SERVER_URL = serverParam["server_url"]
|
||||
SONARR_API_KEY = serverParam["api_key"]
|
||||
|
||||
# -- Read MEDIA_FILTER section --
|
||||
mediaParam = config_obj["MEDIA_FILTER"]
|
||||
|
|
@ -221,7 +318,18 @@ DEADLINE_NEVER_WATCHED = int(mediaParam["deadline_never_watched"])
|
|||
DEADLINE_LAST_WATCHED = int(mediaParam["deadline_last_watched"])
|
||||
FILES_TO_KEEP = ast.literal_eval(mediaParam["files_to_ignore"])
|
||||
|
||||
logger.debug("Loaded config values: \n SERVER_URL: {}\n API_KEY: hidden\n FILM_SECTION_IDS: {}\n DEADLINE_NEVER_WATCHED: {}\n DEADLINE_LAST_WATCHED: {}\n FILES_TO_KEEP: {}".format(SERVER_URL, FILM_SECTION_IDS, DEADLINE_NEVER_WATCHED, DEADLINE_LAST_WATCHED, FILES_TO_KEEP))
|
||||
logger.debug("Loaded config values: \n" \
|
||||
" TAUTULLI_SERVER_URL: {}\n" \
|
||||
" TAUTULLI_API_KEY: hidden\n" \
|
||||
" RADARR_SERVER_URL: {}\n" \
|
||||
" RADARR_API_KEY: hidden\n" \
|
||||
" SONARR_SERVER_URL: {}\n" \
|
||||
" SONARR_API_KEY: hidden\n" \
|
||||
" FILM_SECTION_IDS: {}\n" \
|
||||
" DEADLINE_NEVER_WATCHED: {}\n" \
|
||||
" DEADLINE_LAST_WATCHED: {}\n" \
|
||||
" FILES_TO_KEEP: {}"
|
||||
.format(TAUTULLI_SERVER_URL,RADARR_SERVER_URL, SONARR_SERVER_URL, FILM_SECTION_IDS, DEADLINE_NEVER_WATCHED, DEADLINE_LAST_WATCHED, FILES_TO_KEEP))
|
||||
|
||||
|
||||
### --- Start logic --- ###
|
||||
|
|
@ -236,4 +344,4 @@ try:
|
|||
if args.delete:
|
||||
delete_files(outputfile)
|
||||
except (RequestError, ApplicationError) as err:
|
||||
logger.error(err)
|
||||
logger.error("{}".format(err))
|
||||
Loading…
Reference in New Issue