imdb updates
This commit is contained in:
+22
-3
@@ -1,6 +1,6 @@
|
||||
# NFOGuard Project Summary
|
||||
|
||||
## 📋 Current Status: v0.6.0 (In Development)
|
||||
## 📋 Current Status: v0.6.1 (Latest Improvements)
|
||||
|
||||
### 🎯 Project Goal
|
||||
Preserve movie and TV import dates in Emby/Jellyfin/Plex by preventing upgraded files from appearing as "recently added". NFOGuard listens to Radarr/Sonarr webhooks and manages `.nfo` files and file timestamps to maintain chronological consistency.
|
||||
@@ -112,6 +112,25 @@ Preserve movie and TV import dates in Emby/Jellyfin/Plex by preventing upgraded
|
||||
|
||||
---
|
||||
|
||||
### 🆕 v0.6.1 Recent Improvements (September 2025)
|
||||
|
||||
**🔧 Enhanced Radarr History Detection:**
|
||||
- **Smart Upgrade Detection**: Detects movies where first event is `movieFileRenamed` (upgrade scenarios)
|
||||
- **Improved Logic**: For movies like The Matrix (1999), prefer digital release dates over recent upgrade dates
|
||||
- **True Import Preservation**: Still honors actual import dates when they exist - only enhances edge cases
|
||||
|
||||
**🎯 Improved IMDb ID Extraction:**
|
||||
- **Flexible Regex**: Now supports both `[imdb-tt123]` and `[tt123]` formats
|
||||
- **NFO Fallback**: Scans `.nfo` files when path extraction fails (handles Radarr auto-generated files)
|
||||
- **Broader Compatibility**: Works with various folder naming conventions
|
||||
|
||||
**🧠 Enhanced Priority Logic:**
|
||||
- Movies with rename→upgrade history now get better chronological dates
|
||||
- True import dates always take precedence (no regression)
|
||||
- Smart fallbacks only engage when appropriate
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** September 9, 2025
|
||||
**Version:** v0.6.0-dev
|
||||
**Status:** Active Development
|
||||
**Version:** v0.6.1-dev
|
||||
**Status:** Enhanced Production Ready
|
||||
@@ -250,6 +250,47 @@ class RadarrDbClient:
|
||||
|
||||
return None, "radarr:db.no_date_found"
|
||||
|
||||
def is_first_event_rename_based(self, movie_id: int) -> bool:
|
||||
"""
|
||||
Check if the first event in history is rename-based (not a true import)
|
||||
|
||||
This helps identify movies where:
|
||||
- First event: movieFileRenamed (EventType = 7)
|
||||
- Followed by: downloadFolderImported (EventType = 3) - this is an upgrade
|
||||
|
||||
In such cases, we should prefer release dates over the upgrade date
|
||||
"""
|
||||
query = """
|
||||
SELECT h."EventType" as event_type
|
||||
FROM "History" h
|
||||
WHERE h."MovieId" = %s
|
||||
ORDER BY h."Date" ASC
|
||||
LIMIT 1
|
||||
"""
|
||||
|
||||
if self.db_type == "sqlite":
|
||||
query = query.replace("%s", "?")
|
||||
|
||||
try:
|
||||
with self._get_connection() as conn:
|
||||
if self.db_type == "postgresql":
|
||||
cursor = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
||||
else:
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute(query, (movie_id,))
|
||||
row = cursor.fetchone()
|
||||
|
||||
if row:
|
||||
event_type = row['event_type'] if self.db_type == "postgresql" else row[0]
|
||||
# EventType 7 = movieFileRenamed
|
||||
return event_type == 7
|
||||
|
||||
except Exception as e:
|
||||
_log("DEBUG", f"Error checking first event type for movie {movie_id}: {e}")
|
||||
|
||||
return False
|
||||
|
||||
def get_movie_file_date(self, movie_id: int) -> Optional[str]:
|
||||
"""
|
||||
Get earliest file dateAdded as fallback
|
||||
@@ -305,11 +346,16 @@ class RadarrDbClient:
|
||||
Returns:
|
||||
(date_iso, source_description)
|
||||
"""
|
||||
# Try history first
|
||||
# Try history first - always check for true import dates
|
||||
date_iso, source = self.get_earliest_import_date(movie_id)
|
||||
if date_iso:
|
||||
return date_iso, source
|
||||
|
||||
# If no true import found, check if first event is rename-based (upgrade scenario)
|
||||
if self.is_first_event_rename_based(movie_id):
|
||||
_log("INFO", f"Movie {movie_id} has rename-first history with no true import - signaling to prefer release dates")
|
||||
return None, "radarr:db.prefer_release_dates"
|
||||
|
||||
# Fallback to file date if requested
|
||||
if fallback_to_file_date:
|
||||
file_date = self.get_movie_file_date(movie_id)
|
||||
|
||||
+16
-4
@@ -18,8 +18,8 @@ def _log(level: str, msg: str):
|
||||
class NFOManager:
|
||||
"""Handles creation and updating of NFO files for movies and TV episodes"""
|
||||
|
||||
# Regex patterns
|
||||
IMDB_TAG_PATTERN = re.compile(r"\[imdb-(tt\d+)\]", re.IGNORECASE)
|
||||
# Regex patterns - supports both [imdb-tt123] and [tt123] formats
|
||||
IMDB_TAG_PATTERN = re.compile(r"\[(?:imdb-)?(tt\d+)\]", re.IGNORECASE)
|
||||
LONG_NFO_PATTERN = re.compile(r".*-S\d{2}E\d{2}-.*\.nfo$", re.IGNORECASE)
|
||||
SHORT_NFO_PATTERN = re.compile(r"^S(\d{2})E(\d{2})\.nfo$", re.IGNORECASE)
|
||||
|
||||
@@ -28,9 +28,21 @@ class NFOManager:
|
||||
|
||||
@staticmethod
|
||||
def parse_imdb_from_path(path: Path) -> Optional[str]:
|
||||
"""Extract IMDb ID from directory or filename"""
|
||||
"""Extract IMDb ID from directory or filename, with .nfo fallback"""
|
||||
# First try path name
|
||||
match = NFOManager.IMDB_TAG_PATTERN.search(path.name)
|
||||
return match.group(1).lower() if match else None
|
||||
if match:
|
||||
return match.group(1).lower()
|
||||
|
||||
# Fallback: scan .nfo files in directory
|
||||
if path.is_dir():
|
||||
for nfo_file in path.glob("*.nfo"):
|
||||
imdb_id = NFOManager.parse_imdb_from_nfo(nfo_file)
|
||||
if imdb_id:
|
||||
_log("DEBUG", f"Found IMDb ID {imdb_id} in {nfo_file.name}")
|
||||
return imdb_id
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def parse_imdb_from_nfo(nfo_path: Path) -> Optional[str]:
|
||||
|
||||
+5
-1
@@ -526,8 +526,12 @@ class MovieProcessor:
|
||||
if movie_id:
|
||||
import_date, import_source = self.radarr.get_movie_import_date(movie_id, fallback_to_file_date=config.allow_file_date_fallback)
|
||||
|
||||
# Check for special case: rename-first scenario (should prefer release dates)
|
||||
if import_source == "radarr:db.prefer_release_dates":
|
||||
_log("INFO", f"Movie {imdb_id} has rename-first history - skipping import, preferring release dates")
|
||||
# Fall through to release date logic below
|
||||
# Check if we got a real import date or just file date fallback
|
||||
if import_date and import_source != "radarr:db.file.dateAdded":
|
||||
elif import_date and import_source != "radarr:db.file.dateAdded":
|
||||
return import_date, import_source, released
|
||||
|
||||
# Get digital release date for comparison
|
||||
|
||||
Reference in New Issue
Block a user