diff --git a/API.Tests/ParserTest.cs b/API.Tests/ParserTest.cs index 6cf1a64d1..55257853c 100644 --- a/API.Tests/ParserTest.cs +++ b/API.Tests/ParserTest.cs @@ -74,6 +74,7 @@ namespace API.Tests [InlineData("Ichinensei_ni_Nacchattara_v01_ch01_[Taruby]_v1.1.zip", "Ichinensei ni Nacchattara")] [InlineData("Chrno_Crusade_Dragon_Age_All_Stars[AS].zip", "")] [InlineData("Ichiban_Ushiro_no_Daimaou_v04_ch34_[VISCANS].zip", "Ichiban Ushiro no Daimaou")] + [InlineData("Rent a Girlfriend v01.cbr", "Rent a Girlfriend")] //[InlineData("[Tempus Edax Rerum] Epigraph of the Closed Curve - Chapter 6.zip", "Epigraph of the Closed Curve")] public void ParseSeriesTest(string filename, string expected) { diff --git a/API/Extensions/DirectoryInfoExtensions.cs b/API/Extensions/DirectoryInfoExtensions.cs index 60997b2ca..98480d6bc 100644 --- a/API/Extensions/DirectoryInfoExtensions.cs +++ b/API/Extensions/DirectoryInfoExtensions.cs @@ -52,7 +52,6 @@ namespace API.Extensions var newName = $"{file.Directory.Name}_{file.Name}"; var newPath = Path.Join(root.FullName, newName); file.MoveTo(newPath); - } } diff --git a/API/Services/CacheService.cs b/API/Services/CacheService.cs index 85774e128..8b8696bf9 100644 --- a/API/Services/CacheService.cs +++ b/API/Services/CacheService.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; @@ -41,10 +42,10 @@ namespace API.Services return null; } Volume volume = await _unitOfWork.SeriesRepository.GetVolumeAsync(volumeId); + foreach (var file in volume.Files) { var extractPath = GetVolumeCachePath(volumeId, file); - ExtractArchive(file.FilePath, extractPath); } @@ -91,6 +92,74 @@ namespace API.Services _logger.LogInformation("Cache directory purged"); } + + // private void ExtractArchive(string archivePath, string extractPath, int expectedPages) + // { + // if (!File.Exists(archivePath) || !Parser.Parser.IsArchive(archivePath)) + // { + // _logger.LogError($"Archive {archivePath} could not be found."); + // } + // + // var extractDirectoryInfo = new DirectoryInfo(extractPath); + // + // // If the extraction and flattening aren't perfect, adding extra cases adds a serious amount of extra time. + // if (Directory.Exists(extractPath)) // && extractDirectoryInfo.EnumerateFiles().Count() >= expectedPages + // { + // _logger.LogDebug($"Archive {archivePath} has already been extracted. Returning existing folder."); + // return; + // } + // + // Stopwatch sw = Stopwatch.StartNew(); + // var needsFlattening = false; + // var options = new ExtractionOptions + // { + // ExtractFullPath = true, + // Overwrite = true + // }; + // + // using Stream stream = File.OpenRead(archivePath); + // using var reader = ReaderFactory.Open(stream); + // while (reader.MoveToNextEntry()) + // { + // if (!reader.Entry.IsDirectory) + // { + // try + // { + // reader.WriteEntryToDirectory(extractPath, options); + // } + // catch (Exception e) + // { + // _logger.LogError(e, "There was an issue with extracting image."); + // } + // } + // + // if (!needsFlattening) + // { + // needsFlattening = reader.Entry.IsDirectory; + // } + // } + // + // + // _logger.LogDebug($"Extracted archive to {extractPath} in {sw.ElapsedMilliseconds} milliseconds."); + // + // + // if (needsFlattening) + // { + // sw = Stopwatch.StartNew(); + // _logger.LogInformation("Extracted archive is nested in root folder, flattening..."); + // try + // { + // extractDirectoryInfo.Flatten(); + // } + // catch (Exception ex) + // { + // _logger.LogError(ex, "There was an issue extracting archive."); + // return; + // } + // _logger.LogInformation($"Flattened in {sw.ElapsedMilliseconds} milliseconds"); + // } + // } + /// /// Extracts an archive to a temp cache directory. Returns path to new directory. If temp cache directory already exists, /// will return that without performing an extraction. Returns empty string if there are any invalidations which would @@ -99,35 +168,34 @@ namespace API.Services /// A valid file to an archive file. /// Path to extract to /// - private string ExtractArchive(string archivePath, string extractPath) + private void ExtractArchive(string archivePath, string extractPath) { - // NOTE: This is used by Cache Service if (!File.Exists(archivePath) || !Parser.Parser.IsArchive(archivePath)) { _logger.LogError($"Archive {archivePath} could not be found."); - return ""; } if (Directory.Exists(extractPath)) { _logger.LogDebug($"Archive {archivePath} has already been extracted. Returning existing folder."); - return extractPath; } + Stopwatch sw = Stopwatch.StartNew(); using ZipArchive archive = ZipFile.OpenRead(archivePath); // TODO: Throw error if we couldn't extract var needsFlattening = archive.Entries.Count > 0 && !Path.HasExtension(archive.Entries.ElementAt(0).FullName); - if (!archive.HasFiles() && !needsFlattening) return ""; + if (!archive.HasFiles() && !needsFlattening) return; archive.ExtractToDirectory(extractPath); - _logger.LogDebug($"Extracting archive to {extractPath}"); + _logger.LogDebug($"[OLD] Extracted archive to {extractPath} in {sw.ElapsedMilliseconds} milliseconds."); - if (!needsFlattening) return extractPath; - - _logger.LogInformation("Extracted archive is nested in root folder, flattening..."); - new DirectoryInfo(extractPath).Flatten(); - - return extractPath; + if (needsFlattening) + { + sw = Stopwatch.StartNew(); + _logger.LogInformation("Extracted archive is nested in root folder, flattening..."); + new DirectoryInfo(extractPath).Flatten(); + _logger.LogInformation($"[OLD] Flattened in {sw.ElapsedMilliseconds} milliseconds"); + } } diff --git a/API/Services/ScannerService.cs b/API/Services/ScannerService.cs index 5d1366603..646640fcf 100644 --- a/API/Services/ScannerService.cs +++ b/API/Services/ScannerService.cs @@ -6,7 +6,6 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; -using System.Threading; using System.Threading.Tasks; using API.Entities; using API.Extensions; diff --git a/API/appsettings.Development.json b/API/appsettings.Development.json index 5c67bda6f..d2bf464c4 100644 --- a/API/appsettings.Development.json +++ b/API/appsettings.Development.json @@ -1,13 +1,13 @@ { "ConnectionStrings": { - "DefaultConnection": "Data source=kavita.db", + "DefaultConnection": "Data source=kavita.db" }, "TokenKey": "super secret unguessable key", "Logging": { "LogLevel": { "Default": "Debug", - "Microsoft": "Information", - "Microsoft.Hosting.Lifetime": "Information", + "Microsoft": "Error", + "Microsoft.Hosting.Lifetime": "Error", "Hangfire": "Information" }, "File": {