#nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using API.Data; using API.Data.Repositories; using API.DTOs; using API.Extensions; using API.Services; using AutoMapper; using Kavita.Common; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; namespace API.Controllers; public class ReadingProfileController(ILogger logger, IUnitOfWork unitOfWork, IReadingProfileService readingProfileService): BaseApiController { /// /// Gets all non-implicit reading profiles for a user /// /// [HttpGet("all")] public async Task>> GetAllReadingProfiles() { var profiles = await unitOfWork.AppUserReadingProfileRepository .GetProfilesDtoForUser(User.GetUserId(), true, ReadingProfileIncludes.Series | ReadingProfileIncludes.Library); return Ok(profiles); } /// /// Returns the ReadingProfile that should be applied to the given series, walks up the tree. /// Series -> Library -> Default /// /// /// [HttpGet("{seriesId}")] public async Task> GetProfileForSeries(int seriesId) { return Ok(await readingProfileService.GetReadingProfileForSeries(User.GetUserId(), seriesId)); } /// /// Updates the given reading profile, must belong to the current user /// /// /// /// Optionally, from which series the update is called. /// If set, will delete the implicit reading profile if it exists /// /// /// This does not update connected series, and libraries. Use /// , , /// , /// [HttpPost] public async Task UpdateReadingProfile([FromBody] UserReadingProfileDto dto, [FromQuery] int? seriesCtx) { if (seriesCtx.HasValue) { await readingProfileService.DeleteImplicitForSeries(User.GetUserId(), seriesCtx.Value); } var success = await readingProfileService.UpdateReadingProfile(User.GetUserId(), dto); if (!success) return BadRequest(); return Ok(); } /// /// Creates a new reading profile for the current user /// /// /// [HttpPost("create")] public async Task> CreateReadingProfile([FromBody] UserReadingProfileDto dto) { return Ok(await readingProfileService.CreateReadingProfile(User.GetUserId(), dto)); } /// /// Update the implicit reading profile for a series, creates one if none exists /// /// /// /// [HttpPost("series")] public async Task UpdateReadingProfileForSeries([FromBody] UserReadingProfileDto dto, [FromQuery] int seriesId) { var success = await readingProfileService.UpdateImplicitReadingProfile(User.GetUserId(), seriesId, dto); if (!success) return BadRequest(); return Ok(); } /// /// Sets the given profile as the global default /// /// /// /// /// [HttpPost("set-default")] public async Task SetDefault([FromQuery] int profileId) { await readingProfileService.SetDefaultReadingProfile(User.GetUserId(), profileId); return Ok(); } /// /// Deletes the given profile, requires the profile to belong to the logged-in user /// /// /// /// /// [HttpDelete] public async Task DeleteReadingProfile([FromQuery] int profileId) { await readingProfileService.DeleteReadingProfile(User.GetUserId(), profileId); return Ok(); } /// /// Sets the reading profile for a given series, removes the old one /// /// /// /// [HttpPost("series/{seriesId}")] public async Task AddProfileToSeries(int seriesId, [FromQuery] int profileId) { await readingProfileService.AddProfileToSeries(User.GetUserId(), profileId, seriesId); return Ok(); } /// /// Deletes the reading profile from a series for the current logged-in user /// /// /// /// [HttpDelete("series/{seriesId}")] public async Task DeleteProfileFromSeries(int seriesId, [FromQuery] int profileId) { await readingProfileService.RemoveProfileFromSeries(User.GetUserId(), profileId, seriesId); return Ok(); } /// /// Sets the reading profile for a given library, removes the old one /// /// /// /// [HttpPost("library/{libraryId}")] public async Task AddProfileToLibrary(int libraryId, [FromQuery] int profileId) { await readingProfileService.AddProfileToLibrary(User.GetUserId(), profileId, libraryId); return Ok(); } /// /// Remove the reading profile from a library for the current logged-in user /// /// /// /// [HttpDelete("library/{libraryId}")] public async Task DeleteProfileFromLibrary(int libraryId, [FromQuery] int profileId) { await readingProfileService.RemoveProfileFromLibrary(User.GetUserId(), profileId, libraryId); return Ok(); } }