diff --git a/API/Constants/ResponseCacheProfiles.cs b/API/Constants/ResponseCacheProfiles.cs index 1a092d84e..d7dcaf95b 100644 --- a/API/Constants/ResponseCacheProfiles.cs +++ b/API/Constants/ResponseCacheProfiles.cs @@ -16,5 +16,5 @@ public static class ResponseCacheProfiles public const string Instant = "Instant"; public const string Month = "Month"; public const string LicenseCache = "LicenseCache"; - public const string Recommendation = "Recommendation"; + public const string KavitaPlus = "KavitaPlus"; } diff --git a/API/Controllers/LicenseController.cs b/API/Controllers/LicenseController.cs index b00f6d07f..e0280f78c 100644 --- a/API/Controllers/LicenseController.cs +++ b/API/Controllers/LicenseController.cs @@ -65,7 +65,7 @@ public class LicenseController : BaseApiController } /// - /// Updates server license. Returns true if updated and valid + /// Updates server license /// /// Caches the result /// diff --git a/API/Controllers/RatingController.cs b/API/Controllers/RatingController.cs index accd6ccaa..4b816bab7 100644 --- a/API/Controllers/RatingController.cs +++ b/API/Controllers/RatingController.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using API.Constants; +using API.Data; using API.DTOs; using API.Services.Plus; using EasyCaching.Core; @@ -18,15 +20,17 @@ public class RatingController : BaseApiController private readonly ILicenseService _licenseService; private readonly IRatingService _ratingService; private readonly ILogger _logger; + private readonly IUnitOfWork _unitOfWork; private readonly IEasyCachingProvider _cacheProvider; public const string CacheKey = "rating_"; public RatingController(ILicenseService licenseService, IRatingService ratingService, - ILogger logger, IEasyCachingProviderFactory cachingProviderFactory) + ILogger logger, IEasyCachingProviderFactory cachingProviderFactory, IUnitOfWork unitOfWork) { _licenseService = licenseService; _ratingService = ratingService; _logger = logger; + _unitOfWork = unitOfWork; _cacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings); } @@ -37,12 +41,13 @@ public class RatingController : BaseApiController /// /// [HttpGet] - [ResponseCache(CacheProfileName = ResponseCacheProfiles.Recommendation, VaryByQueryKeys = new []{"seriesId"})] + [ResponseCache(CacheProfileName = ResponseCacheProfiles.KavitaPlus, VaryByQueryKeys = new []{"seriesId"})] public async Task>> GetRating(int seriesId) { + if (!await _licenseService.HasActiveLicense()) { - return Ok(new List()); + return Ok(Enumerable.Empty()); } var cacheKey = CacheKey + seriesId; @@ -56,6 +61,16 @@ public class RatingController : BaseApiController await _cacheProvider.SetAsync(cacheKey, ratings, TimeSpan.FromHours(24)); _logger.LogDebug("Caching external rating for {Key}", cacheKey); return Ok(ratings); + } + [HttpGet("overall")] + public async Task> GetOverallRating(int seriesId) + { + return Ok(new RatingDto() + { + Provider = ScrobbleProvider.Kavita, + AverageScore = await _unitOfWork.SeriesRepository.GetAverageUserRating(seriesId), + FavoriteCount = 0 + }); } } diff --git a/API/Controllers/RecommendedController.cs b/API/Controllers/RecommendedController.cs index 14c9b7bfc..efadb6d60 100644 --- a/API/Controllers/RecommendedController.cs +++ b/API/Controllers/RecommendedController.cs @@ -39,7 +39,7 @@ public class RecommendedController : BaseApiController /// /// [HttpGet("recommendations")] - [ResponseCache(CacheProfileName = ResponseCacheProfiles.Recommendation, VaryByQueryKeys = new []{"seriesId"})] + [ResponseCache(CacheProfileName = ResponseCacheProfiles.KavitaPlus, VaryByQueryKeys = new []{"seriesId"})] public async Task> GetRecommendations(int seriesId) { var userId = User.GetUserId(); diff --git a/API/Controllers/ReviewController.cs b/API/Controllers/ReviewController.cs index 938e5fc77..27508f1ce 100644 --- a/API/Controllers/ReviewController.cs +++ b/API/Controllers/ReviewController.cs @@ -51,7 +51,7 @@ public class ReviewController : BaseApiController /// /// [HttpGet] - [ResponseCache(CacheProfileName = ResponseCacheProfiles.Recommendation, VaryByQueryKeys = new []{"seriesId"})] + [ResponseCache(CacheProfileName = ResponseCacheProfiles.KavitaPlus, VaryByQueryKeys = new []{"seriesId"})] public async Task>> GetReviews(int seriesId) { var userId = User.GetUserId(); diff --git a/API/Controllers/ServerController.cs b/API/Controllers/ServerController.cs index 03b8689f8..22b871529 100644 --- a/API/Controllers/ServerController.cs +++ b/API/Controllers/ServerController.cs @@ -241,7 +241,7 @@ public class ServerController : BaseApiController /// - /// Bust Review and Recommendation Cache + /// Bust Kavita+ Cache /// /// [Authorize("RequireAdminRole")] @@ -250,12 +250,12 @@ public class ServerController : BaseApiController { _logger.LogInformation("Busting Kavita+ Cache"); var provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusReviews); - await provider.FlushAsync(); - provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRecommendations); - await provider.FlushAsync(); - provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings); - await provider.FlushAsync(); - return Ok(); + await provider.FlushAsync(); + provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRecommendations); + await provider.FlushAsync(); + provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings); + await provider.FlushAsync(); + return Ok(); } diff --git a/API/DTOs/SeriesDetail/UserReviewDto.cs b/API/DTOs/SeriesDetail/UserReviewDto.cs index f4f94ebd7..4f74dadbb 100644 --- a/API/DTOs/SeriesDetail/UserReviewDto.cs +++ b/API/DTOs/SeriesDetail/UserReviewDto.cs @@ -1,4 +1,6 @@ -namespace API.DTOs.SeriesDetail; +using API.Services.Plus; + +namespace API.DTOs.SeriesDetail; /// /// Represents a User Review for a given Series @@ -48,4 +50,9 @@ public class UserReviewDto /// The main body with just text, for review preview /// public string? BodyJustText { get; set; } + + /// + /// If this review is External, which Provider did it come from + /// + public ScrobbleProvider Provider { get; set; } = ScrobbleProvider.Kavita; } diff --git a/API/Data/Repositories/SeriesRepository.cs b/API/Data/Repositories/SeriesRepository.cs index 80b00a8c5..dfa85dcad 100644 --- a/API/Data/Repositories/SeriesRepository.cs +++ b/API/Data/Repositories/SeriesRepository.cs @@ -135,8 +135,8 @@ public interface ISeriesRepository Task> GetLibraryIdsForSeriesAsync(); Task> GetSeriesMetadataForIds(IEnumerable seriesIds); Task> GetAllWithCoversInDifferentEncoding(EncodeFormat encodeFormat, bool customOnly = true); - Task GetSeriesDtoByNamesAndMetadataIdsForUser(int userId, IEnumerable names, LibraryType libraryType, string aniListUrl, string malUrl); + Task GetAverageUserRating(int seriesId); } public class SeriesRepository : ISeriesRepository @@ -1658,6 +1658,18 @@ public class SeriesRepository : ISeriesRepository .FirstOrDefaultAsync(); // Some users may have improperly configured libraries } + /// + /// Returns the Average rating for all users within Kavita instance + /// + /// + public async Task GetAverageUserRating(int seriesId) + { + var avg = (await _context.AppUserRating + .Where(r => r.SeriesId == seriesId) + .AverageAsync(r => (int?) r.Rating)); + return avg.HasValue ? (int) avg.Value : 0; + } + public async Task IsSeriesInWantToRead(int userId, int seriesId) { var libraryIds = await _context.Library.GetUserLibraries(userId).ToListAsync(); diff --git a/API/Data/Seed.cs b/API/Data/Seed.cs index d903496ae..93c01d6ed 100644 --- a/API/Data/Seed.cs +++ b/API/Data/Seed.cs @@ -133,6 +133,8 @@ public static class Seed directoryService.CacheDirectory + string.Empty; context.ServerSetting.First(s => s.Key == ServerSettingKey.BackupDirectory).Value = DirectoryService.BackupDirectory + string.Empty; + context.ServerSetting.First(s => s.Key == ServerSettingKey.CacheSize).Value = + Configuration.CacheSize + string.Empty; await context.SaveChangesAsync(); } diff --git a/API/Services/Plus/LicenseService.cs b/API/Services/Plus/LicenseService.cs index ddd67791e..0a2b25cea 100644 --- a/API/Services/Plus/LicenseService.cs +++ b/API/Services/Plus/LicenseService.cs @@ -130,11 +130,13 @@ public class LicenseService : ILicenseService { try { + var license = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.LicenseKey); + if (string.IsNullOrEmpty(license.Value)) return; + _logger.LogInformation("Validating Kavita+ License"); var provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.License); await provider.FlushAsync(); - var license = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.LicenseKey); var isValid = await IsLicenseValid(license.Value); await provider.SetAsync(CacheKey, isValid, _licenseCacheTimeout); diff --git a/API/Services/Plus/ScrobblingService.cs b/API/Services/Plus/ScrobblingService.cs index 61ab9d688..1d1829c3b 100644 --- a/API/Services/Plus/ScrobblingService.cs +++ b/API/Services/Plus/ScrobblingService.cs @@ -22,9 +22,17 @@ using Microsoft.Extensions.Logging; namespace API.Services.Plus; +/// +/// Misleading name but is the source of data (like a review coming from AniList) +/// public enum ScrobbleProvider { - AniList = 1 + /// + /// For now, this means data comes from within this instance of Kavita + /// + Kavita = 0, + AniList = 1, + Mal = 2, } public interface IScrobblingService diff --git a/API/Services/ReviewService.cs b/API/Services/ReviewService.cs index 597e7bbe9..a0f4d18f5 100644 --- a/API/Services/ReviewService.cs +++ b/API/Services/ReviewService.cs @@ -35,6 +35,7 @@ internal class MediaReviewDto /// public string RawBody { get; set; } public string Username { get; set; } + public ScrobbleProvider Provider { get; set; } } public interface IReviewService @@ -74,6 +75,7 @@ public class ReviewService : IReviewService LibraryId = series.LibraryId, SeriesId = series.Id, IsExternal = true, + Provider = r.Provider, BodyJustText = GetCharacters(r.Body), ExternalUrl = r.SiteUrl }); diff --git a/API/Startup.cs b/API/Startup.cs index 90a104158..64f2a3f73 100644 --- a/API/Startup.cs +++ b/API/Startup.cs @@ -116,7 +116,7 @@ public class Startup Location = ResponseCacheLocation.Client, NoStore = false }); - options.CacheProfiles.Add(ResponseCacheProfiles.Recommendation, + options.CacheProfiles.Add(ResponseCacheProfiles.KavitaPlus, new CacheProfile() { Duration = TimeSpan.FromDays(30).Seconds, diff --git a/Kavita.Common/HashUtil.cs b/Kavita.Common/HashUtil.cs index d3757085d..aace6bd13 100644 --- a/Kavita.Common/HashUtil.cs +++ b/Kavita.Common/HashUtil.cs @@ -51,9 +51,7 @@ public static class HashUtil .AddComponent("ProcessorCount", new DeviceIdComponent($"{Environment.ProcessorCount}")) .AddComponent("OSPlatform", new DeviceIdComponent($"{Environment.OSVersion.Platform}")) .OnWindows(windows => windows - .AddSystemUuid() - .AddMotherboardSerialNumber() - .AddSystemDriveSerialNumber()) + .AddProcessorId()) .OnLinux(linux => { var osInfo = RunAndCapture("uname", "-a"); diff --git a/UI/Web/src/app/_services/scrobbling.service.ts b/UI/Web/src/app/_services/scrobbling.service.ts index adb974467..e815410f7 100644 --- a/UI/Web/src/app/_services/scrobbling.service.ts +++ b/UI/Web/src/app/_services/scrobbling.service.ts @@ -24,8 +24,9 @@ import {UtilityService} from "../shared/_services/utility.service"; import {ReadingList} from "../_models/reading-list"; export enum ScrobbleProvider { + Kavita = 0, AniList= 1, - Mal = 2 + Mal = 2, } @Injectable({ diff --git a/UI/Web/src/app/_services/series.service.ts b/UI/Web/src/app/_services/series.service.ts index 3b95e0fa8..b7359a8f6 100644 --- a/UI/Web/src/app/_services/series.service.ts +++ b/UI/Web/src/app/_services/series.service.ts @@ -32,12 +32,12 @@ export class SeriesService { paginatedSeriesForTagsResults: PaginatedResult = new PaginatedResult(); constructor(private httpClient: HttpClient, private imageService: ImageService, - private utilityService: UtilityService, private filterUtilitySerivce: FilterUtilitiesService) { } + private utilityService: UtilityService, private filterUtilityService: FilterUtilitiesService) { } getAllSeries(pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) { let params = new HttpParams(); params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage); - const data = this.filterUtilitySerivce.createSeriesFilter(filter); + const data = this.filterUtilityService.createSeriesFilter(filter); return this.httpClient.post>(this.baseUrl + 'series/all', data, {observe: 'response', params}).pipe( map((response: any) => { @@ -49,7 +49,7 @@ export class SeriesService { getSeriesForLibrary(libraryId: number, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) { let params = new HttpParams(); params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage); - const data = this.filterUtilitySerivce.createSeriesFilter(filter); + const data = this.filterUtilityService.createSeriesFilter(filter); return this.httpClient.post>(this.baseUrl + 'series?libraryId=' + libraryId, data, {observe: 'response', params}).pipe( map((response: any) => { @@ -103,7 +103,7 @@ export class SeriesService { } getRecentlyAdded(libraryId: number = 0, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) { - const data = this.filterUtilitySerivce.createSeriesFilter(filter); + const data = this.filterUtilityService.createSeriesFilter(filter); let params = new HttpParams(); params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage); @@ -119,7 +119,7 @@ export class SeriesService { } getWantToRead(pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter): Observable> { - const data = this.filterUtilitySerivce.createSeriesFilter(filter); + const data = this.filterUtilityService.createSeriesFilter(filter); let params = new HttpParams(); params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage); @@ -138,7 +138,7 @@ export class SeriesService { } getOnDeck(libraryId: number = 0, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) { - const data = this.filterUtilitySerivce.createSeriesFilter(filter); + const data = this.filterUtilityService.createSeriesFilter(filter); let params = new HttpParams(); params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage); @@ -223,4 +223,7 @@ export class SeriesService { getRatings(seriesId: number) { return this.httpClient.get>(this.baseUrl + 'rating?seriesId=' + seriesId); } + getOverallRating(seriesId: number) { + return this.httpClient.get(this.baseUrl + 'rating/overall?seriesId=' + seriesId); + } } diff --git a/UI/Web/src/app/_single-module/review-card/review-card.component.html b/UI/Web/src/app/_single-module/review-card/review-card.component.html index 46360a1a6..5e912aba8 100644 --- a/UI/Web/src/app/_single-module/review-card/review-card.component.html +++ b/UI/Web/src/app/_single-module/review-card/review-card.component.html @@ -19,9 +19,15 @@

- + diff --git a/UI/Web/src/app/_single-module/review-card/review-card.component.scss b/UI/Web/src/app/_single-module/review-card/review-card.component.scss index f1794eba6..62bf3e443 100644 --- a/UI/Web/src/app/_single-module/review-card/review-card.component.scss +++ b/UI/Web/src/app/_single-module/review-card/review-card.component.scss @@ -8,7 +8,10 @@ z-index: 20; top: 38px; left: 38px; - color: var(--review-card-star-color); +} + +.fa-star { + color: var(--review-card-star-color); } .card-text { @@ -29,10 +32,6 @@ overflow: hidden; } -.card-footer { - width: 288px; -} - .card { cursor: pointer; } diff --git a/UI/Web/src/app/_single-module/review-card/review-card.component.ts b/UI/Web/src/app/_single-module/review-card/review-card.component.ts index 13811735f..154f0cd72 100644 --- a/UI/Web/src/app/_single-module/review-card/review-card.component.ts +++ b/UI/Web/src/app/_single-module/review-card/review-card.component.ts @@ -1,5 +1,5 @@ import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core'; -import {CommonModule} from '@angular/common'; +import {CommonModule, NgOptimizedImage} from '@angular/common'; import {UserReview} from "./user-review"; import {NgbModal} from "@ng-bootstrap/ng-bootstrap"; import {ReviewCardModalComponent} from "../review-card-modal/review-card-modal.component"; @@ -7,11 +7,13 @@ import {AccountService} from "../../_services/account.service"; import {ReviewSeriesModalComponent} from "../review-series-modal/review-series-modal.component"; import {ReadMoreComponent} from "../../shared/read-more/read-more.component"; import {DefaultValuePipe} from "../../pipe/default-value.pipe"; +import {ImageComponent} from "../../shared/image/image.component"; +import {ProviderImagePipe} from "../../pipe/provider-image.pipe"; @Component({ selector: 'app-review-card', standalone: true, - imports: [CommonModule, ReadMoreComponent, DefaultValuePipe], + imports: [CommonModule, ReadMoreComponent, DefaultValuePipe, ImageComponent, NgOptimizedImage, ProviderImagePipe], templateUrl: './review-card.component.html', styleUrls: ['./review-card.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush diff --git a/UI/Web/src/app/_single-module/review-card/user-review.ts b/UI/Web/src/app/_single-module/review-card/user-review.ts index 1e0371fc8..f735d9548 100644 --- a/UI/Web/src/app/_single-module/review-card/user-review.ts +++ b/UI/Web/src/app/_single-module/review-card/user-review.ts @@ -1,3 +1,5 @@ +import {ScrobbleProvider} from "../../_services/scrobbling.service"; + export interface UserReview { seriesId: number; libraryId: number; @@ -8,4 +10,5 @@ export interface UserReview { isExternal: boolean; bodyJustText?: string; externalUrl?: string; + provider: ScrobbleProvider; } diff --git a/UI/Web/src/app/admin/dashboard/dashboard.component.html b/UI/Web/src/app/admin/dashboard/dashboard.component.html index 72dcdd961..bde8a9633 100644 --- a/UI/Web/src/app/admin/dashboard/dashboard.component.html +++ b/UI/Web/src/app/admin/dashboard/dashboard.component.html @@ -36,12 +36,9 @@ -

Kavita+ is a premium subscription service which unlocks features for all users on this Kavita instance. Buy a subscription to unlock premium benefits today! FAQ

+

Kavita+ is a premium subscription service which unlocks features for all users on this Kavita instance. Buy a subscription to unlock premium benefits today! FAQ

- - Nothing here yet. This will be built out in a future update. - diff --git a/UI/Web/src/app/admin/manage-settings/manage-settings.component.html b/UI/Web/src/app/admin/manage-settings/manage-settings.component.html index ae15a31b2..36bdd6dd2 100644 --- a/UI/Web/src/app/admin/manage-settings/manage-settings.component.html +++ b/UI/Web/src/app/admin/manage-settings/manage-settings.component.html @@ -100,7 +100,7 @@
  - The amount of memory allowed for caching heavy APIs. Default is 50MB. + The amount of memory allowed for caching heavy APIs. Default is 75MB. The amount of memory allowed for caching heavy APIs. Default is 50MB. -
+
- {{userRating * 20}}% + {{userRating * 20}} + + {{overallRating}}% + %
-
+
{{rating.averageScore}}% @@ -23,5 +26,9 @@ - + {{userRating * 20}}% + + + + {{rating.favoriteCount}} diff --git a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss index 816baab5e..bf59d1ef5 100644 --- a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss +++ b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss @@ -2,3 +2,21 @@ padding-left: 0px; padding-right: 0px; } + +.sm-popover { + width: 150px; + + > .popover-body { + padding-top: 0px; + } +} + +.md-popover { + width: 214px; + + > .popover-body { + padding-top: 0px; + } +} + + diff --git a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts index 8471d6090..e4b4d10a4 100644 --- a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts +++ b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts @@ -1,4 +1,12 @@ -import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + inject, + Input, + OnInit, + ViewEncapsulation +} from '@angular/core'; import {CommonModule, NgOptimizedImage} from '@angular/common'; import {SeriesService} from "../../../_services/series.service"; import {Rating} from "../../../_models/rating"; @@ -7,14 +15,16 @@ import {NgbPopover, NgbRating} from "@ng-bootstrap/ng-bootstrap"; import {LoadingComponent} from "../../../shared/loading/loading.component"; import {AccountService} from "../../../_services/account.service"; import {LibraryType} from "../../../_models/library"; +import {ProviderNamePipe} from "../../../pipe/provider-name.pipe"; @Component({ selector: 'app-external-rating', standalone: true, - imports: [CommonModule, ProviderImagePipe, NgOptimizedImage, NgbRating, NgbPopover, LoadingComponent], + imports: [CommonModule, ProviderImagePipe, NgOptimizedImage, NgbRating, NgbPopover, LoadingComponent, ProviderNamePipe], templateUrl: './external-rating.component.html', styleUrls: ['./external-rating.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None }) export class ExternalRatingComponent implements OnInit { @Input({required: true}) seriesId!: number; @@ -26,10 +36,13 @@ export class ExternalRatingComponent implements OnInit { ratings: Array = []; isLoading: boolean = false; + overallRating: number = -1; ngOnInit() { + this.seriesService.getOverallRating(this.seriesId).subscribe(r => this.overallRating = r.averageScore); + this.accountService.hasValidLicense$.subscribe((res) => { if (!res) return; this.isLoading = true; diff --git a/UI/Web/src/environments/environment.ts b/UI/Web/src/environments/environment.ts index 05f42e187..11db3c23e 100644 --- a/UI/Web/src/environments/environment.ts +++ b/UI/Web/src/environments/environment.ts @@ -6,7 +6,7 @@ export const environment = { production: false, apiUrl: 'http://localhost:5000/api/', hubUrl: 'http://localhost:5000/hubs/', - buyLink: 'https://buy.stripe.com/test_8wM4ie2dg5j77o4cMO?prefilled_promo_code=FREETRIAL', + buyLink: 'https://buy.stripe.com/test_9AQ5mi058h1PcIo3cf?prefilled_promo_code=FREETRIAL', manageLink: 'https://billing.stripe.com/p/login/test_14kfZocuh6Tz5ag7ss' }; diff --git a/openapi.json b/openapi.json index 6fcfd6a94..d5a266433 100644 --- a/openapi.json +++ b/openapi.json @@ -7,7 +7,7 @@ "name": "GPL-3.0", "url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE" }, - "version": "0.7.4.1" + "version": "0.7.4.2" }, "servers": [ { @@ -2827,7 +2827,7 @@ "tags": [ "License" ], - "summary": "Updates server license. Returns true if updated and valid", + "summary": "Updates server license", "description": "Caches the result", "requestBody": { "content": { @@ -3947,6 +3947,45 @@ } } }, + "/api/Rating/overall": { + "get": { + "tags": [ + "Rating" + ], + "parameters": [ + { + "name": "seriesId", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/RatingDto" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/RatingDto" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/RatingDto" + } + } + } + } + } + } + }, "/api/Reader/pdf": { "get": { "tags": [ @@ -6525,9 +6564,12 @@ "in": "query", "schema": { "enum": [ - 1 + 0, + 1, + 2 ], "type": "integer", + "description": "Misleading name but is the source of data (like a review coming from AniList)", "format": "int32" } } @@ -8540,7 +8582,7 @@ "tags": [ "Server" ], - "summary": "Bust Review and Recommendation Cache", + "summary": "Bust Kavita+ Cache", "responses": { "200": { "description": "Success" @@ -13731,9 +13773,12 @@ }, "provider": { "enum": [ - 1 + 0, + 1, + 2 ], "type": "integer", + "description": "Misleading name but is the source of data (like a review coming from AniList)", "format": "int32" } }, @@ -17180,6 +17225,16 @@ "type": "string", "description": "The main body with just text, for review preview", "nullable": true + }, + "provider": { + "enum": [ + 0, + 1, + 2 + ], + "type": "integer", + "description": "If this review is External, which Provider did it come from", + "format": "int32" } }, "additionalProperties": false,