fix: Ensure NFOGuard metadata appears at bottom of movie NFO files
Local Docker Build (Dev) / build-dev (push) Successful in 4s

- Improve element removal logic to only remove clearly NFOGuard-managed elements
- Use batch element addition to ensure NFOGuard metadata appears as contiguous block at bottom
- Better preserve existing non-NFOGuard metadata fields
- Fix issue where lockdata/dateadded appeared scattered throughout NFO instead of grouped at bottom

🤖 Generated with [Claude Code](https://claude.ai/code)
This commit is contained in:
2025-10-12 12:56:10 -04:00
parent a559873999
commit c8fde41dfb
+57 -28
View File
@@ -265,24 +265,45 @@ class NFOManager:
if movie.tag != "movie": if movie.tag != "movie":
raise ValueError("Root element is not <movie>") raise ValueError("Root element is not <movie>")
# Remove existing NFOGuard-managed elements to avoid duplicates # Only remove elements that are clearly NFOGuard-managed
# These will be re-added at the very bottom # Look for elements that have NFOGuard characteristics
nfoguard_fields = ["dateadded", "lockdata", "premiered", "year"] elements_to_remove = []
for tag in nfoguard_fields:
existing = movie.find(tag)
if existing is not None:
# Store the value before removing (for premiered/year)
if tag == "premiered" and not released:
print(f"🔍 Preserving existing premiered date: {existing.text} (released was None)")
released = existing.text # Preserve existing premiered date
elif tag == "premiered":
print(f"🔍 NOT preserving premiered date: existing={existing.text}, released={released}")
movie.remove(existing)
# Remove ALL existing uniqueid with type="imdb" regardless of attributes # Remove lockdata=true (this is definitely NFOGuard)
# We'll add a clean one at the bottom for lockdata in movie.findall("lockdata"):
if lockdata.text == "true":
elements_to_remove.append(lockdata)
# Remove IMDb uniqueids that we manage
for uniqueid in movie.findall("uniqueid[@type='imdb']"): for uniqueid in movie.findall("uniqueid[@type='imdb']"):
movie.remove(uniqueid) elements_to_remove.append(uniqueid)
# For dateadded/premiered/year, only remove if they appear to be NFOGuard-managed
# (i.e., if lockdata=true exists, these are likely ours)
has_nfoguard_lockdata = any(ld.text == "true" for ld in movie.findall("lockdata"))
if has_nfoguard_lockdata:
# This NFO was managed by NFOGuard, safe to remove our fields
for tag in ["dateadded", "premiered", "year"]:
existing = movie.find(tag)
if existing is not None:
# Store the value before removing (for premiered/year)
if tag == "premiered" and not released:
print(f"🔍 Preserving existing premiered date: {existing.text}")
released = existing.text
elements_to_remove.append(existing)
else:
# No NFOGuard lockdata found, be more conservative
# Only remove dateadded if it looks like NFOGuard format (ISO timestamp)
dateadded_elem = movie.find("dateadded")
if dateadded_elem is not None and dateadded_elem.text:
# NFOGuard uses ISO format like "2025-10-12 16:26:02"
if re.match(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}', dateadded_elem.text.strip()):
elements_to_remove.append(dateadded_elem)
# Remove all identified elements
for elem in elements_to_remove:
movie.remove(elem)
except (ET.ParseError, ValueError) as e: except (ET.ParseError, ValueError) as e:
print(f"⚠️ Corrupted NFO detected: {nfo_path} - {str(e)[:100]}...") print(f"⚠️ Corrupted NFO detected: {nfo_path} - {str(e)[:100]}...")
@@ -292,23 +313,24 @@ class NFOManager:
# Create new NFO structure # Create new NFO structure
movie = ET.Element("movie") movie = ET.Element("movie")
# Now append ALL NFOGuard fields at the VERY END of the file # Create all NFOGuard elements first, then append them in correct order
# Create elements and explicitly append them to ensure they're at the bottom # This ensures they appear as a group at the bottom of the file
nfoguard_elements = []
# Add NFOGuard comment marker as the first of our additions # Add NFOGuard comment marker as the first of our additions
nfoguard_comment = ET.Comment(f" NFOGuard - Source: {source} ") nfoguard_comment = ET.Comment(f" NFOGuard - Source: {source} ")
movie.append(nfoguard_comment) nfoguard_elements.append(nfoguard_comment)
# Add IMDb uniqueid at the end (after all existing content) # Add IMDb uniqueid
uniqueid = ET.Element("uniqueid", type="imdb", default="true") uniqueid = ET.Element("uniqueid", type="imdb", default="true")
uniqueid.text = imdb_id uniqueid.text = imdb_id
movie.append(uniqueid) nfoguard_elements.append(uniqueid)
# Add premiered date at the bottom if we have it # Add premiered date if we have it
if released: if released:
premiered_elem = ET.Element("premiered") premiered_elem = ET.Element("premiered")
premiered_elem.text = released[:10] if len(released) >= 10 else released premiered_elem.text = released[:10] if len(released) >= 10 else released
movie.append(premiered_elem) nfoguard_elements.append(premiered_elem)
# Extract year from premiered date for consistency # Extract year from premiered date for consistency
try: try:
@@ -316,17 +338,17 @@ class NFOManager:
if year_value and year_value.isdigit(): if year_value and year_value.isdigit():
year_elem = ET.Element("year") year_elem = ET.Element("year")
year_elem.text = year_value year_elem.text = year_value
movie.append(year_elem) nfoguard_elements.append(year_elem)
except: except:
pass # Skip year if we can't extract it pass # Skip year if we can't extract it
# Add dateadded at the end - THIS IS CRITICAL FOR EMBY PLUGIN # Add dateadded - THIS IS CRITICAL FOR EMBY PLUGIN
print(f"🔍 About to add dateadded: {dateadded} (type: {type(dateadded)})") print(f"🔍 About to add dateadded: {dateadded} (type: {type(dateadded)})")
if dateadded: if dateadded:
dateadded_elem = ET.Element("dateadded") dateadded_elem = ET.Element("dateadded")
dateadded_elem.text = dateadded dateadded_elem.text = dateadded
movie.append(dateadded_elem) nfoguard_elements.append(dateadded_elem)
print(f"✅ Added dateadded to NFO: {dateadded}") print(f"✅ Adding dateadded to NFO: {dateadded}")
else: else:
print(f"❌ dateadded is empty/None, not adding to NFO") print(f"❌ dateadded is empty/None, not adding to NFO")
@@ -334,7 +356,14 @@ class NFOManager:
if lock_metadata: if lock_metadata:
lockdata = ET.Element("lockdata") lockdata = ET.Element("lockdata")
lockdata.text = "true" lockdata.text = "true"
movie.append(lockdata) nfoguard_elements.append(lockdata)
# Now append all NFOGuard elements to the movie in one batch
# This ensures they appear as a contiguous block at the bottom
for elem in nfoguard_elements:
movie.append(elem)
print(f"✅ Added {len(nfoguard_elements)} NFOGuard elements to bottom of NFO")
# Write file with proper formatting # Write file with proper formatting
tree = ET.ElementTree(movie) tree = ET.ElementTree(movie)