Added API benchmark, hash device_id, handled null cases in GET/PUT
This commit is contained in:
parent
e84aed357a
commit
f30e3b17d6
7 changed files with 79 additions and 11 deletions
|
|
@ -26,5 +26,10 @@
|
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Data\AesopsFables.epub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
41
API.Benchmark/KoreaderHashBenchmark.cs
Normal file
41
API.Benchmark/KoreaderHashBenchmark.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using API.Helpers.Builders;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Order;
|
||||
using System;
|
||||
using API.Entities.Enums;
|
||||
|
||||
namespace API.Benchmark
|
||||
{
|
||||
[StopOnFirstError]
|
||||
[MemoryDiagnoser]
|
||||
[RankColumn]
|
||||
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
|
||||
[SimpleJob(launchCount: 1, warmupCount: 5, invocationCount: 20)]
|
||||
public class KoreaderHashBenchmark
|
||||
{
|
||||
private const string sourceEpub = "./Data/AesopsFables.epub";
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public void TestBuildManga_baseline()
|
||||
{
|
||||
var file = new MangaFileBuilder(sourceEpub, MangaFormat.Epub)
|
||||
.Build();
|
||||
if (file == null)
|
||||
{
|
||||
throw new Exception("Failed to build manga file");
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void TestBuildManga_withHash()
|
||||
{
|
||||
var file = new MangaFileBuilder(sourceEpub, MangaFormat.Epub)
|
||||
.WithHash()
|
||||
.Build();
|
||||
if (file == null)
|
||||
{
|
||||
throw new Exception("Failed to build manga file");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -78,11 +78,20 @@ public class KoreaderController : BaseApiController
|
|||
[HttpGet("{apiKey}/syncs/progress/{ebookHash}")]
|
||||
public async Task<ActionResult<KoreaderBookDto>> GetProgress(string apiKey, string ebookHash)
|
||||
{
|
||||
var userId = await GetUserId(apiKey);
|
||||
var response = await _koreaderService.GetProgress(ebookHash, userId);
|
||||
_logger.LogDebug("Koreader response progress: {Progress}", response.Progress);
|
||||
try
|
||||
{
|
||||
var userId = await GetUserId(apiKey);
|
||||
var response = await _koreaderService.GetProgress(ebookHash, userId);
|
||||
_logger.LogDebug("Koreader response progress: {Progress}", response.Progress);
|
||||
|
||||
return Ok(response);
|
||||
return Ok(response);
|
||||
}
|
||||
catch (KavitaException ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
private async Task<int> GetUserId(string apiKey)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using API.DTOs.Koreader;
|
||||
|
||||
namespace API.Helpers.Builders;
|
||||
|
|
@ -36,7 +38,9 @@ public class KoreaderBookDtoBuilder : IEntityBuilder<KoreaderBookDto>
|
|||
|
||||
public KoreaderBookDtoBuilder WithDeviceId(string installId, int userId)
|
||||
{
|
||||
_dto.Device_id = installId;
|
||||
using var sha256 = SHA256.Create();
|
||||
var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(installId + userId));
|
||||
_dto.Device_id = hash.ToString();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using API.DTOs.Koreader;
|
|||
using API.DTOs.Progress;
|
||||
using API.Helpers;
|
||||
using API.Helpers.Builders;
|
||||
using Kavita.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Services;
|
||||
|
|
@ -20,12 +21,14 @@ public class KoreaderService : IKoreaderService
|
|||
{
|
||||
private readonly IReaderService _readerService;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly ILogger<KoreaderService> _logger;
|
||||
|
||||
public KoreaderService(IReaderService readerService, IUnitOfWork unitOfWork, ILogger<KoreaderService> logger)
|
||||
public KoreaderService(IReaderService readerService, IUnitOfWork unitOfWork, ILocalizationService localizationService, ILogger<KoreaderService> logger)
|
||||
{
|
||||
_readerService = readerService;
|
||||
_unitOfWork = unitOfWork;
|
||||
_localizationService = localizationService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
@ -43,10 +46,17 @@ public class KoreaderService : IKoreaderService
|
|||
var userProgressDto = await _unitOfWork.AppUserProgressRepository.GetUserProgressDtoAsync(file.ChapterId, userId);
|
||||
if (userProgressDto == null)
|
||||
{
|
||||
// TODO: Handle this case
|
||||
var chapterDto = await _unitOfWork.ChapterRepository.GetChapterDtoAsync(file.ChapterId);
|
||||
if (chapterDto == null) return;
|
||||
|
||||
var volumeDto = await _unitOfWork.VolumeRepository.GetVolumeByIdAsync(chapterDto.VolumeId);
|
||||
if (volumeDto == null) return;
|
||||
|
||||
userProgressDto = new ProgressDto()
|
||||
{
|
||||
ChapterId = file.ChapterId,
|
||||
VolumeId = chapterDto.VolumeId,
|
||||
SeriesId = volumeDto.SeriesId,
|
||||
};
|
||||
}
|
||||
// Update the bookScrollId if possible
|
||||
|
|
@ -68,15 +78,14 @@ public class KoreaderService : IKoreaderService
|
|||
|
||||
var file = await _unitOfWork.MangaFileRepository.GetByKoreaderHash(bookHash);
|
||||
|
||||
// TODO: How do we handle when file isn't found by hash?
|
||||
if (file == null) return builder.Build();
|
||||
if (file == null) throw new KavitaException(await _localizationService.Translate(userId, "file-missing"));
|
||||
|
||||
var progressDto = await _unitOfWork.AppUserProgressRepository.GetUserProgressDtoAsync(file.ChapterId, userId);
|
||||
var koreaderProgress = KoreaderHelper.GetKoreaderPosition(progressDto);
|
||||
|
||||
return builder.WithProgress(koreaderProgress)
|
||||
.WithPercentage(progressDto?.PageNum, file.Pages)
|
||||
.WithDeviceId(settingsDto.InstallId, userId) // TODO: Should we generate a hash for UserId + InstallId so that this DeviceId is unique to the user on the server?
|
||||
.WithDeviceId(settingsDto.InstallId, userId)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
// const IP = 'localhost';
|
||||
const IP = '10.10.30.215';
|
||||
const IP = 'localhost';
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue