Kavita/API/Data/Repositories/GenreRepository.cs
Joe Milazzo fd6ee42f5f
Reading List Polish (#1879)
* Use Reading Order to count epub pages rather than raw HTML files.

* Send email on background thread for initial invite flow.

* Reorder default writing style for new users so Horizontal is default

* Changed reading activity to use average hours read rather than events to bring more meaningful data.

* added ability to start reading incognito from the top of series detail, needs a bit of styling help though.

* Refactored extensions out into their own package, added new fields for reading list to cover total run, cbl import now takes those dates and overrides on import. Replaced many instances of numbers to be comma separated.

* Added ability to edit reading list run start and end year/month. Refactored some code for valid month/year into a helper method.

* Added a way to see the reading list's release years.

* Added some merged image code, but had to remove due to cover dimensions not fixed.

* tweaked style for accessibility mode on reading list items

* Tweaked css for non virtualized and virtualized containers

* Fixed release updates failing

* Commented out the merge code.

* Typo on words read per year

* Fixed unit tests

* Fixed virtualized scroll

* Cleanup CSS
2023-03-14 06:45:22 -07:00

110 lines
3.4 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using API.DTOs.Metadata;
using API.Entities;
using API.Extensions;
using API.Extensions.QueryExtensions;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
namespace API.Data.Repositories;
public interface IGenreRepository
{
void Attach(Genre genre);
void Remove(Genre genre);
Task<Genre?> FindByNameAsync(string genreName);
Task<IList<Genre>> GetAllGenresAsync();
Task<IList<GenreTagDto>> GetAllGenreDtosAsync(int userId);
Task RemoveAllGenreNoLongerAssociated(bool removeExternal = false);
Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(IList<int> libraryIds, int userId);
Task<int> GetCountAsync();
}
public class GenreRepository : IGenreRepository
{
private readonly DataContext _context;
private readonly IMapper _mapper;
public GenreRepository(DataContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
public void Attach(Genre genre)
{
_context.Genre.Attach(genre);
}
public void Remove(Genre genre)
{
_context.Genre.Remove(genre);
}
public async Task<Genre?> FindByNameAsync(string genreName)
{
var normalizedName = genreName.ToNormalized();
return await _context.Genre
.FirstOrDefaultAsync(g => g.NormalizedTitle != null && g.NormalizedTitle.Equals(normalizedName));
}
public async Task RemoveAllGenreNoLongerAssociated(bool removeExternal = false)
{
var genresWithNoConnections = await _context.Genre
.Include(p => p.SeriesMetadatas)
.Include(p => p.Chapters)
.Where(p => p.SeriesMetadatas.Count == 0 && p.Chapters.Count == 0)
.AsSplitQuery()
.ToListAsync();
_context.Genre.RemoveRange(genresWithNoConnections);
await _context.SaveChangesAsync();
}
/// <summary>
/// Returns a set of Genre tags for a set of library Ids. UserId will restrict returned Genres based on user's age restriction.
/// </summary>
/// <param name="libraryIds"></param>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(IList<int> libraryIds, int userId)
{
var userRating = await _context.AppUser.GetUserAgeRestriction(userId);
return await _context.Series
.Where(s => libraryIds.Contains(s.LibraryId))
.RestrictAgainstAgeRestriction(userRating)
.SelectMany(s => s.Metadata.Genres)
.AsSplitQuery()
.Distinct()
.OrderBy(p => p.NormalizedTitle)
.ProjectTo<GenreTagDto>(_mapper.ConfigurationProvider)
.ToListAsync();
}
public async Task<int> GetCountAsync()
{
return await _context.Genre.CountAsync();
}
public async Task<IList<Genre>> GetAllGenresAsync()
{
return await _context.Genre.ToListAsync();
}
public async Task<IList<GenreTagDto>> GetAllGenreDtosAsync(int userId)
{
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
return await _context.Genre
.RestrictAgainstAgeRestriction(ageRating)
.OrderBy(g => g.NormalizedTitle)
.AsNoTracking()
.ProjectTo<GenreTagDto>(_mapper.ConfigurationProvider)
.ToListAsync();
}
}