fix: Ensure NFOGuard metadata appears at bottom of movie NFO files
Local Docker Build (Dev) / build-dev (push) Successful in 4s
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:
+57
-28
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user