mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Scanner Stuff Again (#3003)
This commit is contained in:
parent
59699e17e2
commit
12ec980204
@ -37,12 +37,14 @@ public class MetadataController(IUnitOfWork unitOfWork, ILocalizationService loc
|
|||||||
public async Task<ActionResult<IList<GenreTagDto>>> GetAllGenres(string? libraryIds)
|
public async Task<ActionResult<IList<GenreTagDto>>> GetAllGenres(string? libraryIds)
|
||||||
{
|
{
|
||||||
var ids = libraryIds?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
|
var ids = libraryIds?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
|
||||||
|
|
||||||
|
// NOTE: libraryIds isn't hooked up in the frontend
|
||||||
if (ids is {Count: > 0})
|
if (ids is {Count: > 0})
|
||||||
{
|
{
|
||||||
return Ok(await unitOfWork.GenreRepository.GetAllGenreDtosForLibrariesAsync(ids, User.GetUserId()));
|
return Ok(await unitOfWork.GenreRepository.GetAllGenreDtosForLibrariesAsync(User.GetUserId(), ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(await unitOfWork.GenreRepository.GetAllGenreDtosAsync(User.GetUserId()));
|
return Ok(await unitOfWork.GenreRepository.GetAllGenreDtosForLibrariesAsync(User.GetUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -71,9 +73,9 @@ public class MetadataController(IUnitOfWork unitOfWork, ILocalizationService loc
|
|||||||
var ids = libraryIds?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
|
var ids = libraryIds?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
|
||||||
if (ids is {Count: > 0})
|
if (ids is {Count: > 0})
|
||||||
{
|
{
|
||||||
return Ok(await unitOfWork.PersonRepository.GetAllPeopleDtosForLibrariesAsync(ids, User.GetUserId()));
|
return Ok(await unitOfWork.PersonRepository.GetAllPeopleDtosForLibrariesAsync(User.GetUserId(), ids));
|
||||||
}
|
}
|
||||||
return Ok(await unitOfWork.PersonRepository.GetAllPersonDtosAsync(User.GetUserId()));
|
return Ok(await unitOfWork.PersonRepository.GetAllPeopleDtosForLibrariesAsync(User.GetUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -88,9 +90,9 @@ public class MetadataController(IUnitOfWork unitOfWork, ILocalizationService loc
|
|||||||
var ids = libraryIds?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
|
var ids = libraryIds?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
|
||||||
if (ids is {Count: > 0})
|
if (ids is {Count: > 0})
|
||||||
{
|
{
|
||||||
return Ok(await unitOfWork.TagRepository.GetAllTagDtosForLibrariesAsync(ids, User.GetUserId()));
|
return Ok(await unitOfWork.TagRepository.GetAllTagDtosForLibrariesAsync(User.GetUserId(), ids));
|
||||||
}
|
}
|
||||||
return Ok(await unitOfWork.TagRepository.GetAllTagDtosAsync(User.GetUserId()));
|
return Ok(await unitOfWork.TagRepository.GetAllTagDtosForLibrariesAsync(User.GetUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -19,9 +19,8 @@ public interface IGenreRepository
|
|||||||
Task<Genre?> FindByNameAsync(string genreName);
|
Task<Genre?> FindByNameAsync(string genreName);
|
||||||
Task<IList<Genre>> GetAllGenresAsync();
|
Task<IList<Genre>> GetAllGenresAsync();
|
||||||
Task<IList<Genre>> GetAllGenresByNamesAsync(IEnumerable<string> normalizedNames);
|
Task<IList<Genre>> GetAllGenresByNamesAsync(IEnumerable<string> normalizedNames);
|
||||||
Task<IList<GenreTagDto>> GetAllGenreDtosAsync(int userId);
|
|
||||||
Task RemoveAllGenreNoLongerAssociated(bool removeExternal = false);
|
Task RemoveAllGenreNoLongerAssociated(bool removeExternal = false);
|
||||||
Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(IList<int> libraryIds, int userId);
|
Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null);
|
||||||
Task<int> GetCountAsync();
|
Task<int> GetCountAsync();
|
||||||
Task<GenreTagDto> GetRandomGenre();
|
Task<GenreTagDto> GetRandomGenre();
|
||||||
Task<GenreTagDto> GetGenreById(int id);
|
Task<GenreTagDto> GetGenreById(int id);
|
||||||
@ -69,27 +68,6 @@ public class GenreRepository : IGenreRepository
|
|||||||
await _context.SaveChangesAsync();
|
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()
|
public async Task<int> GetCountAsync()
|
||||||
{
|
{
|
||||||
return await _context.Genre.CountAsync();
|
return await _context.Genre.CountAsync();
|
||||||
@ -128,13 +106,30 @@ public class GenreRepository : IGenreRepository
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IList<GenreTagDto>> GetAllGenreDtosAsync(int userId)
|
/// <summary>
|
||||||
|
/// Returns a set of Genre tags for a set of library Ids.
|
||||||
|
/// UserId will restrict returned Genres based on user's age restriction and library access.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId"></param>
|
||||||
|
/// <param name="libraryIds"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null)
|
||||||
{
|
{
|
||||||
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
var userRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
||||||
return await _context.Genre
|
var userLibs = await _context.Library.GetUserLibraries(userId).ToListAsync();
|
||||||
.RestrictAgainstAgeRestriction(ageRating)
|
|
||||||
.OrderBy(g => g.NormalizedTitle)
|
if (libraryIds is {Count: > 0})
|
||||||
.AsNoTracking()
|
{
|
||||||
|
userLibs = userLibs.Where(libraryIds.Contains).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _context.Series
|
||||||
|
.Where(s => userLibs.Contains(s.LibraryId))
|
||||||
|
.RestrictAgainstAgeRestriction(userRating)
|
||||||
|
.SelectMany(s => s.Metadata.Genres)
|
||||||
|
.AsSplitQuery()
|
||||||
|
.Distinct()
|
||||||
|
.OrderBy(p => p.NormalizedTitle)
|
||||||
.ProjectTo<GenreTagDto>(_mapper.ConfigurationProvider)
|
.ProjectTo<GenreTagDto>(_mapper.ConfigurationProvider)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public interface IPersonRepository
|
|||||||
Task<IList<PersonDto>> GetAllPersonDtosAsync(int userId);
|
Task<IList<PersonDto>> GetAllPersonDtosAsync(int userId);
|
||||||
Task<IList<PersonDto>> GetAllPersonDtosByRoleAsync(int userId, PersonRole role);
|
Task<IList<PersonDto>> GetAllPersonDtosByRoleAsync(int userId, PersonRole role);
|
||||||
Task RemoveAllPeopleNoLongerAssociated();
|
Task RemoveAllPeopleNoLongerAssociated();
|
||||||
Task<IList<PersonDto>> GetAllPeopleDtosForLibrariesAsync(List<int> libraryIds, int userId);
|
Task<IList<PersonDto>> GetAllPeopleDtosForLibrariesAsync(int userId, List<int>? libraryIds = null);
|
||||||
Task<int> GetCountAsync();
|
Task<int> GetCountAsync();
|
||||||
|
|
||||||
Task<IList<Person>> GetAllPeopleByRoleAndNames(PersonRole role, IEnumerable<string> normalizeNames);
|
Task<IList<Person>> GetAllPeopleByRoleAndNames(PersonRole role, IEnumerable<string> normalizeNames);
|
||||||
@ -61,11 +61,18 @@ public class PersonRepository : IPersonRepository
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IList<PersonDto>> GetAllPeopleDtosForLibrariesAsync(List<int> libraryIds, int userId)
|
public async Task<IList<PersonDto>> GetAllPeopleDtosForLibrariesAsync(int userId, List<int>? libraryIds = null)
|
||||||
{
|
{
|
||||||
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
||||||
|
var userLibs = await _context.Library.GetUserLibraries(userId).ToListAsync();
|
||||||
|
|
||||||
|
if (libraryIds is {Count: > 0})
|
||||||
|
{
|
||||||
|
userLibs = userLibs.Where(libraryIds.Contains).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
return await _context.Series
|
return await _context.Series
|
||||||
.Where(s => libraryIds.Contains(s.LibraryId))
|
.Where(s => userLibs.Contains(s.LibraryId))
|
||||||
.RestrictAgainstAgeRestriction(ageRating)
|
.RestrictAgainstAgeRestriction(ageRating)
|
||||||
.SelectMany(s => s.Metadata.People)
|
.SelectMany(s => s.Metadata.People)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
@ -99,6 +106,7 @@ public class PersonRepository : IPersonRepository
|
|||||||
public async Task<IList<PersonDto>> GetAllPersonDtosAsync(int userId)
|
public async Task<IList<PersonDto>> GetAllPersonDtosAsync(int userId)
|
||||||
{
|
{
|
||||||
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
||||||
|
var libraryIds = await _context.Library.GetUserLibraries(userId).ToListAsync();
|
||||||
return await _context.Person
|
return await _context.Person
|
||||||
.OrderBy(p => p.Name)
|
.OrderBy(p => p.Name)
|
||||||
.RestrictAgainstAgeRestriction(ageRating)
|
.RestrictAgainstAgeRestriction(ageRating)
|
||||||
|
@ -19,7 +19,7 @@ public interface ITagRepository
|
|||||||
Task<IList<Tag>> GetAllTagsByNameAsync(IEnumerable<string> normalizedNames);
|
Task<IList<Tag>> GetAllTagsByNameAsync(IEnumerable<string> normalizedNames);
|
||||||
Task<IList<TagDto>> GetAllTagDtosAsync(int userId);
|
Task<IList<TagDto>> GetAllTagDtosAsync(int userId);
|
||||||
Task RemoveAllTagNoLongerAssociated();
|
Task RemoveAllTagNoLongerAssociated();
|
||||||
Task<IList<TagDto>> GetAllTagDtosForLibrariesAsync(IList<int> libraryIds, int userId);
|
Task<IList<TagDto>> GetAllTagDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TagRepository : ITagRepository
|
public class TagRepository : ITagRepository
|
||||||
@ -57,11 +57,18 @@ public class TagRepository : ITagRepository
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IList<TagDto>> GetAllTagDtosForLibrariesAsync(IList<int> libraryIds, int userId)
|
public async Task<IList<TagDto>> GetAllTagDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null)
|
||||||
{
|
{
|
||||||
var userRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
var userRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
||||||
|
var userLibs = await _context.Library.GetUserLibraries(userId).ToListAsync();
|
||||||
|
|
||||||
|
if (libraryIds is {Count: > 0})
|
||||||
|
{
|
||||||
|
userLibs = userLibs.Where(libraryIds.Contains).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
return await _context.Series
|
return await _context.Series
|
||||||
.Where(s => libraryIds.Contains(s.LibraryId))
|
.Where(s => userLibs.Contains(s.LibraryId))
|
||||||
.RestrictAgainstAgeRestriction(userRating)
|
.RestrictAgainstAgeRestriction(userRating)
|
||||||
.SelectMany(s => s.Metadata.Tags)
|
.SelectMany(s => s.Metadata.Tags)
|
||||||
.AsSplitQuery()
|
.AsSplitQuery()
|
||||||
|
@ -605,7 +605,7 @@ public class DirectoryService : IDirectoryService
|
|||||||
{
|
{
|
||||||
if (!file.Contains(folder)) continue;
|
if (!file.Contains(folder)) continue;
|
||||||
|
|
||||||
var lowestPath = Path.GetDirectoryName(file)?.Replace(folder, string.Empty);
|
var lowestPath = Path.GetDirectoryName(file);
|
||||||
if (!string.IsNullOrEmpty(lowestPath))
|
if (!string.IsNullOrEmpty(lowestPath))
|
||||||
{
|
{
|
||||||
dirs.TryAdd(Parser.NormalizePath(lowestPath), string.Empty);
|
dirs.TryAdd(Parser.NormalizePath(lowestPath), string.Empty);
|
||||||
|
@ -137,19 +137,6 @@ public class ParseScannedFiles
|
|||||||
await _eventHub.SendMessageAsync(MessageFactory.NotificationProgress,
|
await _eventHub.SendMessageAsync(MessageFactory.NotificationProgress,
|
||||||
MessageFactory.FileScanProgressEvent(directory, library.Name, ProgressEventType.Updated));
|
MessageFactory.FileScanProgressEvent(directory, library.Name, ProgressEventType.Updated));
|
||||||
|
|
||||||
// This is debug code to help understand why some installs aren't working correctly
|
|
||||||
if (!forceCheck && seriesPaths.TryGetValue(directory, out var series2) && series2.Count > 1 && series2.All(s => !string.IsNullOrEmpty(s.LowestFolderPath)))
|
|
||||||
{
|
|
||||||
_logger.LogDebug("[ProcessFiles] Dirty check passed, series list: {@SeriesModified}", series2);
|
|
||||||
foreach (var s in series2)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("[ProcessFiles] Last Scanned: {LastScanned} vs Directory Check: {DirectoryLastScanned}",
|
|
||||||
s.LastScanned, _directoryService
|
|
||||||
.GetLastWriteTime(s.LowestFolderPath!)
|
|
||||||
.Truncate(TimeSpan.TicksPerSecond));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasSeriesFolderNotChangedSinceLastScan(seriesPaths, directory, forceCheck))
|
if (HasSeriesFolderNotChangedSinceLastScan(seriesPaths, directory, forceCheck))
|
||||||
{
|
{
|
||||||
@ -177,12 +164,12 @@ public class ParseScannedFiles
|
|||||||
|
|
||||||
if (!hasFolderChangedSinceLastScan)
|
if (!hasFolderChangedSinceLastScan)
|
||||||
{
|
{
|
||||||
_logger.LogDebug("[ProcessFiles] {Directory} subfolder {Folder} did not change since last scan, adding entry to skip", directory, seriesModified.LowestFolderPath);
|
_logger.LogTrace("[ProcessFiles] {Directory} subfolder {Folder} did not change since last scan, adding entry to skip", directory, seriesModified.LowestFolderPath);
|
||||||
result.Add(CreateScanResult(seriesModified.LowestFolderPath!, folderPath, false, ArraySegment<string>.Empty));
|
result.Add(CreateScanResult(seriesModified.LowestFolderPath!, folderPath, false, ArraySegment<string>.Empty));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.LogDebug("[ProcessFiles] {Directory} subfolder {Folder} changed for Series {SeriesName}", directory, seriesModified.LowestFolderPath, seriesModified.SeriesName);
|
_logger.LogTrace("[ProcessFiles] {Directory} subfolder {Folder} changed for Series {SeriesName}", directory, seriesModified.LowestFolderPath, seriesModified.SeriesName);
|
||||||
result.Add(CreateScanResult(directory, folderPath, true,
|
result.Add(CreateScanResult(directory, folderPath, true,
|
||||||
_directoryService.ScanFiles(seriesModified.LowestFolderPath!, fileExtensions, matcher)));
|
_directoryService.ScanFiles(seriesModified.LowestFolderPath!, fileExtensions, matcher)));
|
||||||
}
|
}
|
||||||
@ -190,7 +177,6 @@ public class ParseScannedFiles
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For a scan, this is doing everything in the directory loop before the folder Action is called...which leads to no progress indication
|
|
||||||
result.Add(CreateScanResult(directory, folderPath, true,
|
result.Add(CreateScanResult(directory, folderPath, true,
|
||||||
_directoryService.ScanFiles(directory, fileExtensions, matcher)));
|
_directoryService.ScanFiles(directory, fileExtensions, matcher)));
|
||||||
}
|
}
|
||||||
|
@ -355,44 +355,7 @@ public class ProcessSeries : IProcessSeries
|
|||||||
// Set the AgeRating as highest in all the comicInfos
|
// Set the AgeRating as highest in all the comicInfos
|
||||||
if (!series.Metadata.AgeRatingLocked) series.Metadata.AgeRating = chapters.Max(chapter => chapter.AgeRating);
|
if (!series.Metadata.AgeRatingLocked) series.Metadata.AgeRating = chapters.Max(chapter => chapter.AgeRating);
|
||||||
|
|
||||||
// Count (aka expected total number of chapters or volumes from metadata) across all chapters
|
DeterminePublicationStatus(series, chapters);
|
||||||
series.Metadata.TotalCount = chapters.Max(chapter => chapter.TotalCount);
|
|
||||||
// The actual number of count's defined across all chapter's metadata
|
|
||||||
series.Metadata.MaxCount = chapters.Max(chapter => chapter.Count);
|
|
||||||
|
|
||||||
var maxVolume = (int) series.Volumes.Max(v => v.MaxNumber);
|
|
||||||
var maxChapter = (int) chapters.Max(c => c.MaxNumber);
|
|
||||||
|
|
||||||
// Single books usually don't have a number in their Range (filename)
|
|
||||||
if (series.Format == MangaFormat.Epub || series.Format == MangaFormat.Pdf && chapters.Count == 1)
|
|
||||||
{
|
|
||||||
series.Metadata.MaxCount = 1;
|
|
||||||
} else if (series.Metadata.TotalCount <= 1 && chapters.Count == 1 && chapters[0].IsSpecial)
|
|
||||||
{
|
|
||||||
// If a series has a TotalCount of 1 (or no total count) and there is only a Special, mark it as Complete
|
|
||||||
series.Metadata.MaxCount = series.Metadata.TotalCount;
|
|
||||||
} else if ((maxChapter == Parser.Parser.DefaultChapterNumber || maxChapter > series.Metadata.TotalCount) && maxVolume <= series.Metadata.TotalCount)
|
|
||||||
{
|
|
||||||
series.Metadata.MaxCount = maxVolume;
|
|
||||||
} else if (maxVolume == series.Metadata.TotalCount)
|
|
||||||
{
|
|
||||||
series.Metadata.MaxCount = maxVolume;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
series.Metadata.MaxCount = maxChapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!series.Metadata.PublicationStatusLocked)
|
|
||||||
{
|
|
||||||
series.Metadata.PublicationStatus = PublicationStatus.OnGoing;
|
|
||||||
if (series.Metadata.MaxCount == series.Metadata.TotalCount && series.Metadata.TotalCount > 0)
|
|
||||||
{
|
|
||||||
series.Metadata.PublicationStatus = PublicationStatus.Completed;
|
|
||||||
} else if (series.Metadata.TotalCount > 0 && series.Metadata.MaxCount > 0)
|
|
||||||
{
|
|
||||||
series.Metadata.PublicationStatus = PublicationStatus.Ended;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(firstChapter?.Summary) && !series.Metadata.SummaryLocked)
|
if (!string.IsNullOrEmpty(firstChapter?.Summary) && !series.Metadata.SummaryLocked)
|
||||||
{
|
{
|
||||||
@ -616,6 +579,48 @@ public class ProcessSeries : IProcessSeries
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void DeterminePublicationStatus(Series series, List<Chapter> chapters)
|
||||||
|
{
|
||||||
|
// Count (aka expected total number of chapters or volumes from metadata) across all chapters
|
||||||
|
series.Metadata.TotalCount = chapters.Max(chapter => chapter.TotalCount);
|
||||||
|
// The actual number of count's defined across all chapter's metadata
|
||||||
|
series.Metadata.MaxCount = chapters.Max(chapter => chapter.Count);
|
||||||
|
|
||||||
|
var maxVolume = (int) series.Volumes.Where(v => v.MaxNumber.IsNot(Parser.Parser.SpecialVolumeNumber)).Max(v => v.MaxNumber);
|
||||||
|
var maxChapter = (int) chapters.Max(c => c.MaxNumber);
|
||||||
|
|
||||||
|
// Single books usually don't have a number in their Range (filename)
|
||||||
|
if (series.Format == MangaFormat.Epub || series.Format == MangaFormat.Pdf && chapters.Count == 1)
|
||||||
|
{
|
||||||
|
series.Metadata.MaxCount = 1;
|
||||||
|
} else if (series.Metadata.TotalCount <= 1 && chapters.Count == 1 && chapters[0].IsSpecial)
|
||||||
|
{
|
||||||
|
// If a series has a TotalCount of 1 (or no total count) and there is only a Special, mark it as Complete
|
||||||
|
series.Metadata.MaxCount = series.Metadata.TotalCount;
|
||||||
|
} else if ((maxChapter == Parser.Parser.DefaultChapterNumber || maxChapter > series.Metadata.TotalCount) && maxVolume <= series.Metadata.TotalCount)
|
||||||
|
{
|
||||||
|
series.Metadata.MaxCount = maxVolume;
|
||||||
|
} else if (maxVolume == series.Metadata.TotalCount)
|
||||||
|
{
|
||||||
|
series.Metadata.MaxCount = maxVolume;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
series.Metadata.MaxCount = maxChapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!series.Metadata.PublicationStatusLocked)
|
||||||
|
{
|
||||||
|
series.Metadata.PublicationStatus = PublicationStatus.OnGoing;
|
||||||
|
if (series.Metadata.MaxCount == series.Metadata.TotalCount && series.Metadata.TotalCount > 0)
|
||||||
|
{
|
||||||
|
series.Metadata.PublicationStatus = PublicationStatus.Completed;
|
||||||
|
} else if (series.Metadata.TotalCount > 0 && series.Metadata.MaxCount > 0)
|
||||||
|
{
|
||||||
|
series.Metadata.PublicationStatus = PublicationStatus.Ended;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task UpdateVolumes(Series series, IList<ParserInfo> parsedInfos, bool forceUpdate = false)
|
private async Task UpdateVolumes(Series series, IList<ParserInfo> parsedInfos, bool forceUpdate = false)
|
||||||
{
|
{
|
||||||
// Add new volumes and update chapters per volume
|
// Add new volumes and update chapters per volume
|
||||||
|
@ -241,7 +241,6 @@ export class LibraryDetailComponent implements OnInit {
|
|||||||
async handleAction(action: ActionItem<Library>, library: Library) {
|
async handleAction(action: ActionItem<Library>, library: Library) {
|
||||||
let lib: Partial<Library> = library;
|
let lib: Partial<Library> = library;
|
||||||
if (library === undefined) {
|
if (library === undefined) {
|
||||||
//lib = {id: this.libraryId, name: this.libraryName}; // BUG: We need the whole library for editLibrary
|
|
||||||
this.libraryService.getLibrary(this.libraryId).subscribe(async library => {
|
this.libraryService.getLibrary(this.libraryId).subscribe(async library => {
|
||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
case(Action.Scan):
|
case(Action.Scan):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user