Files
ularsawa/run_unmonitor_excluded.py
Phoenix 487b28e682 Add Plex Sonarr integration script and testing framework
- Implemented a Python script for integrating Plex Media Server with Sonarr to manage TV show seasons based on viewing habits.
- Added features for automated season management, exclusion list support, and detailed logging.
- Created a requirements.txt file to include necessary packages: plexapi, requests, pytest, pytest-mock, and requests-mock.
- Developed unit tests for the API verification function using pytest and requests_mock.
- Included a standalone script to unmonitor excluded shows in Sonarr.
- Added a test script for manual API verification with mock and real API tests.
2025-08-20 23:59:05 +08:00

117 lines
4.4 KiB
Python

"""
Standalone script to unmonitor all excluded shows in Sonarr
"""
from plexapi.server import PlexServer
import requests
# Configuration
PLEX_TOKEN = "uZn42JMVkQpyb_duFsvT"
PLEX_SERVER_URL = "http://192.168.50.111:32400"
SONARR_API_KEY = "2537de37fded4874ae83da9cf3c14f34"
SONARR_SERVER_URL = "http://192.168.50.111:8989"
# Initialize Plex connection
plex = PlexServer(PLEX_SERVER_URL, PLEX_TOKEN)
tv_shows = plex.library.section('TV Shows')
# List of TV show titles to exclude
exclude_shows = ["Stargate SG-1", "Space Sheriff Gavan", "Spider-Man and His Amazing Friends","Super Sentai", "Superman & Lois", "UFO Robot Grendizer","Zorro",
"Saved by the Bell: The College Years","Saber Rider and the Star Sheriffs","Prison Break","Power Rangers","The Outer Limits (1995)","MacGyver","Knight Rider",
"Chuck","Breaking Bad","Amazing Stories (1985)","Airwolf","The Adventures of Superboy (1988)"]
def verify_sonarr_api():
"""Check if Sonarr API is alive and the token is correct"""
url = f"{SONARR_SERVER_URL}/api/v3/system/status?apikey={SONARR_API_KEY}"
try:
response = requests.get(url)
response.raise_for_status()
print("✅ Sonarr API is alive and the token is correct.")
return True
except requests.exceptions.RequestException as e:
print(f"❌ Failed to verify Sonarr API: {e}")
return False
def get_tvdb_id(show):
"""Extract TVDB ID from Plex show metadata"""
for guid in reversed(show.guids):
if guid.id.startswith("tvdb"):
return guid.id.split("://")[1]
raise ValueError(f"No TVDB ID found for show: {show.title}")
def get_series_id_from_tvdb(tvdb_id):
"""Get Sonarr series ID from TVDB ID"""
url = f"{SONARR_SERVER_URL}/api/v3/series/lookup?term=tvdb:{tvdb_id}&apikey={SONARR_API_KEY}"
response = requests.get(url)
response.raise_for_status()
series = response.json()
if series:
return series[0]['id']
else:
raise ValueError(f"No series found for TVDB ID: {tvdb_id}")
def mark_season_unmonitored(series_id, season_number):
"""Mark a season as unmonitored in Sonarr"""
url = f"{SONARR_SERVER_URL}/api/v3/series/{series_id}?apikey={SONARR_API_KEY}"
response = requests.get(url)
response.raise_for_status()
series = response.json()
for season in series['seasons']:
if season['seasonNumber'] == season_number:
season['monitored'] = False
response = requests.put(url, json=series)
response.raise_for_status()
print(f" ✅ Season {season_number} marked as unmonitored for series ID {series_id}")
def unmonitor_all_excluded_shows():
"""Unmonitor all seasons of shows in the exclude list"""
print("🚀 Starting to unmonitor all excluded shows...")
print("=" * 60)
success_count = 0
error_count = 0
for show_title in exclude_shows:
try:
print(f"\n📺 Processing: {show_title}")
show = tv_shows.get(title=show_title)
print(f" Found in Plex: {show.title}")
tvdb_id = get_tvdb_id(show)
print(f" TVDB ID: {tvdb_id}")
series_id = get_series_id_from_tvdb(tvdb_id)
print(f" Sonarr Series ID: {series_id}")
seasons = show.seasons()
print(f" Found {len(seasons)} seasons")
for season in seasons:
mark_season_unmonitored(series_id, season.index)
print(f"✅ All seasons of '{show_title}' have been marked as unmonitored.")
success_count += 1
except Exception as e:
print(f"❌ Error processing '{show_title}': {e}")
error_count += 1
print("\n" + "=" * 60)
print(f"🎉 Processing complete!")
print(f"✅ Successfully processed: {success_count} shows")
print(f"❌ Errors encountered: {error_count} shows")
if __name__ == "__main__":
print("🔍 Verifying Sonarr API connection...")
if verify_sonarr_api():
print("\n🎯 Ready to unmonitor excluded shows")
user_input = input("Do you want to proceed? (y/n): ").lower().strip()
if user_input in ['y', 'yes']:
unmonitor_all_excluded_shows()
else:
print("❌ Operation cancelled by user.")
else:
print("❌ Cannot proceed - Sonarr API verification failed.")