Fallback to other locations when ComicInfo.xml not at root of archive (#1551)

* Fallback to other locations when ComicInfo.xml not at root of archive

* Better ComicInfo test coverage and benchmarks

* Add a rar archive to the ComicInfo test cases
This commit is contained in:
tjarls 2022-09-22 22:44:01 +01:00 committed by GitHub
parent aafbce377b
commit bc1e314326
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 85 additions and 17 deletions

View File

@ -20,5 +20,11 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="../API.Tests/Services/Test Data/ArchiveService/ComicInfos/*.zip">
<LinkBase>Data</LinkBase>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -1,7 +0,0 @@
namespace API.Benchmark;
public class ArchiveSerivceBenchmark
{
// Benchmark to test default GetNumberOfPages from archive
// vs a new method where I try to open the archive and return said stream
}

View File

@ -0,0 +1,54 @@
using System;
using System.IO.Abstractions;
using Microsoft.Extensions.Logging.Abstractions;
using API.Services;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
namespace API.Benchmark;
[StopOnFirstError]
[MemoryDiagnoser]
[RankColumn]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[SimpleJob(launchCount: 1, warmupCount: 5, targetCount: 20)]
public class ArchiveServiceBenchmark
{
private readonly ArchiveService _archiveService;
private readonly IDirectoryService _directoryService;
private readonly IImageService _imageService;
public ArchiveServiceBenchmark()
{
_directoryService = new DirectoryService(null, new FileSystem());
_imageService = new ImageService(null, _directoryService);
_archiveService = new ArchiveService(new NullLogger<ArchiveService>(), _directoryService, _imageService);
}
[Benchmark(Baseline = true)]
public void TestGetComicInfo_baseline()
{
if (_archiveService.GetComicInfo("Data/ComicInfo.zip") == null) {
throw new Exception("ComicInfo not found");
}
}
[Benchmark]
public void TestGetComicInfo_duplicate()
{
if (_archiveService.GetComicInfo("Data/ComicInfo_duplicateInfos.zip") == null) {
throw new Exception("ComicInfo not found");
}
}
[Benchmark]
public void TestGetComicInfo_outside_root()
{
if (_archiveService.GetComicInfo("Data/ComicInfo_outside_root.zip") == null) {
throw new Exception("ComicInfo not found");
}
}
// Benchmark to test default GetNumberOfPages from archive
// vs a new method where I try to open the archive and return said stream
}

View File

@ -256,17 +256,31 @@ public class ArchiveServiceTests
Assert.Equal("Junya Inoue", comicInfo.Writer);
}
[Fact]
public void ShouldHaveComicInfo_TopLevelFileOnly()
[Theory]
[InlineData("ComicInfo_duplicateInfos.zip")]
[InlineData("ComicInfo_duplicateInfos_reversed.zip")]
[InlineData("ComicInfo_duplicateInfos.rar")]
public void ShouldHaveComicInfo_TopLevelFileOnly(string filename)
{
var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/ComicInfos");
var archive = Path.Join(testDirectory, "ComicInfo_duplicateInfos.zip");
var archive = Path.Join(testDirectory, filename);
var comicInfo = _archiveService.GetComicInfo(archive);
Assert.NotNull(comicInfo);
Assert.Equal("BTOOOM!", comicInfo.Series);
}
[Fact]
public void ShouldHaveComicInfo_OutsideRoot()
{
var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/ComicInfos");
var archive = Path.Join(testDirectory, "ComicInfo_outside_root.zip");
var comicInfo = _archiveService.GetComicInfo(archive);
Assert.NotNull(comicInfo);
Assert.Equal("BTOOOM! - Duplicate", comicInfo.Series);
}
#endregion
#region CanParseComicInfo

View File

@ -328,12 +328,11 @@ public class ArchiveService : IArchiveService
return false;
}
private static bool ValidComicInfoArchiveEntry(string fullName, string name)
private static bool IsComicInfoArchiveEntry(string fullName, string name)
{
var filenameWithoutExtension = Path.GetFileNameWithoutExtension(name).ToLower();
return !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(fullName)
&& (fullName.Equals(ComicInfoFilename) || (string.IsNullOrEmpty(fullName) && name.Equals(ComicInfoFilename)))
&& !filenameWithoutExtension.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith);
&& name.Equals(ComicInfoFilename, StringComparison.OrdinalIgnoreCase)
&& !name.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith);
}
/// <summary>
@ -356,7 +355,8 @@ public class ArchiveService : IArchiveService
{
using var archive = ZipFile.OpenRead(archivePath);
var entry = archive.Entries.FirstOrDefault(x => ValidComicInfoArchiveEntry(x.FullName, x.Name));
var entry = archive.Entries.FirstOrDefault(x => (x.FullName ?? x.Name) == ComicInfoFilename) ??
archive.Entries.FirstOrDefault(x => IsComicInfoArchiveEntry(x.FullName, x.Name));
if (entry != null)
{
using var stream = entry.Open();
@ -371,8 +371,9 @@ public class ArchiveService : IArchiveService
case ArchiveLibrary.SharpCompress:
{
using var archive = ArchiveFactory.Open(archivePath);
var entry = archive.Entries.FirstOrDefault(entry =>
ValidComicInfoArchiveEntry(Path.GetDirectoryName(entry.Key), entry.Key));
var entry = archive.Entries.FirstOrDefault(entry => entry.Key == ComicInfoFilename) ??
archive.Entries.FirstOrDefault(entry =>
IsComicInfoArchiveEntry(Path.GetDirectoryName(entry.Key), entry.Key));
if (entry != null)
{