Skip to content

Instantly share code, notes, and snippets.

@PierreDurrr
Created January 28, 2025 15:21
Show Gist options
  • Save PierreDurrr/e0bbea5f35508867690ff096b71f6b2c to your computer and use it in GitHub Desktop.
Save PierreDurrr/e0bbea5f35508867690ff096b71f6b2c to your computer and use it in GitHub Desktop.
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