Skip to content

Instantly share code, notes, and snippets.

@Archmonger
Last active September 29, 2024 00:49
Show Gist options
  • Save Archmonger/85295ca772c08ee738b62bcd930ad67f to your computer and use it in GitHub Desktop.
Save Archmonger/85295ca772c08ee738b62bcd930ad67f to your computer and use it in GitHub Desktop.
"""This script changes all Sonarr series folders to `{current_folder_name} {tvdb-xxx}` format
and removes characters that are illegal on Windows from the path."""
import json
import pathlib
import re
import sys
from requests import request
ILLEGAL_CHARS = ':*?"<>|'
if __name__ == "__main__":
yes_in_sys_argv: bool = len(sys.argv) > 1 and sys.argv[1] in {"-y", "--yes"}
sonarr_json = pathlib.Path("sonarr.json")
if sonarr_json.exists():
with open(sonarr_json, encoding="UTF-8") as f:
data = json.loads(f.read())
api_url = data["api_url"].rstrip("/")
api_key = data["api_key"]
else:
print("Enter Sonarr's URL: ", end="")
api_url = input().rstrip("/")
print("Enter Sonarr's API Key: ", end="")
api_key = input()
response = request(
"GET",
f"{api_url}/api/v3/series?apikey={api_key}",
timeout=30,
)
response.raise_for_status()
all_series = response.json()
needs_path_update = {}
for series in all_series:
# Find series that contain characters that are illegal in Windows paths
if any(char in series["path"] for char in ILLEGAL_CHARS):
needs_path_update[series["id"]] = series
# Find series that have a `tvdb` but the path does not contain `tvdb-`
elif series["tvdbId"] and "tvdb-" not in series["path"]:
needs_path_update[series["id"]] = series
if not needs_path_update:
print("No series need their paths updated.")
sys.exit(0)
# Update the paths for the series that need it using the series editor API
for series_id, series in needs_path_update.items():
# Remove trailing slashes
new_path: str = series["path"].rstrip("/").rstrip("\\")
# Replace illegal characters
for char in ILLEGAL_CHARS:
new_path = new_path.replace(char, " ")
# If the path does not contain `tvdb-`, add it
if series["tvdbId"] and "tvdb-" not in new_path:
new_path = f"{new_path} {{tvdb-{series['tvdbId']}}}"
# Replace duplicate spaces with a single space
new_path = re.sub(r"\s+", " ", new_path)
# Wait for user input
print(f"Updating path for {series['title']} to '{new_path}'")
if not yes_in_sys_argv:
print("Press any button to commit this change, or Ctrl+C to cancel...")
input()
# Commit the change
response = request(
"PUT",
f"{api_url}/api/v3/series/{series_id}?apikey={api_key}&moveFiles=true",
json={**series, "path": new_path},
timeout=30,
)
response.raise_for_status()
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment