Created
January 28, 2025 15:21
-
-
Save PierreDurrr/e0bbea5f35508867690ff096b71f6b2c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
from plexapi.server import PlexServer | |
# Configuration (move library names to the top) | |
RADARR_INSTANCES = [ | |
{"url": "http://address:7878/api/v3", "api_key": "nope"} | |
# Add more Radarr instances here if needed | |
] | |
SONARR_INSTANCES = [ | |
{"url": "http://address:8989/api/v3", "api_key": "nope"} | |
# Add more Sonarr instances here if needed | |
] | |
PLEX_INSTANCES = [ | |
{"url": "http://address:32400", "token": "nope"} | |
# Add more Plex instances here if needed | |
] | |
# Plex Library Names | |
MOVIE_LIBRARY_NAME = "your_movies_library_name" | |
SHOW_LIBRARY_NAME = "your_tvshows_library_name" | |
PLEX_LIBRARY_IDS = { | |
MOVIE_LIBRARY_NAME: 2, # Replace with your movie library ID | |
SHOW_LIBRARY_NAME: 3 # Replace with your show library ID | |
} | |
SYNC_TAGS = ["tag_to_sync"] # Specify tags to sync | |
BATCH_SIZE = 50 | |
# Helper functions for API calls | |
def check_radarr_connection(radarr_url, radarr_api_key): | |
try: | |
response = requests.get(f"{radarr_url}/system/status", headers={"X-Api-Key": radarr_api_key}) | |
response.raise_for_status() | |
version = response.json().get("version") | |
print(f"Radarr connection: OK ({version})") | |
except Exception as e: | |
print(f"Radarr connection failed: {e}") | |
exit(1) | |
def check_sonarr_connection(sonarr_url, sonarr_api_key): | |
try: | |
response = requests.get(f"{sonarr_url}/system/status", headers={"X-Api-Key": sonarr_api_key}) | |
response.raise_for_status() | |
version = response.json().get("version") | |
print(f"Sonarr connection: OK ({version})") | |
except Exception as e: | |
print(f"Sonarr connection failed: {e}") | |
exit(1) | |
def check_plex_connection(plex_url, plex_token): | |
try: | |
plex = PlexServer(plex_url, plex_token) | |
print(f"Plex connection: OK (Libraries: {', '.join([lib.title for lib in plex.library.sections()])})") | |
return plex | |
except Exception as e: | |
print(f"Plex connection failed: {e}") | |
exit(1) | |
def fetch_radarr_tags(radarr_url, radarr_api_key): | |
response = requests.get(f"{radarr_url}/tag", headers={"X-Api-Key": radarr_api_key}) | |
response.raise_for_status() | |
return {tag["id"]: tag["label"] for tag in response.json()} | |
def fetch_sonarr_tags(sonarr_url, sonarr_api_key): | |
response = requests.get(f"{sonarr_url}/tag", headers={"X-Api-Key": sonarr_api_key}) | |
response.raise_for_status() | |
return {tag["id"]: tag["label"] for tag in response.json()} | |
def fetch_radarr_movies(radarr_url, radarr_api_key): | |
response = requests.get(f"{radarr_url}/movie", headers={"X-Api-Key": radarr_api_key}) | |
response.raise_for_status() | |
return response.json() | |
def fetch_sonarr_shows(sonarr_url, sonarr_api_key): | |
response = requests.get(f"{sonarr_url}/series", headers={"X-Api-Key": sonarr_api_key}) | |
response.raise_for_status() | |
return response.json() | |
def fetch_plex_items(plex_url, plex_token, library_id): | |
plex = PlexServer(plex_url, plex_token) | |
library = plex.library.sectionByID(library_id) | |
return library.all() | |
def update_plex_labels(item, tags): | |
existing_labels = [label.tag for label in item.labels] | |
new_labels = [tag for tag in tags if tag not in existing_labels] | |
for label in new_labels: | |
item.addLabel(label) | |
# Main script | |
def sync_tags(): | |
print("Checking connections...") | |
# Check all Radarr instances | |
for radarr in RADARR_INSTANCES: | |
check_radarr_connection(radarr["url"], radarr["api_key"]) | |
# Check all Sonarr instances | |
for sonarr in SONARR_INSTANCES: | |
check_sonarr_connection(sonarr["url"], sonarr["api_key"]) | |
# Check all Plex instances | |
for plex in PLEX_INSTANCES: | |
check_plex_connection(plex["url"], plex["token"]) | |
# Fetch data for all instances | |
radarr_data = [] | |
for radarr in RADARR_INSTANCES: | |
radarr_tag_map = fetch_radarr_tags(radarr["url"], radarr["api_key"]) | |
radarr_movies = fetch_radarr_movies(radarr["url"], radarr["api_key"]) | |
radarr_data.append({"tags": radarr_tag_map, "movies": radarr_movies}) | |
sonarr_data = [] | |
for sonarr in SONARR_INSTANCES: | |
sonarr_tag_map = fetch_sonarr_tags(sonarr["url"], sonarr["api_key"]) | |
sonarr_shows = fetch_sonarr_shows(sonarr["url"], sonarr["api_key"]) | |
sonarr_data.append({"tags": sonarr_tag_map, "shows": sonarr_shows}) | |
plex_data = [] | |
for plex in PLEX_INSTANCES: | |
plex_items_movies = fetch_plex_items(plex["url"], plex["token"], PLEX_LIBRARY_IDS[MOVIE_LIBRARY_NAME]) | |
plex_items_shows = fetch_plex_items(plex["url"], plex["token"], PLEX_LIBRARY_IDS[SHOW_LIBRARY_NAME]) | |
plex_data.append({"movies": plex_items_movies, "shows": plex_items_shows}) | |
print("\nSyncing tags...") | |
print(f"Tags to sync: {SYNC_TAGS}") | |
processed_items = [] | |
# Process Radarr movies across all instances | |
print("\nProcessing movies from Radarr...") | |
for radarr in radarr_data: | |
for movie in radarr["movies"]: | |
movie_tags = [radarr["tags"][tag_id] for tag_id in movie.get("tags", []) if radarr["tags"].get(tag_id) in SYNC_TAGS] | |
print(f" - Radarr movie: {movie['title']} ({movie['year']}) | Tags: {movie_tags}") | |
if not movie_tags: | |
continue | |
# Find the movie in Plex | |
for plex_instance in plex_data: | |
matching_item = next((item for item in plex_instance["movies"] if item.title == movie['title'] and item.year == movie['year']), None) | |
if matching_item: | |
print(f" -> Found in Plex: {matching_item.title} ({matching_item.year})") | |
update_plex_labels(matching_item, movie_tags) | |
processed_items.append({ | |
"title": movie['title'], | |
"year": movie['year'], | |
"library": MOVIE_LIBRARY_NAME, | |
"source": "Radarr", | |
"tags": movie_tags | |
}) | |
print(f" -> Tags synced to Plex: {movie_tags}") | |
else: | |
print(f" -> Not found in Plex: {movie['title']} ({movie['year']})") | |
# Process Sonarr shows across all instances | |
print("\nProcessing shows from Sonarr...") | |
for sonarr in sonarr_data: | |
for show in sonarr["shows"]: | |
show_tags = [sonarr["tags"][tag_id] for tag_id in show.get("tags", []) if sonarr["tags"].get(tag_id) in SYNC_TAGS] | |
print(f" - Sonarr show: {show['title']} ({show['year']}) | Tags: {show_tags}") | |
if not show_tags: | |
continue | |
# Find the show in Plex | |
for plex_instance in plex_data: | |
matching_item = next((item for item in plex_instance["shows"] if item.title == show['title'] and item.year == show['year']), None) | |
if matching_item: | |
print(f" -> Found in Plex: {matching_item.title} ({matching_item.year})") | |
update_plex_labels(matching_item, show_tags) | |
processed_items.append({ | |
"title": show['title'], | |
"year": show['year'], | |
"library": SHOW_LIBRARY_NAME, | |
"source": "Sonarr", | |
"tags": show_tags | |
}) | |
print(f" -> Tags synced to Plex: {show_tags}") | |
else: | |
print(f" -> Not found in Plex: {show['title']} ({show['year']})") | |
print("\nSync complete.") | |
# Summary of processed items | |
print("\nProcessed items summary:") | |
for item in processed_items: | |
print(f" - {item['title']} ({item['year']}) | Library: {item['library']} | Source: {item['source']} | Tags: {', '.join(item['tags'])}") | |
# Run the script | |
if __name__ == "__main__": | |
sync_tags() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment