Feature/tech debt (#199)

* Added an icon for building the exe

* Technical debt
This commit is contained in:
Joseph Milazzo 2021-05-05 21:00:50 -05:00 committed by GitHub
parent d92e9e7602
commit f694145cd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 76 additions and 112 deletions

View File

@ -1,6 +1,4 @@
using System; using API.Data;
using API.Data;
using API.Tests.Helpers;
using Xunit; using Xunit;
namespace API.Tests.Entities namespace API.Tests.Entities

View File

@ -1,10 +1,4 @@
using System; namespace API.Tests.Extensions
using System.IO;
using API.Extensions;
using NSubstitute;
using Xunit;
namespace API.Tests.Extensions
{ {
public class FileInfoExtensionsTests public class FileInfoExtensionsTests
{ {

View File

@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using API.Entities;
using API.Entities.Enums; using API.Entities.Enums;
using API.Extensions; using API.Extensions;
using API.Parser; using API.Parser;
@ -12,7 +11,7 @@ namespace API.Tests.Extensions
public class ParserInfoListExtensions public class ParserInfoListExtensions
{ {
[Theory] [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) public void DistinctVolumesTest(string[] volumeNumbers, string[] expectedNumbers)
{ {
var infos = volumeNumbers.Select(n => new ParserInfo() {Volumes = n}).ToList(); var infos = volumeNumbers.Select(n => new ParserInfo() {Volumes = n}).ToList();
@ -20,9 +19,9 @@ namespace API.Tests.Extensions
} }
[Theory] [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[] {@"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 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[] {@"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 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 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) public void HasInfoTest(string[] inputInfos, string[] inputChapters, bool expectedHasInfo)
{ {
var infos = new List<ParserInfo>(); var infos = new List<ParserInfo>();

View File

@ -1,5 +1,4 @@
using System; using API.Entities;
using API.Entities;
using API.Extensions; using API.Extensions;
using Xunit; using Xunit;

View File

@ -1,6 +1,4 @@
using System.Collections.Generic; using System.IO;
using System.IO;
using API.Services;
namespace API.Tests.Helpers namespace API.Tests.Helpers
{ {

View File

@ -1,5 +1,4 @@
using API.Services; using Xunit;
using Xunit;
namespace API.Tests.Parser namespace API.Tests.Parser
{ {

View File

@ -1,5 +1,4 @@
using System.IO; using System.IO;
using API.Entities.Interfaces;
using API.Interfaces; using API.Interfaces;
using API.Services; using API.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View File

@ -2,7 +2,6 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using API.Services; using API.Services;
using API.Tests.Helpers;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
@ -20,16 +19,15 @@ namespace API.Tests.Services
_directoryService = new DirectoryService(_logger); _directoryService = new DirectoryService(_logger);
} }
[Theory] [Fact]
[InlineData("Manga-testcase.txt", 28)] public void GetFilesTest_Should_Be28()
public void GetFilesTest(string file, int expectedFileCount)
{ {
var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ScannerService/Manga"); var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ScannerService/Manga");
var files = new List<string>(); var files = new List<string>();
var fileCount = DirectoryService.TraverseTreeParallelForEach(testDirectory, s => files.Add(s), var fileCount = DirectoryService.TraverseTreeParallelForEach(testDirectory, s => files.Add(s),
API.Parser.Parser.ArchiveFileExtensions, _logger); API.Parser.Parser.ArchiveFileExtensions, _logger);
Assert.Equal(expectedFileCount, fileCount); Assert.Equal(28, fileCount);
} }
[Fact] [Fact]

View File

@ -29,10 +29,8 @@ namespace API.Tests.Services
private readonly ITestOutputHelper _testOutputHelper; private readonly ITestOutputHelper _testOutputHelper;
private readonly ScannerService _scannerService; private readonly ScannerService _scannerService;
private readonly ILogger<ScannerService> _logger = Substitute.For<ILogger<ScannerService>>(); private readonly ILogger<ScannerService> _logger = Substitute.For<ILogger<ScannerService>>();
private readonly IUnitOfWork _unitOfWork;
private readonly IArchiveService _archiveService = Substitute.For<IArchiveService>(); private readonly IArchiveService _archiveService = Substitute.For<IArchiveService>();
private readonly IBookService _bookService = Substitute.For<IBookService>(); private readonly IBookService _bookService = Substitute.For<IBookService>();
private readonly IMetadataService _metadataService;
private readonly ILogger<MetadataService> _metadataLogger = Substitute.For<ILogger<MetadataService>>(); private readonly ILogger<MetadataService> _metadataLogger = Substitute.For<ILogger<MetadataService>>();
private readonly DbConnection _connection; private readonly DbConnection _connection;
@ -58,13 +56,12 @@ namespace API.Tests.Services
// Substitute.For<UserManager<AppUser>>() - Not needed because only for UserService // Substitute.For<UserManager<AppUser>>() - Not needed because only for UserService
_unitOfWork = new UnitOfWork(_context, Substitute.For<IMapper>(), null, IUnitOfWork unitOfWork = new UnitOfWork(_context, Substitute.For<IMapper>(), null);
Substitute.For<ILogger<UnitOfWork>>());
_testOutputHelper = testOutputHelper; _testOutputHelper = testOutputHelper;
_metadataService= Substitute.For<MetadataService>(_unitOfWork, _metadataLogger, _archiveService, _bookService); IMetadataService metadataService = Substitute.For<MetadataService>(unitOfWork, _metadataLogger, _archiveService, _bookService);
_scannerService = new ScannerService(_unitOfWork, _logger, _archiveService, _metadataService, _bookService); _scannerService = new ScannerService(unitOfWork, _logger, _archiveService, metadataService, _bookService);
} }
private async Task<bool> SeedDb() private async Task<bool> SeedDb()
@ -118,7 +115,6 @@ namespace API.Tests.Services
OriginalName = "Darker Than Black", OriginalName = "Darker Than Black",
NormalizedName = API.Parser.Parser.Normalize("Darker Than Black") NormalizedName = API.Parser.Parser.Normalize("Darker Than Black")
}); });
var expectedSeries = new List<Series>();

View File

@ -9,6 +9,7 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>false</DebugSymbols> <DebugSymbols>false</DebugSymbols>
<ApplicationIcon>../favicon.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -2,9 +2,9 @@
namespace API.Comparators namespace API.Comparators
{ {
public class ChapterSortComparer : IComparer<float> public class ChapterSortComparer : IComparer<double>
{ {
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 == 0.0 && y == 0.0) return 0;
// if x is 0, it comes second // if x is 0, it comes second

View File

@ -6,11 +6,14 @@ using static System.String;
namespace API.Comparators namespace API.Comparators
{ {
public class NaturalSortComparer : IComparer<string>, IDisposable public sealed class NaturalSortComparer : IComparer<string>, IDisposable
{ {
private readonly bool _isAscending; private readonly bool _isAscending;
private Dictionary<string, string[]> _table = new(); private Dictionary<string, string[]> _table = new();
private bool _disposed;
public NaturalSortComparer(bool inAscendingOrder = true) public NaturalSortComparer(bool inAscendingOrder = true)
{ {
_isAscending = inAscendingOrder; _isAscending = inAscendingOrder;
@ -20,17 +23,17 @@ namespace API.Comparators
{ {
if (x == y) return 0; if (x == y) return 0;
if (!_table.TryGetValue(x, out var x1)) if (!_table.TryGetValue(x ?? Empty, out var x1))
{ {
// .Replace(" ", Empty) // .Replace(" ", Empty)
x1 = Regex.Split(x, "([0-9]+)"); x1 = Regex.Split(x ?? Empty, "([0-9]+)");
_table.Add(x, x1); _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]+)"); y1 = Regex.Split(y ?? Empty, "([0-9]+)");
_table.Add(y, y1); _table.Add(y ?? Empty, y1);
} }
int returnVal; int returnVal;
@ -69,11 +72,31 @@ namespace API.Comparators
return x.CompareTo(y); 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() public void Dispose()
{ {
Dispose(true);
SuppressFinalize(this); SuppressFinalize(this);
_table.Clear(); }
_table = null;
~NaturalSortComparer() // the finalizer
{
Dispose(false);
} }
} }
} }

View File

@ -2,7 +2,6 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using API.DTOs; using API.DTOs;
using API.Entities.Interfaces;
using API.Extensions; using API.Extensions;
using API.Interfaces; using API.Interfaces;
using API.Services; using API.Services;

View File

@ -282,6 +282,7 @@ namespace API.Controllers
/// </summary> /// </summary>
/// <param name="seriesId"></param> /// <param name="seriesId"></param>
/// <param name="volumeId"></param> /// <param name="volumeId"></param>
/// <param name="currentChapterId"></param>
/// <returns>chapter id for next manga</returns> /// <returns>chapter id for next manga</returns>
[HttpGet("prev-chapter")] [HttpGet("prev-chapter")]
public async Task<ActionResult<int>> GetPreviousChapter(int seriesId, int volumeId, int currentChapterId) public async Task<ActionResult<int>> GetPreviousChapter(int seriesId, int volumeId, int currentChapterId)

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using API.DTOs; using API.DTOs;
using API.Entities; using API.Entities;

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using API.DTOs; using API.DTOs;
@ -10,7 +9,6 @@ using API.Interfaces;
using AutoMapper; using AutoMapper;
using AutoMapper.QueryableExtensions; using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace API.Data namespace API.Data
{ {
@ -18,13 +16,11 @@ namespace API.Data
{ {
private readonly DataContext _context; private readonly DataContext _context;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly ILogger _logger;
public SeriesRepository(DataContext context, IMapper mapper, ILogger logger) public SeriesRepository(DataContext context, IMapper mapper)
{ {
_context = context; _context = context;
_mapper = mapper; _mapper = mapper;
_logger = logger;
} }
public void Add(Series series) public void Add(Series series)
@ -289,6 +285,7 @@ namespace API.Data
/// <summary> /// <summary>
/// Returns a list of Series that were added, ordered by Created desc /// Returns a list of Series that were added, ordered by Created desc
/// </summary> /// </summary>
/// <param name="userId"></param>
/// <param name="libraryId">Library to restrict to, if 0, will apply to all libraries</param> /// <param name="libraryId">Library to restrict to, if 0, will apply to all libraries</param>
/// <param name="limit">How many series to pick.</param> /// <param name="limit">How many series to pick.</param>
/// <returns></returns> /// <returns></returns>

View File

@ -3,7 +3,6 @@ using API.Entities;
using API.Interfaces; using API.Interfaces;
using AutoMapper; using AutoMapper;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
namespace API.Data namespace API.Data
{ {
@ -12,17 +11,15 @@ namespace API.Data
private readonly DataContext _context; private readonly DataContext _context;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly UserManager<AppUser> _userManager; private readonly UserManager<AppUser> _userManager;
private readonly ILogger<UnitOfWork> _logger;
public UnitOfWork(DataContext context, IMapper mapper, UserManager<AppUser> userManager, ILogger<UnitOfWork> logger) public UnitOfWork(DataContext context, IMapper mapper, UserManager<AppUser> userManager)
{ {
_context = context; _context = context;
_mapper = mapper; _mapper = mapper;
_userManager = userManager; _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 IUserRepository UserRepository => new UserRepository(_context, _userManager);
public ILibraryRepository LibraryRepository => new LibraryRepository(_context, _mapper); public ILibraryRepository LibraryRepository => new LibraryRepository(_context, _mapper);

View File

@ -1,5 +1,4 @@
using API.Data; using API.Data;
using API.Entities.Interfaces;
using API.Helpers; using API.Helpers;
using API.Interfaces; using API.Interfaces;
using API.Interfaces.Services; using API.Interfaces.Services;

View File

@ -1,5 +1,4 @@
using System.Collections; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using API.Entities; using API.Entities;
using API.Parser; using API.Parser;

View File

@ -48,7 +48,7 @@ namespace API.Parser
/// <summary> /// <summary>
/// If the file contains no volume/chapter information or contains Special Keywords <see cref="Parser.MangaSpecialRegex"/> /// If the file contains no volume/chapter information or contains Special Keywords <see cref="Parser.MangaSpecialRegex"/>
/// </summary> /// </summary>
public bool IsSpecial { get; set; } = false; public bool IsSpecial { get; set; }
/// <summary> /// <summary>
/// Used for specials or books, stores what the UI should show. /// Used for specials or books, stores what the UI should show.

View File

@ -4,6 +4,7 @@ using API.Data;
using API.Entities; using API.Entities;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -49,38 +50,12 @@ namespace API
{ {
webBuilder.UseKestrel((opts) => webBuilder.UseKestrel((opts) =>
{ {
opts.ListenAnyIP(HttpPort); opts.ListenAnyIP(HttpPort, options =>
{
options.Protocols = HttpProtocols.Http1AndHttp2;
});
}); });
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();
}); });
// 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<string>);
// }
} }
} }

View File

@ -168,7 +168,7 @@ namespace API.Services
{ {
_logger.LogDebug("Using SharpCompress compression handling"); _logger.LogDebug("Using SharpCompress compression handling");
using var archive = ArchiveFactory.Open(archivePath); 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 entryName = FindFolderEntry(entryNames) ?? FirstFileEntry(entryNames);
var entry = archive.Entries.Single(e => e.Key == entryName); var entry = archive.Entries.Single(e => e.Key == entryName);

View File

@ -4,7 +4,6 @@ using System.Collections.Immutable;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using API.Interfaces.Services; using API.Interfaces.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View File

@ -4,9 +4,9 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using API.Comparators;
using API.Entities; using API.Entities;
using API.Entities.Enums; using API.Entities.Enums;
using API.Entities.Interfaces;
using API.Extensions; using API.Extensions;
using API.Interfaces; using API.Interfaces;
using API.Interfaces.Services; using API.Interfaces.Services;
@ -20,6 +20,7 @@ namespace API.Services
private readonly ILogger<MetadataService> _logger; private readonly ILogger<MetadataService> _logger;
private readonly IArchiveService _archiveService; private readonly IArchiveService _archiveService;
private readonly IBookService _bookService; private readonly IBookService _bookService;
private readonly ChapterSortComparer _chapterSortComparer = new ChapterSortComparer();
public MetadataService(IUnitOfWork unitOfWork, ILogger<MetadataService> logger, IArchiveService archiveService, IBookService bookService) public MetadataService(IUnitOfWork unitOfWork, ILogger<MetadataService> logger, IArchiveService archiveService, IBookService bookService)
{ {
@ -61,9 +62,8 @@ namespace API.Services
{ {
if (volume != null && ShouldFindCoverImage(volume.CoverImage, forceUpdate)) if (volume != null && ShouldFindCoverImage(volume.CoverImage, forceUpdate))
{ {
// TODO: Replace this with ChapterSortComparator
volume.Chapters ??= new List<Chapter>(); volume.Chapters ??= new List<Chapter>();
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 // Skip calculating Cover Image (I/O) if the chapter already has it set
if (firstChapter == null || ShouldFindCoverImage(firstChapter.CoverImage)) if (firstChapter == null || ShouldFindCoverImage(firstChapter.CoverImage))
@ -83,7 +83,6 @@ namespace API.Services
public void UpdateMetadata(Series series, bool forceUpdate) public void UpdateMetadata(Series series, bool forceUpdate)
{ {
// TODO: Use new ChapterSortComparer() here instead
if (series == null) return; if (series == null) return;
if (ShouldFindCoverImage(series.CoverImage, forceUpdate)) 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 firstCover is null and one volume, the whole series is Chapters under Vol 0.
if (series.Volumes.Count == 1) 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; .FirstOrDefault(c => !c.IsSpecial)?.CoverImage;
} }
if (coverImage == null) 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; .FirstOrDefault()?.CoverImage;
} }
} }

View File

@ -203,7 +203,7 @@ namespace API.Services.Tasks
foreach (var (key, infos) in parsedSeries) foreach (var (key, infos) in parsedSeries)
{ {
// Key is normalized already // Key is normalized already
Series existingSeries = null; Series existingSeries;
try try
{ {
existingSeries = library.Series.SingleOrDefault(s => s.NormalizedName == key || Parser.Parser.Normalize(s.OriginalName) == key); existingSeries = library.Series.SingleOrDefault(s => s.NormalizedName == key || Parser.Parser.Normalize(s.OriginalName) == key);
@ -212,15 +212,11 @@ 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); _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 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) foreach (var series in duplicateSeries)
{ {
_logger.LogCritical("{Key} maps with {Series}", key, series.OriginalName); _logger.LogCritical("{Key} maps with {Series}", key, series.OriginalName);
} }
// Merge them together?
//_unitOfWork.AppUserProgressRepository.MapSeriesProgressFromTo(firstSeries.Id, );
continue; continue;
} }
@ -366,7 +362,7 @@ namespace API.Services.Tasks
foreach (var info in parsedInfos) foreach (var info in parsedInfos)
{ {
var specialTreatment = info.IsSpecialInfo(); var specialTreatment = info.IsSpecialInfo();
Chapter chapter = null; Chapter chapter;
try try
{ {
chapter = volume.Chapters.GetChapterByRange(info); chapter = volume.Chapters.GetChapterByRange(info);

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB