OPDS Enhancements (#1687)
* Bump express from 4.17.2 to 4.18.2 in /UI/Web Bumps [express](https://github.com/expressjs/express) from 4.17.2 to 4.18.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.17.2...4.18.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Bump decode-uri-component from 0.2.0 to 0.2.2 in /UI/Web Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2. - [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases) - [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2) --- updated-dependencies: - dependency-name: decode-uri-component dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Bump qs and express in /UI/Web Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `qs` from 6.5.3 to 6.11.0 - [Release notes](https://github.com/ljharb/qs/releases) - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.5.3...v6.11.0) Updates `express` from 4.17.2 to 4.18.2 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.17.2...4.18.2) --- updated-dependencies: - dependency-name: qs dependency-type: indirect - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Added genre and authors to Series level, added summary to volume and chapter level. Force order on reading list title as Chunky enforces their own sort order and doesn't respect the spec. * Moved all the reading list formatting logic to the backend. This allows us to re-use the UI logic for OPDS streams. * Fixed a broken unit test * Code smells Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
fbd9b36e35
commit
1a729adf40
15 changed files with 369 additions and 344 deletions
|
@ -51,6 +51,7 @@ public interface ILibraryRepository
|
|||
Task<bool> DoAnySeriesFoldersMatch(IEnumerable<string> folders);
|
||||
Task<string> GetLibraryCoverImageAsync(int libraryId);
|
||||
Task<IList<string>> GetAllCoverImagesAsync();
|
||||
Task<IDictionary<int, LibraryType>> GetLibraryTypesForIdsAsync(IEnumerable<int> libraryIds);
|
||||
}
|
||||
|
||||
public class LibraryRepository : ILibraryRepository
|
||||
|
@ -397,4 +398,26 @@ public class LibraryRepository : ILibraryRepository
|
|||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IDictionary<int, LibraryType>> GetLibraryTypesForIdsAsync(IEnumerable<int> libraryIds)
|
||||
{
|
||||
var types = await _context.Library
|
||||
.Where(l => libraryIds.Contains(l.Id))
|
||||
.AsNoTracking()
|
||||
.Select(l => new
|
||||
{
|
||||
LibraryId = l.Id,
|
||||
LibraryType = l.Type
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
var dict = new Dictionary<int, LibraryType>();
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
dict.TryAdd(type.LibraryId, type.LibraryType);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||
using System.Threading.Tasks;
|
||||
using API.DTOs.ReadingLists;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Helpers;
|
||||
using AutoMapper;
|
||||
using AutoMapper.QueryableExtensions;
|
||||
|
@ -145,36 +146,41 @@ public class ReadingListRepository : IReadingListRepository
|
|||
TotalPages = chapter.Pages,
|
||||
ChapterNumber = chapter.Range,
|
||||
ReleaseDate = chapter.ReleaseDate,
|
||||
readingListItem = data
|
||||
ReadingListItem = data,
|
||||
ChapterTitleName = chapter.TitleName,
|
||||
|
||||
})
|
||||
.Join(_context.Volume, s => s.readingListItem.VolumeId, volume => volume.Id, (data, volume) => new
|
||||
.Join(_context.Volume, s => s.ReadingListItem.VolumeId, volume => volume.Id, (data, volume) => new
|
||||
{
|
||||
data.readingListItem,
|
||||
data.ReadingListItem,
|
||||
data.TotalPages,
|
||||
data.ChapterNumber,
|
||||
data.ReleaseDate,
|
||||
data.ChapterTitleName,
|
||||
VolumeId = volume.Id,
|
||||
VolumeNumber = volume.Name,
|
||||
})
|
||||
.Join(_context.Series, s => s.readingListItem.SeriesId, series => series.Id,
|
||||
.Join(_context.Series, s => s.ReadingListItem.SeriesId, series => series.Id,
|
||||
(data, s) => new
|
||||
{
|
||||
SeriesName = s.Name,
|
||||
SeriesFormat = s.Format,
|
||||
s.LibraryId,
|
||||
data.readingListItem,
|
||||
data.ReadingListItem,
|
||||
data.TotalPages,
|
||||
data.ChapterNumber,
|
||||
data.VolumeNumber,
|
||||
data.VolumeId,
|
||||
data.ReleaseDate,
|
||||
data.ChapterTitleName,
|
||||
LibraryType = _context.Library.Where(l => l.Id == s.LibraryId).Select(l => l.Type).Single()
|
||||
})
|
||||
.Select(data => new ReadingListItemDto()
|
||||
{
|
||||
Id = data.readingListItem.Id,
|
||||
ChapterId = data.readingListItem.ChapterId,
|
||||
Order = data.readingListItem.Order,
|
||||
SeriesId = data.readingListItem.SeriesId,
|
||||
Id = data.ReadingListItem.Id,
|
||||
ChapterId = data.ReadingListItem.ChapterId,
|
||||
Order = data.ReadingListItem.Order,
|
||||
SeriesId = data.ReadingListItem.SeriesId,
|
||||
SeriesName = data.SeriesName,
|
||||
SeriesFormat = data.SeriesFormat,
|
||||
PagesTotal = data.TotalPages,
|
||||
|
@ -182,8 +188,10 @@ public class ReadingListRepository : IReadingListRepository
|
|||
VolumeNumber = data.VolumeNumber,
|
||||
LibraryId = data.LibraryId,
|
||||
VolumeId = data.VolumeId,
|
||||
ReadingListId = data.readingListItem.ReadingListId,
|
||||
ReleaseDate = data.ReleaseDate
|
||||
ReadingListId = data.ReadingListItem.ReadingListId,
|
||||
ReleaseDate = data.ReleaseDate,
|
||||
LibraryType = data.LibraryType,
|
||||
ChapterTitleName = data.ChapterTitleName
|
||||
})
|
||||
.Where(o => userLibraries.Contains(o.LibraryId))
|
||||
.OrderBy(rli => rli.Order)
|
||||
|
@ -191,6 +199,11 @@ public class ReadingListRepository : IReadingListRepository
|
|||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.Title = ReadingListHelper.FormatTitle(item);
|
||||
}
|
||||
|
||||
// Attach progress information
|
||||
var fetchedChapterIds = items.Select(i => i.ChapterId);
|
||||
var progresses = await _context.AppUserProgresses
|
||||
|
|
|
@ -124,6 +124,8 @@ public interface ISeriesRepository
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<IDictionary<int, int>> GetLibraryIdsForSeriesAsync();
|
||||
|
||||
Task<IList<SeriesMetadataDto>> GetSeriesMetadataForIds(IEnumerable<int> seriesIds);
|
||||
}
|
||||
|
||||
public class SeriesRepository : ISeriesRepository
|
||||
|
@ -526,6 +528,19 @@ public class SeriesRepository : ISeriesRepository
|
|||
return seriesChapters;
|
||||
}
|
||||
|
||||
public async Task<IList<SeriesMetadataDto>> GetSeriesMetadataForIds(IEnumerable<int> seriesIds)
|
||||
{
|
||||
return await _context.SeriesMetadata
|
||||
.Where(metadata => seriesIds.Contains(metadata.SeriesId))
|
||||
.Include(m => m.Genres.OrderBy(g => g.NormalizedTitle))
|
||||
.Include(m => m.Tags.OrderBy(g => g.NormalizedTitle))
|
||||
.Include(m => m.People)
|
||||
.AsNoTracking()
|
||||
.ProjectTo<SeriesMetadataDto>(_mapper.ConfigurationProvider)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task AddSeriesModifiers(int userId, List<SeriesDto> series)
|
||||
{
|
||||
var userProgress = await _context.AppUserProgresses
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue