iupdate
This commit is contained in:
+74
-18
@@ -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"""
|
||||||
|
|||||||
Reference in New Issue
Block a user