Correctly remove implicit profiles when updating

- Add actions (library actions aren't working ?)
- Auto update for implicit is going off too often
This commit is contained in:
Amelia 2025-05-30 12:58:47 +02:00
parent 823121f335
commit 558a1d73f5
No known key found for this signature in database
GPG key ID: D6D0ECE365407EAA
14 changed files with 242 additions and 73 deletions

View file

@ -127,15 +127,14 @@ public class ReadingProfileController(ILogger<ReadingProfileController> logger,
}
/// <summary>
/// Deletes the reading profile from a series for the current logged-in user
/// Clears the reading profile for the given series for the currently logged-in user
/// </summary>
/// <param name="seriesId"></param>
/// <param name="profileId"></param>
/// <returns></returns>
[HttpDelete("series/{seriesId}")]
public async Task<IActionResult> DeleteProfileFromSeries(int seriesId, [FromQuery] int profileId)
public async Task<IActionResult> ClearSeriesProfile(int seriesId)
{
await readingProfileService.RemoveProfileFromSeries(User.GetUserId(), profileId, seriesId);
await readingProfileService.ClearSeriesProfile(User.GetUserId(), seriesId);
return Ok();
}
@ -153,15 +152,15 @@ public class ReadingProfileController(ILogger<ReadingProfileController> logger,
}
/// <summary>
/// Remove the reading profile from a library for the current logged-in user
/// Clears the reading profile for the given library for the currently logged-in user
/// </summary>
/// <param name="libraryId"></param>
/// <param name="profileId"></param>
/// <returns></returns>
[HttpDelete("library/{libraryId}")]
public async Task<IActionResult> DeleteProfileFromLibrary(int libraryId, [FromQuery] int profileId)
public async Task<IActionResult> ClearLibraryProfile(int libraryId)
{
await readingProfileService.RemoveProfileFromLibrary(User.GetUserId(), profileId, libraryId);
await readingProfileService.ClearLibraryProfile(User.GetUserId(), libraryId);
return Ok();
}
@ -171,10 +170,10 @@ public class ReadingProfileController(ILogger<ReadingProfileController> logger,
/// <param name="profileId"></param>
/// <param name="seriesIds"></param>
/// <returns></returns>
[HttpPost("batch")]
public async Task<IActionResult> BatchAddReadingProfile([FromQuery] int profileId, [FromBody] IList<int> seriesIds)
[HttpPost("bulk")]
public async Task<IActionResult> BulkAddReadingProfile([FromQuery] int profileId, [FromBody] IList<int> seriesIds)
{
await readingProfileService.BatchAddProfileToSeries(User.GetUserId(), profileId, seriesIds);
await readingProfileService.BulkAddProfileToSeries(User.GetUserId(), profileId, seriesIds);
return Ok();
}

View file

@ -26,6 +26,14 @@ public interface IAppUserReadingProfileRepository
Task<IList<AppUserReadingProfile>> GetProfilesForUser(int userId, bool nonImplicitOnly, ReadingProfileIncludes includes = ReadingProfileIncludes.None);
Task<IList<UserReadingProfileDto>> GetProfilesDtoForUser(int userId, bool nonImplicitOnly, ReadingProfileIncludes includes = ReadingProfileIncludes.None);
Task<AppUserReadingProfile?> GetProfileForSeries(int userId, int seriesId, ReadingProfileIncludes includes = ReadingProfileIncludes.None);
/// <summary>
/// Returns both implicit and "real" reading profiles
/// </summary>
/// <param name="userId"></param>
/// <param name="seriesId"></param>
/// <param name="includes"></param>
/// <returns></returns>
Task<IList<AppUserReadingProfile>> GetAllProfilesForSeries(int userId, int seriesId, ReadingProfileIncludes includes = ReadingProfileIncludes.None);
Task<IList<AppUserReadingProfile>> GetProfilesForSeries(int userId, IList<int> seriesIds, bool implicitOnly, ReadingProfileIncludes includes = ReadingProfileIncludes.None);
Task<UserReadingProfileDto?> GetProfileDtoForSeries(int userId, int seriesId);
Task<AppUserReadingProfile?> GetProfileForLibrary(int userId, int libraryId, ReadingProfileIncludes includes = ReadingProfileIncludes.None);
@ -76,6 +84,14 @@ public class AppUserReadingProfileRepository(DataContext context, IMapper mapper
.FirstOrDefaultAsync();
}
public async Task<IList<AppUserReadingProfile>> GetAllProfilesForSeries(int userId, int seriesId, ReadingProfileIncludes includes = ReadingProfileIncludes.None)
{
return await context.AppUserReadingProfile
.Where(rp => rp.UserId == userId && rp.Series.Any(s => s.SeriesId == seriesId))
.Includes(includes)
.ToListAsync();
}
public async Task<IList<AppUserReadingProfile>> GetProfilesForSeries(int userId, IList<int> seriesIds, bool implicitOnly, ReadingProfileIncludes includes = ReadingProfileIncludes.None)
{
return await context.AppUserReadingProfile

View file

@ -68,11 +68,11 @@ public interface IReadingProfileService
Task SetDefaultReadingProfile(int userId, int profileId);
Task AddProfileToSeries(int userId, int profileId, int seriesId);
Task BatchAddProfileToSeries(int userId, int profileId, IList<int> seriesIds);
Task RemoveProfileFromSeries(int userId, int profileId, int seriesId);
Task BulkAddProfileToSeries(int userId, int profileId, IList<int> seriesIds);
Task ClearSeriesProfile(int userId, int seriesId);
Task AddProfileToLibrary(int userId, int profileId, int libraryId);
Task RemoveProfileFromLibrary(int userId, int profileId, int libraryId);
Task ClearLibraryProfile(int userId, int libraryId);
}
@ -200,6 +200,10 @@ public class ReadingProfileService(IUnitOfWork unitOfWork, ILocalizationService
if (profile.UserId != userId) throw new UnauthorizedAccessException();
// Remove all implicit profiles
var implicitProfiles = await unitOfWork.AppUserReadingProfileRepository.GetProfilesForSeries(userId, [seriesId], true);
unitOfWork.AppUserReadingProfileRepository.RemoveRange(implicitProfiles);
var seriesProfile = await unitOfWork.AppUserReadingProfileRepository.GetSeriesProfile(userId, seriesId);
if (seriesProfile != null)
{
@ -219,7 +223,7 @@ public class ReadingProfileService(IUnitOfWork unitOfWork, ILocalizationService
await unitOfWork.CommitAsync();
}
public async Task BatchAddProfileToSeries(int userId, int profileId, IList<int> seriesIds)
public async Task BulkAddProfileToSeries(int userId, int profileId, IList<int> seriesIds)
{
var profile = await unitOfWork.AppUserReadingProfileRepository.GetProfile(profileId, ReadingProfileIncludes.Series);
if (profile == null) throw new KavitaException("profile-not-found");
@ -254,14 +258,23 @@ public class ReadingProfileService(IUnitOfWork unitOfWork, ILocalizationService
await unitOfWork.CommitAsync();
}
public async Task RemoveProfileFromSeries(int userId, int profileId, int seriesId)
public async Task ClearSeriesProfile(int userId, int seriesId)
{
var profile = await unitOfWork.AppUserReadingProfileRepository.GetProfile(profileId);
if (profile == null) throw new KavitaException("profile-not-found");
var profiles = await unitOfWork.AppUserReadingProfileRepository.GetAllProfilesForSeries(userId, seriesId, ReadingProfileIncludes.Series);
if (!profiles.Any()) return;
if (profile.UserId != userId) throw new UnauthorizedAccessException();
foreach (var profile in profiles)
{
if (profile.Implicit)
{
unitOfWork.AppUserReadingProfileRepository.Remove(profile);
}
else
{
profile.Series = profile.Series.Where(s => !(s.SeriesId == seriesId && s.AppUserId == userId)).ToList();
}
}
profile.Series = profile.Series.Where(s => s.SeriesId != seriesId).ToList();
await unitOfWork.CommitAsync();
}
@ -286,14 +299,21 @@ public class ReadingProfileService(IUnitOfWork unitOfWork, ILocalizationService
await unitOfWork.CommitAsync();
}
public async Task RemoveProfileFromLibrary(int userId, int profileId, int libraryId)
public async Task ClearLibraryProfile(int userId, int libraryId)
{
var profile = await unitOfWork.AppUserReadingProfileRepository.GetProfile(profileId);
if (profile == null) throw new KavitaException("profile-not-found");
var profile = await unitOfWork.AppUserReadingProfileRepository.GetProfileForLibrary(userId, libraryId, ReadingProfileIncludes.Library);
if (profile == null) return;
if (profile.UserId != userId) throw new UnauthorizedAccessException();
if (profile.Implicit)
{
unitOfWork.AppUserReadingProfileRepository.Remove(profile);
await unitOfWork.CommitAsync();
return;
}
profile.Libraries = profile.Libraries.Where(s => s.LibraryId != libraryId).ToList();
profile.Libraries = profile.Libraries
.Where(s => !(s.LibraryId == libraryId && s.AppUserId == userId))
.ToList();
await unitOfWork.CommitAsync();
}