From f694145cd915ab9447249d90225c1770063442e5 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 5 May 2021 21:00:50 -0500 Subject: [PATCH] Feature/tech debt (#199) * Added an icon for building the exe * Technical debt --- API.Tests/Entities/SeriesTest.cs | 4 +- .../Extensions/FileInfoExtensionsTests.cs | 8 +--- .../ParserInfoListExtensionsTests.cs | 9 ++-- API.Tests/Extensions/SeriesExtensionsTests.cs | 3 +- API.Tests/Helpers/TestCaseGenerator.cs | 4 +- API.Tests/Parser/BookParserTests.cs | 3 +- API.Tests/Services/BookServiceTests.cs | 1 - API.Tests/Services/DirectoryServiceTests.cs | 8 ++-- API.Tests/Services/ScannerServiceTests.cs | 16 +++---- API/API.csproj | 1 + API/Comparators/ChapterSortComparer.cs | 4 +- API/Comparators/NaturalSortComparer.cs | 41 ++++++++++++++---- API/Controllers/BookController.cs | 1 - API/Controllers/ReaderController.cs | 3 +- API/Controllers/SeriesController.cs | 1 - API/Data/SeriesRepository.cs | 7 +-- API/Data/UnitOfWork.cs | 7 +-- .../ApplicationServiceExtensions.cs | 1 - API/Extensions/ParserInfoListExtensions.cs | 3 +- API/Parser/ParserInfo.cs | 2 +- API/Program.cs | 35 +++------------ API/Services/ArchiveService.cs | 2 +- API/Services/DirectoryService.cs | 1 - API/Services/MetadataService.cs | 13 +++--- API/Services/Tasks/ScannerService.cs | 10 ++--- favicon.ico | Bin 0 -> 1150 bytes 26 files changed, 76 insertions(+), 112 deletions(-) create mode 100644 favicon.ico diff --git a/API.Tests/Entities/SeriesTest.cs b/API.Tests/Entities/SeriesTest.cs index dd1f77b29..f0cab0239 100644 --- a/API.Tests/Entities/SeriesTest.cs +++ b/API.Tests/Entities/SeriesTest.cs @@ -1,6 +1,4 @@ -using System; -using API.Data; -using API.Tests.Helpers; +using API.Data; using Xunit; namespace API.Tests.Entities diff --git a/API.Tests/Extensions/FileInfoExtensionsTests.cs b/API.Tests/Extensions/FileInfoExtensionsTests.cs index 371d8ac76..2f385b63f 100644 --- a/API.Tests/Extensions/FileInfoExtensionsTests.cs +++ b/API.Tests/Extensions/FileInfoExtensionsTests.cs @@ -1,10 +1,4 @@ -using System; -using System.IO; -using API.Extensions; -using NSubstitute; -using Xunit; - -namespace API.Tests.Extensions +namespace API.Tests.Extensions { public class FileInfoExtensionsTests { diff --git a/API.Tests/Extensions/ParserInfoListExtensionsTests.cs b/API.Tests/Extensions/ParserInfoListExtensionsTests.cs index 99f1383fc..f6119cc69 100644 --- a/API.Tests/Extensions/ParserInfoListExtensionsTests.cs +++ b/API.Tests/Extensions/ParserInfoListExtensionsTests.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using API.Entities; using API.Entities.Enums; using API.Extensions; using API.Parser; @@ -12,7 +11,7 @@ namespace API.Tests.Extensions public class ParserInfoListExtensions { [Theory] - [InlineData(new string[] {"1", "1", "3-5", "5", "8", "0", "0"}, new string[] {"1", "3-5", "5", "8", "0"})] + [InlineData(new[] {"1", "1", "3-5", "5", "8", "0", "0"}, new[] {"1", "3-5", "5", "8", "0"})] public void DistinctVolumesTest(string[] volumeNumbers, string[] expectedNumbers) { var infos = volumeNumbers.Select(n => new ParserInfo() {Volumes = n}).ToList(); @@ -20,9 +19,9 @@ namespace API.Tests.Extensions } [Theory] - [InlineData(new string[] {@"Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, new string[] {@"E:\Manga\Cynthia the Mission\Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, true)] - [InlineData(new string[] {@"Cynthia The Mission - c000-006 (v06-07) [Desudesu&Brolen].zip"}, new string[] {@"E:\Manga\Cynthia the Mission\Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, true)] - [InlineData(new string[] {@"Cynthia The Mission v20 c12-20 [Desudesu&Brolen].zip"}, new string[] {@"E:\Manga\Cynthia the Mission\Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, false)] + [InlineData(new[] {@"Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, new[] {@"E:\Manga\Cynthia the Mission\Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, true)] + [InlineData(new[] {@"Cynthia The Mission - c000-006 (v06-07) [Desudesu&Brolen].zip"}, new[] {@"E:\Manga\Cynthia the Mission\Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, true)] + [InlineData(new[] {@"Cynthia The Mission v20 c12-20 [Desudesu&Brolen].zip"}, new[] {@"E:\Manga\Cynthia the Mission\Cynthia The Mission - c000-006 (v06) [Desudesu&Brolen].zip"}, false)] public void HasInfoTest(string[] inputInfos, string[] inputChapters, bool expectedHasInfo) { var infos = new List(); diff --git a/API.Tests/Extensions/SeriesExtensionsTests.cs b/API.Tests/Extensions/SeriesExtensionsTests.cs index 59c823fe1..86d788036 100644 --- a/API.Tests/Extensions/SeriesExtensionsTests.cs +++ b/API.Tests/Extensions/SeriesExtensionsTests.cs @@ -1,5 +1,4 @@ -using System; -using API.Entities; +using API.Entities; using API.Extensions; using Xunit; diff --git a/API.Tests/Helpers/TestCaseGenerator.cs b/API.Tests/Helpers/TestCaseGenerator.cs index 57923dfb2..41b99e5e4 100644 --- a/API.Tests/Helpers/TestCaseGenerator.cs +++ b/API.Tests/Helpers/TestCaseGenerator.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using System.IO; -using API.Services; +using System.IO; namespace API.Tests.Helpers { diff --git a/API.Tests/Parser/BookParserTests.cs b/API.Tests/Parser/BookParserTests.cs index 0a43b7c73..abeff081d 100644 --- a/API.Tests/Parser/BookParserTests.cs +++ b/API.Tests/Parser/BookParserTests.cs @@ -1,5 +1,4 @@ -using API.Services; -using Xunit; +using Xunit; namespace API.Tests.Parser { diff --git a/API.Tests/Services/BookServiceTests.cs b/API.Tests/Services/BookServiceTests.cs index 1a53af8fc..ecc374830 100644 --- a/API.Tests/Services/BookServiceTests.cs +++ b/API.Tests/Services/BookServiceTests.cs @@ -1,5 +1,4 @@ using System.IO; -using API.Entities.Interfaces; using API.Interfaces; using API.Services; using Microsoft.Extensions.Logging; diff --git a/API.Tests/Services/DirectoryServiceTests.cs b/API.Tests/Services/DirectoryServiceTests.cs index 04108fd25..3754e910a 100644 --- a/API.Tests/Services/DirectoryServiceTests.cs +++ b/API.Tests/Services/DirectoryServiceTests.cs @@ -2,7 +2,6 @@ using System.IO; using System.Linq; using API.Services; -using API.Tests.Helpers; using Microsoft.Extensions.Logging; using NSubstitute; using Xunit; @@ -20,16 +19,15 @@ namespace API.Tests.Services _directoryService = new DirectoryService(_logger); } - [Theory] - [InlineData("Manga-testcase.txt", 28)] - public void GetFilesTest(string file, int expectedFileCount) + [Fact] + public void GetFilesTest_Should_Be28() { var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ScannerService/Manga"); var files = new List(); var fileCount = DirectoryService.TraverseTreeParallelForEach(testDirectory, s => files.Add(s), API.Parser.Parser.ArchiveFileExtensions, _logger); - Assert.Equal(expectedFileCount, fileCount); + Assert.Equal(28, fileCount); } [Fact] diff --git a/API.Tests/Services/ScannerServiceTests.cs b/API.Tests/Services/ScannerServiceTests.cs index 22f54259c..7b7e6bc2f 100644 --- a/API.Tests/Services/ScannerServiceTests.cs +++ b/API.Tests/Services/ScannerServiceTests.cs @@ -29,10 +29,8 @@ namespace API.Tests.Services private readonly ITestOutputHelper _testOutputHelper; private readonly ScannerService _scannerService; private readonly ILogger _logger = Substitute.For>(); - private readonly IUnitOfWork _unitOfWork; private readonly IArchiveService _archiveService = Substitute.For(); private readonly IBookService _bookService = Substitute.For(); - private readonly IMetadataService _metadataService; private readonly ILogger _metadataLogger = Substitute.For>(); private readonly DbConnection _connection; @@ -58,13 +56,12 @@ namespace API.Tests.Services // Substitute.For>() - Not needed because only for UserService - _unitOfWork = new UnitOfWork(_context, Substitute.For(), null, - Substitute.For>()); + IUnitOfWork unitOfWork = new UnitOfWork(_context, Substitute.For(), null); _testOutputHelper = testOutputHelper; - _metadataService= Substitute.For(_unitOfWork, _metadataLogger, _archiveService, _bookService); - _scannerService = new ScannerService(_unitOfWork, _logger, _archiveService, _metadataService, _bookService); + IMetadataService metadataService = Substitute.For(unitOfWork, _metadataLogger, _archiveService, _bookService); + _scannerService = new ScannerService(unitOfWork, _logger, _archiveService, metadataService, _bookService); } private async Task SeedDb() @@ -118,10 +115,9 @@ namespace API.Tests.Services OriginalName = "Darker Than Black", NormalizedName = API.Parser.Parser.Normalize("Darker Than Black") }); - var expectedSeries = new List(); - - - + + + Assert.Empty(_scannerService.FindSeriesNotOnDisk(existingSeries, infos)); } diff --git a/API/API.csproj b/API/API.csproj index 87fa2f0d0..8c96cb129 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -9,6 +9,7 @@ false + ../favicon.ico diff --git a/API/Comparators/ChapterSortComparer.cs b/API/Comparators/ChapterSortComparer.cs index 249532466..ce7e2f374 100644 --- a/API/Comparators/ChapterSortComparer.cs +++ b/API/Comparators/ChapterSortComparer.cs @@ -2,9 +2,9 @@ namespace API.Comparators { - public class ChapterSortComparer : IComparer + public class ChapterSortComparer : IComparer { - public int Compare(float x, float y) + public int Compare(double x, double y) { if (x == 0.0 && y == 0.0) return 0; // if x is 0, it comes second diff --git a/API/Comparators/NaturalSortComparer.cs b/API/Comparators/NaturalSortComparer.cs index c3beebef1..ac10e09ae 100644 --- a/API/Comparators/NaturalSortComparer.cs +++ b/API/Comparators/NaturalSortComparer.cs @@ -6,10 +6,13 @@ using static System.String; namespace API.Comparators { - public class NaturalSortComparer : IComparer, IDisposable + public sealed class NaturalSortComparer : IComparer, IDisposable { private readonly bool _isAscending; private Dictionary _table = new(); + + private bool _disposed; + public NaturalSortComparer(bool inAscendingOrder = true) { @@ -20,17 +23,17 @@ namespace API.Comparators { if (x == y) return 0; - if (!_table.TryGetValue(x, out var x1)) + if (!_table.TryGetValue(x ?? Empty, out var x1)) { // .Replace(" ", Empty) - x1 = Regex.Split(x, "([0-9]+)"); - _table.Add(x, x1); + x1 = Regex.Split(x ?? Empty, "([0-9]+)"); + _table.Add(x ?? Empty, x1); } - if (!_table.TryGetValue(y, out var y1)) + if (!_table.TryGetValue(y ?? Empty, out var y1)) { - y1 = Regex.Split(y, "([0-9]+)"); - _table.Add(y, y1); + y1 = Regex.Split(y ?? Empty, "([0-9]+)"); + _table.Add(y ?? Empty, y1); } int returnVal; @@ -69,11 +72,31 @@ namespace API.Comparators return x.CompareTo(y); } + private void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // called via myClass.Dispose(). + _table.Clear(); + _table = null; + } + // Release unmanaged resources. + // Set large fields to null. + _disposed = true; + } + } + public void Dispose() { + Dispose(true); SuppressFinalize(this); - _table.Clear(); - _table = null; + } + + ~NaturalSortComparer() // the finalizer + { + Dispose(false); } } } \ No newline at end of file diff --git a/API/Controllers/BookController.cs b/API/Controllers/BookController.cs index 8626c8dcd..01588f3f4 100644 --- a/API/Controllers/BookController.cs +++ b/API/Controllers/BookController.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Threading.Tasks; using API.DTOs; -using API.Entities.Interfaces; using API.Extensions; using API.Interfaces; using API.Services; diff --git a/API/Controllers/ReaderController.cs b/API/Controllers/ReaderController.cs index 020e67c0b..43197248e 100644 --- a/API/Controllers/ReaderController.cs +++ b/API/Controllers/ReaderController.cs @@ -276,12 +276,13 @@ namespace API.Controllers } return Ok(-1); } - + /// /// Returns the previous logical volume from the series. /// /// /// + /// /// chapter id for next manga [HttpGet("prev-chapter")] public async Task> GetPreviousChapter(int seriesId, int volumeId, int currentChapterId) diff --git a/API/Controllers/SeriesController.cs b/API/Controllers/SeriesController.cs index caa69b15f..0654f7d70 100644 --- a/API/Controllers/SeriesController.cs +++ b/API/Controllers/SeriesController.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using API.DTOs; using API.Entities; diff --git a/API/Data/SeriesRepository.cs b/API/Data/SeriesRepository.cs index 07c75891f..e4a715f11 100644 --- a/API/Data/SeriesRepository.cs +++ b/API/Data/SeriesRepository.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using API.DTOs; @@ -10,7 +9,6 @@ using API.Interfaces; using AutoMapper; using AutoMapper.QueryableExtensions; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; namespace API.Data { @@ -18,13 +16,11 @@ namespace API.Data { private readonly DataContext _context; private readonly IMapper _mapper; - private readonly ILogger _logger; - public SeriesRepository(DataContext context, IMapper mapper, ILogger logger) + public SeriesRepository(DataContext context, IMapper mapper) { _context = context; _mapper = mapper; - _logger = logger; } public void Add(Series series) @@ -289,6 +285,7 @@ namespace API.Data /// /// Returns a list of Series that were added, ordered by Created desc /// + /// /// Library to restrict to, if 0, will apply to all libraries /// How many series to pick. /// diff --git a/API/Data/UnitOfWork.cs b/API/Data/UnitOfWork.cs index 8d0491fae..caa97523f 100644 --- a/API/Data/UnitOfWork.cs +++ b/API/Data/UnitOfWork.cs @@ -3,7 +3,6 @@ using API.Entities; using API.Interfaces; using AutoMapper; using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Logging; namespace API.Data { @@ -12,17 +11,15 @@ namespace API.Data private readonly DataContext _context; private readonly IMapper _mapper; private readonly UserManager _userManager; - private readonly ILogger _logger; - public UnitOfWork(DataContext context, IMapper mapper, UserManager userManager, ILogger logger) + public UnitOfWork(DataContext context, IMapper mapper, UserManager userManager) { _context = context; _mapper = mapper; _userManager = userManager; - _logger = logger; } - public ISeriesRepository SeriesRepository => new SeriesRepository(_context, _mapper, _logger); + public ISeriesRepository SeriesRepository => new SeriesRepository(_context, _mapper); public IUserRepository UserRepository => new UserRepository(_context, _userManager); public ILibraryRepository LibraryRepository => new LibraryRepository(_context, _mapper); diff --git a/API/Extensions/ApplicationServiceExtensions.cs b/API/Extensions/ApplicationServiceExtensions.cs index b0e09e18f..a3406ae27 100644 --- a/API/Extensions/ApplicationServiceExtensions.cs +++ b/API/Extensions/ApplicationServiceExtensions.cs @@ -1,5 +1,4 @@ using API.Data; -using API.Entities.Interfaces; using API.Helpers; using API.Interfaces; using API.Interfaces.Services; diff --git a/API/Extensions/ParserInfoListExtensions.cs b/API/Extensions/ParserInfoListExtensions.cs index adbf32c3c..2043583bb 100644 --- a/API/Extensions/ParserInfoListExtensions.cs +++ b/API/Extensions/ParserInfoListExtensions.cs @@ -1,5 +1,4 @@ -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using API.Entities; using API.Parser; diff --git a/API/Parser/ParserInfo.cs b/API/Parser/ParserInfo.cs index c5499d797..e49d87e74 100644 --- a/API/Parser/ParserInfo.cs +++ b/API/Parser/ParserInfo.cs @@ -48,7 +48,7 @@ namespace API.Parser /// /// If the file contains no volume/chapter information or contains Special Keywords /// - public bool IsSpecial { get; set; } = false; + public bool IsSpecial { get; set; } /// /// Used for specials or books, stores what the UI should show. diff --git a/API/Program.cs b/API/Program.cs index f65bba4ff..1eedcaaa5 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -4,6 +4,7 @@ using API.Data; using API.Entities; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -49,38 +50,12 @@ namespace API { webBuilder.UseKestrel((opts) => { - opts.ListenAnyIP(HttpPort); + opts.ListenAnyIP(HttpPort, options => + { + options.Protocols = HttpProtocols.Http1AndHttp2; + }); }); webBuilder.UseStartup(); }); - - // private static void StartNewInstance() - // { - // //_logger.LogInformation("Starting new instance"); - // - // var module = options.RestartPath; - // - // if (string.IsNullOrWhiteSpace(module)) - // { - // module = Environment.GetCommandLineArgs()[0]; - // } - // - // // string commandLineArgsString; - // // if (options.RestartArgs != null) - // // { - // // commandLineArgsString = options.RestartArgs ?? string.Empty; - // // } - // // else - // // { - // // commandLineArgsString = string.Join( - // // ' ', - // // Environment.GetCommandLineArgs().Skip(1).Select(NormalizeCommandLineArgument)); - // // } - // - // //_logger.LogInformation("Executable: {0}", module); - // //_logger.LogInformation("Arguments: {0}", commandLineArgsString); - // - // Process.Start(module, Array.Empty); - // } } } diff --git a/API/Services/ArchiveService.cs b/API/Services/ArchiveService.cs index 90f740599..dc490844c 100644 --- a/API/Services/ArchiveService.cs +++ b/API/Services/ArchiveService.cs @@ -168,7 +168,7 @@ namespace API.Services { _logger.LogDebug("Using SharpCompress compression handling"); using var archive = ArchiveFactory.Open(archivePath); - var entryNames = archive.Entries.Where(entry => !entry.IsDirectory).Select(e => e.Key).ToList(); + var entryNames = archive.Entries.Where(archiveEntry => !archiveEntry.IsDirectory).Select(e => e.Key).ToList(); var entryName = FindFolderEntry(entryNames) ?? FirstFileEntry(entryNames); var entry = archive.Entries.Single(e => e.Key == entryName); diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index 95a48a29e..40271ccd0 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -4,7 +4,6 @@ using System.Collections.Immutable; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using System.Threading; using System.Threading.Tasks; using API.Interfaces.Services; using Microsoft.Extensions.Logging; diff --git a/API/Services/MetadataService.cs b/API/Services/MetadataService.cs index 7096ab0df..122fc90c6 100644 --- a/API/Services/MetadataService.cs +++ b/API/Services/MetadataService.cs @@ -4,9 +4,9 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; +using API.Comparators; using API.Entities; using API.Entities.Enums; -using API.Entities.Interfaces; using API.Extensions; using API.Interfaces; using API.Interfaces.Services; @@ -20,6 +20,7 @@ namespace API.Services private readonly ILogger _logger; private readonly IArchiveService _archiveService; private readonly IBookService _bookService; + private readonly ChapterSortComparer _chapterSortComparer = new ChapterSortComparer(); public MetadataService(IUnitOfWork unitOfWork, ILogger logger, IArchiveService archiveService, IBookService bookService) { @@ -61,10 +62,9 @@ namespace API.Services { if (volume != null && ShouldFindCoverImage(volume.CoverImage, forceUpdate)) { - // TODO: Replace this with ChapterSortComparator volume.Chapters ??= new List(); - var firstChapter = volume.Chapters.OrderBy(x => double.Parse(x.Number)).FirstOrDefault(); - + var firstChapter = volume.Chapters.OrderBy(x => double.Parse(x.Number), _chapterSortComparer).FirstOrDefault(); + // Skip calculating Cover Image (I/O) if the chapter already has it set if (firstChapter == null || ShouldFindCoverImage(firstChapter.CoverImage)) { @@ -83,7 +83,6 @@ namespace API.Services public void UpdateMetadata(Series series, bool forceUpdate) { - // TODO: Use new ChapterSortComparer() here instead if (series == null) return; if (ShouldFindCoverImage(series.CoverImage, forceUpdate)) { @@ -95,13 +94,13 @@ namespace API.Services // If firstCover is null and one volume, the whole series is Chapters under Vol 0. if (series.Volumes.Count == 1) { - coverImage = series.Volumes[0].Chapters.OrderBy(c => double.Parse(c.Number)) + coverImage = series.Volumes[0].Chapters.OrderBy(c => double.Parse(c.Number), _chapterSortComparer) .FirstOrDefault(c => !c.IsSpecial)?.CoverImage; } if (coverImage == null) { - coverImage = series.Volumes[0].Chapters.OrderBy(c => double.Parse(c.Number)) + coverImage = series.Volumes[0].Chapters.OrderBy(c => double.Parse(c.Number), _chapterSortComparer) .FirstOrDefault()?.CoverImage; } } diff --git a/API/Services/Tasks/ScannerService.cs b/API/Services/Tasks/ScannerService.cs index 726e31dc3..432212f6f 100644 --- a/API/Services/Tasks/ScannerService.cs +++ b/API/Services/Tasks/ScannerService.cs @@ -203,7 +203,7 @@ namespace API.Services.Tasks foreach (var (key, infos) in parsedSeries) { // Key is normalized already - Series existingSeries = null; + Series existingSeries; try { existingSeries = library.Series.SingleOrDefault(s => s.NormalizedName == key || Parser.Parser.Normalize(s.OriginalName) == key); @@ -212,16 +212,12 @@ namespace API.Services.Tasks { _logger.LogCritical(e, "There are multiple series that map to normalized key {Key}. You can manually delete the entity via UI and rescan to fix it", key); var duplicateSeries = library.Series.Where(s => s.NormalizedName == key || Parser.Parser.Normalize(s.OriginalName) == key).ToList(); - //var firstSeries = duplicateSeries.First(); - //duplicateSeries. foreach (var series in duplicateSeries) { _logger.LogCritical("{Key} maps with {Series}", key, series.OriginalName); } - // Merge them together? - //_unitOfWork.AppUserProgressRepository.MapSeriesProgressFromTo(firstSeries.Id, ); - + continue; } if (existingSeries == null) @@ -366,7 +362,7 @@ namespace API.Services.Tasks foreach (var info in parsedInfos) { var specialTreatment = info.IsSpecialInfo(); - Chapter chapter = null; + Chapter chapter; try { chapter = volume.Chapters.GetChapterByRange(info); diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..1ed03f4f7601513b81a27d9c247681639e82347a GIT binary patch literal 1150 zcmbu8J#W)c6ozj_B?csjIxsWx511&G+9r-+sMw)v*GNcIOx;LTA%DaUp+5jMG!0c% zJ|s#@UDvp+SRi4BsTmo-A;!+(yw^B2YC82sug~>4?{mMLE5r!@ayh}zYhrFxh^s<~ z>nu)jCdqRUf@@=!63O==4{c{6XYA%@O;>eHPYI;Bj~r@4kU>gwmAlr*;^*ptN>%?h zS)M9|K60qRGXOFj-Bn7pqheV5bcbxeI8>;?qdWOh1{D=AKV!RUq;2M@yn2hu4Hm~o z^W#$G7biJ*;01#*7GB@DZ23w{e_NpPgL_oBmuSUWr03>iYS@Mp`pBUM54>Q&ntO%& zPmfeuT)RoD%NofR#Y8bHZRjJ%4IX&G=*(93Ri}EG@b%><($nh(1jWoj={t(>fCmHC z^wa?7h1`G-eo>DVN0AizP?iS+_PqS*_4g_K&GU7;C-eW?Pj>#n`qT4kj8pwtg(zrI zc)U(wn5-Rp_;39+-amVBemHyi{k%d;+nS(_H#MT4U#Q<{^4vUIKT+KKLlD}=D}&&* zm;sCbfaVluOm8Y`wja{h&Uv25j1NM=4ePLTLNb zWb99o;c|2*6XBhO8a(i(TsEHP{-ooab$@YI+RM}T_s10>zFidJ!v($zBk3q-M|j`` G1NJX<5p^E` literal 0 HcmV?d00001