From d261eaa98fc1413b514a99291d6ac6517f417ab1 Mon Sep 17 00:00:00 2001 From: Amelia <77553571+Fesaa@users.noreply.github.com> Date: Fri, 20 Jun 2025 16:05:45 +0200 Subject: [PATCH] Restrict Genres and Tags to the users library Fixes #3859 --- API/Data/Repositories/GenreRepository.cs | 69 ++++++++++++++++++------ API/Data/Repositories/TagRepository.cs | 69 ++++++++++++++++++------ API/Extensions/EnumerableExtensions.cs | 13 +++++ 3 files changed, 117 insertions(+), 34 deletions(-) diff --git a/API/Data/Repositories/GenreRepository.cs b/API/Data/Repositories/GenreRepository.cs index 3e645cb2e..a18b5e971 100644 --- a/API/Data/Repositories/GenreRepository.cs +++ b/API/Data/Repositories/GenreRepository.cs @@ -173,23 +173,58 @@ public class GenreRepository : IGenreRepository { var ageRating = await _context.AppUser.GetUserAgeRestriction(userId); - var query = _context.Genre - .RestrictAgainstAgeRestriction(ageRating) - .Select(g => new BrowseGenreDto - { - Id = g.Id, - Title = g.Title, - SeriesCount = g.SeriesMetadatas - .Select(sm => sm.Id) - .Distinct() - .Count(), - ChapterCount = g.Chapters - .Select(ch => ch.Id) - .Distinct() - .Count() - }) - .OrderBy(g => g.Title); + var libs = await _context.Library.Includes(LibraryIncludes.AppUser).ToListAsync(); + var userLibs = libs.Where(lib => lib.AppUsers.Any(user => user.Id == userId)) + .Select(lib => lib.Id).ToList(); - return await PagedList.CreateAsync(query, userParams.PageNumber, userParams.PageSize); + var query = _context.Genre.RestrictAgainstAgeRestriction(ageRating); + + IQueryable finalQuery; + if (libs.Count != userLibs.Count) + { + var seriesIds = _context.Series.Where(s => userLibs.Contains(s.LibraryId)).Select(s => s.Id); + query = query.Where(s => s.Chapters.Any(cp => seriesIds.Contains(cp.Volume.SeriesId)) || + s.SeriesMetadatas.Any(sm => seriesIds.Contains(sm.SeriesId))); + + finalQuery = query.Select(g => new BrowseGenreDto + { + Id = g.Id, + Title = g.Title, + SeriesCount = g.SeriesMetadatas + .Where(sm => seriesIds.Contains(sm.SeriesId)) + .RestrictAgainstAgeRestriction(ageRating) + //.Select(sm => sm.Id) + .Distinct() + .Count(), + ChapterCount = g.Chapters + .Where(cp => seriesIds.Contains(cp.Volume.SeriesId)) + .RestrictAgainstAgeRestriction(ageRating) + //.Select(ch => ch.Id) + .Distinct() + .Count() + }) + .OrderBy(g => g.Title); + } + else + { + finalQuery = query.Select(g => new BrowseGenreDto + { + Id = g.Id, + Title = g.Title, + SeriesCount = g.SeriesMetadatas + .Select(sm => sm.Id) + .Distinct() + .Count(), + ChapterCount = g.Chapters + .Select(ch => ch.Id) + .Distinct() + .Count() + }) + .OrderBy(g => g.Title); + } + + + + return await PagedList.CreateAsync(finalQuery, userParams.PageNumber, userParams.PageSize); } } diff --git a/API/Data/Repositories/TagRepository.cs b/API/Data/Repositories/TagRepository.cs index ea39d2b0d..381438735 100644 --- a/API/Data/Repositories/TagRepository.cs +++ b/API/Data/Repositories/TagRepository.cs @@ -111,24 +111,59 @@ public class TagRepository : ITagRepository { var ageRating = await _context.AppUser.GetUserAgeRestriction(userId); - var query = _context.Tag - .RestrictAgainstAgeRestriction(ageRating) - .Select(g => new BrowseTagDto - { - Id = g.Id, - Title = g.Title, - SeriesCount = g.SeriesMetadatas - .Select(sm => sm.Id) - .Distinct() - .Count(), - ChapterCount = g.Chapters - .Select(ch => ch.Id) - .Distinct() - .Count() - }) - .OrderBy(g => g.Title); + var libs = await _context.Library.Includes(LibraryIncludes.AppUser).ToListAsync(); + var userLibs = libs.Where(lib => lib.AppUsers.Any(user => user.Id == userId)) + .Select(lib => lib.Id).ToList(); - return await PagedList.CreateAsync(query, userParams.PageNumber, userParams.PageSize); + var query = _context.Tag.RestrictAgainstAgeRestriction(ageRating); + + IQueryable finalQuery; + if (userLibs.Count != libs.Count) + { + var seriesIds = _context.Series.Where(s => userLibs.Contains(s.LibraryId)).Select(s => s.Id); + query = query.Where(tag => tag.Chapters.Any(cp => seriesIds.Contains(cp.Volume.SeriesId)) || + tag.SeriesMetadatas.Any(sm => seriesIds.Contains(sm.SeriesId))); + + finalQuery = query + .Select(g => new BrowseTagDto + { + Id = g.Id, + Title = g.Title, + SeriesCount = g.SeriesMetadatas + .Where(sm => seriesIds.Contains(sm.SeriesId)) + .RestrictAgainstAgeRestriction(ageRating) + //.Select(sm => sm.SeriesId) + .Distinct() + .Count(), + ChapterCount = g.Chapters + .Where(ch => seriesIds.Contains(ch.Volume.SeriesId)) + .RestrictAgainstAgeRestriction(ageRating) + //.Select(ch => ch.Id) + .Distinct() + .Count() + }) + .OrderBy(g => g.Title); + } + else + { + finalQuery = query + .Select(g => new BrowseTagDto + { + Id = g.Id, + Title = g.Title, + SeriesCount = g.SeriesMetadatas + .Select(sm => sm.Id) + .Distinct() + .Count(), + ChapterCount = g.Chapters + .Select(ch => ch.Id) + .Distinct() + .Count() + }) + .OrderBy(g => g.Title); + } + + return await PagedList.CreateAsync(finalQuery, userParams.PageNumber, userParams.PageSize); } public async Task> GetAllTagsAsync() diff --git a/API/Extensions/EnumerableExtensions.cs b/API/Extensions/EnumerableExtensions.cs index 8beec88ca..9bc06bab4 100644 --- a/API/Extensions/EnumerableExtensions.cs +++ b/API/Extensions/EnumerableExtensions.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using API.Data.Misc; +using API.Entities; using API.Entities.Enums; using API.Entities.Metadata; @@ -55,4 +56,16 @@ public static class EnumerableExtensions return q; } + + public static IEnumerable RestrictAgainstAgeRestriction(this IEnumerable items, AgeRestriction restriction) + { + if (restriction.AgeRating == AgeRating.NotApplicable) return items; + var q = items.Where(s => s.AgeRating <= restriction.AgeRating); + if (!restriction.IncludeUnknowns) + { + return q.Where(s => s.AgeRating != AgeRating.Unknown); + } + + return q; + } }