diff --git a/API.Tests/Entities/SeriesTest.cs b/API.Tests/Entities/SeriesTest.cs index f0cab0239..70897b49f 100644 --- a/API.Tests/Entities/SeriesTest.cs +++ b/API.Tests/Entities/SeriesTest.cs @@ -12,7 +12,7 @@ namespace API.Tests.Entities [InlineData("Darker than Black")] public void CreateSeries(string name) { - var key = API.Parser.Parser.Normalize(name); + var key = API.Services.Tasks.Scanner.Parser.Parser.Normalize(name); var series = DbFactory.Series(name); Assert.Equal(0, series.Id); Assert.Equal(0, series.Pages); diff --git a/API.Tests/Extensions/SeriesExtensionsTests.cs b/API.Tests/Extensions/SeriesExtensionsTests.cs index c00ade1e8..b339b306d 100644 --- a/API.Tests/Extensions/SeriesExtensionsTests.cs +++ b/API.Tests/Extensions/SeriesExtensionsTests.cs @@ -28,7 +28,7 @@ namespace API.Tests.Extensions Name = seriesInput[0], LocalizedName = seriesInput[1], OriginalName = seriesInput[2], - NormalizedName = seriesInput.Length == 4 ? seriesInput[3] : API.Parser.Parser.Normalize(seriesInput[0]), + NormalizedName = seriesInput.Length == 4 ? seriesInput[3] : API.Services.Tasks.Scanner.Parser.Parser.Normalize(seriesInput[0]), Metadata = new SeriesMetadata() }; @@ -52,14 +52,14 @@ namespace API.Tests.Extensions Name = seriesInput[0], LocalizedName = seriesInput[1], OriginalName = seriesInput[2], - NormalizedName = seriesInput.Length == 4 ? seriesInput[3] : API.Parser.Parser.Normalize(seriesInput[0]), + NormalizedName = seriesInput.Length == 4 ? seriesInput[3] : API.Services.Tasks.Scanner.Parser.Parser.Normalize(seriesInput[0]), Metadata = new SeriesMetadata(), }; var parserInfos = list.Select(s => new ParsedSeries() { Name = s, - NormalizedName = API.Parser.Parser.Normalize(s), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(s), }).ToList(); // This doesn't do any checks against format @@ -78,7 +78,7 @@ namespace API.Tests.Extensions Name = seriesInput[0], LocalizedName = seriesInput[1], OriginalName = seriesInput[2], - NormalizedName = seriesInput.Length == 4 ? seriesInput[3] : API.Parser.Parser.Normalize(seriesInput[0]), + NormalizedName = seriesInput.Length == 4 ? seriesInput[3] : API.Services.Tasks.Scanner.Parser.Parser.Normalize(seriesInput[0]), Metadata = new SeriesMetadata() }; var info = new ParserInfo(); diff --git a/API.Tests/Helpers/EntityFactory.cs b/API.Tests/Helpers/EntityFactory.cs index 3632ff9a0..55d947cf5 100644 --- a/API.Tests/Helpers/EntityFactory.cs +++ b/API.Tests/Helpers/EntityFactory.cs @@ -18,7 +18,7 @@ namespace API.Tests.Helpers Name = name, SortName = name, LocalizedName = name, - NormalizedName = API.Parser.Parser.Normalize(name), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(name), Volumes = new List(), Metadata = new SeriesMetadata() }; @@ -31,7 +31,7 @@ namespace API.Tests.Helpers return new Volume() { Name = volumeNumber, - Number = (int) API.Parser.Parser.MinNumberFromRange(volumeNumber), + Number = (int) API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(volumeNumber), Pages = pages, Chapters = chaps }; @@ -43,7 +43,7 @@ namespace API.Tests.Helpers { IsSpecial = isSpecial, Range = range, - Number = API.Parser.Parser.MinNumberFromRange(range) + string.Empty, + Number = API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(range) + string.Empty, Files = files ?? new List(), Pages = pageCount, @@ -73,7 +73,7 @@ namespace API.Tests.Helpers return new CollectionTag() { Id = id, - NormalizedTitle = API.Parser.Parser.Normalize(title).ToUpper(), + NormalizedTitle = API.Services.Tasks.Scanner.Parser.Parser.Normalize(title).ToUpper(), Title = title, Summary = summary, Promoted = promoted diff --git a/API.Tests/Helpers/ParserInfoFactory.cs b/API.Tests/Helpers/ParserInfoFactory.cs index 84847dca2..4b4a8e22a 100644 --- a/API.Tests/Helpers/ParserInfoFactory.cs +++ b/API.Tests/Helpers/ParserInfoFactory.cs @@ -29,12 +29,12 @@ namespace API.Tests.Helpers public static void AddToParsedInfo(IDictionary> collectedSeries, ParserInfo info) { var existingKey = collectedSeries.Keys.FirstOrDefault(ps => - ps.Format == info.Format && ps.NormalizedName == API.Parser.Parser.Normalize(info.Series)); + ps.Format == info.Format && ps.NormalizedName == API.Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series)); existingKey ??= new ParsedSeries() { Format = info.Format, Name = info.Series, - NormalizedName = API.Parser.Parser.Normalize(info.Series) + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series) }; if (collectedSeries.GetType() == typeof(ConcurrentDictionary<,>)) { diff --git a/API.Tests/Helpers/ParserInfoHelperTests.cs b/API.Tests/Helpers/ParserInfoHelperTests.cs index d81e100c0..e51362b81 100644 --- a/API.Tests/Helpers/ParserInfoHelperTests.cs +++ b/API.Tests/Helpers/ParserInfoHelperTests.cs @@ -34,7 +34,7 @@ public class ParserInfoHelperTests Name = "1" } }, - NormalizedName = API.Parser.Parser.Normalize("Darker Than Black"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker Than Black"), Metadata = new SeriesMetadata(), Format = MangaFormat.Epub }; @@ -63,7 +63,7 @@ public class ParserInfoHelperTests Name = "1" } }, - NormalizedName = API.Parser.Parser.Normalize("Darker Than Black"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker Than Black"), Metadata = new SeriesMetadata(), Format = MangaFormat.Epub }; diff --git a/API.Tests/Helpers/SeriesHelperTests.cs b/API.Tests/Helpers/SeriesHelperTests.cs index a8ffd95c3..139803e0a 100644 --- a/API.Tests/Helpers/SeriesHelperTests.cs +++ b/API.Tests/Helpers/SeriesHelperTests.cs @@ -22,21 +22,21 @@ public class SeriesHelperTests { Format = MangaFormat.Archive, Name = "Darker than Black", - NormalizedName = API.Parser.Parser.Normalize("Darker than Black") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker than Black") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Archive, Name = "Darker than Black".ToLower(), - NormalizedName = API.Parser.Parser.Normalize("Darker than Black") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker than Black") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Archive, Name = "Darker than Black".ToUpper(), - NormalizedName = API.Parser.Parser.Normalize("Darker than Black") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker than Black") })); } @@ -50,21 +50,21 @@ public class SeriesHelperTests { Format = MangaFormat.Image, Name = "Darker than Black", - NormalizedName = API.Parser.Parser.Normalize("Darker than Black") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker than Black") })); Assert.False(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "Darker than Black".ToLower(), - NormalizedName = API.Parser.Parser.Normalize("Darker than Black") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker than Black") })); Assert.False(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "Darker than Black".ToUpper(), - NormalizedName = API.Parser.Parser.Normalize("Darker than Black") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker than Black") })); } @@ -78,28 +78,28 @@ public class SeriesHelperTests { Format = MangaFormat.Image, Name = "Something Random", - NormalizedName = API.Parser.Parser.Normalize("Something Random") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something Random") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "Something Random".ToLower(), - NormalizedName = API.Parser.Parser.Normalize("Something Random") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something Random") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "Something Random".ToUpper(), - NormalizedName = API.Parser.Parser.Normalize("Something Random") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something Random") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "SomethingRandom".ToUpper(), - NormalizedName = API.Parser.Parser.Normalize("SomethingRandom") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("SomethingRandom") })); } @@ -113,28 +113,28 @@ public class SeriesHelperTests { Format = MangaFormat.Image, Name = "Something Random", - NormalizedName = API.Parser.Parser.Normalize("Something Random") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something Random") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "Something Random".ToLower(), - NormalizedName = API.Parser.Parser.Normalize("Something Random") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something Random") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "Something Random".ToUpper(), - NormalizedName = API.Parser.Parser.Normalize("Something Random") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something Random") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Image, Name = "SomethingRandom".ToUpper(), - NormalizedName = API.Parser.Parser.Normalize("SomethingRandom") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("SomethingRandom") })); } @@ -148,14 +148,14 @@ public class SeriesHelperTests { Format = MangaFormat.Archive, Name = "My Dress-Up Darling", - NormalizedName = API.Parser.Parser.Normalize("My Dress-Up Darling") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("My Dress-Up Darling") })); Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries() { Format = MangaFormat.Archive, Name = "Sono Bisque Doll wa Koi wo Suru".ToLower(), - NormalizedName = API.Parser.Parser.Normalize("Sono Bisque Doll wa Koi wo Suru") + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Sono Bisque Doll wa Koi wo Suru") })); } #endregion diff --git a/API.Tests/Parser/BookParserTests.cs b/API.Tests/Parser/BookParserTests.cs index 2e8e89b31..23b9c6e63 100644 --- a/API.Tests/Parser/BookParserTests.cs +++ b/API.Tests/Parser/BookParserTests.cs @@ -10,7 +10,7 @@ namespace API.Tests.Parser [InlineData("Faust - Volume 01 [Del Rey][Scans_Compressed]", "Faust")] public void ParseSeriesTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseSeries(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseSeries(filename)); } [Theory] @@ -18,7 +18,7 @@ namespace API.Tests.Parser [InlineData("Faust - Volume 01 [Del Rey][Scans_Compressed]", "1")] public void ParseVolumeTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseVolume(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseVolume(filename)); } // [Theory] diff --git a/API.Tests/Parser/ComicParserTests.cs b/API.Tests/Parser/ComicParserTests.cs index 73f7cede4..74a2b8bb2 100644 --- a/API.Tests/Parser/ComicParserTests.cs +++ b/API.Tests/Parser/ComicParserTests.cs @@ -79,7 +79,7 @@ namespace API.Tests.Parser [InlineData("Fables 2010 Vol. 1 Legends in Exile", "Fables 2010")] public void ParseComicSeriesTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseComicSeries(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseComicSeries(filename)); } [Theory] @@ -126,7 +126,7 @@ namespace API.Tests.Parser [InlineData("Adventure Time TPB (2012)/Adventure Time v01 (2012).cbz", "1")] public void ParseComicVolumeTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseComicVolume(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseComicVolume(filename)); } [Theory] @@ -171,7 +171,7 @@ namespace API.Tests.Parser [InlineData("Adventure Time TPB (2012)/Adventure Time v01 (2012).cbz", "0")] public void ParseComicChapterTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseComicChapter(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseComicChapter(filename)); } @@ -190,7 +190,7 @@ namespace API.Tests.Parser [InlineData("Adventure Time 2013_-_Annual #001 (2013)", true)] public void ParseComicSpecialTest(string input, bool expected) { - Assert.Equal(expected, !string.IsNullOrEmpty(API.Parser.Parser.ParseComicSpecial(input))); + Assert.Equal(expected, !string.IsNullOrEmpty(API.Services.Tasks.Scanner.Parser.Parser.ParseComicSpecial(input))); } } } diff --git a/API.Tests/Parser/MangaParserTests.cs b/API.Tests/Parser/MangaParserTests.cs index 1ee94807c..12e312661 100644 --- a/API.Tests/Parser/MangaParserTests.cs +++ b/API.Tests/Parser/MangaParserTests.cs @@ -75,7 +75,7 @@ namespace API.Tests.Parser [InlineData("スライム倒して300年、知らないうちにレベルMAXになってました 1-3巻", "1-3")] public void ParseVolumeTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseVolume(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseVolume(filename)); } [Theory] @@ -183,7 +183,7 @@ namespace API.Tests.Parser [InlineData("Highschool of the Dead - 02", "Highschool of the Dead")] public void ParseSeriesTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseSeries(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseSeries(filename)); } [Theory] @@ -261,7 +261,7 @@ namespace API.Tests.Parser [InlineData("[ハレム]ナナとカオル ~高校生のSMごっこ~ 第10話", "10")] public void ParseChaptersTest(string filename, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseChapter(filename)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseChapter(filename)); } @@ -277,7 +277,7 @@ namespace API.Tests.Parser [InlineData("Love Hina Omnibus v05 (2015) (Digital-HD) (Asgard-Empire).cbz", "Omnibus")] public void ParseEditionTest(string input, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseEdition(input)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseEdition(input)); } [Theory] [InlineData("Beelzebub Special OneShot - Minna no Kochikame x Beelzebub (2016) [Mangastream].cbz", true)] @@ -296,7 +296,7 @@ namespace API.Tests.Parser [InlineData("The League of Extra-ordinary Gentlemen", false)] public void ParseMangaSpecialTest(string input, bool expected) { - Assert.Equal(expected, !string.IsNullOrEmpty(API.Parser.Parser.ParseMangaSpecial(input))); + Assert.Equal(expected, !string.IsNullOrEmpty(API.Services.Tasks.Scanner.Parser.Parser.ParseMangaSpecial(input))); } [Theory] @@ -305,14 +305,14 @@ namespace API.Tests.Parser [InlineData("image.txt", MangaFormat.Unknown)] public void ParseFormatTest(string inputFile, MangaFormat expected) { - Assert.Equal(expected, API.Parser.Parser.ParseFormat(inputFile)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseFormat(inputFile)); } [Theory] [InlineData("Gifting The Wonderful World With Blessings! - 3 Side Stories [yuNS][Unknown].epub", "Side Stories")] public void ParseSpecialTest(string inputFile, string expected) { - Assert.Equal(expected, API.Parser.Parser.ParseMangaSpecial(inputFile)); + Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseMangaSpecial(inputFile)); } diff --git a/API.Tests/Parser/ParserTest.cs b/API.Tests/Parser/ParserTest.cs index 3d3c95e5c..c1ef966c9 100644 --- a/API.Tests/Parser/ParserTest.cs +++ b/API.Tests/Parser/ParserTest.cs @@ -1,6 +1,6 @@ using System.Linq; using Xunit; -using static API.Parser.Parser; +using static API.Services.Tasks.Scanner.Parser.Parser; namespace API.Tests.Parser { diff --git a/API.Tests/Services/ArchiveServiceTests.cs b/API.Tests/Services/ArchiveServiceTests.cs index 5e12a1aee..2521d17af 100644 --- a/API.Tests/Services/ArchiveServiceTests.cs +++ b/API.Tests/Services/ArchiveServiceTests.cs @@ -198,7 +198,7 @@ namespace API.Tests.Services var imageService = new ImageService(Substitute.For>(), _directoryService); var archiveService = Substitute.For(_logger, new DirectoryService(_directoryServiceLogger, new FileSystem()), imageService); - var testDirectory = API.Parser.Parser.NormalizePath(Path.GetFullPath(Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/CoverImages"))); + var testDirectory = API.Services.Tasks.Scanner.Parser.Parser.NormalizePath(Path.GetFullPath(Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/CoverImages"))); var outputDir = Path.Join(testDirectory, "output"); _directoryService.ClearDirectory(outputDir); diff --git a/API.Tests/Services/BackupServiceTests.cs b/API.Tests/Services/BackupServiceTests.cs index 4ad416dc6..ad7f8b9f9 100644 --- a/API.Tests/Services/BackupServiceTests.cs +++ b/API.Tests/Services/BackupServiceTests.cs @@ -147,7 +147,7 @@ public class BackupServiceTests var backupLogFiles = backupService.GetLogFiles(0, LogDirectory).ToList(); Assert.Single(backupLogFiles); - Assert.Equal(API.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log"), API.Parser.Parser.NormalizePath(backupLogFiles.First())); + Assert.Equal(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log"), API.Services.Tasks.Scanner.Parser.Parser.NormalizePath(backupLogFiles.First())); } [Fact] @@ -168,8 +168,8 @@ public class BackupServiceTests var backupService = new BackupService(_logger, _unitOfWork, ds, configuration, _messageHub); - var backupLogFiles = backupService.GetLogFiles(1, LogDirectory).Select(API.Parser.Parser.NormalizePath).ToList(); - Assert.NotEmpty(backupLogFiles.Where(file => file.Equals(API.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log")) || file.Equals(API.Parser.Parser.NormalizePath($"{LogDirectory}kavita1.log")))); + var backupLogFiles = backupService.GetLogFiles(1, LogDirectory).Select(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath).ToList(); + Assert.NotEmpty(backupLogFiles.Where(file => file.Equals(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log")) || file.Equals(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita1.log")))); } diff --git a/API.Tests/Services/BookmarkServiceTests.cs b/API.Tests/Services/BookmarkServiceTests.cs index e878e5eb5..88f0fc587 100644 --- a/API.Tests/Services/BookmarkServiceTests.cs +++ b/API.Tests/Services/BookmarkServiceTests.cs @@ -401,7 +401,7 @@ public class BookmarkServiceTests var files = await bookmarkService.GetBookmarkFilesById(new[] {1}); var actualFiles = ds.GetFiles(BookmarkDirectory, searchOption: SearchOption.AllDirectories); - Assert.Equal(files.Select(API.Parser.Parser.NormalizePath).ToList(), actualFiles.Select(API.Parser.Parser.NormalizePath).ToList()); + Assert.Equal(files.Select(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath).ToList(), actualFiles.Select(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath).ToList()); } diff --git a/API.Tests/Services/CleanupServiceTests.cs b/API.Tests/Services/CleanupServiceTests.cs index a7575577c..a0934a5ca 100644 --- a/API.Tests/Services/CleanupServiceTests.cs +++ b/API.Tests/Services/CleanupServiceTests.cs @@ -312,13 +312,13 @@ public class CleanupServiceTests new ReadingList() { Title = "Something", - NormalizedTitle = API.Parser.Parser.Normalize("Something"), + NormalizedTitle = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something"), CoverImage = $"{ImageService.GetReadingListFormat(1)}.jpg" }, new ReadingList() { Title = "Something 2", - NormalizedTitle = API.Parser.Parser.Normalize("Something 2"), + NormalizedTitle = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Something 2"), CoverImage = $"{ImageService.GetReadingListFormat(2)}.jpg" } } diff --git a/API.Tests/Services/DirectoryServiceTests.cs b/API.Tests/Services/DirectoryServiceTests.cs index 0bbd5728b..b6ebf6722 100644 --- a/API.Tests/Services/DirectoryServiceTests.cs +++ b/API.Tests/Services/DirectoryServiceTests.cs @@ -34,7 +34,7 @@ namespace API.Tests.Services var ds = new DirectoryService(Substitute.For>(), fileSystem); var files = new List(); var fileCount = ds.TraverseTreeParallelForEach(testDirectory, s => files.Add(s), - API.Parser.Parser.ArchiveFileExtensions, _logger); + API.Services.Tasks.Scanner.Parser.Parser.ArchiveFileExtensions, _logger); Assert.Equal(28, fileCount); Assert.Equal(28, files.Count); @@ -59,7 +59,7 @@ namespace API.Tests.Services try { var fileCount = ds.TraverseTreeParallelForEach("/manga/", s => files.Add(s), - API.Parser.Parser.ImageFileExtensions, _logger); + API.Services.Tasks.Scanner.Parser.Parser.ImageFileExtensions, _logger); Assert.Equal(1, fileCount); } catch (Exception ex) @@ -90,7 +90,7 @@ namespace API.Tests.Services var ds = new DirectoryService(Substitute.For>(), fileSystem); var files = new List(); var fileCount = ds.TraverseTreeParallelForEach(testDirectory, s => files.Add(s), - API.Parser.Parser.ArchiveFileExtensions, _logger); + API.Services.Tasks.Scanner.Parser.Parser.ArchiveFileExtensions, _logger); Assert.Equal(28, fileCount); Assert.Equal(28, files.Count); @@ -111,7 +111,7 @@ namespace API.Tests.Services fileSystem.AddFile($"{testDirectory}file_{29}.jpg", new MockFileData("")); var ds = new DirectoryService(Substitute.For>(), fileSystem); - var files = ds.GetFilesWithExtension(testDirectory, API.Parser.Parser.ArchiveFileExtensions); + var files = ds.GetFilesWithExtension(testDirectory, API.Services.Tasks.Scanner.Parser.Parser.ArchiveFileExtensions); Assert.Equal(10, files.Length); Assert.All(files, s => fileSystem.Path.GetExtension(s).Equals(".zip")); @@ -150,7 +150,7 @@ namespace API.Tests.Services fileSystem.AddFile($"{testDirectory}file_{29}.jpg", new MockFileData("")); var ds = new DirectoryService(Substitute.For>(), fileSystem); - var files = ds.GetFiles(testDirectory, API.Parser.Parser.ArchiveFileExtensions).ToList(); + var files = ds.GetFiles(testDirectory, API.Services.Tasks.Scanner.Parser.Parser.ArchiveFileExtensions).ToList(); Assert.Equal(10, files.Count()); Assert.All(files, s => fileSystem.Path.GetExtension(s).Equals(".zip")); @@ -586,12 +586,12 @@ namespace API.Tests.Services var ds = new DirectoryService(Substitute.For>(), fileSystem); ds.CopyFilesToDirectory(new []{MockUnixSupport.Path($"{testDirectory}file.zip")}, "/manga/output/"); ds.CopyFilesToDirectory(new []{MockUnixSupport.Path($"{testDirectory}file.zip")}, "/manga/output/"); - var outputFiles = ds.GetFiles("/manga/output/").Select(API.Parser.Parser.NormalizePath).ToList(); + var outputFiles = ds.GetFiles("/manga/output/").Select(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath).ToList(); Assert.Equal(4, outputFiles.Count()); // we have 2 already there and 2 copies // For some reason, this has C:/ on directory even though everything is emulated (System.IO.Abstractions issue, not changing) // https://github.com/TestableIO/System.IO.Abstractions/issues/831 - Assert.True(outputFiles.Contains(API.Parser.Parser.NormalizePath("/manga/output/file (3).zip")) - || outputFiles.Contains(API.Parser.Parser.NormalizePath("C:/manga/output/file (3).zip"))); + Assert.True(outputFiles.Contains(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath("/manga/output/file (3).zip")) + || outputFiles.Contains(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath("C:/manga/output/file (3).zip"))); } #endregion diff --git a/API.Tests/Services/ParseScannedFilesTests.cs b/API.Tests/Services/ParseScannedFilesTests.cs index b63205b7a..c019b9643 100644 --- a/API.Tests/Services/ParseScannedFilesTests.cs +++ b/API.Tests/Services/ParseScannedFilesTests.cs @@ -253,7 +253,7 @@ public class ParseScannedFilesTests var foundParsedSeries = new ParsedSeries() { Name = parsedFiles.First().Series, - NormalizedName = API.Parser.Parser.Normalize(parsedFiles.First().Series), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(parsedFiles.First().Series), Format = parsedFiles.First().Format }; diff --git a/API.Tests/Services/ScannerServiceTests.cs b/API.Tests/Services/ScannerServiceTests.cs index 5b806e96b..f54f2d3e9 100644 --- a/API.Tests/Services/ScannerServiceTests.cs +++ b/API.Tests/Services/ScannerServiceTests.cs @@ -36,7 +36,7 @@ namespace API.Tests.Services Name = "1" } }, - NormalizedName = API.Parser.Parser.Normalize("Darker Than Black"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker Than Black"), Metadata = new SeriesMetadata(), Format = MangaFormat.Epub } @@ -61,7 +61,7 @@ namespace API.Tests.Services Name = "Cage of Eden", LocalizedName = "Cage of Eden", OriginalName = "Cage of Eden", - NormalizedName = API.Parser.Parser.Normalize("Cage of Eden"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Cage of Eden"), Metadata = new SeriesMetadata(), Format = MangaFormat.Archive }, @@ -70,7 +70,7 @@ namespace API.Tests.Services Name = "Darker Than Black", LocalizedName = "Darker Than Black", OriginalName = "Darker Than Black", - NormalizedName = API.Parser.Parser.Normalize("Darker Than Black"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Darker Than Black"), Metadata = new SeriesMetadata(), Format = MangaFormat.Archive } diff --git a/API.Tests/Services/SiteThemeServiceTests.cs b/API.Tests/Services/SiteThemeServiceTests.cs index ea43c6644..2ab523e59 100644 --- a/API.Tests/Services/SiteThemeServiceTests.cs +++ b/API.Tests/Services/SiteThemeServiceTests.cs @@ -157,7 +157,7 @@ public class SiteThemeServiceTests await siteThemeService.Scan(); var customThemes = (await _unitOfWork.SiteThemeRepository.GetThemeDtos()).Where(t => - API.Parser.Parser.Normalize(t.Name).Equals(API.Parser.Parser.Normalize("custom"))); + API.Services.Tasks.Scanner.Parser.Parser.Normalize(t.Name).Equals(API.Services.Tasks.Scanner.Parser.Parser.Normalize("custom"))); Assert.Single(customThemes); } @@ -177,7 +177,7 @@ public class SiteThemeServiceTests await siteThemeService.Scan(); var customThemes = (await _unitOfWork.SiteThemeRepository.GetThemeDtos()).Where(t => - API.Parser.Parser.Normalize(t.Name).Equals(API.Parser.Parser.Normalize("custom"))); + API.Services.Tasks.Scanner.Parser.Parser.Normalize(t.Name).Equals(API.Services.Tasks.Scanner.Parser.Parser.Normalize("custom"))); Assert.Empty(customThemes); } @@ -194,7 +194,7 @@ public class SiteThemeServiceTests _context.SiteTheme.Add(new SiteTheme() { Name = "Custom", - NormalizedName = API.Parser.Parser.Normalize("Custom"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Custom"), Provider = ThemeProvider.User, FileName = "custom.css", IsDefault = false @@ -219,7 +219,7 @@ public class SiteThemeServiceTests _context.SiteTheme.Add(new SiteTheme() { Name = "Custom", - NormalizedName = API.Parser.Parser.Normalize("Custom"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Custom"), Provider = ThemeProvider.User, FileName = "custom.css", IsDefault = false @@ -247,7 +247,7 @@ public class SiteThemeServiceTests _context.SiteTheme.Add(new SiteTheme() { Name = "Custom", - NormalizedName = API.Parser.Parser.Normalize("Custom"), + NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize("Custom"), Provider = ThemeProvider.User, FileName = "custom.css", IsDefault = false diff --git a/API/Controllers/AccountController.cs b/API/Controllers/AccountController.cs index bae44b208..abe81d1b2 100644 --- a/API/Controllers/AccountController.cs +++ b/API/Controllers/AccountController.cs @@ -472,12 +472,27 @@ namespace API.Controllers } var token = await _userManager.GenerateEmailConfirmationTokenAsync(user); - if (string.IsNullOrEmpty(token)) return BadRequest("There was an issue sending email"); + if (string.IsNullOrEmpty(token)) + { + _logger.LogError("There was an issue generating a token for the email"); + return BadRequest("There was an creating the invite user"); + } + user.ConfirmationToken = token; + await _unitOfWork.CommitAsync(); + } + catch (Exception ex) + { + _logger.LogError(ex, "There was an error during invite user flow, unable to create user. Deleting user for retry"); + _unitOfWork.UserRepository.Delete(user); + await _unitOfWork.CommitAsync(); + } - var emailLink = GenerateEmailLink(token, "confirm-email", dto.Email); + try + { + var emailLink = GenerateEmailLink(user.ConfirmationToken, "confirm-email", dto.Email); _logger.LogCritical("[Invite User]: Email Link for {UserName}: {Link}", user.UserName, emailLink); - _logger.LogCritical("[Invite User]: Token {UserName}: {Token}", user.UserName, token); + _logger.LogCritical("[Invite User]: Token {UserName}: {Token}", user.UserName, user.ConfirmationToken); var host = _environment.IsDevelopment() ? "localhost:4200" : Request.Host.ToString(); var accessible = await _emailService.CheckIfAccessible(host); if (accessible) @@ -490,23 +505,22 @@ namespace API.Controllers InvitingUser = adminUser.UserName, ServerConfirmationLink = emailLink }); - } catch(Exception) {/* Swallow exception */} + } + catch (Exception) + { + /* Swallow exception */ + } } - user.ConfirmationToken = token; - - await _unitOfWork.CommitAsync(); - return Ok(new InviteUserResponse { EmailLink = emailLink, EmailSent = accessible }); } - catch (Exception) + catch (Exception ex) { - _unitOfWork.UserRepository.Delete(user); - await _unitOfWork.CommitAsync(); + _logger.LogError(ex, "There was an error during invite user flow, unable to send an email"); } return BadRequest("There was an error setting up your account. Please check the logs"); diff --git a/API/Controllers/CollectionController.cs b/API/Controllers/CollectionController.cs index 0b2f2bcd6..f030bd166 100644 --- a/API/Controllers/CollectionController.cs +++ b/API/Controllers/CollectionController.cs @@ -76,7 +76,7 @@ namespace API.Controllers existingTag.Promoted = updatedTag.Promoted; existingTag.Title = updatedTag.Title.Trim(); - existingTag.NormalizedTitle = Parser.Parser.Normalize(updatedTag.Title).ToUpper(); + existingTag.NormalizedTitle = Services.Tasks.Scanner.Parser.Parser.Normalize(updatedTag.Title).ToUpper(); existingTag.Summary = updatedTag.Summary.Trim(); if (_unitOfWork.HasChanges()) diff --git a/API/Controllers/LibraryController.cs b/API/Controllers/LibraryController.cs index 22f8cf90c..3a387d83e 100644 --- a/API/Controllers/LibraryController.cs +++ b/API/Controllers/LibraryController.cs @@ -218,12 +218,12 @@ namespace API.Controllers if (!isAdmin) return BadRequest("API key must belong to an admin"); if (dto.FolderPath.Contains("..")) return BadRequest("Invalid Path"); - dto.FolderPath = Parser.Parser.NormalizePath(dto.FolderPath); + dto.FolderPath = Services.Tasks.Scanner.Parser.Parser.NormalizePath(dto.FolderPath); var libraryFolder = (await _unitOfWork.LibraryRepository.GetLibraryDtosAsync()) .SelectMany(l => l.Folders) .Distinct() - .Select(Parser.Parser.NormalizePath); + .Select(Services.Tasks.Scanner.Parser.Parser.NormalizePath); var seriesFolder = _directoryService.FindHighestDirectoriesFromFiles(libraryFolder, new List() {dto.FolderPath}); diff --git a/API/Controllers/ReaderController.cs b/API/Controllers/ReaderController.cs index c9393ac9a..5569fb9f8 100644 --- a/API/Controllers/ReaderController.cs +++ b/API/Controllers/ReaderController.cs @@ -179,17 +179,17 @@ namespace API.Controllers info.Title += " - " + info.ChapterTitle; } - if (info.IsSpecial && dto.VolumeNumber.Equals(Parser.Parser.DefaultVolume)) + if (info.IsSpecial && dto.VolumeNumber.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultVolume)) { info.Subtitle = info.FileName; - } else if (!info.IsSpecial && info.VolumeNumber.Equals(Parser.Parser.DefaultVolume)) + } else if (!info.IsSpecial && info.VolumeNumber.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultVolume)) { info.Subtitle = _readerService.FormatChapterName(info.LibraryType, true, true) + info.ChapterNumber; } else { info.Subtitle = "Volume " + info.VolumeNumber; - if (!info.ChapterNumber.Equals(Parser.Parser.DefaultChapter)) + if (!info.ChapterNumber.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultChapter)) { info.Subtitle += " " + _readerService.FormatChapterName(info.LibraryType, true, true) + info.ChapterNumber; diff --git a/API/Controllers/ReadingListController.cs b/API/Controllers/ReadingListController.cs index f07f17724..5f2b61ff0 100644 --- a/API/Controllers/ReadingListController.cs +++ b/API/Controllers/ReadingListController.cs @@ -219,7 +219,7 @@ namespace API.Controllers if (!string.IsNullOrEmpty(dto.Title)) { readingList.Title = dto.Title; // Should I check if this is unique? - readingList.NormalizedTitle = Parser.Parser.Normalize(readingList.Title); + readingList.NormalizedTitle = Services.Tasks.Scanner.Parser.Parser.Normalize(readingList.Title); } if (!string.IsNullOrEmpty(dto.Title)) { diff --git a/API/Controllers/SeriesController.cs b/API/Controllers/SeriesController.cs index c931694e0..6f458b6b8 100644 --- a/API/Controllers/SeriesController.cs +++ b/API/Controllers/SeriesController.cs @@ -156,14 +156,14 @@ namespace API.Controllers } series.Name = updateSeries.Name.Trim(); - series.NormalizedName = Parser.Parser.Normalize(series.Name); + series.NormalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(series.Name); if (!string.IsNullOrEmpty(updateSeries.SortName.Trim())) { series.SortName = updateSeries.SortName.Trim(); } series.LocalizedName = updateSeries.LocalizedName.Trim(); - series.NormalizedLocalizedName = Parser.Parser.Normalize(series.LocalizedName); + series.NormalizedLocalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(series.LocalizedName); series.NameLocked = updateSeries.NameLocked; series.SortNameLocked = updateSeries.SortNameLocked; diff --git a/API/Data/DbFactory.cs b/API/Data/DbFactory.cs index 58cd834ef..921b55c54 100644 --- a/API/Data/DbFactory.cs +++ b/API/Data/DbFactory.cs @@ -23,8 +23,8 @@ namespace API.Data Name = name, OriginalName = name, LocalizedName = name, - NormalizedName = Parser.Parser.Normalize(name), - NormalizedLocalizedName = Parser.Parser.Normalize(name), + NormalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name), + NormalizedLocalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name), SortName = name, Volumes = new List(), Metadata = SeriesMetadata(Array.Empty()) @@ -42,8 +42,8 @@ namespace API.Data Name = name, OriginalName = name, LocalizedName = localizedName, - NormalizedName = Parser.Parser.Normalize(name), - NormalizedLocalizedName = Parser.Parser.Normalize(localizedName), + NormalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name), + NormalizedLocalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(localizedName), SortName = name, Volumes = new List(), Metadata = SeriesMetadata(Array.Empty()) @@ -55,7 +55,7 @@ namespace API.Data return new Volume() { Name = volumeNumber, - Number = (int) Parser.Parser.MinNumberFromRange(volumeNumber), + Number = (int) Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(volumeNumber), Chapters = new List() }; } @@ -66,7 +66,7 @@ namespace API.Data var specialTitle = specialTreatment ? info.Filename : info.Chapters; return new Chapter() { - Number = specialTreatment ? "0" : Parser.Parser.MinNumberFromRange(info.Chapters) + string.Empty, + Number = specialTreatment ? "0" : Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(info.Chapters) + string.Empty, Range = specialTreatment ? info.Filename : info.Chapters, Title = (specialTreatment && info.Format == MangaFormat.Epub) ? info.Title @@ -95,7 +95,7 @@ namespace API.Data return new CollectionTag() { Id = id, - NormalizedTitle = API.Parser.Parser.Normalize(title?.Trim()).ToUpper(), + NormalizedTitle = Services.Tasks.Scanner.Parser.Parser.Normalize(title?.Trim()).ToUpper(), Title = title?.Trim(), Summary = summary?.Trim(), Promoted = promoted @@ -106,7 +106,7 @@ namespace API.Data { return new ReadingList() { - NormalizedTitle = API.Parser.Parser.Normalize(title?.Trim()).ToUpper(), + NormalizedTitle = Services.Tasks.Scanner.Parser.Parser.Normalize(title?.Trim()).ToUpper(), Title = title?.Trim(), Summary = summary?.Trim(), Promoted = promoted, @@ -130,7 +130,7 @@ namespace API.Data return new Genre() { Title = name.Trim().SentenceCase(), - NormalizedTitle = Parser.Parser.Normalize(name), + NormalizedTitle = Services.Tasks.Scanner.Parser.Parser.Normalize(name), ExternalTag = external }; } @@ -140,7 +140,7 @@ namespace API.Data return new Tag() { Title = name.Trim().SentenceCase(), - NormalizedTitle = Parser.Parser.Normalize(name), + NormalizedTitle = Services.Tasks.Scanner.Parser.Parser.Normalize(name), ExternalTag = external }; } @@ -150,7 +150,7 @@ namespace API.Data return new Person() { Name = name.Trim(), - NormalizedName = Parser.Parser.Normalize(name), + NormalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name), Role = role }; } diff --git a/API/Data/Metadata/ComicInfo.cs b/API/Data/Metadata/ComicInfo.cs index 167638a01..d34901daa 100644 --- a/API/Data/Metadata/ComicInfo.cs +++ b/API/Data/Metadata/ComicInfo.cs @@ -107,16 +107,16 @@ namespace API.Data.Metadata info.SeriesSort = info.SeriesSort.Trim(); info.LocalizedSeries = info.LocalizedSeries.Trim(); - info.Writer = Parser.Parser.CleanAuthor(info.Writer); - info.Colorist = Parser.Parser.CleanAuthor(info.Colorist); - info.Editor = Parser.Parser.CleanAuthor(info.Editor); - info.Inker = Parser.Parser.CleanAuthor(info.Inker); - info.Letterer = Parser.Parser.CleanAuthor(info.Letterer); - info.Penciller = Parser.Parser.CleanAuthor(info.Penciller); - info.Publisher = Parser.Parser.CleanAuthor(info.Publisher); - info.Characters = Parser.Parser.CleanAuthor(info.Characters); - info.Translator = Parser.Parser.CleanAuthor(info.Translator); - info.CoverArtist = Parser.Parser.CleanAuthor(info.CoverArtist); + info.Writer = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Writer); + info.Colorist = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Colorist); + info.Editor = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Editor); + info.Inker = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Inker); + info.Letterer = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Letterer); + info.Penciller = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Penciller); + info.Publisher = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Publisher); + info.Characters = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Characters); + info.Translator = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.Translator); + info.CoverArtist = Services.Tasks.Scanner.Parser.Parser.CleanAuthor(info.CoverArtist); } diff --git a/API/Data/MigrateBookmarks.cs b/API/Data/MigrateBookmarks.cs index 6649e83e7..a659afd17 100644 --- a/API/Data/MigrateBookmarks.cs +++ b/API/Data/MigrateBookmarks.cs @@ -72,7 +72,7 @@ public static class MigrateBookmarks continue; } - var files = directoryService.GetFilesWithExtension(chapterExtractPath, Parser.Parser.ImageFileExtensions); + var files = directoryService.GetFilesWithExtension(chapterExtractPath, Services.Tasks.Scanner.Parser.Parser.ImageFileExtensions); // Filter out images that aren't in bookmarks Array.Sort(files, numericComparer); foreach (var chapterPage in chapterPages) diff --git a/API/Data/MigrateNormalizedLocalizedName.cs b/API/Data/MigrateNormalizedLocalizedName.cs index 3e70094df..37ea705e3 100644 --- a/API/Data/MigrateNormalizedLocalizedName.cs +++ b/API/Data/MigrateNormalizedLocalizedName.cs @@ -21,7 +21,7 @@ public static class MigrateNormalizedLocalizedName foreach (var series in await dataContext.Series.ToListAsync()) { - series.NormalizedLocalizedName = Parser.Parser.Normalize(series.LocalizedName ?? string.Empty); + series.NormalizedLocalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(series.LocalizedName ?? string.Empty); logger.LogInformation("Updated {SeriesName} normalized localized name: {LocalizedName}", series.Name, series.NormalizedLocalizedName); unitOfWork.SeriesRepository.Update(series); } diff --git a/API/Data/Repositories/GenreRepository.cs b/API/Data/Repositories/GenreRepository.cs index c5b151ac7..7457adb24 100644 --- a/API/Data/Repositories/GenreRepository.cs +++ b/API/Data/Repositories/GenreRepository.cs @@ -44,7 +44,7 @@ public class GenreRepository : IGenreRepository public async Task FindByNameAsync(string genreName) { - var normalizedName = Parser.Parser.Normalize(genreName); + var normalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(genreName); return await _context.Genre .FirstOrDefaultAsync(g => g.NormalizedTitle.Equals(normalizedName)); } diff --git a/API/Data/Repositories/LibraryRepository.cs b/API/Data/Repositories/LibraryRepository.cs index b39a74e35..b967cece8 100644 --- a/API/Data/Repositories/LibraryRepository.cs +++ b/API/Data/Repositories/LibraryRepository.cs @@ -334,13 +334,13 @@ public class LibraryRepository : ILibraryRepository /// public async Task DoAnySeriesFoldersMatch(IEnumerable folders) { - var normalized = folders.Select(Parser.Parser.NormalizePath); + var normalized = folders.Select(Services.Tasks.Scanner.Parser.Parser.NormalizePath); return await _context.Series.AnyAsync(s => normalized.Contains(s.FolderPath)); } public Library? GetLibraryByFolder(string folder) { - var normalized = Parser.Parser.NormalizePath(folder); + var normalized = Services.Tasks.Scanner.Parser.Parser.NormalizePath(folder); return _context.Library .Include(l => l.Folders) .AsSplitQuery() diff --git a/API/Data/Repositories/PersonRepository.cs b/API/Data/Repositories/PersonRepository.cs index ff59fe596..83aa18f62 100644 --- a/API/Data/Repositories/PersonRepository.cs +++ b/API/Data/Repositories/PersonRepository.cs @@ -42,7 +42,7 @@ public class PersonRepository : IPersonRepository public async Task FindByNameAsync(string name) { - var normalizedName = Parser.Parser.Normalize(name); + var normalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name); return await _context.Person .Where(p => normalizedName.Equals(p.NormalizedName)) .SingleOrDefaultAsync(); diff --git a/API/Data/Repositories/SeriesRepository.cs b/API/Data/Repositories/SeriesRepository.cs index b3bf0f2a9..b5178a8af 100644 --- a/API/Data/Repositories/SeriesRepository.cs +++ b/API/Data/Repositories/SeriesRepository.cs @@ -301,7 +301,7 @@ public class SeriesRepository : ISeriesRepository { const int maxRecords = 15; var result = new SearchResultGroupDto(); - var searchQueryNormalized = Parser.Parser.Normalize(searchQuery); + var searchQueryNormalized = Services.Tasks.Scanner.Parser.Parser.Normalize(searchQuery); var seriesIds = _context.Series .Where(s => libraryIds.Contains(s.LibraryId)) @@ -1151,7 +1151,7 @@ public class SeriesRepository : ISeriesRepository /// public async Task GetSeriesIdByFolder(string folder) { - var normalized = Parser.Parser.NormalizePath(folder); + var normalized = Services.Tasks.Scanner.Parser.Parser.NormalizePath(folder); var series = await _context.Series .Where(s => s.FolderPath.Equals(normalized)) .SingleOrDefaultAsync(); @@ -1165,7 +1165,7 @@ public class SeriesRepository : ISeriesRepository /// public async Task GetSeriesByFolderPath(string folder) { - var normalized = Parser.Parser.NormalizePath(folder); + var normalized = Services.Tasks.Scanner.Parser.Parser.NormalizePath(folder); return await _context.Series.SingleOrDefaultAsync(s => s.FolderPath.Equals(normalized)); } @@ -1178,7 +1178,7 @@ public class SeriesRepository : ISeriesRepository /// public Task GetFullSeriesByName(string series, int libraryId) { - var localizedSeries = Parser.Parser.Normalize(series); + var localizedSeries = Services.Tasks.Scanner.Parser.Parser.Normalize(series); return _context.Series .Where(s => (s.NormalizedName.Equals(localizedSeries) || s.LocalizedName.Equals(series)) && s.LibraryId == libraryId) @@ -1221,8 +1221,8 @@ public class SeriesRepository : ISeriesRepository /// public Task GetFullSeriesByAnyName(string seriesName, string localizedName, int libraryId, MangaFormat format, bool withFullIncludes = true) { - var normalizedSeries = Parser.Parser.Normalize(seriesName); - var normalizedLocalized = Parser.Parser.Normalize(localizedName); + var normalizedSeries = Services.Tasks.Scanner.Parser.Parser.Normalize(seriesName); + var normalizedLocalized = Services.Tasks.Scanner.Parser.Parser.Normalize(localizedName); var query = _context.Series .Where(s => s.LibraryId == libraryId) .Where(s => s.Format == format && format != MangaFormat.Unknown) diff --git a/API/Data/Repositories/TagRepository.cs b/API/Data/Repositories/TagRepository.cs index 8ddb52d67..8faf0440b 100644 --- a/API/Data/Repositories/TagRepository.cs +++ b/API/Data/Repositories/TagRepository.cs @@ -43,7 +43,7 @@ public class TagRepository : ITagRepository public async Task FindByNameAsync(string tagName) { - var normalizedName = Parser.Parser.Normalize(tagName); + var normalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(tagName); return await _context.Tag .FirstOrDefaultAsync(g => g.NormalizedTitle.Equals(normalizedName)); } diff --git a/API/Data/Seed.cs b/API/Data/Seed.cs index fb1256362..97e141eab 100644 --- a/API/Data/Seed.cs +++ b/API/Data/Seed.cs @@ -29,7 +29,7 @@ namespace API.Data new() { Name = "Dark", - NormalizedName = Parser.Parser.Normalize("Dark"), + NormalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize("Dark"), Provider = ThemeProvider.System, FileName = "dark.scss", IsDefault = true, diff --git a/API/Entities/Enums/MangaFormat.cs b/API/Entities/Enums/MangaFormat.cs index 45497df4b..07e34ed77 100644 --- a/API/Entities/Enums/MangaFormat.cs +++ b/API/Entities/Enums/MangaFormat.cs @@ -9,13 +9,13 @@ namespace API.Entities.Enums { /// /// Image file - /// See for supported extensions + /// See for supported extensions /// [Description("Image")] Image = 0, /// /// Archive based file - /// See for supported extensions + /// See for supported extensions /// [Description("Archive")] Archive = 1, diff --git a/API/Entities/Series.cs b/API/Entities/Series.cs index b343240c0..7fa02f67b 100644 --- a/API/Entities/Series.cs +++ b/API/Entities/Series.cs @@ -14,11 +14,11 @@ public class Series : IEntityDate, IHasReadTimeEstimate /// public string Name { get; set; } /// - /// Used internally for name matching. + /// Used internally for name matching. /// public string NormalizedName { get; set; } /// - /// Used internally for localized name matching. + /// Used internally for localized name matching. /// public string NormalizedLocalizedName { get; set; } /// @@ -57,7 +57,7 @@ public class Series : IEntityDate, IHasReadTimeEstimate /// /// Highest path (that is under library root) that contains the series. /// - /// must be used before setting + /// must be used before setting public string FolderPath { get; set; } /// /// Last time the folder was scanned diff --git a/API/Extensions/SeriesExtensions.cs b/API/Extensions/SeriesExtensions.cs index cd3254e34..acd828480 100644 --- a/API/Extensions/SeriesExtensions.cs +++ b/API/Extensions/SeriesExtensions.cs @@ -16,8 +16,8 @@ namespace API.Extensions /// public static bool NameInList(this Series series, IEnumerable list) { - return list.Any(name => Parser.Parser.Normalize(name) == series.NormalizedName || Parser.Parser.Normalize(name) == Parser.Parser.Normalize(series.Name) - || name == series.Name || name == series.LocalizedName || name == series.OriginalName || Parser.Parser.Normalize(name) == Parser.Parser.Normalize(series.OriginalName)); + return list.Any(name => Services.Tasks.Scanner.Parser.Parser.Normalize(name) == series.NormalizedName || Services.Tasks.Scanner.Parser.Parser.Normalize(name) == Services.Tasks.Scanner.Parser.Parser.Normalize(series.Name) + || name == series.Name || name == series.LocalizedName || name == series.OriginalName || Services.Tasks.Scanner.Parser.Parser.Normalize(name) == Services.Tasks.Scanner.Parser.Parser.Normalize(series.OriginalName)); } /// @@ -28,8 +28,8 @@ namespace API.Extensions /// public static bool NameInList(this Series series, IEnumerable list) { - return list.Any(name => Parser.Parser.Normalize(name.Name) == series.NormalizedName || Parser.Parser.Normalize(name.Name) == Parser.Parser.Normalize(series.Name) - || name.Name == series.Name || name.Name == series.LocalizedName || name.Name == series.OriginalName || Parser.Parser.Normalize(name.Name) == Parser.Parser.Normalize(series.OriginalName) && series.Format == name.Format); + return list.Any(name => Services.Tasks.Scanner.Parser.Parser.Normalize(name.Name) == series.NormalizedName || Services.Tasks.Scanner.Parser.Parser.Normalize(name.Name) == Services.Tasks.Scanner.Parser.Parser.Normalize(series.Name) + || name.Name == series.Name || name.Name == series.LocalizedName || name.Name == series.OriginalName || Services.Tasks.Scanner.Parser.Parser.Normalize(name.Name) == Services.Tasks.Scanner.Parser.Parser.Normalize(series.OriginalName) && series.Format == name.Format); } /// @@ -41,9 +41,9 @@ namespace API.Extensions public static bool NameInParserInfo(this Series series, ParserInfo info) { if (info == null) return false; - return Parser.Parser.Normalize(info.Series) == series.NormalizedName || Parser.Parser.Normalize(info.Series) == Parser.Parser.Normalize(series.Name) - || info.Series == series.Name || info.Series == series.LocalizedName || info.Series == series.OriginalName - || Parser.Parser.Normalize(info.Series) == Parser.Parser.Normalize(series.OriginalName); + return Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series) == series.NormalizedName || Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series) == Services.Tasks.Scanner.Parser.Parser.Normalize(series.Name) + || info.Series == series.Name || info.Series == series.LocalizedName || info.Series == series.OriginalName + || Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series) == Services.Tasks.Scanner.Parser.Parser.Normalize(series.OriginalName); } } } diff --git a/API/Helpers/GenreHelper.cs b/API/Helpers/GenreHelper.cs index 6c74b3e4a..5eadea8fa 100644 --- a/API/Helpers/GenreHelper.cs +++ b/API/Helpers/GenreHelper.cs @@ -22,7 +22,7 @@ public static class GenreHelper { if (string.IsNullOrEmpty(name.Trim())) continue; - var normalizedName = Parser.Parser.Normalize(name); + var normalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name); var genre = allGenres.FirstOrDefault(p => p.NormalizedTitle.Equals(normalizedName) && p.ExternalTag == isExternal); if (genre == null) @@ -57,7 +57,7 @@ public static class GenreHelper public static void AddGenreIfNotExists(ICollection metadataGenres, Genre genre) { var existingGenre = metadataGenres.FirstOrDefault(p => - p.NormalizedTitle == Parser.Parser.Normalize(genre.Title)); + p.NormalizedTitle == Services.Tasks.Scanner.Parser.Parser.Normalize(genre.Title)); if (existingGenre == null) { metadataGenres.Add(genre); @@ -67,7 +67,7 @@ public static class GenreHelper public static void AddGenreIfNotExists(BlockingCollection metadataGenres, Genre genre) { var existingGenre = metadataGenres.FirstOrDefault(p => - p.NormalizedTitle == Parser.Parser.Normalize(genre.Title)); + p.NormalizedTitle == Services.Tasks.Scanner.Parser.Parser.Normalize(genre.Title)); if (existingGenre == null) { metadataGenres.Add(genre); diff --git a/API/Helpers/ParserInfoHelpers.cs b/API/Helpers/ParserInfoHelpers.cs index 920361800..c303fd2fb 100644 --- a/API/Helpers/ParserInfoHelpers.cs +++ b/API/Helpers/ParserInfoHelpers.cs @@ -22,14 +22,14 @@ public static class ParserInfoHelpers foreach (var pSeries in parsedSeries.Keys) { var name = pSeries.Name; - var normalizedName = Parser.Parser.Normalize(name); + var normalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name); //if (series.NameInParserInfo(pSeries.)) if (normalizedName == series.NormalizedName || - normalizedName == Parser.Parser.Normalize(series.Name) || + normalizedName == Services.Tasks.Scanner.Parser.Parser.Normalize(series.Name) || name == series.Name || name == series.LocalizedName || name == series.OriginalName || - normalizedName == Parser.Parser.Normalize(series.OriginalName)) + normalizedName == Services.Tasks.Scanner.Parser.Parser.Normalize(series.OriginalName)) { format = pSeries.Format; if (format == series.Format) diff --git a/API/Helpers/PersonHelper.cs b/API/Helpers/PersonHelper.cs index fd6ca7baa..adcdd4b08 100644 --- a/API/Helpers/PersonHelper.cs +++ b/API/Helpers/PersonHelper.cs @@ -26,7 +26,7 @@ public static class PersonHelper foreach (var name in names) { - var normalizedName = Parser.Parser.Normalize(name); + var normalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name); var person = allPeopleTypeRole.FirstOrDefault(p => p.NormalizedName.Equals(normalizedName)); if (person == null) @@ -49,7 +49,7 @@ public static class PersonHelper /// Callback which will be executed for each person removed public static void RemovePeople(ICollection existingPeople, IEnumerable people, PersonRole role, Action action = null) { - var normalizedPeople = people.Select(Parser.Parser.Normalize).ToList(); + var normalizedPeople = people.Select(Services.Tasks.Scanner.Parser.Parser.Normalize).ToList(); if (normalizedPeople.Count == 0) { var peopleToRemove = existingPeople.Where(p => p.Role == role).ToList(); @@ -99,7 +99,7 @@ public static class PersonHelper public static void AddPersonIfNotExists(ICollection metadataPeople, Person person) { var existingPerson = metadataPeople.SingleOrDefault(p => - p.NormalizedName == Parser.Parser.Normalize(person.Name) && p.Role == person.Role); + p.NormalizedName == Services.Tasks.Scanner.Parser.Parser.Normalize(person.Name) && p.Role == person.Role); if (existingPerson == null) { metadataPeople.Add(person); @@ -114,7 +114,7 @@ public static class PersonHelper public static void AddPersonIfNotExists(BlockingCollection metadataPeople, Person person) { var existingPerson = metadataPeople.SingleOrDefault(p => - p.NormalizedName == Parser.Parser.Normalize(person.Name) && p.Role == person.Role); + p.NormalizedName == Services.Tasks.Scanner.Parser.Parser.Normalize(person.Name) && p.Role == person.Role); if (existingPerson == null) { metadataPeople.Add(person); diff --git a/API/Helpers/SeriesHelper.cs b/API/Helpers/SeriesHelper.cs index f92039a24..b30969805 100644 --- a/API/Helpers/SeriesHelper.cs +++ b/API/Helpers/SeriesHelper.cs @@ -17,8 +17,8 @@ public static class SeriesHelper public static bool FindSeries(Series series, ParsedSeries parsedInfoKey) { return (series.NormalizedName.Equals(parsedInfoKey.NormalizedName) || - Parser.Parser.Normalize(series.LocalizedName).Equals(parsedInfoKey.NormalizedName) || - Parser.Parser.Normalize(series.OriginalName).Equals(parsedInfoKey.NormalizedName)) + Services.Tasks.Scanner.Parser.Parser.Normalize(series.LocalizedName).Equals(parsedInfoKey.NormalizedName) || + Services.Tasks.Scanner.Parser.Parser.Normalize(series.OriginalName).Equals(parsedInfoKey.NormalizedName)) && (series.Format == parsedInfoKey.Format || series.Format == MangaFormat.Unknown); } diff --git a/API/Helpers/TagHelper.cs b/API/Helpers/TagHelper.cs index b4d689f66..f7b1abfd4 100644 --- a/API/Helpers/TagHelper.cs +++ b/API/Helpers/TagHelper.cs @@ -23,7 +23,7 @@ public static class TagHelper if (string.IsNullOrEmpty(name.Trim())) continue; var added = false; - var normalizedName = Parser.Parser.Normalize(name); + var normalizedName = Services.Tasks.Scanner.Parser.Parser.Normalize(name); var genre = allTags.FirstOrDefault(p => p.NormalizedTitle.Equals(normalizedName) && p.ExternalTag == isExternal); @@ -59,7 +59,7 @@ public static class TagHelper public static void AddTagIfNotExists(ICollection metadataTags, Tag tag) { var existingGenre = metadataTags.FirstOrDefault(p => - p.NormalizedTitle == Parser.Parser.Normalize(tag.Title)); + p.NormalizedTitle == Services.Tasks.Scanner.Parser.Parser.Normalize(tag.Title)); if (existingGenre == null) { metadataTags.Add(tag); @@ -69,7 +69,7 @@ public static class TagHelper public static void AddTagIfNotExists(BlockingCollection metadataTags, Tag tag) { var existingGenre = metadataTags.FirstOrDefault(p => - p.NormalizedTitle == Parser.Parser.Normalize(tag.Title)); + p.NormalizedTitle == Services.Tasks.Scanner.Parser.Parser.Normalize(tag.Title)); if (existingGenre == null) { metadataTags.Add(tag); @@ -86,7 +86,7 @@ public static class TagHelper /// Callback which will be executed for each tag removed public static void RemoveTags(ICollection existingTags, IEnumerable tags, bool isExternal, Action action = null) { - var normalizedTags = tags.Select(Parser.Parser.Normalize).ToList(); + var normalizedTags = tags.Select(Services.Tasks.Scanner.Parser.Parser.Normalize).ToList(); foreach (var person in normalizedTags) { var existingTag = existingTags.FirstOrDefault(p => p.ExternalTag == isExternal && person.Equals(p.NormalizedTitle)); diff --git a/API/Services/ArchiveService.cs b/API/Services/ArchiveService.cs index 25ff8365b..58a2b0aae 100644 --- a/API/Services/ArchiveService.cs +++ b/API/Services/ArchiveService.cs @@ -60,7 +60,7 @@ namespace API.Services /// public virtual ArchiveLibrary CanOpen(string archivePath) { - if (string.IsNullOrEmpty(archivePath) || !(File.Exists(archivePath) && Parser.Parser.IsArchive(archivePath) || Parser.Parser.IsEpub(archivePath))) return ArchiveLibrary.NotSupported; + if (string.IsNullOrEmpty(archivePath) || !(File.Exists(archivePath) && Tasks.Scanner.Parser.Parser.IsArchive(archivePath) || Tasks.Scanner.Parser.Parser.IsEpub(archivePath))) return ArchiveLibrary.NotSupported; var ext = _directoryService.FileSystem.Path.GetExtension(archivePath).ToUpper(); if (ext.Equals(".CBR") || ext.Equals(".RAR")) return ArchiveLibrary.SharpCompress; @@ -100,14 +100,14 @@ namespace API.Services case ArchiveLibrary.Default: { using var archive = ZipFile.OpenRead(archivePath); - return archive.Entries.Count(e => !Parser.Parser.HasBlacklistedFolderInPath(e.FullName) && Parser.Parser.IsImage(e.FullName)); + return archive.Entries.Count(e => !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(e.FullName) && Tasks.Scanner.Parser.Parser.IsImage(e.FullName)); } case ArchiveLibrary.SharpCompress: { using var archive = ArchiveFactory.Open(archivePath); return archive.Entries.Count(entry => !entry.IsDirectory && - !Parser.Parser.HasBlacklistedFolderInPath(Path.GetDirectoryName(entry.Key) ?? string.Empty) - && Parser.Parser.IsImage(entry.Key)); + !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(Path.GetDirectoryName(entry.Key) ?? string.Empty) + && Tasks.Scanner.Parser.Parser.IsImage(entry.Key)); } case ArchiveLibrary.NotSupported: _logger.LogWarning("[GetNumberOfPagesFromArchive] This archive cannot be read: {ArchivePath}. Defaulting to 0 pages", archivePath); @@ -132,9 +132,9 @@ namespace API.Services public static string FindFolderEntry(IEnumerable entryFullNames) { var result = entryFullNames - .Where(path => !(Path.EndsInDirectorySeparator(path) || Parser.Parser.HasBlacklistedFolderInPath(path) || path.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith))) + .Where(path => !(Path.EndsInDirectorySeparator(path) || Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(path) || path.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith))) .OrderByNatural(Path.GetFileNameWithoutExtension) - .FirstOrDefault(Parser.Parser.IsCoverImage); + .FirstOrDefault(Tasks.Scanner.Parser.Parser.IsCoverImage); return string.IsNullOrEmpty(result) ? null : result; } @@ -150,7 +150,7 @@ namespace API.Services // First check if there are any files that are not in a nested folder before just comparing by filename. This is needed // because NaturalSortComparer does not work with paths and doesn't seem 001.jpg as before chapter 1/001.jpg. var fullNames = entryFullNames - .Where(path => !(Path.EndsInDirectorySeparator(path) || Parser.Parser.HasBlacklistedFolderInPath(path) || path.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith)) && Parser.Parser.IsImage(path)) + .Where(path => !(Path.EndsInDirectorySeparator(path) || Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(path) || path.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith)) && Tasks.Scanner.Parser.Parser.IsImage(path)) .OrderByNatural(c => c.GetFullPathWithoutExtension()) .ToList(); if (fullNames.Count == 0) return null; @@ -187,7 +187,7 @@ namespace API.Services /// /// Generates byte array of cover image. - /// Given a path to a compressed file , will ensure the first image (respects directory structure) is returned unless + /// Given a path to a compressed file , will ensure the first image (respects directory structure) is returned unless /// a folder/cover.(image extension) exists in the the compressed file (if duplicate, the first is chosen) /// /// This skips over any __MACOSX folder/file iteration. @@ -265,7 +265,7 @@ namespace API.Services // Sometimes ZipArchive will list the directory and others it will just keep it in the FullName return archive.Entries.Count > 0 && !Path.HasExtension(archive.Entries.ElementAt(0).FullName) || - archive.Entries.Any(e => e.FullName.Contains(Path.AltDirectorySeparatorChar) && !Parser.Parser.HasBlacklistedFolderInPath(e.FullName)); + archive.Entries.Any(e => e.FullName.Contains(Path.AltDirectorySeparatorChar) && !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(e.FullName)); } /// @@ -322,7 +322,7 @@ namespace API.Services return false; } - if (Parser.Parser.IsArchive(archivePath) || Parser.Parser.IsEpub(archivePath)) return true; + if (Tasks.Scanner.Parser.Parser.IsArchive(archivePath) || Tasks.Scanner.Parser.Parser.IsEpub(archivePath)) return true; _logger.LogWarning("Archive {ArchivePath} is not a valid archive", archivePath); return false; @@ -331,10 +331,10 @@ namespace API.Services private static bool ValidComicInfoArchiveEntry(string fullName, string name) { var filenameWithoutExtension = Path.GetFileNameWithoutExtension(name).ToLower(); - return !Parser.Parser.HasBlacklistedFolderInPath(fullName) + return !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(fullName) && filenameWithoutExtension.Equals(ComicInfoFilename, StringComparison.InvariantCultureIgnoreCase) - && !filenameWithoutExtension.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith) - && Parser.Parser.IsXml(name); + && !filenameWithoutExtension.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith) + && Tasks.Scanner.Parser.Parser.IsXml(name); } /// @@ -467,8 +467,8 @@ namespace API.Services { using var archive = ArchiveFactory.Open(archivePath); ExtractArchiveEntities(archive.Entries.Where(entry => !entry.IsDirectory - && !Parser.Parser.HasBlacklistedFolderInPath(Path.GetDirectoryName(entry.Key) ?? string.Empty) - && Parser.Parser.IsImage(entry.Key)), extractPath); + && !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(Path.GetDirectoryName(entry.Key) ?? string.Empty) + && Tasks.Scanner.Parser.Parser.IsImage(entry.Key)), extractPath); break; } case ArchiveLibrary.NotSupported: diff --git a/API/Services/BookService.cs b/API/Services/BookService.cs index 26c41edbb..d28183f9e 100644 --- a/API/Services/BookService.cs +++ b/API/Services/BookService.cs @@ -167,7 +167,7 @@ namespace API.Services // @Import statements will be handled by browser, so we must inline the css into the original file that request it, so they can be Scoped var prepend = filename.Length > 0 ? filename.Replace(Path.GetFileName(filename), string.Empty) : string.Empty; var importBuilder = new StringBuilder(); - foreach (Match match in Parser.Parser.CssImportUrlRegex.Matches(stylesheetHtml)) + foreach (Match match in Tasks.Scanner.Parser.Parser.CssImportUrlRegex.Matches(stylesheetHtml)) { if (!match.Success) continue; @@ -218,7 +218,7 @@ namespace API.Services private static void EscapeCssImportReferences(ref string stylesheetHtml, string apiBase, string prepend) { - foreach (Match match in Parser.Parser.CssImportUrlRegex.Matches(stylesheetHtml)) + foreach (Match match in Tasks.Scanner.Parser.Parser.CssImportUrlRegex.Matches(stylesheetHtml)) { if (!match.Success) continue; var importFile = match.Groups["Filename"].Value; @@ -228,7 +228,7 @@ namespace API.Services private static void EscapeFontFamilyReferences(ref string stylesheetHtml, string apiBase, string prepend) { - foreach (Match match in Parser.Parser.FontSrcUrlRegex.Matches(stylesheetHtml)) + foreach (Match match in Tasks.Scanner.Parser.Parser.FontSrcUrlRegex.Matches(stylesheetHtml)) { if (!match.Success) continue; var importFile = match.Groups["Filename"].Value; @@ -238,7 +238,7 @@ namespace API.Services private static void EscapeCssImageReferences(ref string stylesheetHtml, string apiBase, EpubBookRef book) { - var matches = Parser.Parser.CssImageUrlRegex.Matches(stylesheetHtml); + var matches = Tasks.Scanner.Parser.Parser.CssImageUrlRegex.Matches(stylesheetHtml); foreach (Match match in matches) { if (!match.Success) continue; @@ -394,7 +394,7 @@ namespace API.Services public ComicInfo GetComicInfo(string filePath) { - if (!IsValidFile(filePath) || Parser.Parser.IsPdf(filePath)) return null; + if (!IsValidFile(filePath) || Tasks.Scanner.Parser.Parser.IsPdf(filePath)) return null; try { @@ -425,7 +425,7 @@ namespace API.Services var info = new ComicInfo() { Summary = epubBook.Schema.Package.Metadata.Description, - Writer = string.Join(",", epubBook.Schema.Package.Metadata.Creators.Select(c => Parser.Parser.CleanAuthor(c.Creator))), + Writer = string.Join(",", epubBook.Schema.Package.Metadata.Creators.Select(c => Tasks.Scanner.Parser.Parser.CleanAuthor(c.Creator))), Publisher = string.Join(",", epubBook.Schema.Package.Metadata.Publishers), Month = month, Day = day, @@ -468,7 +468,7 @@ namespace API.Services return false; } - if (Parser.Parser.IsBook(filePath)) return true; + if (Tasks.Scanner.Parser.Parser.IsBook(filePath)) return true; _logger.LogWarning("[BookService] Book {EpubFile} is not a valid EPUB/PDF", filePath); return false; @@ -480,7 +480,7 @@ namespace API.Services try { - if (Parser.Parser.IsPdf(filePath)) + if (Tasks.Scanner.Parser.Parser.IsPdf(filePath)) { using var docReader = DocLib.Instance.GetDocReader(filePath, new PageDimensions(1080, 1920)); return docReader.GetPageCount(); @@ -536,7 +536,7 @@ namespace API.Services /// public ParserInfo ParseInfo(string filePath) { - if (!Parser.Parser.IsEpub(filePath)) return null; + if (!Tasks.Scanner.Parser.Parser.IsEpub(filePath)) return null; try { @@ -601,7 +601,7 @@ namespace API.Services } var info = new ParserInfo() { - Chapters = Parser.Parser.DefaultChapter, + Chapters = Tasks.Scanner.Parser.Parser.DefaultChapter, Edition = string.Empty, Format = MangaFormat.Epub, Filename = Path.GetFileName(filePath), @@ -628,7 +628,7 @@ namespace API.Services return new ParserInfo() { - Chapters = Parser.Parser.DefaultChapter, + Chapters = Tasks.Scanner.Parser.Parser.DefaultChapter, Edition = string.Empty, Format = MangaFormat.Epub, Filename = Path.GetFileName(filePath), @@ -636,7 +636,7 @@ namespace API.Services FullFilePath = filePath, IsSpecial = false, Series = epubBook.Title.Trim(), - Volumes = Parser.Parser.DefaultVolume, + Volumes = Tasks.Scanner.Parser.Parser.DefaultVolume, }; } catch (Exception ex) @@ -876,7 +876,7 @@ namespace API.Services { if (!IsValidFile(fileFilePath)) return string.Empty; - if (Parser.Parser.IsPdf(fileFilePath)) + if (Tasks.Scanner.Parser.Parser.IsPdf(fileFilePath)) { return GetPdfCoverImage(fileFilePath, fileName, outputDirectory); } @@ -887,7 +887,7 @@ namespace API.Services { // Try to get the cover image from OPF file, if not set, try to parse it from all the files, then result to the first one. var coverImageContent = epubBook.Content.Cover - ?? epubBook.Content.Images.Values.FirstOrDefault(file => Parser.Parser.IsCoverImage(file.FileName)) + ?? epubBook.Content.Images.Values.FirstOrDefault(file => Tasks.Scanner.Parser.Parser.IsCoverImage(file.FileName)) ?? epubBook.Content.Images.Values.FirstOrDefault(); if (coverImageContent == null) return string.Empty; diff --git a/API/Services/BookmarkService.cs b/API/Services/BookmarkService.cs index 6b07efd00..c798c47d1 100644 --- a/API/Services/BookmarkService.cs +++ b/API/Services/BookmarkService.cs @@ -51,7 +51,7 @@ public class BookmarkService : IBookmarkService var bookmarkDirectory = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.BookmarkDirectory)).Value; - var bookmarkFilesToDelete = bookmarks.Select(b => Parser.Parser.NormalizePath( + var bookmarkFilesToDelete = bookmarks.Select(b => Tasks.Scanner.Parser.Parser.NormalizePath( _directoryService.FileSystem.Path.Join(bookmarkDirectory, b.FileName))).ToList(); @@ -165,7 +165,7 @@ public class BookmarkService : IBookmarkService var bookmarks = await _unitOfWork.UserRepository.GetAllBookmarksByIds(bookmarkIds.ToList()); return bookmarks - .Select(b => Parser.Parser.NormalizePath(_directoryService.FileSystem.Path.Join(bookmarkDirectory, + .Select(b => Tasks.Scanner.Parser.Parser.NormalizePath(_directoryService.FileSystem.Path.Join(bookmarkDirectory, b.FileName))); } diff --git a/API/Services/CacheService.cs b/API/Services/CacheService.cs index 0a2edd07b..b81b87d91 100644 --- a/API/Services/CacheService.cs +++ b/API/Services/CacheService.cs @@ -57,7 +57,7 @@ namespace API.Services { // Calculate what chapter the page belongs to var path = GetBookmarkCachePath(seriesId); - var files = _directoryService.GetFilesWithExtension(path, Parser.Parser.ImageFileExtensions); + var files = _directoryService.GetFilesWithExtension(path, Tasks.Scanner.Parser.Parser.ImageFileExtensions); files = files .AsEnumerable() .OrderByNatural(Path.GetFileNameWithoutExtension) @@ -214,7 +214,7 @@ namespace API.Services // Calculate what chapter the page belongs to var path = GetCachePath(chapter.Id); // TODO: We can optimize this by extracting and renaming, so we don't need to scan for the files and can do a direct access - var files = _directoryService.GetFilesWithExtension(path, Parser.Parser.ImageFileExtensions) + var files = _directoryService.GetFilesWithExtension(path, Tasks.Scanner.Parser.Parser.ImageFileExtensions) .OrderByNatural(Path.GetFileNameWithoutExtension) .ToArray(); diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index 145106a33..54757f651 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.IO; using System.IO.Abstractions; using System.Linq; @@ -116,7 +117,7 @@ namespace API.Services /// /// Given a set of regex search criteria, get files in the given path. /// - /// This will always exclude patterns + /// This will always exclude patterns /// Directory to search /// Regex version of search pattern (ie \.mp3|\.mp4). Defaults to * meaning all files. /// SearchOption to use, defaults to TopDirectoryOnly @@ -130,7 +131,7 @@ namespace API.Services return FileSystem.Directory.EnumerateFiles(path, "*", searchOption) .Where(file => - reSearchPattern.IsMatch(FileSystem.Path.GetExtension(file)) && !FileSystem.Path.GetFileName(file).StartsWith(Parser.Parser.MacOsMetadataFileStartsWith)); + reSearchPattern.IsMatch(FileSystem.Path.GetExtension(file)) && !FileSystem.Path.GetFileName(file).StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith)); } @@ -207,12 +208,12 @@ namespace API.Services { var fileName = FileSystem.Path.GetFileName(file); return reSearchPattern.IsMatch(fileName) && - !fileName.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith); + !fileName.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith); }); } return FileSystem.Directory.EnumerateFiles(path, "*", searchOption).Where(file => - !FileSystem.Path.GetFileName(file).StartsWith(Parser.Parser.MacOsMetadataFileStartsWith)); + !FileSystem.Path.GetFileName(file).StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith)); } /// @@ -496,10 +497,10 @@ namespace API.Services { var stopLookingForDirectories = false; var dirs = new Dictionary(); - foreach (var folder in libraryFolders.Select(Parser.Parser.NormalizePath)) + foreach (var folder in libraryFolders.Select(Tasks.Scanner.Parser.Parser.NormalizePath)) { if (stopLookingForDirectories) break; - foreach (var file in filePaths.Select(Parser.Parser.NormalizePath)) + foreach (var file in filePaths.Select(Tasks.Scanner.Parser.Parser.NormalizePath)) { if (!file.Contains(folder)) continue; @@ -512,7 +513,7 @@ namespace API.Services break; } - var fullPath = Parser.Parser.NormalizePath(Path.Join(folder, parts.Last())); + var fullPath = Tasks.Scanner.Parser.Parser.NormalizePath(Path.Join(folder, parts.Last())); if (!dirs.ContainsKey(fullPath)) { dirs.Add(fullPath, string.Empty); @@ -579,7 +580,7 @@ namespace API.Services { try { - return Parser.Parser.NormalizePath(Directory.GetParent(fileOrFolder)?.FullName); + return Tasks.Scanner.Parser.Parser.NormalizePath(Directory.GetParent(fileOrFolder)?.FullName); } catch (Exception) { @@ -621,12 +622,12 @@ namespace API.Services // Get the matcher from either ignore or global (default setup) if (matcher == null) { - files.AddRange(GetFilesWithCertainExtensions(folderPath, Parser.Parser.SupportedExtensions)); + files.AddRange(GetFilesWithCertainExtensions(folderPath, Tasks.Scanner.Parser.Parser.SupportedExtensions)); } else { var foundFiles = GetFilesWithCertainExtensions(folderPath, - Parser.Parser.SupportedExtensions) + Tasks.Scanner.Parser.Parser.SupportedExtensions) .Where(file => !matcher.ExcludeMatches(FileSystem.FileInfo.FromFileName(file).Name)); files.AddRange(foundFiles); } @@ -635,18 +636,14 @@ namespace API.Services } /// - /// Recursively scans a folder and returns the max last write time on any folders + /// Recursively scans a folder and returns the max last write time on any folders and files /// /// /// Max Last Write Time public DateTime GetLastWriteTime(string folderPath) { if (!FileSystem.Directory.Exists(folderPath)) throw new IOException($"{folderPath} does not exist"); - - var directories = GetAllDirectories(folderPath).ToList(); - if (directories.Count == 0) return FileSystem.Directory.GetLastWriteTime(folderPath); - - return directories.Max(d => FileSystem.Directory.GetLastWriteTime(d)); + return Directory.GetFileSystemEntries(folderPath, "*.*", SearchOption.AllDirectories).Max(path => FileSystem.File.GetLastWriteTime(path)); } /// @@ -848,7 +845,7 @@ namespace API.Services /// Fully qualified directory public void RemoveNonImages(string directoryName) { - DeleteFiles(GetFiles(directoryName, searchOption:SearchOption.AllDirectories).Where(file => !Parser.Parser.IsImage(file))); + DeleteFiles(GetFiles(directoryName, searchOption:SearchOption.AllDirectories).Where(file => !Tasks.Scanner.Parser.Parser.IsImage(file))); } @@ -921,9 +918,9 @@ namespace API.Services foreach (var file in directory.EnumerateFiles().OrderByNatural(file => file.FullName)) { if (file.Directory == null) continue; - var paddedIndex = Parser.Parser.PadZeros(directoryIndex + ""); + var paddedIndex = Tasks.Scanner.Parser.Parser.PadZeros(directoryIndex + ""); // We need to rename the files so that after flattening, they are in the order we found them - var newName = $"{paddedIndex}_{Parser.Parser.PadZeros(fileIndex + "")}{file.Extension}"; + var newName = $"{paddedIndex}_{Tasks.Scanner.Parser.Parser.PadZeros(fileIndex + "")}{file.Extension}"; var newPath = Path.Join(root.FullName, newName); if (!File.Exists(newPath)) file.MoveTo(newPath); fileIndex++; @@ -935,7 +932,7 @@ namespace API.Services foreach (var subDirectory in directory.EnumerateDirectories().OrderByNatural(d => d.FullName)) { // We need to check if the directory is not a blacklisted (ie __MACOSX) - if (Parser.Parser.HasBlacklistedFolderInPath(subDirectory.FullName)) continue; + if (Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(subDirectory.FullName)) continue; FlattenDirectory(root, subDirectory, ref directoryIndex); } diff --git a/API/Services/EmailService.cs b/API/Services/EmailService.cs index c5ba90464..819a0c77a 100644 --- a/API/Services/EmailService.cs +++ b/API/Services/EmailService.cs @@ -82,8 +82,15 @@ public class EmailService : IEmailService public async Task CheckIfAccessible(string host) { // This is the only exception for using the default because we need an external service to check if the server is accessible for emails - if (IsLocalIpAddress(host)) return false; - return await SendEmailWithGet(DefaultApiUrl + "/api/email/reachable?host=" + host); + try + { + if (IsLocalIpAddress(host)) return false; + return await SendEmailWithGet(DefaultApiUrl + "/api/email/reachable?host=" + host); + } + catch (Exception) + { + return false; + } } public async Task SendMigrationEmail(EmailMigrationDto data) diff --git a/API/Services/ImageService.cs b/API/Services/ImageService.cs index 03d589776..1d1271ad5 100644 --- a/API/Services/ImageService.cs +++ b/API/Services/ImageService.cs @@ -63,7 +63,7 @@ public class ImageService : IImageService else { _directoryService.CopyDirectoryToDirectory(Path.GetDirectoryName(fileFilePath), targetDirectory, - Parser.Parser.ImageFileExtensions); + Tasks.Scanner.Parser.Parser.ImageFileExtensions); } } diff --git a/API/Services/ReaderService.cs b/API/Services/ReaderService.cs index 1c993a487..197731a8b 100644 --- a/API/Services/ReaderService.cs +++ b/API/Services/ReaderService.cs @@ -59,7 +59,7 @@ public class ReaderService : IReaderService public static string FormatBookmarkFolderPath(string baseDirectory, int userId, int seriesId, int chapterId) { - return Parser.Parser.NormalizePath(Path.Join(baseDirectory, $"{userId}", $"{seriesId}", $"{chapterId}")); + return Tasks.Scanner.Parser.Parser.NormalizePath(Path.Join(baseDirectory, $"{userId}", $"{seriesId}", $"{chapterId}")); } /// @@ -496,7 +496,7 @@ public class ReaderService : IReaderService { var chapters = volume.Chapters .OrderBy(c => float.Parse(c.Number)) - .Where(c => !c.IsSpecial && Parser.Parser.MaxNumberFromRange(c.Range) <= chapterNumber); + .Where(c => !c.IsSpecial && Tasks.Scanner.Parser.Parser.MaxNumberFromRange(c.Range) <= chapterNumber); await MarkChaptersAsRead(user, volume.SeriesId, chapters); } } diff --git a/API/Services/ReadingItemService.cs b/API/Services/ReadingItemService.cs index b29cb0efa..8e4676639 100644 --- a/API/Services/ReadingItemService.cs +++ b/API/Services/ReadingItemService.cs @@ -40,12 +40,12 @@ public class ReadingItemService : IReadingItemService /// public ComicInfo? GetComicInfo(string filePath) { - if (Parser.Parser.IsEpub(filePath)) + if (Tasks.Scanner.Parser.Parser.IsEpub(filePath)) { return _bookService.GetComicInfo(filePath); } - if (Parser.Parser.IsComicInfoExtension(filePath)) + if (Tasks.Scanner.Parser.Parser.IsComicInfoExtension(filePath)) { return _archiveService.GetComicInfo(filePath); } @@ -69,7 +69,7 @@ public class ReadingItemService : IReadingItemService // This catches when original library type is Manga/Comic and when parsing with non - if (Parser.Parser.IsEpub(path) && Parser.Parser.ParseVolume(info.Series) != Parser.Parser.DefaultVolume) // Shouldn't this be info.Volume != DefaultVolume? + if (Tasks.Scanner.Parser.Parser.IsEpub(path) && Tasks.Scanner.Parser.Parser.ParseVolume(info.Series) != Tasks.Scanner.Parser.Parser.DefaultVolume) // Shouldn't this be info.Volume != DefaultVolume? { info = _defaultParser.Parse(path, rootPath, LibraryType.Book); var info2 = Parse(path, rootPath, type); @@ -98,11 +98,11 @@ public class ReadingItemService : IReadingItemService info.SeriesSort = info.ComicInfo.TitleSort.Trim(); } - if (!string.IsNullOrEmpty(info.ComicInfo.Format) && Parser.Parser.HasComicInfoSpecial(info.ComicInfo.Format)) + if (!string.IsNullOrEmpty(info.ComicInfo.Format) && Tasks.Scanner.Parser.Parser.HasComicInfoSpecial(info.ComicInfo.Format)) { info.IsSpecial = true; - info.Chapters = Parser.Parser.DefaultChapter; - info.Volumes = Parser.Parser.DefaultVolume; + info.Chapters = Tasks.Scanner.Parser.Parser.DefaultChapter; + info.Volumes = Tasks.Scanner.Parser.Parser.DefaultVolume; } if (!string.IsNullOrEmpty(info.ComicInfo.SeriesSort)) @@ -200,6 +200,6 @@ public class ReadingItemService : IReadingItemService /// public ParserInfo Parse(string path, string rootPath, LibraryType type) { - return Parser.Parser.IsEpub(path) ? _bookService.ParseInfo(path) : _defaultParser.Parse(path, rootPath, type); + return Tasks.Scanner.Parser.Parser.IsEpub(path) ? _bookService.ParseInfo(path) : _defaultParser.Parse(path, rootPath, type); } } diff --git a/API/Services/ReadingListService.cs b/API/Services/ReadingListService.cs index 1669145dc..60314e3a9 100644 --- a/API/Services/ReadingListService.cs +++ b/API/Services/ReadingListService.cs @@ -166,7 +166,7 @@ public class ReadingListService : IReadingListService var existingChapterExists = readingList.Items.Select(rli => rli.ChapterId).ToHashSet(); var chaptersForSeries = (await _unitOfWork.ChapterRepository.GetChaptersByIdsAsync(chapterIds)) - .OrderBy(c => Parser.Parser.MinNumberFromRange(c.Volume.Name)) + .OrderBy(c => Tasks.Scanner.Parser.Parser.MinNumberFromRange(c.Volume.Name)) .ThenBy(x => double.Parse(x.Number), _chapterSortComparerForInChapterSorting); var index = lastOrder + 1; diff --git a/API/Services/SeriesService.cs b/API/Services/SeriesService.cs index bb9b6af76..471cb2b16 100644 --- a/API/Services/SeriesService.cs +++ b/API/Services/SeriesService.cs @@ -254,7 +254,7 @@ public class SeriesService : ISeriesService // At this point, all tags that aren't in dto have been removed. foreach (var tagTitle in tags.Select(t => t.Title)) { - var normalizedTitle = Parser.Parser.Normalize(tagTitle); + var normalizedTitle = Tasks.Scanner.Parser.Parser.Normalize(tagTitle); var existingTag = allTags.SingleOrDefault(t => t.NormalizedTitle == normalizedTitle); if (existingTag != null) { @@ -295,7 +295,7 @@ public class SeriesService : ISeriesService // At this point, all tags that aren't in dto have been removed. foreach (var tagTitle in tags.Select(t => t.Title)) { - var normalizedTitle = Parser.Parser.Normalize(tagTitle); + var normalizedTitle = Tasks.Scanner.Parser.Parser.Normalize(tagTitle); var existingTag = allTags.SingleOrDefault(t => t.NormalizedTitle.Equals(normalizedTitle)); if (existingTag != null) { @@ -465,7 +465,7 @@ public class SeriesService : ISeriesService var libraryType = await _unitOfWork.LibraryRepository.GetLibraryTypeAsync(series.LibraryId); var volumes = (await _unitOfWork.VolumeRepository.GetVolumesDtoAsync(seriesId, userId)) - .OrderBy(v => Parser.Parser.MinNumberFromRange(v.Name)) + .OrderBy(v => Tasks.Scanner.Parser.Parser.MinNumberFromRange(v.Name)) .ToList(); // For books, the Name of the Volume is remapped to the actual name of the book, rather than Volume number. @@ -542,7 +542,7 @@ public class SeriesService : ISeriesService /// private static bool ShouldIncludeChapter(ChapterDto chapter) { - return !chapter.IsSpecial && !chapter.Number.Equals(Parser.Parser.DefaultChapter); + return !chapter.IsSpecial && !chapter.Number.Equals(Tasks.Scanner.Parser.Parser.DefaultChapter); } public static void RenameVolumeName(ChapterDto firstChapter, VolumeDto volume, LibraryType libraryType) @@ -551,7 +551,7 @@ public class SeriesService : ISeriesService { if (string.IsNullOrEmpty(firstChapter.TitleName)) { - if (firstChapter.Range.Equals(Parser.Parser.DefaultVolume)) return; + if (firstChapter.Range.Equals(Tasks.Scanner.Parser.Parser.DefaultVolume)) return; var title = Path.GetFileNameWithoutExtension(firstChapter.Range); if (string.IsNullOrEmpty(title)) return; volume.Name += $" - {title}"; @@ -572,7 +572,7 @@ public class SeriesService : ISeriesService { if (isSpecial) { - return Parser.Parser.CleanSpecialTitle(chapterTitle); + return Tasks.Scanner.Parser.Parser.CleanSpecialTitle(chapterTitle); } var hashSpot = withHash ? "#" : string.Empty; diff --git a/API/Services/TaskScheduler.cs b/API/Services/TaskScheduler.cs index 12e6d94c8..affbec32b 100644 --- a/API/Services/TaskScheduler.cs +++ b/API/Services/TaskScheduler.cs @@ -168,7 +168,7 @@ public class TaskScheduler : ITaskScheduler public void ScanFolder(string folderPath) { - _scannerService.ScanFolder(Parser.Parser.NormalizePath(folderPath)); + _scannerService.ScanFolder(Tasks.Scanner.Parser.Parser.NormalizePath(folderPath)); } #endregion diff --git a/API/Services/Tasks/Scanner/Parser/DefaultParser.cs b/API/Services/Tasks/Scanner/Parser/DefaultParser.cs index 2d4c520e9..60317e97d 100644 --- a/API/Services/Tasks/Scanner/Parser/DefaultParser.cs +++ b/API/Services/Tasks/Scanner/Parser/DefaultParser.cs @@ -36,15 +36,15 @@ public class DefaultParser : IDefaultParser var fileName = _directoryService.FileSystem.Path.GetFileNameWithoutExtension(filePath); ParserInfo ret; - if (Parser.IsEpub(filePath)) + if (Services.Tasks.Scanner.Parser.Parser.IsEpub(filePath)) { ret = new ParserInfo() { - Chapters = Parser.ParseChapter(fileName) ?? Parser.ParseComicChapter(fileName), - Series = Parser.ParseSeries(fileName) ?? Parser.ParseComicSeries(fileName), - Volumes = Parser.ParseVolume(fileName) ?? Parser.ParseComicVolume(fileName), + Chapters = Services.Tasks.Scanner.Parser.Parser.ParseChapter(fileName) ?? Services.Tasks.Scanner.Parser.Parser.ParseComicChapter(fileName), + Series = Services.Tasks.Scanner.Parser.Parser.ParseSeries(fileName) ?? Services.Tasks.Scanner.Parser.Parser.ParseComicSeries(fileName), + Volumes = Services.Tasks.Scanner.Parser.Parser.ParseVolume(fileName) ?? Services.Tasks.Scanner.Parser.Parser.ParseComicVolume(fileName), Filename = Path.GetFileName(filePath), - Format = Parser.ParseFormat(filePath), + Format = Services.Tasks.Scanner.Parser.Parser.ParseFormat(filePath), FullFilePath = filePath }; } @@ -52,65 +52,65 @@ public class DefaultParser : IDefaultParser { ret = new ParserInfo() { - Chapters = type == LibraryType.Comic ? Parser.ParseComicChapter(fileName) : Parser.ParseChapter(fileName), - Series = type == LibraryType.Comic ? Parser.ParseComicSeries(fileName) : Parser.ParseSeries(fileName), - Volumes = type == LibraryType.Comic ? Parser.ParseComicVolume(fileName) : Parser.ParseVolume(fileName), + Chapters = type == LibraryType.Comic ? Services.Tasks.Scanner.Parser.Parser.ParseComicChapter(fileName) : Services.Tasks.Scanner.Parser.Parser.ParseChapter(fileName), + Series = type == LibraryType.Comic ? Services.Tasks.Scanner.Parser.Parser.ParseComicSeries(fileName) : Services.Tasks.Scanner.Parser.Parser.ParseSeries(fileName), + Volumes = type == LibraryType.Comic ? Services.Tasks.Scanner.Parser.Parser.ParseComicVolume(fileName) : Services.Tasks.Scanner.Parser.Parser.ParseVolume(fileName), Filename = Path.GetFileName(filePath), - Format = Parser.ParseFormat(filePath), + Format = Services.Tasks.Scanner.Parser.Parser.ParseFormat(filePath), Title = Path.GetFileNameWithoutExtension(fileName), FullFilePath = filePath }; } - if (Parser.IsImage(filePath) && Parser.IsCoverImage(filePath)) return null; + if (Services.Tasks.Scanner.Parser.Parser.IsImage(filePath) && Services.Tasks.Scanner.Parser.Parser.IsCoverImage(filePath)) return null; - if (Parser.IsImage(filePath)) + if (Services.Tasks.Scanner.Parser.Parser.IsImage(filePath)) { // Reset Chapters, Volumes, and Series as images are not good to parse information out of. Better to use folders. - ret.Volumes = Parser.DefaultVolume; - ret.Chapters = Parser.DefaultChapter; + ret.Volumes = Services.Tasks.Scanner.Parser.Parser.DefaultVolume; + ret.Chapters = Services.Tasks.Scanner.Parser.Parser.DefaultChapter; ret.Series = string.Empty; } - if (ret.Series == string.Empty || Parser.IsImage(filePath)) + if (ret.Series == string.Empty || Services.Tasks.Scanner.Parser.Parser.IsImage(filePath)) { // Try to parse information out of each folder all the way to rootPath ParseFromFallbackFolders(filePath, rootPath, type, ref ret); } - var edition = Parser.ParseEdition(fileName); + var edition = Services.Tasks.Scanner.Parser.Parser.ParseEdition(fileName); if (!string.IsNullOrEmpty(edition)) { - ret.Series = Parser.CleanTitle(ret.Series.Replace(edition, ""), type is LibraryType.Comic); + ret.Series = Services.Tasks.Scanner.Parser.Parser.CleanTitle(ret.Series.Replace(edition, ""), type is LibraryType.Comic); ret.Edition = edition; } - var isSpecial = type == LibraryType.Comic ? Parser.ParseComicSpecial(fileName) : Parser.ParseMangaSpecial(fileName); + var isSpecial = type == LibraryType.Comic ? Services.Tasks.Scanner.Parser.Parser.ParseComicSpecial(fileName) : Services.Tasks.Scanner.Parser.Parser.ParseMangaSpecial(fileName); // We must ensure that we can only parse a special out. As some files will have v20 c171-180+Omake and that // could cause a problem as Omake is a special term, but there is valid volume/chapter information. - if (ret.Chapters == Parser.DefaultChapter && ret.Volumes == Parser.DefaultVolume && !string.IsNullOrEmpty(isSpecial)) + if (ret.Chapters == Services.Tasks.Scanner.Parser.Parser.DefaultChapter && ret.Volumes == Services.Tasks.Scanner.Parser.Parser.DefaultVolume && !string.IsNullOrEmpty(isSpecial)) { ret.IsSpecial = true; ParseFromFallbackFolders(filePath, rootPath, type, ref ret); // NOTE: This can cause some complications, we should try to be a bit less aggressive to fallback to folder } // If we are a special with marker, we need to ensure we use the correct series name. we can do this by falling back to Folder name - if (Parser.HasSpecialMarker(fileName)) + if (Services.Tasks.Scanner.Parser.Parser.HasSpecialMarker(fileName)) { ret.IsSpecial = true; - ret.Chapters = Parser.DefaultChapter; - ret.Volumes = Parser.DefaultVolume; + ret.Chapters = Services.Tasks.Scanner.Parser.Parser.DefaultChapter; + ret.Volumes = Services.Tasks.Scanner.Parser.Parser.DefaultVolume; ParseFromFallbackFolders(filePath, rootPath, type, ref ret); } if (string.IsNullOrEmpty(ret.Series)) { - ret.Series = Parser.CleanTitle(fileName, type is LibraryType.Comic); + ret.Series = Services.Tasks.Scanner.Parser.Parser.CleanTitle(fileName, type is LibraryType.Comic); } // Pdfs may have .pdf in the series name, remove that - if (Parser.IsPdf(filePath) && ret.Series.ToLower().EndsWith(".pdf")) + if (Services.Tasks.Scanner.Parser.Parser.IsPdf(filePath) && ret.Series.ToLower().EndsWith(".pdf")) { ret.Series = ret.Series.Substring(0, ret.Series.Length - ".pdf".Length); } @@ -131,18 +131,18 @@ public class DefaultParser : IDefaultParser for (var i = 0; i < fallbackFolders.Count; i++) { var folder = fallbackFolders[i]; - if (!string.IsNullOrEmpty(Parser.ParseMangaSpecial(folder))) continue; + if (!string.IsNullOrEmpty(Services.Tasks.Scanner.Parser.Parser.ParseMangaSpecial(folder))) continue; - var parsedVolume = type is LibraryType.Manga ? Parser.ParseVolume(folder) : Parser.ParseComicVolume(folder); - var parsedChapter = type is LibraryType.Manga ? Parser.ParseChapter(folder) : Parser.ParseComicChapter(folder); + var parsedVolume = type is LibraryType.Manga ? Services.Tasks.Scanner.Parser.Parser.ParseVolume(folder) : Services.Tasks.Scanner.Parser.Parser.ParseComicVolume(folder); + var parsedChapter = type is LibraryType.Manga ? Services.Tasks.Scanner.Parser.Parser.ParseChapter(folder) : Services.Tasks.Scanner.Parser.Parser.ParseComicChapter(folder); - if (!parsedVolume.Equals(Parser.DefaultVolume) || !parsedChapter.Equals(Parser.DefaultChapter)) + if (!parsedVolume.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultVolume) || !parsedChapter.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultChapter)) { - if ((string.IsNullOrEmpty(ret.Volumes) || ret.Volumes.Equals(Parser.DefaultVolume)) && !parsedVolume.Equals(Parser.DefaultVolume)) + if ((string.IsNullOrEmpty(ret.Volumes) || ret.Volumes.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultVolume)) && !parsedVolume.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultVolume)) { ret.Volumes = parsedVolume; } - if ((string.IsNullOrEmpty(ret.Chapters) || ret.Chapters.Equals(Parser.DefaultChapter)) && !parsedChapter.Equals(Parser.DefaultChapter)) + if ((string.IsNullOrEmpty(ret.Chapters) || ret.Chapters.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultChapter)) && !parsedChapter.Equals(Services.Tasks.Scanner.Parser.Parser.DefaultChapter)) { ret.Chapters = parsedChapter; } @@ -151,11 +151,11 @@ public class DefaultParser : IDefaultParser // Generally users group in series folders. Let's try to parse series from the top folder if (!folder.Equals(ret.Series) && i == fallbackFolders.Count - 1) { - var series = Parser.ParseSeries(folder); + var series = Services.Tasks.Scanner.Parser.Parser.ParseSeries(folder); if (string.IsNullOrEmpty(series)) { - ret.Series = Parser.CleanTitle(folder, type is LibraryType.Comic); + ret.Series = Services.Tasks.Scanner.Parser.Parser.CleanTitle(folder, type is LibraryType.Comic); break; } diff --git a/API/Services/Tasks/Scanner/Parser/Parser.cs b/API/Services/Tasks/Scanner/Parser/Parser.cs index 8ddac4126..8db88333e 100644 --- a/API/Services/Tasks/Scanner/Parser/Parser.cs +++ b/API/Services/Tasks/Scanner/Parser/Parser.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text.RegularExpressions; using API.Entities.Enums; -namespace API.Parser +namespace API.Services.Tasks.Scanner.Parser { public static class Parser { diff --git a/API/Services/Tasks/Scanner/Parser/ParserInfo.cs b/API/Services/Tasks/Scanner/Parser/ParserInfo.cs index caae49f84..4a0a3fdc6 100644 --- a/API/Services/Tasks/Scanner/Parser/ParserInfo.cs +++ b/API/Services/Tasks/Scanner/Parser/ParserInfo.cs @@ -1,5 +1,6 @@ using API.Data.Metadata; using API.Entities.Enums; +using API.Services.Tasks.Scanner.Parser; namespace API.Parser { diff --git a/API/Services/Tasks/ScannerService.cs b/API/Services/Tasks/ScannerService.cs index 7f3bf7a86..1dbf8057f 100644 --- a/API/Services/Tasks/ScannerService.cs +++ b/API/Services/Tasks/ScannerService.cs @@ -111,11 +111,11 @@ public class ScannerService : IScannerService var libraries = (await _unitOfWork.LibraryRepository.GetLibraryDtosAsync()).ToList(); var libraryFolders = libraries.SelectMany(l => l.Folders); - var libraryFolder = libraryFolders.Select(Parser.Parser.NormalizePath).SingleOrDefault(f => f.Contains(parentDirectory)); + var libraryFolder = libraryFolders.Select(Scanner.Parser.Parser.NormalizePath).SingleOrDefault(f => f.Contains(parentDirectory)); if (string.IsNullOrEmpty(libraryFolder)) return; - var library = libraries.FirstOrDefault(l => l.Folders.Select(Parser.Parser.NormalizePath).Contains(libraryFolder)); + var library = libraries.FirstOrDefault(l => l.Folders.Select(Scanner.Parser.Parser.NormalizePath).Contains(libraryFolder)); if (library != null) { BackgroundJob.Enqueue(() => ScanLibrary(library.Id, false)); @@ -188,7 +188,7 @@ public class ScannerService : IScannerService var foundParsedSeries = new ParsedSeries() { Name = parsedFiles.First().Series, - NormalizedName = Parser.Parser.Normalize(parsedFiles.First().Series), + NormalizedName = Scanner.Parser.Parser.Normalize(parsedFiles.First().Series), Format = parsedFiles.First().Format }; @@ -457,7 +457,7 @@ public class ScannerService : IScannerService var foundParsedSeries = new ParsedSeries() { Name = parsedFiles.First().Series, - NormalizedName = Parser.Parser.Normalize(parsedFiles.First().Series), + NormalizedName = Scanner.Parser.Parser.Normalize(parsedFiles.First().Series), Format = parsedFiles.First().Format }; @@ -466,7 +466,7 @@ public class ScannerService : IScannerService seenSeries.AddRange(parsedFiles.Select(pf => new ParsedSeries() { Name = pf.Series, - NormalizedName = Parser.Parser.Normalize(pf.Series), + NormalizedName = Scanner.Parser.Parser.Normalize(pf.Series), Format = pf.Format })); return; diff --git a/API/Services/Tasks/SiteThemeService.cs b/API/Services/Tasks/SiteThemeService.cs index aa52215c8..8de7f879c 100644 --- a/API/Services/Tasks/SiteThemeService.cs +++ b/API/Services/Tasks/SiteThemeService.cs @@ -55,8 +55,8 @@ public class ThemeService : IThemeService _directoryService.ExistOrCreate(_directoryService.SiteThemeDirectory); var reservedNames = Seed.DefaultThemes.Select(t => t.NormalizedName).ToList(); var themeFiles = _directoryService - .GetFilesWithExtension(Parser.Parser.NormalizePath(_directoryService.SiteThemeDirectory), @"\.css") - .Where(name => !reservedNames.Contains(Parser.Parser.Normalize(name))).ToList(); + .GetFilesWithExtension(Scanner.Parser.Parser.NormalizePath(_directoryService.SiteThemeDirectory), @"\.css") + .Where(name => !reservedNames.Contains(Scanner.Parser.Parser.Normalize(name))).ToList(); var allThemes = (await _unitOfWork.SiteThemeRepository.GetThemes()).ToList(); @@ -64,7 +64,7 @@ public class ThemeService : IThemeService var userThemes = allThemes.Where(t => t.Provider == ThemeProvider.User).ToList(); foreach (var userTheme in userThemes) { - var filepath = Parser.Parser.NormalizePath( + var filepath = Scanner.Parser.Parser.NormalizePath( _directoryService.FileSystem.Path.Join(_directoryService.SiteThemeDirectory, userTheme.FileName)); if (_directoryService.FileSystem.File.Exists(filepath)) continue; @@ -78,7 +78,7 @@ public class ThemeService : IThemeService foreach (var themeFile in themeFiles) { var themeName = - Parser.Parser.Normalize(_directoryService.FileSystem.Path.GetFileNameWithoutExtension(themeFile)); + Scanner.Parser.Parser.Normalize(_directoryService.FileSystem.Path.GetFileNameWithoutExtension(themeFile)); if (allThemeNames.Contains(themeName)) continue; _unitOfWork.SiteThemeRepository.Add(new SiteTheme()