Added English voice work updater.

This commit is contained in:
2025-10-23 10:07:50 -04:00
parent 3a115bc7b8
commit 36fcd5379a
19 changed files with 651 additions and 401 deletions

View File

@@ -3,26 +3,51 @@ using JSMR.Application.Integrations.DLSite.Models;
namespace JSMR.Application.Scanning.Contracts;
public record VoiceWorkIngest(DLSiteWork Work, VoiceWorkDetails? Details)
public sealed record VoiceWorkIngest
{
public string MakerId { get; init; } = Work.MakerId;
public string MakerName { get; init; } = Work.Maker;
public string ProductId { get; init; } = Work.ProductId;
public string Title { get; init; } = Work.ProductName;
public string? Description { get; init; } = Work.Description;
public ICollection<string> Tags { get; init; } = Work.Tags;
public ICollection<string> Creators { get; init; } = Work.Creators;
public int WishlistCount { get; init; } = Details?.WishlistCount ?? 0;
public int Downloads { get; init; } = Math.Max(Work.Downloads, Details?.DownloadCount ?? 0);
public bool HasTrial { get; init; } = Work.HasTrial || (Details?.HasTrial ?? false);
public bool HasDLPlay { get; init; } = Details?.HasDLPlay ?? false;
public byte? StarRating { get; init; } = Work.StarRating;
public int? Votes { get; init; } = Work.Votes;
public AgeRating AgeRating { get; init; } = Details?.AgeRating ?? Work.AgeRating;
public bool HasImage { get; init; } = Work.ImageUrl.Contains("no_img") == false;
public ICollection<ISupportedLanguage> SupportedLanguages { get; init; } = Details?.SupportedLanguages ?? [];
public DateOnly? ExpectedDate { get; init; } = Work.ExpectedDate;
public DateOnly? SalesDate { get; init; } = Work.SalesDate;
public DateTime? RegistrationDate { get; init; } = Details?.RegistrationDate;
// TODO: Other properties
public required string MakerId { get; init; }
public required string MakerName { get; init; }
public required string ProductId { get; init; }
public required string Title { get; init; }
public required string Description { get; init; }
public ICollection<string> Tags { get; init; } = [];
public ICollection<string> Creators { get; init; } = [];
public int WishlistCount { get; init; }
public int Downloads { get; init; }
public bool HasTrial { get; init; }
public bool HasDLPlay { get; init; }
public byte? StarRating { get; init; }
public int? Votes { get; init; }
public AgeRating AgeRating { get; init; }
public bool HasImage { get; init; }
public ICollection<ISupportedLanguage> SupportedLanguages { get; init; } = [];
public DateOnly? ExpectedDate { get; init; }
public DateOnly? SalesDate { get; init; }
public DateTime? RegistrationDate { get; init; }
public static VoiceWorkIngest From(DLSiteWork work, VoiceWorkDetails? details)
{
return new VoiceWorkIngest()
{
MakerId = work.MakerId,
MakerName = work.Maker,
ProductId = work.ProductId,
Title = work.ProductName,
Description = work.Description ?? string.Empty,
Tags = work.Tags,
Creators = work.Creators,
WishlistCount = details?.WishlistCount ?? 0,
Downloads = Math.Max(work.Downloads, details?.DownloadCount ?? 0),
HasTrial = work.HasTrial || (details?.HasTrial ?? false),
HasDLPlay = details?.HasDLPlay ?? false,
StarRating = work.StarRating,
Votes = work.Votes,
AgeRating = details?.AgeRating ?? work.AgeRating,
HasImage = !string.IsNullOrEmpty(work.ImageUrl) && !work.ImageUrl.Contains("no_img", StringComparison.OrdinalIgnoreCase),
SupportedLanguages = details?.SupportedLanguages ?? [],
ExpectedDate = work.ExpectedDate,
SalesDate = work.SalesDate,
RegistrationDate = details?.RegistrationDate
};
}
}

View File

@@ -0,0 +1,8 @@
using JSMR.Application.Scanning.Contracts;
namespace JSMR.Application.Scanning.Ports;
public interface IVoiceWorkUpdater
{
Task<int[]> UpsertAsync(IReadOnlyCollection<VoiceWorkIngest> ingests, CancellationToken cancellationToken);
}

View File

@@ -3,7 +3,6 @@ using JSMR.Application.Integrations.DLSite.Models;
using JSMR.Application.Integrations.Ports;
using JSMR.Application.Scanning.Contracts;
using JSMR.Application.Scanning.Ports;
using JSMR.Application.VoiceWorks.Ports;
using Microsoft.Extensions.DependencyInjection;
namespace JSMR.Application.Scanning;
@@ -12,14 +11,14 @@ public sealed class ScanVoiceWorksHandler(
IServiceProvider serviceProvider,
IDLSiteClient dlsiteClient,
ISpamCircleCache spamCircleCache,
IVoiceWorkWriter writer,
IVoiceWorkSearchUpdater searchUpdater)
{
public async Task<ScanVoiceWorksResponse> HandleAsync(ScanVoiceWorksRequest request, CancellationToken cancellationToken)
{
IVoiceWorksScanner? scanner = serviceProvider.GetKeyedService<IVoiceWorksScanner>(request.Locale);
IVoiceWorkUpdater? updater = serviceProvider.GetKeyedService<IVoiceWorkUpdater>(request.Locale);
if (scanner is null)
if (scanner is null || updater is null)
return new();
VoiceWorkScanOptions options = new(
@@ -41,10 +40,10 @@ public sealed class ScanVoiceWorksHandler(
VoiceWorkIngest[] ingests = [.. works.Select(work =>
{
voiceWorkDetails.TryGetValue(work.ProductId!, out VoiceWorkDetails? value);
return new VoiceWorkIngest(work, value);
return VoiceWorkIngest.From(work, value);
})];
int[] voiceWorkIds = await writer.UpsertAsync(ingests, cancellationToken);
int[] voiceWorkIds = await updater.UpsertAsync(ingests, cancellationToken);
await searchUpdater.UpdateAsync(voiceWorkIds, cancellationToken);
return new();

View File

@@ -1,10 +1,8 @@
using JSMR.Application.Scanning.Contracts;
using JSMR.Application.VoiceWorks.Commands.SetFavorite;
using JSMR.Application.VoiceWorks.Commands.SetFavorite;
namespace JSMR.Application.VoiceWorks.Ports;
public interface IVoiceWorkWriter
{
Task<int[]> UpsertAsync(IReadOnlyCollection<VoiceWorkIngest> ingests, CancellationToken cancellationToken);
Task<SetVoiceWorkFavoriteResponse> SetFavoriteAsync(SetVoiceWorkFavoriteRequest request, CancellationToken cancellationToken);
}

View File

@@ -29,4 +29,35 @@ public sealed class SearchVoiceWorksHandler(IVoiceWorkSearchProvider provider, I
return new SearchVoiceWorksResponse(results);
}
}
}
//public record SearchProviderContext(
//);
//public class SearchHandler<TSearchResult, TCriteria, TSortField>(ISearchProvider<TSearchResult, TCriteria, TSortField> searchProvider, ILogger logger)
// where TCriteria : notnull, new()
// where TSortField : struct, Enum
//{
// public async Task<SearchVoiceWorksResponse> HandleAsync(SearchOptions<TCriteria, TSortField> options, CancellationToken cancellationToken)
// {
// Stopwatch stopWatch = Stopwatch.StartNew();
// SearchResult<TSearchResult> results = await searchProvider.SearchAsync(options, cancellationToken);
// long elapsedMilliseconds = stopWatch.ElapsedMilliseconds;
// LogEvents.SearchCompleted(
// logger,
// Elapsed: elapsedMilliseconds,
// Items: results.Items.Length,
// Total: results.TotalItems,
// Page: options.PageNumber,
// Size: options.PageSize,
// Sort: options.SortOptions.ToLogObject(),
// Criteria: options.Criteria.ToLogObject()
// );
// return new SearchVoiceWorksResponse(results);
// }
//}