ScanLibrary now respects the library a series belongs to, doesn't reset series every run but updates/removes/inserts as needed.

This commit is contained in:
Joseph Milazzo 2021-01-19 14:35:24 -06:00
parent 44ebca36ec
commit e180032a8e
5 changed files with 54 additions and 29 deletions

View File

@ -170,7 +170,7 @@ namespace API.Controllers
{
var username = User.GetUsername();
_logger.LogInformation($"Library {libraryId} is being deleted by {username}.");
var series = await _unitOfWork.SeriesRepository.GetSeriesDtoForLibraryIdAsync(libraryId);
var series = await _unitOfWork.SeriesRepository.GetSeriesForLibraryIdAsync(libraryId);
var volumes = (await _unitOfWork.SeriesRepository.GetVolumesForSeriesAsync(series.Select(x => x.Id).ToArray()))
.Select(x => x.Id).ToArray();
var result = await _unitOfWork.LibraryRepository.DeleteLibrary(libraryId);

View File

@ -81,6 +81,7 @@ namespace API.Data
return await _context.Library
.Where(x => x.Id == libraryId)
.Include(f => f.Folders)
.Include(l => l.Series)
.SingleAsync();
}

View File

@ -23,6 +23,11 @@ namespace API.Data
_mapper = mapper;
}
public void Add(Series series)
{
_context.Series.Add(series);
}
public void Update(Series series)
{
_context.Entry(series).State = EntityState.Modified;
@ -48,7 +53,15 @@ namespace API.Data
return _context.Series.SingleOrDefault(x => x.Name == name);
}
public async Task<IEnumerable<SeriesDto>> GetSeriesDtoForLibraryIdAsync(int libraryId, int userId = 0)
public async Task<IEnumerable<Series>> GetSeriesForLibraryIdAsync(int libraryId)
{
return await _context.Series
.Where(s => s.LibraryId == libraryId)
.OrderBy(s => s.SortName)
.ToListAsync();
}
public async Task<IEnumerable<SeriesDto>> GetSeriesDtoForLibraryIdAsync(int libraryId, int userId)
{
// if (userId > 0)
// {

View File

@ -7,10 +7,12 @@ namespace API.Interfaces
{
public interface ISeriesRepository
{
void Add(Series series);
void Update(Series series);
Task<Series> GetSeriesByNameAsync(string name);
Series GetSeriesByName(string name);
Task<IEnumerable<SeriesDto>> GetSeriesDtoForLibraryIdAsync(int libraryId, int userId = 0);
Task<IEnumerable<SeriesDto>> GetSeriesDtoForLibraryIdAsync(int libraryId, int userId);
Task<IEnumerable<Series>> GetSeriesForLibraryIdAsync(int libraryId);
Task<IEnumerable<VolumeDto>> GetVolumesDtoAsync(int seriesId, int userId = 0);
IEnumerable<Volume> GetVolumes(int seriesId);
Task<SeriesDto> GetSeriesDtoByIdAsync(int seriesId);
@ -21,5 +23,6 @@ namespace API.Interfaces
Task<IEnumerable<Volume>> GetVolumesForSeriesAsync(int[] seriesIds);
Task<bool> DeleteSeriesAsync(int seriesId);
Task<Volume> GetVolumeByIdAsync(int volumeId);
}
}

View File

@ -40,7 +40,7 @@ namespace API.Services
/// <param name="searchPatternExpression">Regex version of search pattern (ie \.mp3|\.mp4). Defaults to * meaning all files.</param>
/// <param name="searchOption">SearchOption to use, defaults to TopDirectoryOnly</param>
/// <returns>List of file paths</returns>
public static IEnumerable<string> GetFilesWithCertainExtensions(string path,
private static IEnumerable<string> GetFilesWithCertainExtensions(string path,
string searchPatternExpression = "",
SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
@ -57,9 +57,7 @@ namespace API.Services
return Directory.GetFiles(path);
}
public IEnumerable<string> ListDirectory(string rootPath)
public IEnumerable<string> ListDirectory(string rootPath)
{
if (!Directory.Exists(rootPath)) return ImmutableList<string>.Empty;
@ -72,13 +70,6 @@ namespace API.Services
return dirs;
}
// public IList<string> ListFiles(string rootPath)
// {
// if (!Directory.Exists(rootPath)) return ImmutableList<string>.Empty;
// return Directory.GetFiles(rootPath);
// }
/// <summary>
/// Processes files found during a library scan. Generates a collection of series->volume->files for DB processing later.
/// </summary>
@ -117,20 +108,20 @@ namespace API.Services
}
}
private Series UpdateSeries(string seriesName, ParserInfo[] infos, bool forceUpdate)
private Series UpdateSeries(Series series, ParserInfo[] infos, bool forceUpdate)
{
var series = _unitOfWork.SeriesRepository.GetSeriesByName(seriesName) ?? new Series
{
Name = seriesName,
OriginalName = seriesName,
SortName = seriesName,
Summary = "" // TODO: Check if comicInfo.xml in file and parse metadata out.
};
var volumes = UpdateVolumes(series, infos, forceUpdate);
series.Volumes = volumes;
series.CoverImage = volumes.OrderBy(x => x.Number).FirstOrDefault()?.CoverImage;
series.Pages = volumes.Sum(v => v.Pages);
if (series.CoverImage == null || forceUpdate)
{
series.CoverImage = volumes.OrderBy(x => x.Number).FirstOrDefault()?.CoverImage;
}
if (string.IsNullOrEmpty(series.Summary) || forceUpdate)
{
series.Summary = ""; // TODO: Check if comicInfo.xml in file and parse metadata out.
}
return series;
}
@ -262,17 +253,34 @@ namespace API.Services
var series = filtered.ToImmutableDictionary(v => v.Key, v => v.Value);
// Perform DB activities
library.Series = new List<Series>(); // Temp delete everything until we can mark items Unavailable
var allSeries = Task.Run(() => _unitOfWork.SeriesRepository.GetSeriesForLibraryIdAsync(libraryId)).Result.ToList();
foreach (var seriesKey in series.Keys)
{
// TODO: Critical bug: Code is not taking libraryId into account and series are being linked across libraries.
var mangaSeries = UpdateSeries(seriesKey, series[seriesKey].ToArray(), forceUpdate);
_logger.LogInformation($"Created/Updated series {mangaSeries.Name}");
var mangaSeries = allSeries.SingleOrDefault(s => s.Name == seriesKey) ?? new Series
{
Name = seriesKey,
OriginalName = seriesKey,
SortName = seriesKey,
Summary = ""
};
mangaSeries = UpdateSeries(mangaSeries, series[seriesKey].ToArray(), forceUpdate);
_logger.LogInformation($"Created/Updated series {mangaSeries.Name} for {library.Name} library");
library.Series ??= new List<Series>();
library.Series.Add(mangaSeries);
}
// Remove series that are no longer on disk
foreach (var existingSeries in allSeries)
{
if (!series.ContainsKey(existingSeries.Name) || !series.ContainsKey(existingSeries.OriginalName))
{
// Delete series, there is no file to backup any longer.
library.Series.Remove(existingSeries);
}
}
_unitOfWork.LibraryRepository.Update(library);
if (Task.Run(() => _unitOfWork.Complete()).Result)
{
_logger.LogInformation($"Scan completed on {library.Name}. Parsed {series.Keys.Count()} series.");