fix: Preserve and convert NFO filenames to match video files
Local Docker Build (Dev) / build-dev (push) Successful in 23s
Local Docker Build (Dev) / build-dev (push) Successful in 23s
- Preserve existing long-named NFO files instead of migrating to short names - Convert existing short NFO names (S01E01.nfo) to match video filenames - Create new NFOs with long names based on matching video files - Only fallback to short names if no matching video file exists
This commit is contained in:
+71
-27
@@ -596,7 +596,7 @@ class NFOManager:
|
||||
file_episode = int(episode_elem.text)
|
||||
|
||||
if file_season == season_num and file_episode == episode_num:
|
||||
print(f"🔍 Found existing episode NFO: {nfo_file.name} -> will migrate to {standard_pattern}")
|
||||
print(f"🔍 Found existing episode NFO: {nfo_file.name} -> will preserve filename")
|
||||
return nfo_file
|
||||
except ValueError:
|
||||
continue
|
||||
@@ -607,23 +607,79 @@ class NFOManager:
|
||||
|
||||
return None
|
||||
|
||||
def find_video_file_for_episode(self, season_dir: Path, season_num: int, episode_num: int) -> Optional[Path]:
|
||||
"""Find video file that matches the given season and episode"""
|
||||
if not season_dir.exists():
|
||||
return None
|
||||
|
||||
season_episode_pattern = f"S{season_num:02d}E{episode_num:02d}"
|
||||
video_extensions = [".mkv", ".mp4", ".avi", ".mov", ".m4v"]
|
||||
|
||||
# Look for video files that contain the season/episode pattern
|
||||
for video_file in season_dir.iterdir():
|
||||
if (video_file.is_file() and
|
||||
video_file.suffix.lower() in video_extensions and
|
||||
season_episode_pattern in video_file.name):
|
||||
print(f"🎬 Found matching video file: {video_file.name}")
|
||||
return video_file
|
||||
|
||||
return None
|
||||
|
||||
def create_episode_nfo(self, season_dir: Path, season_num: int, episode_num: int,
|
||||
aired: Optional[str], dateadded: Optional[str], source: str,
|
||||
lock_metadata: bool = True, enhanced_metadata: Optional[Dict[str, Any]] = None) -> None:
|
||||
"""Create or update episode NFO file preserving existing content"""
|
||||
# Generate episode filename pattern
|
||||
episode_filename = f"S{season_num:02d}E{episode_num:02d}.nfo"
|
||||
nfo_path = season_dir / episode_filename
|
||||
"""Create or update episode NFO file preserving existing content and long filenames"""
|
||||
|
||||
# Track if we need to delete an old long-named NFO file
|
||||
old_nfo_to_delete = None
|
||||
|
||||
try:
|
||||
# First, check for existing long-named NFO files that need migration
|
||||
# First, check for existing long-named NFO files (PRESERVE these)
|
||||
existing_long_nfo = self.find_existing_episode_nfo(season_dir, season_num, episode_num)
|
||||
|
||||
# Prioritize long-named file for migration, otherwise use standard file
|
||||
source_nfo_path = existing_long_nfo if existing_long_nfo else nfo_path if nfo_path.exists() else None
|
||||
# Check if there's a short-named NFO that needs to be converted to long name
|
||||
short_episode_filename = f"S{season_num:02d}E{episode_num:02d}.nfo"
|
||||
short_nfo_path = season_dir / short_episode_filename
|
||||
|
||||
if existing_long_nfo:
|
||||
# PRESERVE the long filename - update it in place
|
||||
nfo_path = existing_long_nfo
|
||||
print(f"🎯 Updating existing NFO (preserving name): {existing_long_nfo.name}")
|
||||
elif short_nfo_path.exists():
|
||||
# Convert short name to long name by finding matching video file
|
||||
matching_video = self.find_video_file_for_episode(season_dir, season_num, episode_num)
|
||||
if matching_video:
|
||||
# Create long NFO name based on video filename
|
||||
video_name_without_ext = matching_video.stem
|
||||
long_nfo_name = f"{video_name_without_ext}.nfo"
|
||||
long_nfo_path = season_dir / long_nfo_name
|
||||
|
||||
print(f"📝 Converting short NFO to long name: {short_episode_filename} -> {long_nfo_name}")
|
||||
|
||||
# Move/rename the short NFO to the long name
|
||||
try:
|
||||
short_nfo_path.rename(long_nfo_path)
|
||||
nfo_path = long_nfo_path
|
||||
print(f"✅ Successfully renamed NFO to match video file")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not rename NFO file: {e}. Using short name.")
|
||||
nfo_path = short_nfo_path
|
||||
else:
|
||||
# No matching video found, use existing short name
|
||||
nfo_path = short_nfo_path
|
||||
print(f"⚠️ No matching video file found for {short_episode_filename}, keeping short name")
|
||||
else:
|
||||
# No existing NFO, create new one with long name if video exists
|
||||
matching_video = self.find_video_file_for_episode(season_dir, season_num, episode_num)
|
||||
if matching_video:
|
||||
video_name_without_ext = matching_video.stem
|
||||
long_nfo_name = f"{video_name_without_ext}.nfo"
|
||||
nfo_path = season_dir / long_nfo_name
|
||||
print(f"🆕 Creating new NFO with long name: {long_nfo_name}")
|
||||
else:
|
||||
# Fallback to short name if no video file found
|
||||
nfo_path = short_nfo_path
|
||||
print(f"🆕 Creating new NFO with short name: {short_episode_filename}")
|
||||
|
||||
try:
|
||||
# Load existing NFO file if it exists
|
||||
source_nfo_path = nfo_path if nfo_path.exists() else None
|
||||
|
||||
if source_nfo_path:
|
||||
try:
|
||||
@@ -634,12 +690,8 @@ class NFOManager:
|
||||
if episode.tag != "episodedetails":
|
||||
raise ValueError("Root element is not <episodedetails>")
|
||||
|
||||
# If we're migrating from a long-named file, mark it for deletion
|
||||
if existing_long_nfo and source_nfo_path == existing_long_nfo:
|
||||
old_nfo_to_delete = existing_long_nfo
|
||||
print(f"📦 Migrating episode NFO: {existing_long_nfo.name} -> {episode_filename}")
|
||||
|
||||
# Show what content fields are being preserved
|
||||
# Show what content fields are being preserved (for debugging)
|
||||
if self.debug:
|
||||
content_fields = ["title", "plot", "runtime", "premiered"]
|
||||
preserved_content = []
|
||||
for field in content_fields:
|
||||
@@ -647,7 +699,7 @@ class NFOManager:
|
||||
if elem is not None and elem.text:
|
||||
preserved_content.append(field)
|
||||
if preserved_content:
|
||||
print(f" 📄 Preserving content: {', '.join(preserved_content)}")
|
||||
print(f" 📄 Content preserved: {', '.join(preserved_content)}")
|
||||
|
||||
# Preserve existing content fields and store NFOGuard-managed fields for re-adding
|
||||
preserved_values = {}
|
||||
@@ -756,14 +808,6 @@ class NFOManager:
|
||||
print(f"✅ Successfully created/updated episode NFO: {nfo_path}")
|
||||
print(f" S{season_num:02d}E{episode_num:02d}, Aired: {aired}, Date Added: {dateadded}")
|
||||
|
||||
# Clean up old long-named NFO file if we migrated from it
|
||||
if old_nfo_to_delete and old_nfo_to_delete.exists():
|
||||
try:
|
||||
old_nfo_to_delete.unlink()
|
||||
print(f"🗑️ Cleaned up old NFO file: {old_nfo_to_delete.name}")
|
||||
except Exception as cleanup_error:
|
||||
print(f"⚠️ Warning: Could not delete old NFO file {old_nfo_to_delete.name}: {cleanup_error}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error creating/updating episode NFO {nfo_path}: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user