Report Media Issues (#1964)

* Started working on a report problems implementation.

* Started code

* Added logging to book and archive service.

* Removed an additional ComicInfo read when comicinfo is null when trying to load. But we've already done it once earlier, so there really isn't any point.

* Added basic implementation for media errors.

* MediaErrors will ignore duplicate errors when there are multiple issues on same file in a scan.

* Fixed unit tests

* Basic code in place to view and clear. Just UI Cleanup needed.

* Slight css upgrade

* Fixed up centering and simplified the code to use regular array instead of observables as it wasn't working.

* Fixed unit tests

* Fixed unit tests for real
This commit is contained in:
Joe Milazzo 2023-05-07 12:14:39 -05:00 committed by GitHub
parent 642b23ed61
commit d1e4878345
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 2586 additions and 57 deletions

View file

@ -3,10 +3,13 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using API.Data;
using API.DTOs.Jobs;
using API.DTOs.MediaErrors;
using API.DTOs.Stats;
using API.DTOs.Update;
using API.Extensions;
using API.Helpers;
using API.Services;
using API.Services.Tasks;
using Hangfire;
@ -14,7 +17,6 @@ using Hangfire.Storage;
using Kavita.Common;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using TaskScheduler = API.Services.TaskScheduler;
@ -23,7 +25,6 @@ namespace API.Controllers;
[Authorize(Policy = "RequireAdminRole")]
public class ServerController : BaseApiController
{
private readonly IHostApplicationLifetime _applicationLifetime;
private readonly ILogger<ServerController> _logger;
private readonly IBackupService _backupService;
private readonly IArchiveService _archiveService;
@ -34,13 +35,13 @@ public class ServerController : BaseApiController
private readonly IScannerService _scannerService;
private readonly IAccountService _accountService;
private readonly ITaskScheduler _taskScheduler;
private readonly IUnitOfWork _unitOfWork;
public ServerController(IHostApplicationLifetime applicationLifetime, ILogger<ServerController> logger,
public ServerController(ILogger<ServerController> logger,
IBackupService backupService, IArchiveService archiveService, IVersionUpdaterService versionUpdaterService, IStatsService statsService,
ICleanupService cleanupService, IBookmarkService bookmarkService, IScannerService scannerService, IAccountService accountService,
ITaskScheduler taskScheduler)
ITaskScheduler taskScheduler, IUnitOfWork unitOfWork)
{
_applicationLifetime = applicationLifetime;
_logger = logger;
_backupService = backupService;
_archiveService = archiveService;
@ -51,6 +52,7 @@ public class ServerController : BaseApiController
_scannerService = scannerService;
_accountService = accountService;
_taskScheduler = taskScheduler;
_unitOfWork = unitOfWork;
}
/// <summary>
@ -213,5 +215,28 @@ public class ServerController : BaseApiController
return Ok(recurringJobs);
}
/// <summary>
/// Returns a list of issues found during scanning or reading in which files may have corruption or bad metadata (structural metadata)
/// </summary>
/// <returns></returns>
[Authorize("RequireAdminRole")]
[HttpGet("media-errors")]
public ActionResult<PagedList<MediaErrorDto>> GetMediaErrors()
{
return Ok(_unitOfWork.MediaErrorRepository.GetAllErrorDtosAsync());
}
/// <summary>
/// Deletes all media errors
/// </summary>
/// <returns></returns>
[Authorize("RequireAdminRole")]
[HttpPost("clear-media-alerts")]
public async Task<ActionResult> ClearMediaErrors()
{
await _unitOfWork.MediaErrorRepository.DeleteAll();
return Ok();
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using API.Constants;
using API.Data;
using API.DTOs.Uploads;
using API.Extensions;
@ -78,7 +79,7 @@ public class UploadController : BaseApiController
/// <param name="uploadFileDto"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[RequestSizeLimit(8_000_000)]
[RequestSizeLimit(ControllerConstants.MaxUploadSizeBytes)]
[HttpPost("series")]
public async Task<ActionResult> UploadSeriesCoverImageFromUrl(UploadFileDto uploadFileDto)
{
@ -126,7 +127,7 @@ public class UploadController : BaseApiController
/// <param name="uploadFileDto"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[RequestSizeLimit(8_000_000)]
[RequestSizeLimit(ControllerConstants.MaxUploadSizeBytes)]
[HttpPost("collection")]
public async Task<ActionResult> UploadCollectionCoverImageFromUrl(UploadFileDto uploadFileDto)
{
@ -174,7 +175,7 @@ public class UploadController : BaseApiController
/// <remarks>This is the only API that can be called by non-admins, but the authenticated user must have a readinglist permission</remarks>
/// <param name="uploadFileDto"></param>
/// <returns></returns>
[RequestSizeLimit(8_000_000)]
[RequestSizeLimit(ControllerConstants.MaxUploadSizeBytes)]
[HttpPost("reading-list")]
public async Task<ActionResult> UploadReadingListCoverImageFromUrl(UploadFileDto uploadFileDto)
{
@ -238,7 +239,7 @@ public class UploadController : BaseApiController
/// <param name="uploadFileDto"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[RequestSizeLimit(8_000_000)]
[RequestSizeLimit(ControllerConstants.MaxUploadSizeBytes)]
[HttpPost("chapter")]
public async Task<ActionResult> UploadChapterCoverImageFromUrl(UploadFileDto uploadFileDto)
{
@ -294,7 +295,7 @@ public class UploadController : BaseApiController
/// <param name="uploadFileDto"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[RequestSizeLimit(8_000_000)]
[RequestSizeLimit(ControllerConstants.MaxUploadSizeBytes)]
[HttpPost("library")]
public async Task<ActionResult> UploadLibraryCoverImageFromUrl(UploadFileDto uploadFileDto)
{