This commit is contained in:
2025-09-13 19:15:22 -04:00
parent e3038ee279
commit 1bf2725a5b
+74 -18
View File
@@ -619,39 +619,51 @@ class TVProcessor:
return episode_dates return episode_dates
def _get_single_episode_date(self, imdb_id: str, season_num: int, episode_num: int, series_metadata: Optional[Dict[str, Any]] = None) -> Tuple[Optional[str], Optional[str], str]: def _get_single_episode_date(self, imdb_id: str, season_num: int, episode_num: int, series_metadata: Optional[Dict[str, Any]] = None) -> Tuple[Optional[str], Optional[str], str]:
"""Get date info for a single episode""" """
# Try database first Get date info for a single episode during backfill scans.
Priority: 1) Database 2) Sonarr import history 3) Air dates
"""
# Step 1: Try database first
existing = self.db.get_episode_date(imdb_id, season_num, episode_num) existing = self.db.get_episode_date(imdb_id, season_num, episode_num)
if existing and existing.get("dateadded"): if existing and existing.get("dateadded"):
return existing.get("aired"), existing["dateadded"], existing.get("source", "database") _log("DEBUG", f"Using existing database entry for S{season_num:02d}E{episode_num:02d}")
return existing.get("aired"), existing["dateadded"], existing.get("source", "database:existing")
# Try Sonarr API if metadata available # Step 2: Try Sonarr import history (the real import date)
if series_metadata and "episodes" in series_metadata: aired = None
for episode in series_metadata["episodes"]: import_date = None
if episode.get("seasonNumber") == season_num and episode.get("episodeNumber") == episode_num:
aired = episode.get("airDateUtc")
if aired:
return aired, aired, "sonarr:episode.airDateUtc"
# Try Sonarr API history
if self.sonarr.enabled: if self.sonarr.enabled:
try: try:
# Get episode ID from Sonarr
series = self.sonarr.series_by_imdb(imdb_id) series = self.sonarr.series_by_imdb(imdb_id)
if series: if series:
episodes = self.sonarr.episodes_for_series(series["id"]) episodes = self.sonarr.episodes_for_series(series["id"])
for ep in episodes: for ep in episodes:
if ep.get("seasonNumber") == season_num and ep.get("episodeNumber") == episode_num: if ep.get("seasonNumber") == season_num and ep.get("episodeNumber") == episode_num:
aired = ep.get("airDateUtc")
import_date = self.sonarr.get_episode_import_history(ep["id"]) import_date = self.sonarr.get_episode_import_history(ep["id"])
if import_date: if import_date:
return ep.get("airDateUtc"), import_date, "sonarr:history.import" _log("INFO", f"Found Sonarr import history for S{season_num:02d}E{episode_num:02d}: {import_date}")
elif ep.get("airDateUtc"): return aired, import_date, "sonarr:history.import"
return ep.get("airDateUtc"), ep.get("airDateUtc"), "sonarr:episode.airDateUtc" break
except Exception as e: except Exception as e:
_log("DEBUG", f"Sonarr API error for episode S{season_num:02d}E{episode_num:02d}: {e}") _log("DEBUG", f"Sonarr API error for episode S{season_num:02d}E{episode_num:02d}: {e}")
# Fallback to current time # Step 3: Try Sonarr metadata for air date
if not aired and series_metadata and "episodes" in series_metadata:
for episode in series_metadata["episodes"]:
if episode.get("seasonNumber") == season_num and episode.get("episodeNumber") == episode_num:
aired = episode.get("airDateUtc")
break
# Step 4: Only if we have an air date but no import history, use air date as fallback
if aired:
_log("WARNING", f"No import history found for S{season_num:02d}E{episode_num:02d}, using air date as fallback")
return aired, aired, "sonarr:episode.airDateUtc"
# Step 5: Last resort - current time (shouldn't happen in normal operation)
current_time = datetime.now(timezone.utc).isoformat(timespec="seconds") current_time = datetime.now(timezone.utc).isoformat(timespec="seconds")
_log("WARNING", f"No data found for S{season_num:02d}E{episode_num:02d}, using current time")
return None, current_time, "fallback:current_time" return None, current_time, "fallback:current_time"
def process_webhook_episodes(self, series_path: Path, webhook_episodes: List[Dict[str, Any]]) -> None: def process_webhook_episodes(self, series_path: Path, webhook_episodes: List[Dict[str, Any]]) -> None:
@@ -701,8 +713,8 @@ class TVProcessor:
_log("WARNING", f"No video files found for S{season_num:02d}E{episode_num:02d}") _log("WARNING", f"No video files found for S{season_num:02d}E{episode_num:02d}")
continue continue
# Get episode date information # Get episode date information - webhook processing prioritizes existing DB entries
aired, dateadded, source = self._get_single_episode_date(imdb_id, season_num, episode_num, series_metadata) aired, dateadded, source = self._get_webhook_episode_date(imdb_id, season_num, episode_num, series_metadata)
enhanced_metadata = self._get_episode_metadata(series_metadata, season_num, episode_num) if series_metadata else None enhanced_metadata = self._get_episode_metadata(series_metadata, season_num, episode_num) if series_metadata else None
# Create NFO # Create NFO
@@ -739,6 +751,50 @@ class TVProcessor:
_log("INFO", f"Completed targeted processing: {episodes_processed}/{len(webhook_episodes)} episodes processed") _log("INFO", f"Completed targeted processing: {episodes_processed}/{len(webhook_episodes)} episodes processed")
def _get_webhook_episode_date(self, imdb_id: str, season_num: int, episode_num: int, series_metadata: Optional[Dict[str, Any]] = None) -> Tuple[Optional[str], Optional[str], str]:
"""
Get episode date for webhook processing with correct priority:
1. Check existing NFOGuard database entry (preserve previous import dates)
2. If not found, use current time (webhook = new download)
3. Get aired date from Sonarr/TMDB for reference
"""
# Step 1: Check if we already have this episode in our database
existing = self.db.get_episode_date(imdb_id, season_num, episode_num)
if existing and existing.get("dateadded"):
_log("INFO", f"Using existing database entry for S{season_num:02d}E{episode_num:02d}: {existing['dateadded']}")
return existing.get("aired"), existing["dateadded"], existing.get("source", "database:existing")
# Step 2: This is a new download (webhook triggered) - use current time
current_time = datetime.now(timezone.utc).isoformat(timespec="seconds")
_log("INFO", f"New episode download detected via webhook - using current time: {current_time}")
# Step 3: Try to get air date for reference
aired = None
# Try Sonarr metadata first
if series_metadata and "episodes" in series_metadata:
for episode in series_metadata["episodes"]:
if episode.get("seasonNumber") == season_num and episode.get("episodeNumber") == episode_num:
aired = episode.get("airDateUtc")
if aired:
break
# Fallback to Sonarr API if no metadata
if not aired and self.sonarr.enabled:
try:
series = self.sonarr.series_by_imdb(imdb_id)
if series:
episodes = self.sonarr.episodes_for_series(series["id"])
for ep in episodes:
if ep.get("seasonNumber") == season_num and ep.get("episodeNumber") == episode_num:
aired = ep.get("airDateUtc")
break
except Exception as e:
_log("DEBUG", f"Error getting air date from Sonarr: {e}")
# Return: aired date for reference, current time as import date
return aired, current_time, "webhook:new_download"
class MovieProcessor: class MovieProcessor:
"""Handles movie processing""" """Handles movie processing"""