diff --git a/API.Tests/Extensions/ChapterListExtensionsTests.cs b/API.Tests/Extensions/ChapterListExtensionsTests.cs index d27903ca9..f19a0cede 100644 --- a/API.Tests/Extensions/ChapterListExtensionsTests.cs +++ b/API.Tests/Extensions/ChapterListExtensionsTests.cs @@ -142,7 +142,7 @@ public class ChapterListExtensionsTests CreateChapter("darker than black", "1", CreateFile("/manga/darker than black.cbz", MangaFormat.Archive), false), }; - Assert.Equal(chapterList.First(), chapterList.GetFirstChapterWithFiles()); + Assert.Equal(chapterList[0], chapterList.GetFirstChapterWithFiles()); } [Fact] @@ -150,13 +150,13 @@ public class ChapterListExtensionsTests { var chapterList = new List() { - CreateChapter("darker than black", API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter, CreateFile("/manga/darker than black.cbz", MangaFormat.Archive), true), + CreateChapter("darker than black", Parser.DefaultChapter, CreateFile("/manga/darker than black.cbz", MangaFormat.Archive), true), CreateChapter("darker than black", "1", CreateFile("/manga/darker than black.cbz", MangaFormat.Archive), false), }; - chapterList.First().Files = new List(); + chapterList[0].Files = new List(); - Assert.Equal(chapterList.Last(), chapterList.GetFirstChapterWithFiles()); + Assert.Equal(chapterList[^1], chapterList.GetFirstChapterWithFiles()); } @@ -181,7 +181,7 @@ public class ChapterListExtensionsTests CreateChapter("detective comics", API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter, CreateFile("/manga/detective comics #001.cbz", MangaFormat.Archive), true) }; - chapterList[0].ReleaseDate = new DateTime(10, 1, 1); + chapterList[0].ReleaseDate = new DateTime(10, 1, 1, 0, 0, 0, DateTimeKind.Utc); chapterList[1].ReleaseDate = DateTime.MinValue; Assert.Equal(0, chapterList.MinimumReleaseYear()); @@ -196,8 +196,8 @@ public class ChapterListExtensionsTests CreateChapter("detective comics", API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter, CreateFile("/manga/detective comics #001.cbz", MangaFormat.Archive), true) }; - chapterList[0].ReleaseDate = new DateTime(2002, 1, 1); - chapterList[1].ReleaseDate = new DateTime(2012, 2, 1); + chapterList[0].ReleaseDate = new DateTime(2002, 1, 1, 0, 0, 0, DateTimeKind.Utc); + chapterList[1].ReleaseDate = new DateTime(2012, 2, 1, 0, 0, 0, DateTimeKind.Utc); Assert.Equal(2002, chapterList.MinimumReleaseYear()); } diff --git a/API/Controllers/ChapterController.cs b/API/Controllers/ChapterController.cs index ca270d7a8..f305e7de6 100644 --- a/API/Controllers/ChapterController.cs +++ b/API/Controllers/ChapterController.cs @@ -419,7 +419,7 @@ public class ChapterController : BaseApiController ret.HasBeenRated = ownRating.HasBeenRated; } - var externalReviews = await _unitOfWork.ChapterRepository.GetExternalChapterReviews(chapterId); + var externalReviews = await _unitOfWork.ChapterRepository.GetExternalChapterReviewDtos(chapterId); if (externalReviews.Count > 0) { userReviews.AddRange(ReviewHelper.SelectSpectrumOfReviews(externalReviews)); @@ -427,7 +427,7 @@ public class ChapterController : BaseApiController ret.Reviews = userReviews; - ret.Ratings = await _unitOfWork.ChapterRepository.GetExternalChapterRatings(chapterId); + ret.Ratings = await _unitOfWork.ChapterRepository.GetExternalChapterRatingDtos(chapterId); return Ok(ret); } diff --git a/API/Data/Repositories/ChapterRepository.cs b/API/Data/Repositories/ChapterRepository.cs index 650b9ac93..5badb315e 100644 --- a/API/Data/Repositories/ChapterRepository.cs +++ b/API/Data/Repositories/ChapterRepository.cs @@ -8,6 +8,7 @@ using API.DTOs.Reader; using API.DTOs.SeriesDetail; using API.Entities; using API.Entities.Enums; +using API.Entities.Metadata; using API.Extensions; using API.Extensions.QueryExtensions; using AutoMapper; @@ -51,8 +52,10 @@ public interface IChapterRepository IEnumerable GetChaptersForSeries(int seriesId); Task> GetAllChaptersForSeries(int seriesId); Task GetAverageUserRating(int chapterId, int userId); - Task> GetExternalChapterReviews(int chapterId); - Task> GetExternalChapterRatings(int chapterId); + Task> GetExternalChapterReviewDtos(int chapterId); + Task> GetExternalChapterReview(int chapterId); + Task> GetExternalChapterRatingDtos(int chapterId); + Task> GetExternalChapterRatings(int chapterId); } public class ChapterRepository : IChapterRepository { @@ -332,7 +335,7 @@ public class ChapterRepository : IChapterRepository return avg.HasValue ? (int) (avg.Value * 20) : 0; } - public async Task> GetExternalChapterReviews(int chapterId) + public async Task> GetExternalChapterReviewDtos(int chapterId) { return await _context.Chapter .Where(c => c.Id == chapterId) @@ -342,7 +345,15 @@ public class ChapterRepository : IChapterRepository .ToListAsync(); } - public async Task> GetExternalChapterRatings(int chapterId) + public async Task> GetExternalChapterReview(int chapterId) + { + return await _context.Chapter + .Where(c => c.Id == chapterId) + .SelectMany(c => c.ExternalReviews) + .ToListAsync(); + } + + public async Task> GetExternalChapterRatingDtos(int chapterId) { return await _context.Chapter .Where(c => c.Id == chapterId) @@ -350,4 +361,12 @@ public class ChapterRepository : IChapterRepository .ProjectTo(_mapper.ConfigurationProvider) .ToListAsync(); } + + public async Task> GetExternalChapterRatings(int chapterId) + { + return await _context.Chapter + .Where(c => c.Id == chapterId) + .SelectMany(c => c.ExternalRatings) + .ToListAsync(); + } } diff --git a/API/Services/Plus/ExternalMetadataService.cs b/API/Services/Plus/ExternalMetadataService.cs index c5d0c1f4c..f9af923a2 100644 --- a/API/Services/Plus/ExternalMetadataService.cs +++ b/API/Services/Plus/ExternalMetadataService.cs @@ -1085,7 +1085,7 @@ public class ExternalMetadataService : IExternalMetadataService madeModification = await UpdateChapterPeople(chapter, settings, PersonRole.Writer, potentialMatch.Writers) || madeModification; madeModification = await UpdateChapterCoverImage(chapter, settings, potentialMatch.CoverImageUrl) || madeModification; - madeModification = UpdateExternalChapterMetadata(chapter, settings, potentialMatch) || madeModification; + madeModification = await UpdateExternalChapterMetadata(chapter, settings, potentialMatch) || madeModification; _unitOfWork.ChapterRepository.Update(chapter); await _unitOfWork.CommitAsync(); @@ -1094,7 +1094,7 @@ public class ExternalMetadataService : IExternalMetadataService return madeModification; } - private bool UpdateExternalChapterMetadata(Chapter chapter, MetadataSettingsDto settings, ExternalChapterDto metadata) + private async Task UpdateExternalChapterMetadata(Chapter chapter, MetadataSettingsDto settings, ExternalChapterDto metadata) { if (!settings.Enabled) return false; @@ -1106,7 +1106,12 @@ public class ExternalMetadataService : IExternalMetadataService var madeModification = false; #region Review - _unitOfWork.ExternalSeriesMetadataRepository.Remove(chapter.ExternalReviews); + + // Remove existing Reviews + var existingReviews = await _unitOfWork.ChapterRepository.GetExternalChapterReview(chapter.Id); + _unitOfWork.ExternalSeriesMetadataRepository.Remove(existingReviews); + + List externalReviews = []; externalReviews.AddRange(metadata.CriticReviews .Where(r => !string.IsNullOrWhiteSpace(r.Username) && !string.IsNullOrWhiteSpace(r.Body)) @@ -1139,7 +1144,9 @@ public class ExternalMetadataService : IExternalMetadataService var averageCriticRating = metadata.CriticReviews.Average(r => r.Rating); var averageUserRating = metadata.UserReviews.Average(r => r.Rating); - _unitOfWork.ExternalSeriesMetadataRepository.Remove(chapter.ExternalRatings); + var existingRatings = await _unitOfWork.ChapterRepository.GetExternalChapterRatings(chapter.Id); + _unitOfWork.ExternalSeriesMetadataRepository.Remove(existingRatings); + chapter.ExternalRatings = [ new ExternalRating diff --git a/API/Services/SeriesService.cs b/API/Services/SeriesService.cs index 2de1c6ee8..805b3b06f 100644 --- a/API/Services/SeriesService.cs +++ b/API/Services/SeriesService.cs @@ -458,7 +458,7 @@ public class SeriesService : ISeriesService allChapterIds.AddRange(mapping.Value); } - // BUG: This isn't getting all the people and whatnot currently + // NOTE: This isn't getting all the people and whatnot currently due to the lack of includes var series = await _unitOfWork.SeriesRepository.GetSeriesByIdsAsync(seriesIds); _unitOfWork.SeriesRepository.Remove(series); @@ -481,6 +481,7 @@ public class SeriesService : ISeriesService await _unitOfWork.AppUserProgressRepository.CleanupAbandonedChapters(); await _unitOfWork.CollectionTagRepository.RemoveCollectionsWithoutSeries(); _taskScheduler.CleanupChapters([.. allChapterIds]); + return true; } catch (Exception ex) diff --git a/API/Services/Tasks/Metadata/CoverDbService.cs b/API/Services/Tasks/Metadata/CoverDbService.cs index cbcff9284..1b315b921 100644 --- a/API/Services/Tasks/Metadata/CoverDbService.cs +++ b/API/Services/Tasks/Metadata/CoverDbService.cs @@ -308,6 +308,7 @@ public class CoverDbService : ICoverDbService .AllowHttpStatus("2xx,304") .GetStreamAsync(); + using var image = Image.NewFromStream(personStream); switch (encodeFormat) { @@ -553,6 +554,7 @@ public class CoverDbService : ICoverDbService { try { + // BUG: There might be a bug here where it's comparing the same 2 images var betterImage = Path.Join(_directoryService.CoverImageDirectory, series.CoverImage) .GetBetterImage(Path.Join(_directoryService.CoverImageDirectory, filePath))!; filePath = Path.GetFileName(betterImage);