From c1b8c70473c04fdb92d289b4adc6166804684c94 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Tue, 29 Apr 2025 11:18:22 -0500 Subject: [PATCH] Fixed a missing cache check for publisher images when they fail. --- API/Constants/CacheProfiles.cs | 4 ++++ API/Controllers/ChapterController.cs | 8 ++++++-- API/Controllers/RatingController.cs | 10 ++++++++++ API/Data/Repositories/UserRepository.cs | 4 ++-- API/Extensions/ApplicationServiceExtensions.cs | 1 + API/Services/Tasks/Metadata/CoverDbService.cs | 12 +++++++++++- 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/API/Constants/CacheProfiles.cs b/API/Constants/CacheProfiles.cs index ccbbf2479..afc82f19c 100644 --- a/API/Constants/CacheProfiles.cs +++ b/API/Constants/CacheProfiles.cs @@ -8,6 +8,10 @@ public static class EasyCacheProfiles public const string RevokedJwt = "revokedJWT"; public const string Favicon = "favicon"; /// + /// Images for Publishers + /// + public const string Publisher = "publisherImages"; + /// /// If a user's license is valid /// public const string License = "license"; diff --git a/API/Controllers/ChapterController.cs b/API/Controllers/ChapterController.cs index 596731345..ca270d7a8 100644 --- a/API/Controllers/ChapterController.cs +++ b/API/Controllers/ChapterController.cs @@ -397,7 +397,11 @@ public class ChapterController : BaseApiController return Ok(); } - + /// + /// Returns Ratings and Reviews for an individual Chapter + /// + /// + /// [HttpGet("chapter-detail-plus")] public async Task> ChapterDetailPlus([FromQuery] int chapterId) { @@ -425,7 +429,7 @@ public class ChapterController : BaseApiController ret.Ratings = await _unitOfWork.ChapterRepository.GetExternalChapterRatings(chapterId); - return ret; + return Ok(ret); } } diff --git a/API/Controllers/RatingController.cs b/API/Controllers/RatingController.cs index c577239ed..9283ef6d3 100644 --- a/API/Controllers/RatingController.cs +++ b/API/Controllers/RatingController.cs @@ -68,6 +68,11 @@ public class RatingController : BaseApiController return BadRequest(await _localizationService.Translate(User.GetUserId(), "generic-error")); } + /// + /// Overall rating from all Kavita users for a given Series + /// + /// + /// [HttpGet("overall-series")] public async Task> GetOverallSeriesRating(int seriesId) { @@ -79,6 +84,11 @@ public class RatingController : BaseApiController }); } + /// + /// Overall rating from all Kavita users for a given Chapter + /// + /// + /// [HttpGet("overall-chapter")] public async Task> GetOverallChapterRating(int chapterId) { diff --git a/API/Data/Repositories/UserRepository.cs b/API/Data/Repositories/UserRepository.cs index e75b82430..e55338c8b 100644 --- a/API/Data/Repositories/UserRepository.cs +++ b/API/Data/Repositories/UserRepository.cs @@ -590,14 +590,14 @@ public class UserRepository : IUserRepository { return await _context.AppUserRating .Where(r => r.SeriesId == seriesId && r.AppUserId == userId) - .SingleOrDefaultAsync(); + .FirstOrDefaultAsync(); } public async Task GetUserChapterRatingAsync(int userId, int chapterId) { return await _context.AppUserChapterRating .Where(r => r.AppUserId == userId && r.ChapterId == chapterId) - .SingleOrDefaultAsync(); + .FirstOrDefaultAsync(); } public async Task> GetUserRatingDtosForSeriesAsync(int seriesId, int userId) diff --git a/API/Extensions/ApplicationServiceExtensions.cs b/API/Extensions/ApplicationServiceExtensions.cs index 6b91de60b..e004fcc25 100644 --- a/API/Extensions/ApplicationServiceExtensions.cs +++ b/API/Extensions/ApplicationServiceExtensions.cs @@ -85,6 +85,7 @@ public static class ApplicationServiceExtensions services.AddEasyCaching(options => { options.UseInMemory(EasyCacheProfiles.Favicon); + options.UseInMemory(EasyCacheProfiles.Publisher); options.UseInMemory(EasyCacheProfiles.Library); options.UseInMemory(EasyCacheProfiles.RevokedJwt); options.UseInMemory(EasyCacheProfiles.LocaleOptions); diff --git a/API/Services/Tasks/Metadata/CoverDbService.cs b/API/Services/Tasks/Metadata/CoverDbService.cs index c76bb99d1..5f32404b9 100644 --- a/API/Services/Tasks/Metadata/CoverDbService.cs +++ b/API/Services/Tasks/Metadata/CoverDbService.cs @@ -45,6 +45,7 @@ public class CoverDbService : ICoverDbService private readonly IImageService _imageService; private readonly IUnitOfWork _unitOfWork; private readonly IEventHub _eventHub; + private TimeSpan _cacheTime = TimeSpan.FromDays(10); private const string NewHost = "https://www.kavitareader.com/CoversDB/"; @@ -97,7 +98,7 @@ public class CoverDbService : ICoverDbService throw new KavitaException($"Kavita has already tried to fetch from {sanitizedBaseUrl} and failed. Skipping duplicate check"); } - await provider.SetAsync(baseUrl, string.Empty, TimeSpan.FromDays(10)); + await provider.SetAsync(baseUrl, string.Empty, _cacheTime); if (FaviconUrlMapper.TryGetValue(baseUrl, out var value)) { url = value; @@ -185,6 +186,15 @@ public class CoverDbService : ICoverDbService { try { + var provider = _cacheFactory.GetCachingProvider(EasyCacheProfiles.Publisher); + var res = await provider.GetAsync(publisherName); + if (res.HasValue) + { + _logger.LogInformation("Kavita has already tried to fetch Publisher: {PublisherName} and failed. Skipping duplicate check", publisherName); + throw new KavitaException($"Kavita has already tried to fetch Publisher: {publisherName} and failed. Skipping duplicate check"); + } + + await provider.SetAsync(publisherName, string.Empty, _cacheTime); var publisherLink = await FallbackToKavitaReaderPublisher(publisherName); if (string.IsNullOrEmpty(publisherLink)) {