On Deck + Misc Fixes and Changes (#1215)

* Added playwright and started writing e2e tests.

* To make things easy, disabled other browsers while I get confortable. Added a login flow (assumes my dev env)

* More tests on login page

* Lots more testing code, trying to figure out auth code.

* Ensure we don't track DBs inside config

* Added a new date property for when chapters are added to a series which helps with OnDeck calculations. Changed a lot of heavy api calls to use IEnumerable to stream repsonse to UI.

* Fixed OnDeck with a new field for when last chapter was added on Series. This is a streamlined way to query.

Updated Reading List with NormalizedTitle, CoverImage, CoverImageLocked.

* Implemented the ability to read a random item in the reading list and for the reading list to be intact for order.

* Tweaked the style for webtoon to not span the whole width, but use max width

* When we update a cover image just send an event so we don't need to have logic for when updates occur

* Fixed a bad name for entity type on cover updates

* Aligned the edit collection tag modal to align with new tab design

* Rewrote code for picking the first file for metadata to ensure it always picks the correct file, esp if the first chapter of a series starts with a float (1.1)

* Refactored setting LastChapterAdded to ensure we do it on the Series.

* Updated Chapter updating in scan loop to avoid nested for loop and an additional loop.

* Fixed a bug where locked person fields wouldn't persist between scans.

* Updated Contributing to reflect how to view the swagger api
This commit is contained in:
Joseph Milazzo 2022-04-11 17:43:40 -05:00 committed by GitHub
parent 912dfa8a80
commit 3bbb02f574
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 3397 additions and 343 deletions

View file

@ -157,7 +157,7 @@ namespace API.Controllers
tag.CoverImageLocked = false;
tag.CoverImage = string.Empty;
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
MessageFactory.CoverUpdateEvent(tag.Id, "collectionTag"), false);
MessageFactory.CoverUpdateEvent(tag.Id, "collection"), false);
_unitOfWork.CollectionTagRepository.Update(tag);
}

View file

@ -88,6 +88,22 @@ namespace API.Controllers
return PhysicalFile(path, "image/" + format, _directoryService.FileSystem.Path.GetFileName(path));
}
/// <summary>
/// Returns cover image for a Reading List
/// </summary>
/// <param name="readingListId"></param>
/// <returns></returns>
[HttpGet("readinglist-cover")]
public async Task<ActionResult> GetReadingListCoverImage(int readingListId)
{
var path = Path.Join(_directoryService.CoverImageDirectory, await _unitOfWork.ReadingListRepository.GetCoverImageAsync(readingListId));
if (string.IsNullOrEmpty(path) || !_directoryService.FileSystem.File.Exists(path)) return BadRequest($"No cover image");
var format = _directoryService.FileSystem.Path.GetExtension(path).Replace(".", "");
Response.AddCacheHeader(path);
return PhysicalFile(path, "image/" + format, _directoryService.FileSystem.Path.GetFileName(path));
}
/// <summary>
/// Returns image for a given bookmark page
/// </summary>

View file

@ -7,6 +7,7 @@ using API.DTOs.ReadingLists;
using API.Entities;
using API.Extensions;
using API.Helpers;
using API.SignalR;
using Microsoft.AspNetCore.Mvc;
namespace API.Controllers
@ -14,11 +15,13 @@ namespace API.Controllers
public class ReadingListController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork;
private readonly IEventHub _eventHub;
private readonly ChapterSortComparerZeroFirst _chapterSortComparerForInChapterSorting = new ChapterSortComparerZeroFirst();
public ReadingListController(IUnitOfWork unitOfWork)
public ReadingListController(IUnitOfWork unitOfWork, IEventHub eventHub)
{
_unitOfWork = unitOfWork;
_eventHub = eventHub;
}
/// <summary>
@ -233,9 +236,12 @@ namespace API.Controllers
var readingList = await _unitOfWork.ReadingListRepository.GetReadingListByIdAsync(dto.ReadingListId);
if (readingList == null) return BadRequest("List does not exist");
if (!string.IsNullOrEmpty(dto.Title))
{
readingList.Title = dto.Title; // Should I check if this is unique?
readingList.NormalizedTitle = Parser.Parser.Normalize(readingList.Title);
}
if (!string.IsNullOrEmpty(dto.Title))
{
@ -244,6 +250,19 @@ namespace API.Controllers
readingList.Promoted = dto.Promoted;
readingList.CoverImageLocked = dto.CoverImageLocked;
if (!dto.CoverImageLocked)
{
readingList.CoverImageLocked = false;
readingList.CoverImage = string.Empty;
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
MessageFactory.CoverUpdateEvent(readingList.Id, "readingList"), false);
_unitOfWork.ReadingListRepository.Update(readingList);
}
_unitOfWork.ReadingListRepository.Update(readingList);
if (await _unitOfWork.CommitAsync())

View file

@ -214,13 +214,6 @@ namespace API.Controllers
return Ok(await _unitOfWork.SeriesRepository.GetRecentlyUpdatedSeries(userId));
}
[HttpPost("recently-added-chapters")]
public async Task<ActionResult<IEnumerable<RecentlyAddedItemDto>>> GetRecentlyAddedChaptersAlt()
{
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
return Ok(await _unitOfWork.SeriesRepository.GetRecentlyAddedChapters(userId));
}
[HttpPost("all")]
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetAllSeries(FilterDto filterDto, [FromQuery] UserParams userParams, [FromQuery] int libraryId = 0)
{

View file

@ -5,6 +5,7 @@ using API.Data;
using API.DTOs.Uploads;
using API.Extensions;
using API.Services;
using API.SignalR;
using Flurl.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@ -24,16 +25,18 @@ namespace API.Controllers
private readonly ILogger<UploadController> _logger;
private readonly ITaskScheduler _taskScheduler;
private readonly IDirectoryService _directoryService;
private readonly IEventHub _eventHub;
/// <inheritdoc />
public UploadController(IUnitOfWork unitOfWork, IImageService imageService, ILogger<UploadController> logger,
ITaskScheduler taskScheduler, IDirectoryService directoryService)
ITaskScheduler taskScheduler, IDirectoryService directoryService, IEventHub eventHub)
{
_unitOfWork = unitOfWork;
_imageService = imageService;
_logger = logger;
_taskScheduler = taskScheduler;
_directoryService = directoryService;
_eventHub = eventHub;
}
/// <summary>
@ -145,6 +148,8 @@ namespace API.Controllers
if (_unitOfWork.HasChanges())
{
await _unitOfWork.CommitAsync();
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
MessageFactory.CoverUpdateEvent(tag.Id, "collection"), false);
return Ok();
}
@ -158,6 +163,53 @@ namespace API.Controllers
return BadRequest("Unable to save cover image to Collection Tag");
}
/// <summary>
/// Replaces reading list cover image and locks it with a base64 encoded image
/// </summary>
/// <param name="uploadFileDto"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[RequestSizeLimit(8_000_000)]
[HttpPost("reading-list")]
public async Task<ActionResult> UploadReadingListCoverImageFromUrl(UploadFileDto uploadFileDto)
{
// Check if Url is non empty, request the image and place in temp, then ask image service to handle it.
// See if we can do this all in memory without touching underlying system
if (string.IsNullOrEmpty(uploadFileDto.Url))
{
return BadRequest("You must pass a url to use");
}
try
{
var filePath = _imageService.CreateThumbnailFromBase64(uploadFileDto.Url, $"{ImageService.GetReadingListFormat(uploadFileDto.Id)}");
var readingList = await _unitOfWork.ReadingListRepository.GetReadingListByIdAsync(uploadFileDto.Id);
if (!string.IsNullOrEmpty(filePath))
{
readingList.CoverImage = filePath;
readingList.CoverImageLocked = true;
_unitOfWork.ReadingListRepository.Update(readingList);
}
if (_unitOfWork.HasChanges())
{
await _unitOfWork.CommitAsync();
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
MessageFactory.CoverUpdateEvent(readingList.Id, "readingList"), false);
return Ok();
}
}
catch (Exception e)
{
_logger.LogError(e, "There was an issue uploading cover image for Reading List {Id}", uploadFileDto.Id);
await _unitOfWork.RollbackAsync();
}
return BadRequest("Unable to save cover image to Reading List");
}
/// <summary>
/// Replaces chapter cover image and locks it with a base64 encoded image. This will update the parent volume's cover image.
/// </summary>