diff --git a/API.Tests/Services/ArchiveServiceTests.cs b/API.Tests/Services/ArchiveServiceTests.cs index 6182cac28..a05beaee6 100644 --- a/API.Tests/Services/ArchiveServiceTests.cs +++ b/API.Tests/Services/ArchiveServiceTests.cs @@ -63,7 +63,6 @@ namespace API.Tests.Services [InlineData("not supported 1.zip", 1)] [InlineData("not supported 2.cbz", 0)] [InlineData("not supported 3.cbz", 0)] - [InlineData("mangadex_131.zip", 577)] public void GetNumberOfPagesFromArchiveTest(string archivePath, int expected) { var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/Archives"); @@ -119,7 +118,6 @@ namespace API.Tests.Services [InlineData("not supported 1.zip", 1)] [InlineData("not supported 2.cbz", 169)] [InlineData("not supported 3.cbz", 1)] - [InlineData("mangadex_131.zip", 577)] public void CanExtractArchive(string archivePath, int expectedFileCount) { @@ -128,17 +126,10 @@ namespace API.Tests.Services DirectoryService.ClearAndDeleteDirectory(extractDirectory); Stopwatch sw = Stopwatch.StartNew(); - try - { - _archiveService.ExtractArchive(Path.Join(testDirectory, archivePath), extractDirectory); - var di1 = new DirectoryInfo(extractDirectory); - Assert.Equal(expectedFileCount, di1.GetFiles().Length); - _testOutputHelper.WriteLine($"Processed Original in {sw.ElapsedMilliseconds} ms"); - } - catch (Exception e) - { - _testOutputHelper.WriteLine("Could not process"); - } + _archiveService.ExtractArchive(Path.Join(testDirectory, archivePath), extractDirectory); + var di1 = new DirectoryInfo(extractDirectory); + Assert.Equal(expectedFileCount, di1.Exists ? di1.GetFiles().Length : 0); + _testOutputHelper.WriteLine($"Processed in {sw.ElapsedMilliseconds} ms"); DirectoryService.ClearAndDeleteDirectory(extractDirectory); } @@ -159,6 +150,15 @@ namespace API.Tests.Services _testOutputHelper.WriteLine($"Processed in {sw.ElapsedMilliseconds} ms"); } + [Theory] + [InlineData("not supported 2.cbz")] + [InlineData("06_v01[DMM].zip")] + public void CanParseCoverImage(string inputFile) + { + var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/Archives"); + Assert.NotEmpty(_archiveService.GetCoverImage(Path.Join(testDirectory, inputFile))); + } + [Fact] public void ShouldHaveComicInfo() { diff --git a/API.Tests/Services/Test Data/ArchiveService/Archives/06_v01[DMM].zip b/API.Tests/Services/Test Data/ArchiveService/Archives/06_v01[DMM].zip new file mode 100644 index 000000000..8fa84e0ac Binary files /dev/null and b/API.Tests/Services/Test Data/ArchiveService/Archives/06_v01[DMM].zip differ diff --git a/API.Tests/Services/Test Data/ArchiveService/Thumbnails/001.jpg b/API.Tests/Services/Test Data/ArchiveService/Thumbnails/001.jpg new file mode 100644 index 000000000..575b9e556 Binary files /dev/null and b/API.Tests/Services/Test Data/ArchiveService/Thumbnails/001.jpg differ diff --git a/API/Controllers/ServerController.cs b/API/Controllers/ServerController.cs index 36491de4a..2da9d0b2f 100644 --- a/API/Controllers/ServerController.cs +++ b/API/Controllers/ServerController.cs @@ -52,7 +52,7 @@ namespace API.Controllers var dateString = DateTime.Now.ToShortDateString().Replace("/", "_"); var tempLocation = Path.Join(tempDirectory, "logs_" + dateString); - _directoryService.ExistOrCreate(tempLocation); + DirectoryService.ExistOrCreate(tempLocation); if (!_directoryService.CopyFilesToDirectory(files, tempLocation)) { return BadRequest("Unable to copy files to temp directory for log download."); diff --git a/API/Interfaces/Services/IDirectoryService.cs b/API/Interfaces/Services/IDirectoryService.cs index 1437df69b..d2485e0da 100644 --- a/API/Interfaces/Services/IDirectoryService.cs +++ b/API/Interfaces/Services/IDirectoryService.cs @@ -20,12 +20,7 @@ namespace API.Interfaces.Services /// /// string[] GetFilesWithExtension(string path, string searchPatternExpression = ""); - /// - /// Returns true if the path exists and is a directory. If path does not exist, this will create it. Returns false in all fail cases. - /// - /// - /// - bool ExistOrCreate(string directoryPath); + //bool ExistOrCreate(string directoryPath); Task ReadFileAsync(string path); diff --git a/API/Parser/Parser.cs b/API/Parser/Parser.cs index 0a3466dbf..785de6f3b 100644 --- a/API/Parser/Parser.cs +++ b/API/Parser/Parser.cs @@ -9,7 +9,7 @@ namespace API.Parser public static class Parser { public static readonly string MangaFileExtensions = @"\.cbz|\.zip|\.rar|\.cbr|.tar.gz|.7zip"; - public static readonly string ImageFileExtensions = @"\.png|\.jpeg|\.jpg|\.gif"; + public static readonly string ImageFileExtensions = @"\.png|\.jpeg|\.jpg"; private static readonly string XmlRegexExtensions = @"\.xml"; private static readonly Regex ImageRegex = new Regex(ImageFileExtensions, RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex MangaFileRegex = new Regex(MangaFileExtensions, RegexOptions.IgnoreCase | RegexOptions.Compiled); diff --git a/API/Services/ArchiveService.cs b/API/Services/ArchiveService.cs index 1d27c3b42..d598ab248 100644 --- a/API/Services/ArchiveService.cs +++ b/API/Services/ArchiveService.cs @@ -87,39 +87,38 @@ namespace API.Services { if (!IsValidArchive(filepath)) return Array.Empty(); - if (SharpCompress.Archives.Zip.ZipArchive.IsZipFile(filepath)) - { - using var archive = SharpCompress.Archives.Zip.ZipArchive.Open(filepath); - return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory), createThumbnail); - } - - if (GZipArchive.IsGZipFile(filepath)) - { - using var archive = GZipArchive.Open(filepath); - return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory), createThumbnail); - } - - if (RarArchive.IsRarFile(filepath)) - { - using var archive = RarArchive.Open(filepath); - return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory), createThumbnail); - } - - if (SevenZipArchive.IsSevenZipFile(filepath)) - { - using var archive = SevenZipArchive.Open(filepath); - return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory), createThumbnail); - } - - if (TarArchive.IsTarFile(filepath)) - { - using var archive = TarArchive.Open(filepath); - return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory), createThumbnail); - } - - _logger.LogError("Could not parse archive file"); - return Array.Empty(); + // if (SharpCompress.Archives.Zip.ZipArchive.IsZipFile(filepath)) + // { + // using var archive = SharpCompress.Archives.Zip.ZipArchive.Open(filepath); + // return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), createThumbnail); + // } + // + // if (GZipArchive.IsGZipFile(filepath)) + // { + // using var archive = GZipArchive.Open(filepath); + // return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), createThumbnail); + // } + // + // if (RarArchive.IsRarFile(filepath)) + // { + // using var archive = RarArchive.Open(filepath); + // return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), createThumbnail); + // } + // + // if (SevenZipArchive.IsSevenZipFile(filepath)) + // { + // using var archive = SevenZipArchive.Open(filepath); + // return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), createThumbnail); + // } + // + // if (TarArchive.IsTarFile(filepath)) + // { + // using var archive = TarArchive.Open(filepath); + // return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), createThumbnail); + // } + using var archive = ArchiveFactory.Open(filepath); + return FindCoverImage(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), createThumbnail); } catch (Exception ex) { @@ -163,6 +162,7 @@ namespace API.Services { formatExtension = "." + formatExtension; } + // TODO: Validate if jpeg is same as jpg try { using var thumbnail = Image.ThumbnailBuffer(entry, ThumbnailWidth); @@ -230,27 +230,27 @@ namespace API.Services if (SharpCompress.Archives.Zip.ZipArchive.IsZipFile(archivePath)) { using var archive = SharpCompress.Archives.Zip.ZipArchive.Open(archivePath); - info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory)); + info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsXml(entry.Key))); } else if (GZipArchive.IsGZipFile(archivePath)) { using var archive = GZipArchive.Open(archivePath); - info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory)); + info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsXml(entry.Key))); } else if (RarArchive.IsRarFile(archivePath)) { using var archive = RarArchive.Open(archivePath); - info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory)); + info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsXml(entry.Key))); } else if (SevenZipArchive.IsSevenZipFile(archivePath)) { using var archive = SevenZipArchive.Open(archivePath); - info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory)); + info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsXml(entry.Key))); } else if (TarArchive.IsTarFile(archivePath)) { using var archive = TarArchive.Open(archivePath); - info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory)); + info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsXml(entry.Key))); } if (info != null) @@ -270,6 +270,7 @@ namespace API.Services private void ExtractArchiveEntities(IEnumerable entries, string extractPath) { + DirectoryService.ExistOrCreate(extractPath); foreach (var entry in entries) { entry.WriteToDirectory(extractPath, new ExtractionOptions() @@ -293,34 +294,38 @@ namespace API.Services if (!File.Exists(archivePath)) return; var sw = Stopwatch.StartNew(); - if (SharpCompress.Archives.Zip.ZipArchive.IsZipFile(archivePath)) - { - using var archive = SharpCompress.Archives.Zip.ZipArchive.Open(archivePath); - ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory), extractPath); - } - else if (GZipArchive.IsGZipFile(archivePath)) - { - using var archive = GZipArchive.Open(archivePath); - ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory), extractPath); - } else if (RarArchive.IsRarFile(archivePath)) - { - using var archive = RarArchive.Open(archivePath); - ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory), extractPath); - } else if (SevenZipArchive.IsSevenZipFile(archivePath)) - { - using var archive = SevenZipArchive.Open(archivePath); - ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory), extractPath); - } - else if (TarArchive.IsTarFile(archivePath)) - { - using var archive = TarArchive.Open(archivePath); - ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory), extractPath); - } - else - { - _logger.LogError("Could not parse archive file"); - return; - } + // if (SharpCompress.Archives.Zip.ZipArchive.IsZipFile(archivePath)) + // { + // + // //using var archive = SharpCompress.Archives.Zip.ZipArchive.Open(archivePath); + // using var archive = ArchiveFactory.Open(archivePath); + // ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), extractPath); + // } + // else if (GZipArchive.IsGZipFile(archivePath)) + // { + // using var archive = GZipArchive.Open(archivePath); + // ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), extractPath); + // } else if (RarArchive.IsRarFile(archivePath)) + // { + // using var archive = RarArchive.Open(archivePath); + // ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), extractPath); + // } else if (SevenZipArchive.IsSevenZipFile(archivePath)) + // { + // using var archive = SevenZipArchive.Open(archivePath); + // ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), extractPath); + // } + // else if (TarArchive.IsTarFile(archivePath)) + // { + // using var archive = TarArchive.Open(archivePath); + // ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), extractPath); + // } + // else + // { + // _logger.LogError("Could not parse archive file"); + // return; + // } + using var archive = ArchiveFactory.Open(archivePath); + ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory && Parser.Parser.IsImage(entry.Key)), extractPath); _logger.LogDebug("[Fallback] Extracted archive to {ExtractPath} in {ElapsedMilliseconds} milliseconds", extractPath, sw.ElapsedMilliseconds); } diff --git a/API/Services/CacheService.cs b/API/Services/CacheService.cs index 549139fe4..7be693a41 100644 --- a/API/Services/CacheService.cs +++ b/API/Services/CacheService.cs @@ -32,7 +32,7 @@ namespace API.Services public void EnsureCacheDirectory() { _logger.LogDebug("Checking if valid Cache directory: {CacheDirectory}", CacheDirectory); - if (!_directoryService.ExistOrCreate(CacheDirectory)) + if (!DirectoryService.ExistOrCreate(CacheDirectory)) { _logger.LogError("Cache directory {CacheDirectory} is not accessible or does not exist. Creating...", CacheDirectory); } diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index 6ae953802..638d487cc 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -71,7 +71,12 @@ namespace API.Services return !Directory.Exists(path) ? Array.Empty() : Directory.GetFiles(path); } - public bool ExistOrCreate(string directoryPath) + /// + /// Returns true if the path exists and is a directory. If path does not exist, this will create it. Returns false in all fail cases. + /// + /// + /// + public static bool ExistOrCreate(string directoryPath) { var di = new DirectoryInfo(directoryPath); if (di.Exists) return true; @@ -81,7 +86,6 @@ namespace API.Services } catch (Exception ex) { - _logger.LogError(ex, "There was an issue creating directory: {Directory}", directoryPath); return false; } return true; diff --git a/API/Services/Tasks/BackupService.cs b/API/Services/Tasks/BackupService.cs index ee8b3cf89..e24a8f89e 100644 --- a/API/Services/Tasks/BackupService.cs +++ b/API/Services/Tasks/BackupService.cs @@ -66,7 +66,7 @@ namespace API.Services.Tasks var backupDirectory = Task.Run(() => _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.BackupDirectory)).Result.Value; _logger.LogDebug("Backing up to {BackupDirectory}", backupDirectory); - if (!_directoryService.ExistOrCreate(backupDirectory)) + if (!DirectoryService.ExistOrCreate(backupDirectory)) { _logger.LogError("Could not write to {BackupDirectory}; aborting backup", backupDirectory); return; @@ -82,7 +82,7 @@ namespace API.Services.Tasks } var tempDirectory = Path.Join(_tempDirectory, dateString); - _directoryService.ExistOrCreate(tempDirectory); + DirectoryService.ExistOrCreate(tempDirectory); _directoryService.ClearDirectory(tempDirectory); _directoryService.CopyFilesToDirectory( diff --git a/API/Services/Tasks/ScannerService.cs b/API/Services/Tasks/ScannerService.cs index 61842eac8..af7b6eca8 100644 --- a/API/Services/Tasks/ScannerService.cs +++ b/API/Services/Tasks/ScannerService.cs @@ -33,7 +33,7 @@ namespace API.Services.Tasks _metadataService = metadataService; } - //[DisableConcurrentExecution(timeoutInSeconds: 5)] + [DisableConcurrentExecution(timeoutInSeconds: 5)] [AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Delete)] public void ScanLibraries() { @@ -64,7 +64,7 @@ namespace API.Services.Tasks _scannedSeries = null; } - //[DisableConcurrentExecution(5)] + [DisableConcurrentExecution(5)] [AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Delete)] public void ScanLibrary(int libraryId, bool forceUpdate) {