Performance Improvements (#2449)
This commit is contained in:
parent
419a827d42
commit
5ed1eebd26
34 changed files with 389 additions and 132 deletions
11
API/DTOs/Search/BookmarkSearchResultDto.cs
Normal file
11
API/DTOs/Search/BookmarkSearchResultDto.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace API.DTOs.Search;
|
||||
|
||||
public class BookmarkSearchResultDto
|
||||
{
|
||||
public int LibraryId { get; set; }
|
||||
public int VolumeId { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public int ChapterId { get; set; }
|
||||
public string SeriesName { get; set; }
|
||||
public string LocalizedSeriesName { get; set; }
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using API.DTOs.CollectionTags;
|
||||
using API.DTOs.Metadata;
|
||||
using API.DTOs.Reader;
|
||||
using API.DTOs.ReadingLists;
|
||||
|
||||
namespace API.DTOs.Search;
|
||||
|
@ -19,6 +20,7 @@ public class SearchResultGroupDto
|
|||
public IEnumerable<TagDto> Tags { get; set; } = default!;
|
||||
public IEnumerable<MangaFileDto> Files { get; set; } = default!;
|
||||
public IEnumerable<ChapterDto> Chapters { get; set; } = default!;
|
||||
public IEnumerable<BookmarkSearchResultDto> Bookmarks { get; set; } = default!;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.DTOs.CollectionTags;
|
||||
|
||||
namespace API.DTOs;
|
||||
|
|
|
@ -33,6 +33,9 @@ public interface ICollectionTagRepository
|
|||
void Update(CollectionTag tag);
|
||||
Task<int> RemoveTagsWithoutSeries();
|
||||
Task<IEnumerable<CollectionTag>> GetAllTagsAsync(CollectionTagIncludes includes = CollectionTagIncludes.None);
|
||||
|
||||
Task<IEnumerable<CollectionTag>> GetAllTagsByNamesAsync(IEnumerable<string> normalizedTitles,
|
||||
CollectionTagIncludes includes = CollectionTagIncludes.None);
|
||||
Task<IList<string>> GetAllCoverImagesAsync();
|
||||
Task<bool> TagExists(string title);
|
||||
Task<IList<CollectionTag>> GetAllWithCoversInDifferentEncoding(EncodeFormat encodeFormat);
|
||||
|
@ -87,6 +90,15 @@ public class CollectionTagRepository : ICollectionTagRepository
|
|||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CollectionTag>> GetAllTagsByNamesAsync(IEnumerable<string> normalizedTitles, CollectionTagIncludes includes = CollectionTagIncludes.None)
|
||||
{
|
||||
return await _context.CollectionTag
|
||||
.Where(c => normalizedTitles.Contains(c.NormalizedTitle))
|
||||
.OrderBy(c => c.NormalizedTitle)
|
||||
.Includes(includes)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<string?> GetCoverImageAsync(int collectionTagId)
|
||||
{
|
||||
return await _context.CollectionTag
|
||||
|
|
|
@ -17,6 +17,7 @@ public interface IGenreRepository
|
|||
void Remove(Genre genre);
|
||||
Task<Genre?> FindByNameAsync(string genreName);
|
||||
Task<IList<Genre>> GetAllGenresAsync();
|
||||
Task<IList<Genre>> GetAllGenresByNamesAsync(IEnumerable<string> normalizedNames);
|
||||
Task<IList<GenreTagDto>> GetAllGenreDtosAsync(int userId);
|
||||
Task RemoveAllGenreNoLongerAssociated(bool removeExternal = false);
|
||||
Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(IList<int> libraryIds, int userId);
|
||||
|
@ -96,6 +97,13 @@ public class GenreRepository : IGenreRepository
|
|||
return await _context.Genre.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<Genre>> GetAllGenresByNamesAsync(IEnumerable<string> normalizedNames)
|
||||
{
|
||||
return await _context.Genre
|
||||
.Where(g => normalizedNames.Contains(g.NormalizedTitle))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<GenreTagDto>> GetAllGenreDtosAsync(int userId)
|
||||
{
|
||||
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
||||
|
|
|
@ -23,6 +23,7 @@ public interface IPersonRepository
|
|||
Task<IList<PersonDto>> GetAllPeopleDtosForLibrariesAsync(List<int> libraryIds, int userId);
|
||||
Task<int> GetCountAsync();
|
||||
|
||||
Task<IList<Person>> GetAllPeopleByRoleAndNames(PersonRole role, IEnumerable<string> normalizeNames);
|
||||
}
|
||||
|
||||
public class PersonRepository : IPersonRepository
|
||||
|
@ -80,6 +81,13 @@ public class PersonRepository : IPersonRepository
|
|||
return await _context.Person.CountAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<Person>> GetAllPeopleByRoleAndNames(PersonRole role, IEnumerable<string> normalizeNames)
|
||||
{
|
||||
return await _context.Person
|
||||
.Where(p => p.Role == role && normalizeNames.Contains(p.NormalizedName))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task<IList<Person>> GetAllPeople()
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@ using API.DTOs.Dashboard;
|
|||
using API.DTOs.Filtering;
|
||||
using API.DTOs.Filtering.v2;
|
||||
using API.DTOs.Metadata;
|
||||
using API.DTOs.Reader;
|
||||
using API.DTOs.ReadingLists;
|
||||
using API.DTOs.Search;
|
||||
using API.DTOs.SeriesDetail;
|
||||
|
@ -374,6 +375,33 @@ public class SeriesRepository : ISeriesRepository
|
|||
.ProjectTo<SearchResultDto>(_mapper.ConfigurationProvider)
|
||||
.AsEnumerable();
|
||||
|
||||
result.Bookmarks = (await _context.AppUserBookmark
|
||||
.Join(
|
||||
_context.Series,
|
||||
bookmark => bookmark.SeriesId,
|
||||
series => series.Id,
|
||||
(bookmark, series) => new {Bookmark = bookmark, Series = series}
|
||||
)
|
||||
.Where(joined => joined.Bookmark.AppUserId == userId &&
|
||||
(EF.Functions.Like(joined.Series.Name, $"%{searchQuery}%") ||
|
||||
(joined.Series.OriginalName != null &&
|
||||
EF.Functions.Like(joined.Series.OriginalName, $"%{searchQuery}%")) ||
|
||||
(joined.Series.LocalizedName != null &&
|
||||
EF.Functions.Like(joined.Series.LocalizedName, $"%{searchQuery}%"))))
|
||||
.OrderBy(joined => joined.Series.Name)
|
||||
.Take(maxRecords)
|
||||
.Select(joined => new BookmarkSearchResultDto()
|
||||
{
|
||||
SeriesName = joined.Series.Name,
|
||||
LocalizedSeriesName = joined.Series.LocalizedName,
|
||||
LibraryId = joined.Series.LibraryId,
|
||||
SeriesId = joined.Bookmark.SeriesId,
|
||||
ChapterId = joined.Bookmark.ChapterId,
|
||||
VolumeId = joined.Bookmark.VolumeId
|
||||
})
|
||||
.ToListAsync()).DistinctBy(s => s.SeriesId);
|
||||
|
||||
|
||||
result.ReadingLists = await _context.ReadingList
|
||||
.Where(rl => rl.AppUserId == userId || rl.Promoted)
|
||||
.Where(rl => EF.Functions.Like(rl.Title, $"%{searchQuery}%"))
|
||||
|
|
|
@ -16,6 +16,7 @@ public interface ITagRepository
|
|||
void Attach(Tag tag);
|
||||
void Remove(Tag tag);
|
||||
Task<IList<Tag>> GetAllTagsAsync();
|
||||
Task<IList<Tag>> GetAllTagsByNameAsync(IEnumerable<string> normalizedNames);
|
||||
Task<IList<TagDto>> GetAllTagDtosAsync(int userId);
|
||||
Task RemoveAllTagNoLongerAssociated();
|
||||
Task<IList<TagDto>> GetAllTagDtosForLibrariesAsync(IList<int> libraryIds, int userId);
|
||||
|
@ -76,6 +77,13 @@ public class TagRepository : ITagRepository
|
|||
return await _context.Tag.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<Tag>> GetAllTagsByNameAsync(IEnumerable<string> normalizedNames)
|
||||
{
|
||||
return await _context.Tag
|
||||
.Where(t => normalizedNames.Contains(t.NormalizedTitle))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<TagDto>> GetAllTagDtosAsync(int userId)
|
||||
{
|
||||
var userRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
||||
|
|
|
@ -164,4 +164,19 @@ public static class PersonHelper
|
|||
onModified();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasAnyPeople(SeriesMetadataDto? seriesMetadata)
|
||||
{
|
||||
if (seriesMetadata == null) return false;
|
||||
return seriesMetadata.Writers.Any() ||
|
||||
seriesMetadata.CoverArtists.Any() ||
|
||||
seriesMetadata.Publishers.Any() ||
|
||||
seriesMetadata.Characters.Any() ||
|
||||
seriesMetadata.Pencillers.Any() ||
|
||||
seriesMetadata.Inkers.Any() ||
|
||||
seriesMetadata.Colorists.Any() ||
|
||||
seriesMetadata.Letterers.Any() ||
|
||||
seriesMetadata.Editors.Any() ||
|
||||
seriesMetadata.Translators.Any();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,10 +189,10 @@
|
|||
"user-no-access-library-from-series": "User does not have access to the library this series belongs to",
|
||||
"series-restricted-age-restriction": "User is not allowed to view this series due to age restrictions",
|
||||
|
||||
"next-volume-num": "Next Volume: {0}",
|
||||
"next-book-num": "Next Book: {0}",
|
||||
"next-issue-num": "Next Issue: {0}{1}",
|
||||
"next-chapter-num": "Next Chapter: {0}",
|
||||
"next-volume-num": "Upcoming Volume: {0}",
|
||||
"next-book-num": "Upcoming Book: {0}",
|
||||
"next-issue-num": "Upcoming Issue: {0}{1}",
|
||||
"next-chapter-num": "Upcoming Chapter: {0}",
|
||||
|
||||
|
||||
"volume-num": "Volume {0}",
|
||||
|
|
|
@ -130,7 +130,7 @@ public class MetadataService : IMetadataService
|
|||
return Task.CompletedTask;
|
||||
|
||||
series.Volumes ??= new List<Volume>();
|
||||
series.CoverImage = series.GetCoverImage();
|
||||
series.CoverImage = series.GetCoverImage(); // BUG: At this point the volume or chapter hasn't regenerated the cover
|
||||
|
||||
_updateEvents.Add(MessageFactory.CoverUpdateEvent(series.Id, MessageFactoryEntityTypes.Series));
|
||||
return Task.CompletedTask;
|
||||
|
|
|
@ -17,13 +17,14 @@ using API.Extensions;
|
|||
using API.Helpers;
|
||||
using API.Helpers.Builders;
|
||||
using API.Services.Plus;
|
||||
using API.Services.Tasks.Scanner.Parser;
|
||||
using API.SignalR;
|
||||
using Hangfire;
|
||||
using Kavita.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Services;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public interface ISeriesService
|
||||
{
|
||||
|
@ -51,7 +52,7 @@ public class SeriesService : ISeriesService
|
|||
private readonly IScrobblingService _scrobblingService;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
private readonly NextExpectedChapterDto _emptyExpectedChapter = new NextExpectedChapterDto()
|
||||
private readonly NextExpectedChapterDto _emptyExpectedChapter = new NextExpectedChapterDto
|
||||
{
|
||||
ExpectedDate = null,
|
||||
ChapterNumber = 0,
|
||||
|
@ -106,11 +107,6 @@ public class SeriesService : ISeriesService
|
|||
var seriesId = updateSeriesMetadataDto.SeriesMetadata.SeriesId;
|
||||
var series = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(seriesId);
|
||||
if (series == null) return false;
|
||||
var allCollectionTags = (await _unitOfWork.CollectionTagRepository.GetAllTagsAsync()).ToList();
|
||||
// TODO: This is Diesel's performance problem with Komf. For some systems, this is too heavy of a call if komf is spamming updates.
|
||||
var allGenres = (await _unitOfWork.GenreRepository.GetAllGenresAsync()).ToList();
|
||||
var allPeople = (await _unitOfWork.PersonRepository.GetAllPeople()).ToList();
|
||||
var allTags = (await _unitOfWork.TagRepository.GetAllTagsAsync()).ToList();
|
||||
|
||||
series.Metadata ??= new SeriesMetadataBuilder()
|
||||
.WithCollectionTags(updateSeriesMetadataDto.CollectionTags.Select(dto =>
|
||||
|
@ -169,51 +165,102 @@ public class SeriesService : ISeriesService
|
|||
}
|
||||
|
||||
|
||||
series.Metadata.CollectionTags ??= new List<CollectionTag>();
|
||||
UpdateCollectionsList(updateSeriesMetadataDto.CollectionTags, series, allCollectionTags, (tag) =>
|
||||
if (updateSeriesMetadataDto.CollectionTags.Any())
|
||||
{
|
||||
series.Metadata.CollectionTags.Add(tag);
|
||||
});
|
||||
|
||||
series.Metadata.Genres ??= new List<Genre>();
|
||||
GenreHelper.UpdateGenreList(updateSeriesMetadataDto.SeriesMetadata?.Genres, series, allGenres, (genre) =>
|
||||
{
|
||||
series.Metadata.Genres.Add(genre);
|
||||
}, () => series.Metadata.GenresLocked = true);
|
||||
|
||||
series.Metadata.Tags ??= new List<Tag>();
|
||||
TagHelper.UpdateTagList(updateSeriesMetadataDto.SeriesMetadata?.Tags, series, allTags, (tag) =>
|
||||
{
|
||||
series.Metadata.Tags.Add(tag);
|
||||
}, () => series.Metadata.TagsLocked = true);
|
||||
|
||||
void HandleAddPerson(Person person)
|
||||
{
|
||||
PersonHelper.AddPersonIfNotExists(series.Metadata.People, person);
|
||||
allPeople.Add(person);
|
||||
var allCollectionTags = (await _unitOfWork.CollectionTagRepository
|
||||
.GetAllTagsByNamesAsync(updateSeriesMetadataDto.CollectionTags.Select(t => Parser.Normalize(t.Title)))).ToList();
|
||||
series.Metadata.CollectionTags ??= new List<CollectionTag>();
|
||||
UpdateCollectionsList(updateSeriesMetadataDto.CollectionTags, series, allCollectionTags, tag =>
|
||||
{
|
||||
series.Metadata.CollectionTags.Add(tag);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (updateSeriesMetadataDto.SeriesMetadata?.Genres != null &&
|
||||
updateSeriesMetadataDto.SeriesMetadata.Genres.Any())
|
||||
{
|
||||
var allGenres = (await _unitOfWork.GenreRepository.GetAllGenresByNamesAsync(updateSeriesMetadataDto.SeriesMetadata.Genres.Select(t => Parser.Normalize(t.Title)))).ToList();
|
||||
series.Metadata.Genres ??= new List<Genre>();
|
||||
GenreHelper.UpdateGenreList(updateSeriesMetadataDto.SeriesMetadata?.Genres, series, allGenres, genre =>
|
||||
{
|
||||
series.Metadata.Genres.Add(genre);
|
||||
}, () => series.Metadata.GenresLocked = true);
|
||||
}
|
||||
|
||||
|
||||
if (updateSeriesMetadataDto.SeriesMetadata?.Tags != null && updateSeriesMetadataDto.SeriesMetadata.Tags.Any())
|
||||
{
|
||||
var allTags = (await _unitOfWork.TagRepository
|
||||
.GetAllTagsByNameAsync(updateSeriesMetadataDto.SeriesMetadata.Tags.Select(t => Parser.Normalize(t.Title))))
|
||||
.ToList();
|
||||
series.Metadata.Tags ??= new List<Tag>();
|
||||
TagHelper.UpdateTagList(updateSeriesMetadataDto.SeriesMetadata?.Tags, series, allTags, tag =>
|
||||
{
|
||||
series.Metadata.Tags.Add(tag);
|
||||
}, () => series.Metadata.TagsLocked = true);
|
||||
}
|
||||
|
||||
|
||||
if (PersonHelper.HasAnyPeople(updateSeriesMetadataDto.SeriesMetadata))
|
||||
{
|
||||
void HandleAddPerson(Person person)
|
||||
{
|
||||
PersonHelper.AddPersonIfNotExists(series.Metadata.People, person);
|
||||
}
|
||||
|
||||
series.Metadata.People ??= new List<Person>();
|
||||
var allWriters = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Writer,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Writers.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Writer, updateSeriesMetadataDto.SeriesMetadata!.Writers, series, allWriters.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.WriterLocked = true);
|
||||
|
||||
var allCharacters = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Character,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Characters.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Character, updateSeriesMetadataDto.SeriesMetadata.Characters, series, allCharacters.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.CharacterLocked = true);
|
||||
|
||||
var allColorists = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Colorist,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Colorists.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Colorist, updateSeriesMetadataDto.SeriesMetadata.Colorists, series, allColorists.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.ColoristLocked = true);
|
||||
|
||||
var allEditors = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Editor,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Editors.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Editor, updateSeriesMetadataDto.SeriesMetadata.Editors, series, allEditors.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.EditorLocked = true);
|
||||
|
||||
var allInkers = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Inker,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Inkers.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Inker, updateSeriesMetadataDto.SeriesMetadata.Inkers, series, allInkers.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.InkerLocked = true);
|
||||
|
||||
var allLetterers = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Letterer,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Letterers.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Letterer, updateSeriesMetadataDto.SeriesMetadata.Letterers, series, allLetterers.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.LettererLocked = true);
|
||||
|
||||
var allPencillers = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Penciller,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Pencillers.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Penciller, updateSeriesMetadataDto.SeriesMetadata.Pencillers, series, allPencillers.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.PencillerLocked = true);
|
||||
|
||||
var allPublishers = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Publisher,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Publishers.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Publisher, updateSeriesMetadataDto.SeriesMetadata.Publishers, series, allPublishers.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.PublisherLocked = true);
|
||||
|
||||
var allTranslators = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.Translator,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.Translators.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Translator, updateSeriesMetadataDto.SeriesMetadata.Translators, series, allTranslators.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.TranslatorLocked = true);
|
||||
|
||||
var allCoverArtists = await _unitOfWork.PersonRepository.GetAllPeopleByRoleAndNames(PersonRole.CoverArtist,
|
||||
updateSeriesMetadataDto.SeriesMetadata!.CoverArtists.Select(p => Parser.Normalize(p.Name)));
|
||||
PersonHelper.UpdatePeopleList(PersonRole.CoverArtist, updateSeriesMetadataDto.SeriesMetadata.CoverArtists, series, allCoverArtists.AsReadOnly(),
|
||||
HandleAddPerson, () => series.Metadata.CoverArtistLocked = true);
|
||||
}
|
||||
|
||||
series.Metadata.People ??= new List<Person>();
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Writer, updateSeriesMetadataDto.SeriesMetadata!.Writers, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.WriterLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Character, updateSeriesMetadataDto.SeriesMetadata.Characters, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.CharacterLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Colorist, updateSeriesMetadataDto.SeriesMetadata.Colorists, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.ColoristLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Editor, updateSeriesMetadataDto.SeriesMetadata.Editors, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.EditorLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Inker, updateSeriesMetadataDto.SeriesMetadata.Inkers, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.InkerLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Letterer, updateSeriesMetadataDto.SeriesMetadata.Letterers, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.LettererLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Penciller, updateSeriesMetadataDto.SeriesMetadata.Pencillers, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.PencillerLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Publisher, updateSeriesMetadataDto.SeriesMetadata.Publishers, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.PublisherLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.Translator, updateSeriesMetadataDto.SeriesMetadata.Translators, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.TranslatorLocked = true);
|
||||
PersonHelper.UpdatePeopleList(PersonRole.CoverArtist, updateSeriesMetadataDto.SeriesMetadata.CoverArtists, series, allPeople,
|
||||
HandleAddPerson, () => series.Metadata.CoverArtistLocked = true);
|
||||
|
||||
series.Metadata.AgeRatingLocked = updateSeriesMetadataDto.SeriesMetadata.AgeRatingLocked;
|
||||
series.Metadata.PublicationStatusLocked = updateSeriesMetadataDto.SeriesMetadata.PublicationStatusLocked;
|
||||
|
@ -270,7 +317,7 @@ public class SeriesService : ISeriesService
|
|||
}
|
||||
|
||||
|
||||
public static void UpdateCollectionsList(ICollection<CollectionTagDto>? tags, Series series, IReadOnlyCollection<CollectionTag> allTags,
|
||||
private static void UpdateCollectionsList(ICollection<CollectionTagDto>? tags, Series series, IReadOnlyCollection<CollectionTag> allTags,
|
||||
Action<CollectionTag> handleAdd)
|
||||
{
|
||||
// TODO: Move UpdateCollectionsList to a helper so we can easily test
|
||||
|
@ -430,7 +477,7 @@ public class SeriesService : ISeriesService
|
|||
|
||||
var libraryType = await _unitOfWork.LibraryRepository.GetLibraryTypeAsync(series.LibraryId);
|
||||
var volumes = (await _unitOfWork.VolumeRepository.GetVolumesDtoAsync(seriesId, userId))
|
||||
.OrderBy(v => Tasks.Scanner.Parser.Parser.MinNumberFromRange(v.Name))
|
||||
.OrderBy(v => Parser.MinNumberFromRange(v.Name))
|
||||
.ToList();
|
||||
|
||||
// For books, the Name of the Volume is remapped to the actual name of the book, rather than Volume number.
|
||||
|
@ -499,7 +546,7 @@ public class SeriesService : ISeriesService
|
|||
retChapters = retChapters.OrderBy(c => c.Number.AsFloat(), ChapterSortComparer.Default);
|
||||
}
|
||||
|
||||
return new SeriesDetailDto()
|
||||
return new SeriesDetailDto
|
||||
{
|
||||
Specials = specials,
|
||||
Chapters = retChapters,
|
||||
|
@ -517,7 +564,7 @@ public class SeriesService : ISeriesService
|
|||
/// <returns></returns>
|
||||
private static bool ShouldIncludeChapter(ChapterDto chapter)
|
||||
{
|
||||
return !chapter.IsSpecial && !chapter.Number.Equals(Tasks.Scanner.Parser.Parser.DefaultChapter);
|
||||
return !chapter.IsSpecial && !chapter.Number.Equals(Parser.DefaultChapter);
|
||||
}
|
||||
|
||||
public static void RenameVolumeName(ChapterDto firstChapter, VolumeDto volume, LibraryType libraryType, string volumeLabel = "Volume")
|
||||
|
@ -526,7 +573,7 @@ public class SeriesService : ISeriesService
|
|||
{
|
||||
if (string.IsNullOrEmpty(firstChapter.TitleName))
|
||||
{
|
||||
if (firstChapter.Range.Equals(Tasks.Scanner.Parser.Parser.DefaultVolume)) return;
|
||||
if (firstChapter.Range.Equals(Parser.DefaultVolume)) return;
|
||||
var title = Path.GetFileNameWithoutExtension(firstChapter.Range);
|
||||
if (string.IsNullOrEmpty(title)) return;
|
||||
volume.Name += $" - {title}";
|
||||
|
@ -553,7 +600,7 @@ public class SeriesService : ISeriesService
|
|||
|
||||
if (isSpecial)
|
||||
{
|
||||
return Tasks.Scanner.Parser.Parser.CleanSpecialTitle(chapterTitle);
|
||||
return Parser.CleanSpecialTitle(chapterTitle);
|
||||
}
|
||||
|
||||
var hashSpot = withHash ? "#" : string.Empty;
|
||||
|
@ -650,7 +697,7 @@ public class SeriesService : ISeriesService
|
|||
r.RelationKind == kind && r.TargetSeriesId == targetSeriesId) !=
|
||||
null) continue;
|
||||
|
||||
series.Relations.Add(new SeriesRelation()
|
||||
series.Relations.Add(new SeriesRelation
|
||||
{
|
||||
Series = series,
|
||||
SeriesId = series.Id,
|
||||
|
@ -669,7 +716,7 @@ public class SeriesService : ISeriesService
|
|||
{
|
||||
throw new UnauthorizedAccessException("user-no-access-library-from-series");
|
||||
}
|
||||
if (series?.Metadata.PublicationStatus is not (PublicationStatus.OnGoing or PublicationStatus.Ended) || series.Library.Type == LibraryType.Book)
|
||||
if (series.Metadata.PublicationStatus is not (PublicationStatus.OnGoing or PublicationStatus.Ended) || series.Library.Type == LibraryType.Book)
|
||||
{
|
||||
return _emptyExpectedChapter;
|
||||
}
|
||||
|
@ -732,7 +779,7 @@ public class SeriesService : ISeriesService
|
|||
|
||||
var lastVolumeNum = chapters.Select(c => c.Volume.Number).Max();
|
||||
|
||||
var result = new NextExpectedChapterDto()
|
||||
var result = new NextExpectedChapterDto
|
||||
{
|
||||
ChapterNumber = 0,
|
||||
VolumeNumber = 0,
|
||||
|
@ -746,21 +793,16 @@ public class SeriesService : ISeriesService
|
|||
result.VolumeNumber = lastChapter.Volume.Number;
|
||||
result.Title = series.Library.Type switch
|
||||
{
|
||||
LibraryType.Manga => await _localizationService.Translate(userId, "next-chapter-num",
|
||||
new object[] {result.ChapterNumber}),
|
||||
LibraryType.Comic => await _localizationService.Translate(userId, "next-issue-num",
|
||||
new object[] {"#", result.ChapterNumber}),
|
||||
LibraryType.Book => await _localizationService.Translate(userId, "next-book-num",
|
||||
new object[] {result.ChapterNumber}),
|
||||
_ => await _localizationService.Translate(userId, "next-chapter-num",
|
||||
new object[] {result.ChapterNumber})
|
||||
LibraryType.Manga => await _localizationService.Translate(userId, "next-chapter-num", result.ChapterNumber),
|
||||
LibraryType.Comic => await _localizationService.Translate(userId, "next-issue-num", "#", result.ChapterNumber),
|
||||
LibraryType.Book => await _localizationService.Translate(userId, "next-book-num", result.ChapterNumber),
|
||||
_ => await _localizationService.Translate(userId, "next-chapter-num", result.ChapterNumber)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
result.VolumeNumber = lastVolumeNum + 1;
|
||||
result.Title = await _localizationService.Translate(userId, "volume-num",
|
||||
new object[] {result.VolumeNumber});
|
||||
result.Title = await _localizationService.Translate(userId, "volume-num", result.VolumeNumber);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -296,8 +296,8 @@ public class ScannerService : IScannerService
|
|||
MessageFactory.ScanSeriesEvent(library.Id, seriesId, series.Name));
|
||||
|
||||
await _metadataService.RemoveAbandonedMetadataKeys();
|
||||
BackgroundJob.Enqueue(() => _metadataService.GenerateCoversForSeries(series.LibraryId, seriesId, false));
|
||||
BackgroundJob.Enqueue(() => _wordCountAnalyzerService.ScanSeries(library.Id, seriesId, false));
|
||||
//BackgroundJob.Enqueue(() => _metadataService.GenerateCoversForSeries(series.LibraryId, seriesId, false));
|
||||
//BackgroundJob.Enqueue(() => _wordCountAnalyzerService.ScanSeries(library.Id, seriesId, false));
|
||||
BackgroundJob.Enqueue(() => _cacheService.CleanupChapters(chapterIds));
|
||||
BackgroundJob.Enqueue(() => _directoryService.ClearDirectory(_directoryService.TempDirectory));
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue