fix: Add title extraction directly to create_episode_nfo method
Local Docker Build (Dev) / build-dev (push) Successful in 19s
Local Docker Build (Dev) / build-dev (push) Successful in 19s
- Add _extract_title_from_filename method to NFOManager class - Integrate title extraction fallback in create_episode_nfo method - Extract titles when NFO lacks title element or has empty title - Support both .mkv and .mp4 files with comprehensive logging - Fix applied to actual NFO creation method being used by episodes Resolves title extraction by working in the correct code path rather than relying on metadata processing that wasn't being called.
This commit is contained in:
@@ -248,6 +248,59 @@ class NFOManager:
|
|||||||
print(f"⚠️ Error enhancing NFO with title: {e}")
|
print(f"⚠️ Error enhancing NFO with title: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _extract_title_from_filename(self, season_dir: Path, season_num: int, episode_num: int) -> Optional[str]:
|
||||||
|
"""Extract episode title from video filename as fallback when metadata doesn't provide it"""
|
||||||
|
try:
|
||||||
|
import re
|
||||||
|
# Look for video files matching this episode
|
||||||
|
season_pattern = f"S{season_num:02d}E{episode_num:02d}"
|
||||||
|
print(f"🔍 Searching for title in files for {season_pattern} in directory: {season_dir}")
|
||||||
|
|
||||||
|
for video_file in season_dir.glob("*.mkv"):
|
||||||
|
filename = video_file.name
|
||||||
|
print(f"🔍 Checking file: {filename}")
|
||||||
|
if season_pattern in filename:
|
||||||
|
print(f"✅ Found matching file: {filename}")
|
||||||
|
# Pattern: SeriesName-S01E01-Episode Title[WEBDL-1080p][AAC2.0][h264].mkv
|
||||||
|
# Extract the part between season/episode and the first bracket
|
||||||
|
pattern = rf'{season_pattern}-(.*?)\['
|
||||||
|
print(f"🔍 Using regex pattern: {pattern}")
|
||||||
|
match = re.search(pattern, filename)
|
||||||
|
if match:
|
||||||
|
title = match.group(1).strip()
|
||||||
|
print(f"🔍 Raw extracted title: '{title}'")
|
||||||
|
# Clean up common encoding artifacts and separators
|
||||||
|
title = title.replace('-', ' ').strip()
|
||||||
|
if title:
|
||||||
|
print(f"✅ Extracted title from filename: '{title}' for {season_pattern}")
|
||||||
|
return title
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Title was empty after cleanup")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Regex pattern didn't match filename")
|
||||||
|
|
||||||
|
# Also check .mp4 files
|
||||||
|
for video_file in season_dir.glob("*.mp4"):
|
||||||
|
filename = video_file.name
|
||||||
|
print(f"🔍 Checking .mp4 file: {filename}")
|
||||||
|
if season_pattern in filename:
|
||||||
|
print(f"✅ Found matching .mp4 file: {filename}")
|
||||||
|
pattern = rf'{season_pattern}-(.*?)\['
|
||||||
|
match = re.search(pattern, filename)
|
||||||
|
if match:
|
||||||
|
title = match.group(1).strip()
|
||||||
|
print(f"🔍 Raw extracted title from .mp4: '{title}'")
|
||||||
|
title = title.replace('-', ' ').strip()
|
||||||
|
if title:
|
||||||
|
print(f"✅ Extracted title from .mp4 filename: '{title}' for {season_pattern}")
|
||||||
|
return title
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Error extracting title from filename for S{season_num:02d}E{episode_num:02d}: {e}")
|
||||||
|
|
||||||
|
print(f"⚠️ No title found in filenames for {season_pattern}")
|
||||||
|
return None
|
||||||
|
|
||||||
def _parse_nfo_with_tolerance(self, nfo_path: Path):
|
def _parse_nfo_with_tolerance(self, nfo_path: Path):
|
||||||
"""Parse NFO file with tolerance for URLs appended after XML"""
|
"""Parse NFO file with tolerance for URLs appended after XML"""
|
||||||
try:
|
try:
|
||||||
@@ -643,6 +696,23 @@ class NFOManager:
|
|||||||
runtime_elem = ET.SubElement(episode, "runtime")
|
runtime_elem = ET.SubElement(episode, "runtime")
|
||||||
runtime_elem.text = str(enhanced_metadata["runtime"])
|
runtime_elem.text = str(enhanced_metadata["runtime"])
|
||||||
|
|
||||||
|
# Fallback: Extract title from filename if no title present
|
||||||
|
if not episode.find("title") or not episode.find("title").text:
|
||||||
|
print(f"🔍 No title found in NFO for S{season_num:02d}E{episode_num:02d}, attempting filename extraction")
|
||||||
|
filename_title = self._extract_title_from_filename(season_dir, season_num, episode_num)
|
||||||
|
if filename_title:
|
||||||
|
# Remove existing empty title element if present
|
||||||
|
existing_title = episode.find("title")
|
||||||
|
if existing_title is not None:
|
||||||
|
episode.remove(existing_title)
|
||||||
|
|
||||||
|
# Add new title element
|
||||||
|
title_elem = ET.SubElement(episode, "title")
|
||||||
|
title_elem.text = filename_title
|
||||||
|
print(f"✅ Added filename-extracted title to NFO: S{season_num:02d}E{episode_num:02d} - '{filename_title}'")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Could not extract title from filename for S{season_num:02d}E{episode_num:02d}")
|
||||||
|
|
||||||
# Add NFOGuard fields at the bottom
|
# Add NFOGuard fields at the bottom
|
||||||
|
|
||||||
# Basic episode info at the end
|
# Basic episode info at the end
|
||||||
|
|||||||
Reference in New Issue
Block a user