refactor: update and remove anything to do with NFO files
Local Docker Build (Dev) / build-dev (push) Successful in 35s
Local Docker Build (Dev) / build-dev (push) Successful in 35s
moving to an all DB approach since radarr overwrites .nfo files
This commit is contained in:
+42
-319
@@ -11,12 +11,12 @@ from datetime import datetime, timezone
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from core.database import NFOGuardDatabase
|
||||
from core.nfo_manager import NFOManager
|
||||
from core.path_mapper import PathMapper
|
||||
from clients.radarr_client import RadarrClient
|
||||
from clients.external_clients import ExternalClientManager
|
||||
from config.settings import config
|
||||
from utils.logging import _log
|
||||
from utils.imdb_utils import find_imdb_in_directory # Phase 3: Replaced NFOManager
|
||||
from utils.file_utils import find_media_path_by_imdb_and_title
|
||||
|
||||
|
||||
@@ -68,9 +68,9 @@ def convert_utc_to_local(utc_iso_string: str) -> str:
|
||||
class MovieProcessor:
|
||||
"""Handles movie processing"""
|
||||
|
||||
def __init__(self, db: NFOGuardDatabase, nfo_manager: NFOManager, path_mapper: PathMapper):
|
||||
def __init__(self, db: NFOGuardDatabase, nfo_manager, path_mapper: PathMapper):
|
||||
# nfo_manager parameter kept for backward compatibility but no longer used (Phase 3)
|
||||
self.db = db
|
||||
self.nfo_manager = nfo_manager
|
||||
self.path_mapper = path_mapper
|
||||
self.radarr = RadarrClient(
|
||||
os.environ.get("RADARR_URL", ""),
|
||||
@@ -153,7 +153,7 @@ class MovieProcessor:
|
||||
|
||||
def process_movie(self, movie_path: Path, webhook_mode: bool = False, force_scan: bool = False, scan_mode: str = "smart", shutdown_event=None) -> str:
|
||||
"""Process a movie directory"""
|
||||
imdb_id = self.nfo_manager.find_movie_imdb_id(movie_path)
|
||||
imdb_id = find_imdb_in_directory(movie_path) # Phase 3: Using imdb_utils instead of NFOManager
|
||||
if not imdb_id:
|
||||
_log("ERROR", f"No IMDb ID found in movie directory, filenames, or NFO file: {movie_path}")
|
||||
return "error"
|
||||
@@ -225,106 +225,16 @@ class MovieProcessor:
|
||||
if released and hasattr(released, 'isoformat'):
|
||||
released = released.isoformat()
|
||||
|
||||
# Create NFO with existing data and update files
|
||||
if config.manage_nfo:
|
||||
self.nfo_manager.create_movie_nfo(
|
||||
movie_path, imdb_id, dateadded, released, source, config.lock_metadata
|
||||
)
|
||||
|
||||
if config.fix_dir_mtimes and dateadded:
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
# NFO file operations removed - database is now the single source of truth
|
||||
# (Phase 1: Remove NFO file write operations)
|
||||
|
||||
_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [database-cached]")
|
||||
return "processed"
|
||||
else:
|
||||
_log("INFO", f"🔍 TIER 1 SKIP - {imdb_id}: Database incomplete, proceeding to Tier 2")
|
||||
|
||||
# TIER 2: Check if NFO file has NFOGuard data and cache it in database
|
||||
nfo_path = movie_path / "movie.nfo"
|
||||
_log("INFO", f"🔍 TIER 2 - Checking NFO file: {nfo_path}")
|
||||
_log("INFO", f"🔍 TIER 2 - NFO exists: {nfo_path.exists()}")
|
||||
|
||||
nfo_data = self.nfo_manager.extract_nfoguard_dates_from_nfo(nfo_path)
|
||||
_log("INFO", f"🔍 TIER 2 - NFOGuard data extracted: {nfo_data}")
|
||||
|
||||
if nfo_data:
|
||||
_log("INFO", f"🚀 TIER 2 - Found NFOGuard data in NFO file: {nfo_data['dateadded']} (source: {nfo_data['source']})")
|
||||
dateadded = nfo_data["dateadded"]
|
||||
source = nfo_data["source"]
|
||||
released = nfo_data.get("released")
|
||||
|
||||
# Cache NFO data in database for future lookups
|
||||
# Fixed parameter order: imdb_id, released, dateadded, source
|
||||
self.db.upsert_movie_dates(imdb_id, released, dateadded, source, True)
|
||||
_log("INFO", f"✅ Cached NFO data in database for {imdb_id}")
|
||||
|
||||
# Update file mtimes if enabled (NFO is already correct)
|
||||
if config.fix_dir_mtimes and dateadded:
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
|
||||
_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [nfo-cached]")
|
||||
return "processed"
|
||||
|
||||
# TIER 2.5: Check for any existing valid date data in NFO (even without lockdata marker)
|
||||
# Only use NFO dates if prioritize_nfo is enabled, otherwise check external APIs first
|
||||
existing_nfo_data = self._extract_any_valid_dates_from_nfo(nfo_path)
|
||||
if existing_nfo_data and config.manual_scan_prioritize_nfo:
|
||||
_log("INFO", f"🔍 TIER 2.5 - Found existing date data in NFO (no lockdata): {existing_nfo_data['dateadded']} (source: {existing_nfo_data['source']})")
|
||||
_log("INFO", f"⚡ MANUAL_SCAN_PRIORITIZE_NFO=True - Using NFO date for speed")
|
||||
dateadded = existing_nfo_data["dateadded"]
|
||||
source = existing_nfo_data["source"]
|
||||
released = existing_nfo_data.get("released")
|
||||
|
||||
# Cache existing data in database and add proper NFOGuard formatting
|
||||
# Fixed parameter order: imdb_id, released, dateadded, source
|
||||
self.db.upsert_movie_dates(imdb_id, released, dateadded, source, True)
|
||||
_log("INFO", f"✅ Cached existing NFO data in database for {imdb_id}")
|
||||
|
||||
# Update NFO file to add NFOGuard formatting (lockdata, comment)
|
||||
if config.manage_nfo:
|
||||
self.nfo_manager.create_movie_nfo(
|
||||
movie_path, imdb_id, dateadded, released, source, config.lock_metadata
|
||||
)
|
||||
_log("INFO", f"✅ Added NFOGuard formatting to existing NFO for {imdb_id}")
|
||||
|
||||
# Update file mtimes if enabled
|
||||
if config.fix_dir_mtimes and dateadded:
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
|
||||
_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [existing-nfo-enhanced]")
|
||||
return "processed"
|
||||
elif existing_nfo_data:
|
||||
_log("INFO", f"🔍 TIER 2.5 - Found existing date data in NFO (no lockdata): {existing_nfo_data['dateadded']} (source: {existing_nfo_data['source']})")
|
||||
_log("INFO", f"🎯 MANUAL_SCAN_PRIORITIZE_NFO=False - Will verify against external APIs first")
|
||||
# Store NFO data as fallback but continue to TIER 3 to check external APIs
|
||||
nfo_fallback_data = existing_nfo_data
|
||||
|
||||
# TIER 1.5: Special handling for TMDB-only movies - extract dates from existing NFO
|
||||
if is_tmdb_fallback:
|
||||
tmdb_nfo_data = self._extract_dates_from_tmdb_nfo(nfo_path)
|
||||
if tmdb_nfo_data:
|
||||
_log("INFO", f"🎬 Using TMDB data from existing NFO file: {tmdb_nfo_data['dateadded']} (source: {tmdb_nfo_data['source']})")
|
||||
dateadded = tmdb_nfo_data["dateadded"]
|
||||
source = tmdb_nfo_data["source"]
|
||||
released = tmdb_nfo_data.get("released")
|
||||
|
||||
# Create NFO with NFOGuard fields added
|
||||
if config.manage_nfo:
|
||||
self.nfo_manager.create_movie_nfo(
|
||||
movie_path, imdb_id, dateadded, released, source, config.lock_metadata
|
||||
)
|
||||
|
||||
# Update file mtimes if enabled
|
||||
if config.fix_dir_mtimes and dateadded:
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
|
||||
# Save to database
|
||||
self.db.upsert_movie_dates(imdb_id, released, dateadded, source, True)
|
||||
|
||||
_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [tmdb-nfo]")
|
||||
return "processed"
|
||||
|
||||
# TIER 3: No cached data found - proceed with API lookups and verification
|
||||
# TIER 2: Query external APIs directly (NFO layer removed in Phase 2)
|
||||
_log("INFO", f"🔍 TIER 2 - No database cache, querying external APIs")
|
||||
|
||||
# Check for shutdown signal before expensive API operations
|
||||
if shutdown_event and shutdown_event.is_set():
|
||||
@@ -362,18 +272,8 @@ class MovieProcessor:
|
||||
final_source = f"{source}_as_dateadded" if source else "release_date_fallback"
|
||||
_log("INFO", f"Using release date as dateadded: {final_dateadded} (source: {final_source})")
|
||||
|
||||
# Create NFO regardless of date availability (preserves existing metadata)
|
||||
if config.debug:
|
||||
print(f"🔍 TIER3 - config.manage_nfo: {config.manage_nfo}")
|
||||
if config.manage_nfo:
|
||||
if config.debug:
|
||||
print(f"🔍 TIER3 - Calling create_movie_nfo with final_dateadded: {final_dateadded}")
|
||||
self.nfo_manager.create_movie_nfo(
|
||||
movie_path, imdb_id, final_dateadded, released, final_source, config.lock_metadata
|
||||
)
|
||||
else:
|
||||
if config.debug:
|
||||
print(f"❌ TIER3 - manage_nfo is disabled, skipping NFO creation")
|
||||
# NFO file operations removed - database is now the single source of truth
|
||||
# (Phase 1: Remove NFO file write operations)
|
||||
|
||||
# Skip remaining processing if no valid date found and file dates disabled
|
||||
if final_dateadded is None:
|
||||
@@ -387,9 +287,8 @@ class MovieProcessor:
|
||||
|
||||
_log("DEBUG", f"Movie {movie_path.name} proceeding to save: dateadded={dateadded}, source={source}")
|
||||
|
||||
# Update file mtimes (only if we have a valid date)
|
||||
if config.fix_dir_mtimes and dateadded and dateadded != "MANUAL_REVIEW_NEEDED":
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
# File mtime operations removed - database is now the single source of truth
|
||||
# (Phase 1: Remove NFO file write operations)
|
||||
|
||||
_log("DEBUG", f"Movie processing reached file mtime section: fix_dir_mtimes={config.fix_dir_mtimes}, dateadded={dateadded}")
|
||||
|
||||
@@ -407,76 +306,34 @@ class MovieProcessor:
|
||||
return "processed"
|
||||
|
||||
def _process_movie_nfo_first(self, movie_path: Path, imdb_id: str, shutdown_event=None) -> str:
|
||||
"""Process movie for incomplete mode: Check NFO files first for missing dateadded elements"""
|
||||
_log("INFO", f"🔍 NFO-FIRST MODE: Checking movie for missing dateadded in NFO file: {movie_path.name}")
|
||||
|
||||
"""Process movie for incomplete mode: Database-first then API (NFO checks removed in Phase 2)"""
|
||||
_log("INFO", f"🔍 INCOMPLETE MODE: Checking movie for missing data: {movie_path.name}")
|
||||
|
||||
# Check for shutdown signal
|
||||
if shutdown_event and shutdown_event.is_set():
|
||||
_log("INFO", f"⚠️ SHUTDOWN SIGNAL RECEIVED - Stopping movie NFO-first processing: {movie_path.name}")
|
||||
_log("INFO", f"⚠️ SHUTDOWN SIGNAL RECEIVED - Stopping movie processing: {movie_path.name}")
|
||||
return "shutdown"
|
||||
|
||||
nfo_path = movie_path / "movie.nfo"
|
||||
|
||||
# STEP 1: Check if NFO file exists and has dateadded
|
||||
_log("DEBUG", f"STEP 1 - Checking NFO file for missing dateadded: {nfo_path}")
|
||||
_log("INFO", f"🔍 NFO exists: {nfo_path.exists()}")
|
||||
|
||||
if nfo_path.exists():
|
||||
nfo_data = self.nfo_manager.extract_nfoguard_dates_from_nfo(nfo_path)
|
||||
_log("INFO", f"🔍 NFOGuard data extracted: {nfo_data}")
|
||||
|
||||
if nfo_data and nfo_data.get('dateadded'):
|
||||
# NFO has dateadded - this movie is complete
|
||||
_log("INFO", f"✅ NFO has dateadded={nfo_data['dateadded']}, movie marked as complete")
|
||||
dateadded = nfo_data["dateadded"]
|
||||
source = nfo_data["source"]
|
||||
released = nfo_data.get("released")
|
||||
|
||||
# Cache NFO data in database for future lookups
|
||||
self.db.upsert_movie_dates(imdb_id, released, dateadded, source, True)
|
||||
|
||||
# Update file mtimes if needed
|
||||
if config.fix_dir_mtimes and dateadded:
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
|
||||
_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [nfo-complete]")
|
||||
return "processed"
|
||||
else:
|
||||
# NFO exists but missing dateadded
|
||||
_log("INFO", f"🔍 NFO exists but missing dateadded - needs DB/API lookup")
|
||||
else:
|
||||
# No NFO file found
|
||||
_log("INFO", f"🔍 No NFO file found - needs DB/API lookup")
|
||||
|
||||
# STEP 2: For movies missing dateadded in NFO, check database
|
||||
_log("DEBUG", f"STEP 2 - Checking database for missing dateadded")
|
||||
|
||||
# STEP 1: Check database for existing data (Phase 2: NFO check removed)
|
||||
_log("DEBUG", f"STEP 1 - Checking database for existing data")
|
||||
existing = self.db.get_movie_dates(imdb_id)
|
||||
|
||||
|
||||
if existing and existing.get("dateadded") and existing.get("source") != "no_valid_date_source":
|
||||
# Found in database - use cached data and will add to NFO
|
||||
_log("INFO", f"✅ Database has dateadded={existing['dateadded']} - will add to NFO")
|
||||
# Found in database - data is complete
|
||||
_log("INFO", f"✅ Database has dateadded={existing['dateadded']}")
|
||||
dateadded, source, released = existing["dateadded"], existing["source"], existing.get("released")
|
||||
|
||||
# Convert datetime objects to strings for NFO manager
|
||||
|
||||
# Convert datetime objects to strings
|
||||
if hasattr(dateadded, 'isoformat'):
|
||||
dateadded = dateadded.isoformat()
|
||||
if released and hasattr(released, 'isoformat'):
|
||||
released = released.isoformat()
|
||||
|
||||
# Create NFO with database data
|
||||
if config.manage_nfo:
|
||||
self.nfo_manager.create_movie_nfo(
|
||||
movie_path, imdb_id, dateadded, released, source, config.lock_metadata
|
||||
)
|
||||
|
||||
if config.fix_dir_mtimes and dateadded:
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
|
||||
_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [database-to-nfo]")
|
||||
|
||||
_log("INFO", f"Completed processing movie: {movie_path.name} (source: {source}) [database-cached]")
|
||||
return "processed"
|
||||
|
||||
# STEP 3: For movies still missing dateadded, query APIs
|
||||
_log("DEBUG", f"STEP 3 - Querying APIs for missing dateadded")
|
||||
|
||||
# STEP 2: Database incomplete or missing, query APIs
|
||||
_log("DEBUG", f"STEP 2 - Querying APIs for missing data")
|
||||
|
||||
# Check for shutdown signal before API calls
|
||||
if shutdown_event and shutdown_event.is_set():
|
||||
@@ -487,19 +344,10 @@ class MovieProcessor:
|
||||
is_tmdb_fallback = imdb_id.startswith("tmdb-")
|
||||
|
||||
if is_tmdb_fallback:
|
||||
# TMDB fallback processing
|
||||
# TMDB fallback processing - use file modification time
|
||||
_log("INFO", f"🔍 TMDB fallback processing for {imdb_id}")
|
||||
|
||||
# Check for existing TMDB NFO date data
|
||||
tmdb_data = self._extract_dates_from_tmdb_nfo(nfo_path)
|
||||
if tmdb_data and tmdb_data.get('dateadded'):
|
||||
dateadded = tmdb_data['dateadded']
|
||||
released = tmdb_data.get('released')
|
||||
source = "tmdb_nfo"
|
||||
else:
|
||||
# Use file modification time as fallback for TMDB
|
||||
dateadded, source, released = self._get_file_mtime_date(movie_path)
|
||||
_log("INFO", f"Using file mtime as fallback for TMDB movie: {dateadded}")
|
||||
dateadded, source, released = self._get_file_mtime_date(movie_path)
|
||||
_log("INFO", f"Using file mtime for TMDB movie: {dateadded}")
|
||||
else:
|
||||
# Standard IMDb processing
|
||||
# Try to get digital release date from external APIs
|
||||
@@ -511,116 +359,22 @@ class MovieProcessor:
|
||||
released = digital_date # For movies, digital release is often the key date
|
||||
_log("INFO", f"Got digital release date from APIs: {dateadded} (source: {source})")
|
||||
else:
|
||||
# Check Radarr NFO for premiered date
|
||||
radarr_premiered = self._get_radarr_nfo_premiered_date(movie_path)
|
||||
if radarr_premiered:
|
||||
dateadded = radarr_premiered
|
||||
source = "radarr_nfo"
|
||||
released = radarr_premiered
|
||||
_log("INFO", f"Got premiered date from Radarr NFO: {dateadded}")
|
||||
else:
|
||||
# Last resort: file modification time
|
||||
dateadded, source, released = self._get_file_mtime_date(movie_path)
|
||||
_log("INFO", f"Using file mtime as last resort: {dateadded}")
|
||||
# Last resort: file modification time
|
||||
dateadded, source, released = self._get_file_mtime_date(movie_path)
|
||||
_log("INFO", f"Using file mtime as fallback: {dateadded}")
|
||||
|
||||
# Save to database and create NFO
|
||||
# Save to database only (NFO operations removed in Phase 1)
|
||||
if dateadded:
|
||||
self.db.upsert_movie_dates(imdb_id, released, dateadded, source, True)
|
||||
|
||||
if config.manage_nfo:
|
||||
self.nfo_manager.create_movie_nfo(
|
||||
movie_path, imdb_id, dateadded, released, source, config.lock_metadata
|
||||
)
|
||||
|
||||
if config.fix_dir_mtimes and dateadded:
|
||||
self.nfo_manager.update_movie_files_mtime(movie_path, dateadded)
|
||||
|
||||
_log("INFO", f"🔍 NFO-FIRST COMPLETE: {movie_path.name} (source: {source})")
|
||||
_log("INFO", f"🔍 INCOMPLETE MODE COMPLETE: {movie_path.name} (source: {source})")
|
||||
return "processed"
|
||||
else:
|
||||
_log("WARNING", f"Could not determine dateadded for movie: {movie_path.name}")
|
||||
return "error"
|
||||
|
||||
def _extract_dates_from_tmdb_nfo(self, nfo_path: Path) -> Optional[Dict[str, str]]:
|
||||
"""Extract date information from TMDB-based NFO file"""
|
||||
if not nfo_path.exists():
|
||||
return None
|
||||
|
||||
try:
|
||||
root = self.nfo_manager._parse_nfo_with_tolerance(nfo_path)
|
||||
|
||||
# Look for premiered date (from TMDB)
|
||||
premiered_elem = root.find('.//premiered')
|
||||
if premiered_elem is not None and premiered_elem.text:
|
||||
premiered_date = premiered_elem.text.strip()
|
||||
print(f"✅ Found TMDB premiered date: {premiered_date}")
|
||||
|
||||
return {
|
||||
"dateadded": premiered_date,
|
||||
"source": "tmdb:premiered_from_nfo",
|
||||
"released": premiered_date
|
||||
}
|
||||
|
||||
except (ET.ParseError, Exception) as e:
|
||||
print(f"⚠️ Error parsing TMDB NFO for dates: {e}")
|
||||
|
||||
return None
|
||||
|
||||
def _extract_any_valid_dates_from_nfo(self, nfo_path: Path) -> Optional[Dict[str, str]]:
|
||||
"""Extract any valid date information from NFO file, even without NFOGuard markers"""
|
||||
if not nfo_path.exists():
|
||||
return None
|
||||
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
tree = ET.parse(nfo_path)
|
||||
root = tree.getroot()
|
||||
|
||||
# Look for dateadded element (indicates previously processed by NFOGuard or similar)
|
||||
dateadded_elem = root.find('.//dateadded')
|
||||
premiered_elem = root.find('.//premiered')
|
||||
|
||||
if dateadded_elem is not None and dateadded_elem.text:
|
||||
dateadded = dateadded_elem.text.strip()
|
||||
|
||||
# Try to determine source from NFOGuard comment if present
|
||||
source = "existing_nfo_data"
|
||||
try:
|
||||
nfo_content = nfo_path.read_text(encoding='utf-8')
|
||||
import re
|
||||
# Look for NFOGuard comment pattern
|
||||
source_match = re.search(r'<!--.*?NFOGuard.*?Source:\s*([^-\s]+).*?-->', nfo_content, re.DOTALL | re.IGNORECASE)
|
||||
if source_match:
|
||||
source = source_match.group(1).strip()
|
||||
_log("DEBUG", f"Found source in NFOGuard comment: {source}")
|
||||
else:
|
||||
# Try to infer source from dateadded format/content
|
||||
if "tmdb" in nfo_content.lower() or (premiered_elem and premiered_elem.text):
|
||||
source = "tmdb:digital"
|
||||
elif "radarr" in nfo_content.lower():
|
||||
source = "radarr:db.history.import"
|
||||
else:
|
||||
source = "existing_nfo_data"
|
||||
_log("DEBUG", f"Inferred source from NFO content: {source}")
|
||||
except Exception as e:
|
||||
_log("DEBUG", f"Could not determine source from NFO content: {e}")
|
||||
|
||||
result = {
|
||||
"dateadded": dateadded,
|
||||
"source": source
|
||||
}
|
||||
|
||||
if premiered_elem is not None and premiered_elem.text:
|
||||
result["released"] = premiered_elem.text.strip()
|
||||
|
||||
_log("INFO", f"✅ Found existing date data in NFO: dateadded={dateadded}, source={source}")
|
||||
return result
|
||||
|
||||
except (ET.ParseError, Exception) as e:
|
||||
_log("DEBUG", f"Error parsing NFO for existing date data: {e}")
|
||||
|
||||
return None
|
||||
|
||||
# NFO helper methods removed in Phase 2 - database is the single source of truth
|
||||
|
||||
def _decide_movie_dates(self, imdb_id: str, movie_path: Path, should_query: bool, existing: Optional[Dict]) -> Tuple[str, str, Optional[str]]:
|
||||
"""Decide movie dates based on configuration and available data"""
|
||||
_log("DEBUG", f"_decide_movie_dates for {imdb_id}: should_query={should_query}, existing={existing}")
|
||||
@@ -687,14 +441,7 @@ class MovieProcessor:
|
||||
# When using digital release date, store it as both dateadded and released
|
||||
return digital_date, digital_source, digital_date
|
||||
else:
|
||||
_log("WARNING", f"⚠️ Movie {imdb_id}: No import date OR digital release date found - trying additional fallbacks")
|
||||
|
||||
# Try Radarr's own NFO premiered date as fallback
|
||||
radarr_premiered = self._get_radarr_nfo_premiered_date(movie_path)
|
||||
if radarr_premiered:
|
||||
_log("INFO", f"✅ Movie {imdb_id}: Using Radarr NFO premiered date {radarr_premiered}")
|
||||
# When using Radarr NFO premiered date, store it as both dateadded and released
|
||||
return radarr_premiered, "radarr:nfo.premiered", radarr_premiered
|
||||
_log("WARNING", f"⚠️ Movie {imdb_id}: No import date OR digital release date found")
|
||||
|
||||
else: # digital_then_import
|
||||
# Try digital release first
|
||||
@@ -753,32 +500,8 @@ class MovieProcessor:
|
||||
_log("ERROR", f"External clients error for {imdb_id}: {e}")
|
||||
return None, f"release:error:{str(e)}"
|
||||
|
||||
def _get_radarr_nfo_premiered_date(self, movie_path: Path) -> Optional[str]:
|
||||
"""Extract premiered date from Radarr's existing movie.nfo file"""
|
||||
try:
|
||||
nfo_path = movie_path / "movie.nfo"
|
||||
if not nfo_path.exists():
|
||||
_log("DEBUG", f"No existing NFO file found at {nfo_path}")
|
||||
return None
|
||||
|
||||
nfo_content = nfo_path.read_text(encoding='utf-8')
|
||||
|
||||
# Look for <premiered>YYYY-MM-DD</premiered>
|
||||
match = re.search(r'<premiered>(\d{4}-\d{2}-\d{2})</premiered>', nfo_content)
|
||||
if match:
|
||||
premiered_date = match.group(1)
|
||||
# Convert to ISO format with timezone
|
||||
iso_date = f"{premiered_date}T00:00:00+00:00"
|
||||
_log("INFO", f"✅ Found Radarr NFO premiered date: {premiered_date}")
|
||||
return iso_date
|
||||
else:
|
||||
_log("DEBUG", f"No <premiered> tag found in existing NFO")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
_log("ERROR", f"Error reading Radarr NFO file: {e}")
|
||||
return None
|
||||
|
||||
# _get_radarr_nfo_premiered_date() removed in Phase 2 - no longer reading NFO files
|
||||
|
||||
def _log_failed_movie(self, movie_path: Path, imdb_id: str, reason: str, available_countries: List[str] = None):
|
||||
"""Log movies that failed to get valid dates to a debug file"""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user