diff --git a/API.Tests/Services/ArchiveServiceTests.cs b/API.Tests/Services/ArchiveServiceTests.cs index 526abde3e..7de8bb2bf 100644 --- a/API.Tests/Services/ArchiveServiceTests.cs +++ b/API.Tests/Services/ArchiveServiceTests.cs @@ -257,6 +257,17 @@ namespace API.Tests.Services Assert.Equal("Junya Inoue", comicInfo.Writer); } + [Fact] + public void ShouldHaveComicInfo_TopLevelFileOnly() + { + var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/ComicInfos"); + var archive = Path.Join(testDirectory, "ComicInfo_duplicateInfos.zip"); + + var comicInfo = _archiveService.GetComicInfo(archive); + Assert.NotNull(comicInfo); + Assert.Equal("BTOOOM!", comicInfo.Series); + } + #endregion #region CanParseComicInfo diff --git a/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos.zip b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos.zip new file mode 100644 index 000000000..53182a168 Binary files /dev/null and b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos.zip differ diff --git a/API/Services/ArchiveService.cs b/API/Services/ArchiveService.cs index 11042ed34..cdf4df4db 100644 --- a/API/Services/ArchiveService.cs +++ b/API/Services/ArchiveService.cs @@ -322,27 +322,13 @@ namespace API.Services return false; } - - private static ComicInfo FindComicInfoXml(IEnumerable entries) + private static bool ValidComicInfoArchiveEntry(string fullName, string name) { - foreach (var entry in entries) - { - var filename = Path.GetFileNameWithoutExtension(entry.Key).ToLower(); - if (filename.EndsWith(ComicInfoFilename) - && !filename.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith) - && !Parser.Parser.HasBlacklistedFolderInPath(entry.Key) - && Parser.Parser.IsXml(entry.Key)) - { - using var ms = entry.OpenEntryStream(); - - var serializer = new XmlSerializer(typeof(ComicInfo)); - var info = (ComicInfo) serializer.Deserialize(ms); - return info; - } - } - - - return null; + var filenameWithoutExtension = Path.GetFileNameWithoutExtension(name).ToLower(); + return !Parser.Parser.HasBlacklistedFolderInPath(fullName) + && filenameWithoutExtension.Equals(ComicInfoFilename, StringComparison.InvariantCultureIgnoreCase) + && !filenameWithoutExtension.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith) + && Parser.Parser.IsXml(name); } /// @@ -364,12 +350,8 @@ namespace API.Services case ArchiveLibrary.Default: { using var archive = ZipFile.OpenRead(archivePath); - var entry = archive.Entries.FirstOrDefault(x => - !Parser.Parser.HasBlacklistedFolderInPath(x.FullName) - && Path.GetFileNameWithoutExtension(x.Name)?.ToLower() == ComicInfoFilename - && !Path.GetFileNameWithoutExtension(x.Name) - .StartsWith(Parser.Parser.MacOsMetadataFileStartsWith) - && Parser.Parser.IsXml(x.FullName)); + + var entry = archive.Entries.FirstOrDefault(x => ValidComicInfoArchiveEntry(x.FullName, x.Name)); if (entry != null) { using var stream = entry.Open(); @@ -384,20 +366,19 @@ namespace API.Services case ArchiveLibrary.SharpCompress: { using var archive = ArchiveFactory.Open(archivePath); - var info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory - && !Parser.Parser - .HasBlacklistedFolderInPath( - Path.GetDirectoryName( - entry.Key) ?? string.Empty) - && !Path - .GetFileNameWithoutExtension( - entry.Key).StartsWith(Parser - .Parser - .MacOsMetadataFileStartsWith) - && Parser.Parser.IsXml(entry.Key))); - ComicInfo.CleanComicInfo(info); + var entry = archive.Entries.FirstOrDefault(entry => + ValidComicInfoArchiveEntry(Path.GetDirectoryName(entry.Key), entry.Key)); - return info; + if (entry != null) + { + using var stream = entry.OpenEntryStream(); + var serializer = new XmlSerializer(typeof(ComicInfo)); + var info = (ComicInfo) serializer.Deserialize(stream); + ComicInfo.CleanComicInfo(info); + return info; + } + + break; } case ArchiveLibrary.NotSupported: _logger.LogWarning("[GetComicInfo] This archive cannot be read: {ArchivePath}", archivePath);