mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-05-24 00:52:23 -04:00
Refactored ScanLibrary to accept and library id rather than DTO. Refactored ScanLibrary to use Task.Run() rather than having synchronous repo methods.
This commit is contained in:
parent
9168e12483
commit
7b1714349d
@ -70,8 +70,9 @@ namespace API.Controllers
|
||||
|
||||
|
||||
if (await _userRepository.SaveAllAsync())
|
||||
{
|
||||
//TODO: Enqueue scan library task
|
||||
{
|
||||
var createdLibrary = await _libraryRepository.GetLibraryForNameAsync(library.Name);
|
||||
BackgroundJob.Enqueue(() => _directoryService.ScanLibrary(createdLibrary.Id));
|
||||
return Ok();
|
||||
}
|
||||
|
||||
@ -128,27 +129,22 @@ namespace API.Controllers
|
||||
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[HttpPost("scan")]
|
||||
public async Task<ActionResult> ScanLibrary(int libraryId)
|
||||
public ActionResult ScanLibrary(int libraryId)
|
||||
{
|
||||
var library = await _libraryRepository.GetLibraryDtoForIdAsync(libraryId);
|
||||
|
||||
// We have to send a json encoded Library (aka a DTO) to the Background Job thread.
|
||||
// Because we use EF, we have circular dependencies back to Library and it will crap out
|
||||
// TODO: Refactor this to use libraryId and move Library call in method.
|
||||
BackgroundJob.Enqueue(() => _directoryService.ScanLibrary(library));
|
||||
BackgroundJob.Enqueue(() => _directoryService.ScanLibrary(libraryId));
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpGet("libraries-for")]
|
||||
public async Task<ActionResult<IEnumerable<LibraryDto>>> GetLibrariesForUser(string username)
|
||||
{
|
||||
return Ok(await _libraryRepository.GetLibrariesForUsernameAysnc(username));
|
||||
return Ok(await _libraryRepository.GetLibrariesDtoForUsernameAsync(username));
|
||||
}
|
||||
|
||||
[HttpGet("series")]
|
||||
public async Task<ActionResult<IEnumerable<Series>>> GetSeriesForLibrary(int libraryId)
|
||||
{
|
||||
return Ok(await _seriesRepository.GetSeriesForLibraryIdAsync(libraryId));
|
||||
return Ok(await _seriesRepository.GetSeriesDtoForLibraryIdAsync(libraryId));
|
||||
}
|
||||
}
|
||||
}
|
@ -27,13 +27,13 @@ namespace API.Controllers
|
||||
[HttpGet("{seriesId}")]
|
||||
public async Task<ActionResult<SeriesDto>> GetSeries(int seriesId)
|
||||
{
|
||||
return Ok(await _seriesRepository.GetSeriesByIdAsync(seriesId));
|
||||
return Ok(await _seriesRepository.GetSeriesDtoByIdAsync(seriesId));
|
||||
}
|
||||
|
||||
[HttpGet("volumes")]
|
||||
public async Task<ActionResult<IEnumerable<VolumeDto>>> GetVolumes(int seriesId)
|
||||
{
|
||||
return Ok(await _seriesRepository.GetVolumesAsync(seriesId));
|
||||
return Ok(await _seriesRepository.GetVolumesDtoAsync(seriesId));
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.DTOs;
|
||||
using API.Entities;
|
||||
using API.Extensions;
|
||||
using API.Interfaces;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@ -51,7 +50,7 @@ namespace API.Controllers
|
||||
|
||||
if (user == null) return BadRequest("Could not validate user");
|
||||
|
||||
var libs = await _libraryRepository.GetLibrariesForUsernameAysnc(user.UserName);
|
||||
var libs = await _libraryRepository.GetLibrariesDtoForUsernameAsync(user.UserName);
|
||||
|
||||
return Ok(libs.Any(x => x.Id == libraryId));
|
||||
}
|
||||
|
@ -36,16 +36,7 @@ namespace API.Data
|
||||
return _context.SaveChanges() > 0;
|
||||
}
|
||||
|
||||
public Library GetLibraryForName(string libraryName)
|
||||
{
|
||||
return _context.Library
|
||||
.Where(x => x.Name == libraryName)
|
||||
.Include(f => f.Folders)
|
||||
.Include(s => s.Series)
|
||||
.Single();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LibraryDto>> GetLibrariesForUsernameAysnc(string userName)
|
||||
public async Task<IEnumerable<LibraryDto>> GetLibrariesDtoForUsernameAsync(string userName)
|
||||
{
|
||||
return await _context.Library
|
||||
.Include(l => l.AppUsers)
|
||||
@ -53,21 +44,22 @@ namespace API.Data
|
||||
.ProjectTo<LibraryDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Library> GetLibraryForNameAsync(string libraryName)
|
||||
{
|
||||
return await _context.Library
|
||||
.Where(x => x.Name == libraryName)
|
||||
.Include(f => f.Folders)
|
||||
.Include(s => s.Series)
|
||||
.SingleAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LibraryDto>> GetLibrariesAsync()
|
||||
{
|
||||
return await _context.Library
|
||||
.Include(f => f.Folders)
|
||||
.ProjectTo<LibraryDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<LibraryDto> GetLibraryDtoForIdAsync(int libraryId)
|
||||
{
|
||||
return await _context.Library
|
||||
.Where(x => x.Id == libraryId)
|
||||
.Include(f => f.Folders)
|
||||
.ProjectTo<LibraryDto>(_mapper.ConfigurationProvider).SingleAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task<Library> GetLibraryForIdAsync(int libraryId)
|
||||
{
|
||||
return await _context.Library
|
||||
|
@ -46,7 +46,7 @@ namespace API.Data
|
||||
return _context.Series.SingleOrDefault(x => x.Name == name);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SeriesDto>> GetSeriesForLibraryIdAsync(int libraryId)
|
||||
public async Task<IEnumerable<SeriesDto>> GetSeriesDtoForLibraryIdAsync(int libraryId)
|
||||
{
|
||||
return await _context.Series
|
||||
.Where(series => series.LibraryId == libraryId)
|
||||
@ -54,22 +54,14 @@ namespace API.Data
|
||||
.ProjectTo<SeriesDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<VolumeDto>> GetVolumesAsync(int seriesId)
|
||||
public async Task<IEnumerable<VolumeDto>> GetVolumesDtoAsync(int seriesId)
|
||||
{
|
||||
return await _context.Volume
|
||||
.Where(vol => vol.SeriesId == seriesId)
|
||||
.OrderBy(volume => volume.Number)
|
||||
.ProjectTo<VolumeDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
public IEnumerable<VolumeDto> GetVolumesDto(int seriesId)
|
||||
{
|
||||
return _context.Volume
|
||||
.Where(vol => vol.SeriesId == seriesId)
|
||||
.OrderBy(vol => vol.Number)
|
||||
.ProjectTo<VolumeDto>(_mapper.ConfigurationProvider).ToList();
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<Volume> GetVolumes(int seriesId)
|
||||
{
|
||||
return _context.Volume
|
||||
@ -78,7 +70,7 @@ namespace API.Data
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async Task<SeriesDto> GetSeriesByIdAsync(int seriesId)
|
||||
public async Task<SeriesDto> GetSeriesDtoByIdAsync(int seriesId)
|
||||
{
|
||||
return await _context.Series.Where(x => x.Id == seriesId)
|
||||
.ProjectTo<SeriesDto>(_mapper.ConfigurationProvider).SingleAsync();
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using API.DTOs;
|
||||
|
||||
namespace API.Interfaces
|
||||
{
|
||||
@ -7,6 +6,6 @@ namespace API.Interfaces
|
||||
{
|
||||
IEnumerable<string> ListDirectory(string rootPath);
|
||||
|
||||
void ScanLibrary(LibraryDto library);
|
||||
void ScanLibrary(int libraryId);
|
||||
}
|
||||
}
|
@ -10,16 +10,10 @@ namespace API.Interfaces
|
||||
void Update(Library library);
|
||||
Task<bool> SaveAllAsync();
|
||||
Task<IEnumerable<LibraryDto>> GetLibrariesAsync();
|
||||
/// <summary>
|
||||
/// Checks to see if a library of the same name exists. We only allow unique library names, no duplicates per LibraryType.
|
||||
/// </summary>
|
||||
/// <param name="libraryName"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> LibraryExists(string libraryName);
|
||||
Task<LibraryDto> GetLibraryDtoForIdAsync(int libraryId);
|
||||
Task<Library> GetLibraryForIdAsync(int libraryId);
|
||||
bool SaveAll();
|
||||
Library GetLibraryForName(string libraryName);
|
||||
Task<IEnumerable<LibraryDto>> GetLibrariesForUsernameAysnc(string userName);
|
||||
Task<IEnumerable<LibraryDto>> GetLibrariesDtoForUsernameAsync(string userName);
|
||||
Task<Library> GetLibraryForNameAsync(string libraryName);
|
||||
}
|
||||
}
|
@ -12,11 +12,10 @@ namespace API.Interfaces
|
||||
Task<Series> GetSeriesByNameAsync(string name);
|
||||
Series GetSeriesByName(string name);
|
||||
bool SaveAll();
|
||||
Task<IEnumerable<SeriesDto>> GetSeriesForLibraryIdAsync(int libraryId);
|
||||
Task<IEnumerable<VolumeDto>> GetVolumesAsync(int seriesId);
|
||||
IEnumerable<VolumeDto> GetVolumesDto(int seriesId);
|
||||
Task<IEnumerable<SeriesDto>> GetSeriesDtoForLibraryIdAsync(int libraryId);
|
||||
Task<IEnumerable<VolumeDto>> GetVolumesDtoAsync(int seriesId);
|
||||
IEnumerable<Volume> GetVolumes(int seriesId);
|
||||
Task<SeriesDto> GetSeriesByIdAsync(int seriesId);
|
||||
Task<SeriesDto> GetSeriesDtoByIdAsync(int seriesId);
|
||||
|
||||
}
|
||||
}
|
@ -5,11 +5,9 @@ using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using API.DTOs;
|
||||
using API.Entities;
|
||||
using API.Interfaces;
|
||||
using API.Parser;
|
||||
@ -149,6 +147,7 @@ namespace API.Services
|
||||
|
||||
// BUG: This is creating new volume entries and not resetting each run.
|
||||
IList<Volume> existingVolumes = _seriesRepository.GetVolumes(series.Id).ToList();
|
||||
//IList<Volume> existingVolumes = Task.Run(() => _seriesRepository.GetVolumesAsync(series.Id)).Result.ToList();
|
||||
foreach (var info in infos)
|
||||
{
|
||||
var existingVolume = existingVolumes.SingleOrDefault(v => v.Name == info.Volumes);
|
||||
@ -189,46 +188,45 @@ namespace API.Services
|
||||
return series;
|
||||
}
|
||||
|
||||
public void ScanLibrary(LibraryDto library)
|
||||
public void ScanLibrary(int libraryId)
|
||||
{
|
||||
var library = Task.Run(() => _libraryRepository.GetLibraryForIdAsync(libraryId)).Result;
|
||||
_scannedSeries = new ConcurrentDictionary<string, ConcurrentBag<ParserInfo>>();
|
||||
_logger.LogInformation($"Beginning scan on {library.Name}");
|
||||
|
||||
foreach (var folderPath in library.Folders)
|
||||
{
|
||||
try {
|
||||
TraverseTreeParallelForEach(folderPath, (f) =>
|
||||
TraverseTreeParallelForEach(folderPath.Path, (f) =>
|
||||
{
|
||||
// Exceptions are no-ops.
|
||||
try
|
||||
{
|
||||
Process(f);
|
||||
}
|
||||
catch (FileNotFoundException) {}
|
||||
catch (IOException) {}
|
||||
catch (UnauthorizedAccessException) {}
|
||||
catch (SecurityException) {}
|
||||
catch (FileNotFoundException exception)
|
||||
{
|
||||
_logger.LogError(exception, "The file could not be found");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (ArgumentException ex) {
|
||||
_logger.LogError(ex, "The directory '{folderPath}' does not exist");
|
||||
_logger.LogError(ex, $"The directory '{folderPath}' does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
var filtered = _scannedSeries.Where(kvp => !kvp.Value.IsEmpty);
|
||||
var series = filtered.ToImmutableDictionary(v => v.Key, v => v.Value);
|
||||
|
||||
// Perform DB activities on ImmutableDictionary
|
||||
var libraryEntity = _libraryRepository.GetLibraryForName(library.Name);
|
||||
libraryEntity.Series = new List<Series>(); // Temp delete everything for testing
|
||||
// Perform DB activities
|
||||
library.Series = new List<Series>(); // Temp delete everything until we can mark items Unavailable
|
||||
foreach (var seriesKey in series.Keys)
|
||||
{
|
||||
var s = UpdateSeries(seriesKey, series[seriesKey].ToArray());
|
||||
_logger.LogInformation($"Created/Updated series {s.Name}");
|
||||
libraryEntity.Series.Add(s);
|
||||
library.Series.Add(s);
|
||||
}
|
||||
|
||||
_libraryRepository.Update(libraryEntity);
|
||||
_libraryRepository.Update(library);
|
||||
|
||||
if (_libraryRepository.SaveAll())
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user