mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
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:
parent
44ebca36ec
commit
e180032a8e
@ -170,7 +170,7 @@ namespace API.Controllers
|
|||||||
{
|
{
|
||||||
var username = User.GetUsername();
|
var username = User.GetUsername();
|
||||||
_logger.LogInformation($"Library {libraryId} is being deleted by {username}.");
|
_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()))
|
var volumes = (await _unitOfWork.SeriesRepository.GetVolumesForSeriesAsync(series.Select(x => x.Id).ToArray()))
|
||||||
.Select(x => x.Id).ToArray();
|
.Select(x => x.Id).ToArray();
|
||||||
var result = await _unitOfWork.LibraryRepository.DeleteLibrary(libraryId);
|
var result = await _unitOfWork.LibraryRepository.DeleteLibrary(libraryId);
|
||||||
|
@ -81,6 +81,7 @@ namespace API.Data
|
|||||||
return await _context.Library
|
return await _context.Library
|
||||||
.Where(x => x.Id == libraryId)
|
.Where(x => x.Id == libraryId)
|
||||||
.Include(f => f.Folders)
|
.Include(f => f.Folders)
|
||||||
|
.Include(l => l.Series)
|
||||||
.SingleAsync();
|
.SingleAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,11 @@ namespace API.Data
|
|||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Add(Series series)
|
||||||
|
{
|
||||||
|
_context.Series.Add(series);
|
||||||
|
}
|
||||||
|
|
||||||
public void Update(Series series)
|
public void Update(Series series)
|
||||||
{
|
{
|
||||||
_context.Entry(series).State = EntityState.Modified;
|
_context.Entry(series).State = EntityState.Modified;
|
||||||
@ -48,7 +53,15 @@ namespace API.Data
|
|||||||
return _context.Series.SingleOrDefault(x => x.Name == name);
|
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)
|
// if (userId > 0)
|
||||||
// {
|
// {
|
||||||
|
@ -7,10 +7,12 @@ namespace API.Interfaces
|
|||||||
{
|
{
|
||||||
public interface ISeriesRepository
|
public interface ISeriesRepository
|
||||||
{
|
{
|
||||||
|
void Add(Series series);
|
||||||
void Update(Series series);
|
void Update(Series series);
|
||||||
Task<Series> GetSeriesByNameAsync(string name);
|
Task<Series> GetSeriesByNameAsync(string name);
|
||||||
Series GetSeriesByName(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);
|
Task<IEnumerable<VolumeDto>> GetVolumesDtoAsync(int seriesId, int userId = 0);
|
||||||
IEnumerable<Volume> GetVolumes(int seriesId);
|
IEnumerable<Volume> GetVolumes(int seriesId);
|
||||||
Task<SeriesDto> GetSeriesDtoByIdAsync(int seriesId);
|
Task<SeriesDto> GetSeriesDtoByIdAsync(int seriesId);
|
||||||
@ -21,5 +23,6 @@ namespace API.Interfaces
|
|||||||
Task<IEnumerable<Volume>> GetVolumesForSeriesAsync(int[] seriesIds);
|
Task<IEnumerable<Volume>> GetVolumesForSeriesAsync(int[] seriesIds);
|
||||||
Task<bool> DeleteSeriesAsync(int seriesId);
|
Task<bool> DeleteSeriesAsync(int seriesId);
|
||||||
Task<Volume> GetVolumeByIdAsync(int volumeId);
|
Task<Volume> GetVolumeByIdAsync(int volumeId);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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="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>
|
/// <param name="searchOption">SearchOption to use, defaults to TopDirectoryOnly</param>
|
||||||
/// <returns>List of file paths</returns>
|
/// <returns>List of file paths</returns>
|
||||||
public static IEnumerable<string> GetFilesWithCertainExtensions(string path,
|
private static IEnumerable<string> GetFilesWithCertainExtensions(string path,
|
||||||
string searchPatternExpression = "",
|
string searchPatternExpression = "",
|
||||||
SearchOption searchOption = SearchOption.TopDirectoryOnly)
|
SearchOption searchOption = SearchOption.TopDirectoryOnly)
|
||||||
{
|
{
|
||||||
@ -57,9 +57,7 @@ namespace API.Services
|
|||||||
return Directory.GetFiles(path);
|
return Directory.GetFiles(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> ListDirectory(string rootPath)
|
||||||
|
|
||||||
public IEnumerable<string> ListDirectory(string rootPath)
|
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(rootPath)) return ImmutableList<string>.Empty;
|
if (!Directory.Exists(rootPath)) return ImmutableList<string>.Empty;
|
||||||
|
|
||||||
@ -72,13 +70,6 @@ namespace API.Services
|
|||||||
return dirs;
|
return dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public IList<string> ListFiles(string rootPath)
|
|
||||||
// {
|
|
||||||
// if (!Directory.Exists(rootPath)) return ImmutableList<string>.Empty;
|
|
||||||
// return Directory.GetFiles(rootPath);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes files found during a library scan. Generates a collection of series->volume->files for DB processing later.
|
/// Processes files found during a library scan. Generates a collection of series->volume->files for DB processing later.
|
||||||
/// </summary>
|
/// </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);
|
var volumes = UpdateVolumes(series, infos, forceUpdate);
|
||||||
series.Volumes = volumes;
|
series.Volumes = volumes;
|
||||||
series.CoverImage = volumes.OrderBy(x => x.Number).FirstOrDefault()?.CoverImage;
|
|
||||||
series.Pages = volumes.Sum(v => v.Pages);
|
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;
|
return series;
|
||||||
}
|
}
|
||||||
@ -262,17 +253,34 @@ namespace API.Services
|
|||||||
var series = filtered.ToImmutableDictionary(v => v.Key, v => v.Value);
|
var series = filtered.ToImmutableDictionary(v => v.Key, v => v.Value);
|
||||||
|
|
||||||
// Perform DB activities
|
// 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)
|
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 = allSeries.SingleOrDefault(s => s.Name == seriesKey) ?? new Series
|
||||||
var mangaSeries = UpdateSeries(seriesKey, series[seriesKey].ToArray(), forceUpdate);
|
{
|
||||||
_logger.LogInformation($"Created/Updated series {mangaSeries.Name}");
|
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);
|
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);
|
_unitOfWork.LibraryRepository.Update(library);
|
||||||
|
|
||||||
if (Task.Run(() => _unitOfWork.Complete()).Result)
|
if (Task.Run(() => _unitOfWork.Complete()).Result)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Scan completed on {library.Name}. Parsed {series.Keys.Count()} series.");
|
_logger.LogInformation($"Scan completed on {library.Name}. Parsed {series.Keys.Count()} series.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user