mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-05-24 00:52:23 -04:00
183 lines
6.7 KiB
C#
183 lines
6.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using API.Comparators;
|
|
using API.DTOs;
|
|
using API.Entities;
|
|
using API.Extensions;
|
|
using API.Interfaces;
|
|
using AutoMapper;
|
|
using AutoMapper.QueryableExtensions;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace API.Data
|
|
{
|
|
public class VolumeRepository : IVolumeRepository
|
|
{
|
|
private readonly DataContext _context;
|
|
private readonly IMapper _mapper;
|
|
private readonly ILogger _logger;
|
|
|
|
public VolumeRepository(DataContext context, IMapper mapper, ILogger logger)
|
|
{
|
|
_context = context;
|
|
_mapper = mapper;
|
|
_logger = logger;
|
|
}
|
|
|
|
public void Update(Volume volume)
|
|
{
|
|
_context.Entry(volume).State = EntityState.Modified;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a Chapter for an Id. Includes linked <see cref="MangaFile"/>s.
|
|
/// </summary>
|
|
/// <param name="chapterId"></param>
|
|
/// <returns></returns>
|
|
public async Task<Chapter> GetChapterAsync(int chapterId)
|
|
{
|
|
return await _context.Chapter
|
|
.Include(c => c.Files)
|
|
.SingleOrDefaultAsync(c => c.Id == chapterId);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns Chapters for a volume id.
|
|
/// </summary>
|
|
/// <param name="volumeId"></param>
|
|
/// <returns></returns>
|
|
public async Task<IList<Chapter>> GetChaptersAsync(int volumeId)
|
|
{
|
|
return await _context.Chapter
|
|
.Where(c => c.VolumeId == volumeId)
|
|
.ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the cover image for a chapter id.
|
|
/// </summary>
|
|
/// <param name="chapterId"></param>
|
|
/// <returns></returns>
|
|
public async Task<byte[]> GetChapterCoverImageAsync(int chapterId)
|
|
{
|
|
return await _context.Chapter
|
|
.Where(c => c.Id == chapterId)
|
|
.Select(c => c.CoverImage)
|
|
.AsNoTracking()
|
|
.SingleOrDefaultAsync();
|
|
}
|
|
|
|
|
|
public async Task<ChapterDto> GetChapterDtoAsync(int chapterId)
|
|
{
|
|
var chapter = await _context.Chapter
|
|
.Include(c => c.Files)
|
|
.ProjectTo<ChapterDto>(_mapper.ConfigurationProvider)
|
|
.AsNoTracking()
|
|
.SingleOrDefaultAsync(c => c.Id == chapterId);
|
|
|
|
return chapter;
|
|
}
|
|
|
|
public async Task<IList<MangaFile>> GetFilesForChapter(int chapterId)
|
|
{
|
|
return await _context.MangaFile
|
|
.Where(c => chapterId == c.Id)
|
|
.AsNoTracking()
|
|
.ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the first (ordered) volume/chapter in a series where the user has progress on it. Only completed volumes/chapters, next entity shouldn't
|
|
/// have any read progress on it.
|
|
/// </summary>
|
|
/// <param name="userId"></param>
|
|
/// <param name="libraryId"></param>
|
|
/// <param name="limit"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<InProgressChapterDto>> GetContinueReading(int userId, int libraryId, int limit)
|
|
{
|
|
_logger.LogInformation("Get Continue Reading");
|
|
var progress = await _context.Chapter
|
|
.Join(_context.AppUserProgresses, chapter => chapter.Id, progress => progress.ChapterId,
|
|
(chapter, progress) =>
|
|
new
|
|
{
|
|
Chapter = chapter,
|
|
Progress = progress
|
|
})
|
|
.Join(_context.Series, arg => arg.Progress.SeriesId, series => series.Id, (arg, series) =>
|
|
new
|
|
{
|
|
arg.Chapter,
|
|
arg.Progress,
|
|
Series = series
|
|
})
|
|
.AsNoTracking()
|
|
.Where(arg => arg.Progress.AppUserId == userId
|
|
&& arg.Progress.PagesRead < arg.Chapter.Pages)
|
|
.OrderByDescending(d => d.Progress.LastModified)
|
|
.Take(limit)
|
|
.ToListAsync();
|
|
|
|
return progress
|
|
.OrderBy(c => float.Parse(c.Chapter.Number), new ChapterSortComparer())
|
|
.DistinctBy(p => p.Series.Id)
|
|
.Select(arg => new InProgressChapterDto()
|
|
{
|
|
Id = arg.Chapter.Id,
|
|
Number = arg.Chapter.Number,
|
|
Range = arg.Chapter.Range,
|
|
SeriesId = arg.Progress.SeriesId,
|
|
SeriesName = arg.Series.Name,
|
|
LibraryId = arg.Series.LibraryId,
|
|
Pages = arg.Chapter.Pages,
|
|
});
|
|
|
|
// var chapters = await _context.Chapter
|
|
// .Join(_context.AppUserProgresses, chapter => chapter.Id, progress => progress.ChapterId, (chapter, progress) =>
|
|
// new
|
|
// {
|
|
// Chapter = chapter,
|
|
// Progress = progress
|
|
// })
|
|
// .Where(arg => arg.Progress.AppUserId == userId && arg.Progress.PagesRead < arg.Chapter.Pages)
|
|
// .Join(_context.Series, arg => arg.Progress.SeriesId, series => series.Id, (arg, series) =>
|
|
// new
|
|
// {
|
|
// arg.Chapter,
|
|
// arg.Progress,
|
|
// Series = series
|
|
// })
|
|
// .AsNoTracking()
|
|
// //.OrderBy(s => s.Chapter.Number)
|
|
// .GroupBy(p => p.Series.Id)
|
|
// .Select(g => g.FirstOrDefault())
|
|
// .Select(arg => new InProgressChapterDto()
|
|
// {
|
|
// Id = arg.Chapter.Id,
|
|
// Number = arg.Chapter.Number,
|
|
// Range = arg.Chapter.Range,
|
|
// SeriesId = arg.Progress.SeriesId,
|
|
// SeriesName = arg.Series.Name,
|
|
// LibraryId = arg.Series.LibraryId,
|
|
// Pages = arg.Chapter.Pages,
|
|
// })
|
|
//
|
|
// //.OrderBy(c => float.Parse(c.Number)) //can't convert to SQL
|
|
//
|
|
// .ToListAsync();
|
|
//
|
|
//
|
|
// return chapters;
|
|
|
|
|
|
// return chapters
|
|
// .OrderBy(c => float.Parse(c.Number), new ChapterSortComparer())
|
|
// .DistinctBy(c => c.SeriesName);
|
|
}
|
|
}
|
|
} |