From e2ffa705292b5dba22dca4a545990c3202d953d6 Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Tue, 1 Jul 2025 02:59:18 +0000 Subject: [PATCH] support episodedetails and musicvideo as top-level other video nfo tags (#2098) --- CHANGELOG.md | 2 + .../Metadata/Nfo/OtherVideoNfoReaderTests.cs | 39 +++++++++++++------ .../Core/Metadata/Nfo/OtherVideoNfoReader.cs | 8 +++- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f46cd2f25..2129d1b8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Allow `Other Video` libraries and `Image` libraries to use the same folders - Try to mitigate inotify limit error by disabling automatic reloading of `appsettings.json` config files +- Support `movie`, `musicvideo` and `episodedetails` top-level tags in other video NFO files + - Note that no change has been made to the metadata tags that are actually parsed, but this should help with various types of content ### Fixed - Fix QSV acceleration in docker with older Intel devices diff --git a/ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/OtherVideoNfoReaderTests.cs b/ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/OtherVideoNfoReaderTests.cs index 815b4bdc8..a1086b855 100644 --- a/ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/OtherVideoNfoReaderTests.cs +++ b/ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/OtherVideoNfoReaderTests.cs @@ -33,9 +33,12 @@ public class OtherVideoNfoReaderTests } [Test] - public async Task MetadataNfo_Should_Return_Nfo() + [TestCase("movie")] + [TestCase("episodedetails")] + [TestCase("musicvideo")] + public async Task MetadataNfo_Should_Return_Nfo(string topLevel) { - await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"")); + await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@$"<{topLevel}>")); Either result = await _otherVideoNfoReader.Read(stream); @@ -43,11 +46,14 @@ public class OtherVideoNfoReaderTests } [Test] - public async Task CombinationNfo_Should_Return_Nfo() + [TestCase("movie")] + [TestCase("episodedetails")] + [TestCase("musicvideo")] + public async Task CombinationNfo_Should_Return_Nfo(string topLevel) { await using var stream = new MemoryStream( Encoding.UTF8.GetBytes( - @" + @$"<{topLevel}> https://www.themoviedb.org/movie/11-star-wars")); Either result = await _otherVideoNfoReader.Read(stream); @@ -56,12 +62,15 @@ https://www.themoviedb.org/movie/11-star-wars")); } [Test] - public async Task FullSample_Should_Return_Nfo() + [TestCase("movie")] + [TestCase("episodedetails")] + [TestCase("musicvideo")] + public async Task FullSample_Should_Return_Nfo(string topLevel) { await using var stream = new MemoryStream( Encoding.UTF8.GetBytes( - @" - + @$" +<{topLevel}> Zack Snyder's Justice League Zack Snyder's Justice League Justice League 2 @@ -166,7 +175,7 @@ https://www.themoviedb.org/movie/11-star-wars")); 0.000000 2021-03-26 11:35:50 -")); +")); Either result = await _otherVideoNfoReader.Read(stream); @@ -223,9 +232,12 @@ https://www.themoviedb.org/movie/11-star-wars")); } [Test] - public async Task MetadataNfo_With_Tag_Should_Return_Nfo() + [TestCase("movie")] + [TestCase("episodedetails")] + [TestCase("musicvideo")] + public async Task MetadataNfo_With_Tag_Should_Return_Nfo(string topLevel) { - await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"Test Tag")); + await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@$"<{topLevel}>Test Tag")); Either result = await _otherVideoNfoReader.Read(stream); @@ -237,10 +249,13 @@ https://www.themoviedb.org/movie/11-star-wars")); } [Test] - public async Task MetadataNfo_With_Outline_Should_Return_Nfo() + [TestCase("movie")] + [TestCase("episodedetails")] + [TestCase("musicvideo")] + public async Task MetadataNfo_With_Outline_Should_Return_Nfo(string topLevel) { await using var stream = - new MemoryStream(Encoding.UTF8.GetBytes(@"Test Outline")); + new MemoryStream(Encoding.UTF8.GetBytes(@$"<{topLevel}>Test Outline")); Either result = await _otherVideoNfoReader.Read(stream); diff --git a/ErsatzTV.Scanner/Core/Metadata/Nfo/OtherVideoNfoReader.cs b/ErsatzTV.Scanner/Core/Metadata/Nfo/OtherVideoNfoReader.cs index 7c0adb2cc..9c24164f8 100644 --- a/ErsatzTV.Scanner/Core/Metadata/Nfo/OtherVideoNfoReader.cs +++ b/ErsatzTV.Scanner/Core/Metadata/Nfo/OtherVideoNfoReader.cs @@ -49,7 +49,13 @@ public class OtherVideoNfoReader : NfoReader, IOtherVideoNfoReade case XmlNodeType.Element: switch (reader.Name.ToLowerInvariant()) { + case "episodedetails": case "movie": + case "musicvideo": + if (nfo is not null) + { + throw new InvalidOperationException("Cannot have multiple opening tags"); + } nfo = new OtherVideoNfo(); break; case "title": @@ -107,7 +113,7 @@ public class OtherVideoNfoReader : NfoReader, IOtherVideoNfoReade break; case XmlNodeType.EndElement: - if (reader.Name == "movie") + if (reader.Name is "episodedetails" or "movie" or "musicvideo") { done = true; }