Updated scanner and table names.
All checks were successful
ci / build-test (push) Successful in 2m38s
ci / publish-image (push) Has been skipped

This commit is contained in:
2026-03-05 20:56:57 -05:00
parent 79bece9e1c
commit 61f2e64972
12 changed files with 79 additions and 17 deletions

View File

@@ -1,4 +1,5 @@
using JSMR.Application.Scanning.Contracts; using JSMR.Application.Scanning.Contracts;
using JSMR.Domain.Enums;
namespace JSMR.Application.Scanning.Ports; namespace JSMR.Application.Scanning.Ports;
@@ -10,6 +11,7 @@ public interface IVoiceWorkUpdater
public class VoiceWorkUpsertResult public class VoiceWorkUpsertResult
{ {
public int? VoiceWorkId { get; set; } public int? VoiceWorkId { get; set; }
public VoiceWorkStatus UpdateStatus { get; set; }
public ICollection<VoiceWorkUpsertIssue> Issues { get; } = []; public ICollection<VoiceWorkUpsertIssue> Issues { get; } = [];
public VoiceWorkUpsertStatus Status { get; set; } = VoiceWorkUpsertStatus.Unchanged; public VoiceWorkUpsertStatus Status { get; set; } = VoiceWorkUpsertStatus.Unchanged;
} }

View File

@@ -8,7 +8,7 @@ public sealed class VoiceWorkLocalizationConfiguration : IEntityTypeConfiguratio
{ {
public void Configure(EntityTypeBuilder<VoiceWorkLocalization> builder) public void Configure(EntityTypeBuilder<VoiceWorkLocalization> builder)
{ {
builder.ToTable("voice_work_localizations"); builder.ToTable("VoiceWorkLocalizations");
builder.HasKey(x => x.VoiceWorkLocalizationId); builder.HasKey(x => x.VoiceWorkLocalizationId);
builder.Property(x => x.Language).IsRequired().HasMaxLength(10); builder.Property(x => x.Language).IsRequired().HasMaxLength(10);

View File

@@ -8,7 +8,7 @@ public sealed class VoiceWorkSearchConfiguration : IEntityTypeConfiguration<Voic
{ {
public void Configure(EntityTypeBuilder<VoiceWorkSearch> builder) public void Configure(EntityTypeBuilder<VoiceWorkSearch> builder)
{ {
builder.ToTable("VoiceWorkSearches2"); builder.ToTable("VoiceWorkSearches");
builder.HasKey(x => x.VoiceWorkId); // also the FK builder.HasKey(x => x.VoiceWorkId); // also the FK
builder.Property(x => x.SearchText).IsRequired(); // TEXT/LONGTEXT builder.Property(x => x.SearchText).IsRequired(); // TEXT/LONGTEXT

View File

@@ -8,7 +8,7 @@ public sealed class VoiceWorkSupportedLanguageConfiguration : IEntityTypeConfigu
{ {
public void Configure(EntityTypeBuilder<VoiceWorkSupportedLanguage> builder) public void Configure(EntityTypeBuilder<VoiceWorkSupportedLanguage> builder)
{ {
builder.ToTable("voice_work_supported_languages"); builder.ToTable("VoiceWorkSupportedLanguages");
builder.HasKey(x => x.VoiceWorkSupportedLanguageId); builder.HasKey(x => x.VoiceWorkSupportedLanguageId);
builder.Property(x => x.Language).IsRequired().HasMaxLength(10); builder.Property(x => x.Language).IsRequired().HasMaxLength(10);

View File

@@ -28,6 +28,9 @@ public class VoiceWorkUpdater(AppDbContext dbContext, ITimeProvider timeProvider
} }
result.Status = Upsert(ingest, upsertContext); result.Status = Upsert(ingest, upsertContext);
VoiceWork voiceWork = upsertContext.VoiceWorks[ingest.ProductId];
result.UpdateStatus = (VoiceWorkStatus)voiceWork.Status;
} }
await dbContext.SaveChangesAsync(cancellationToken); await dbContext.SaveChangesAsync(cancellationToken);
@@ -125,7 +128,7 @@ public class VoiceWorkUpdater(AppDbContext dbContext, ITimeProvider timeProvider
if (voiceWork.SalesDate is not null && ingest.SalesDate is null) if (voiceWork.SalesDate is not null && ingest.SalesDate is null)
{ {
string message = $"Voice work has a sales date of {voiceWork.SalesDate.Value.ToShortDateString()}, but ingest does not"; string message = $"Voice work has a sales date of {voiceWork.SalesDate.Value:d}, but ingest does not";
result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Error)); result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Error));
} }
} }

View File

@@ -19,8 +19,8 @@ public sealed class MariaDbContainerFixture : IAsyncLifetime
public async ValueTask InitializeAsync() public async ValueTask InitializeAsync()
{ {
_container = new MariaDbBuilder() _container = new MariaDbBuilder($"mariadb:{MajorVersion}.{MinorVersion}.{Build}")
.WithImage($"mariadb:{MajorVersion}.{MinorVersion}.{Build}") //.WithImage($"mariadb:{MajorVersion}.{MinorVersion}.{Build}")
.WithEnvironment("MARIADB_ROOT_PASSWORD", "rootpw") .WithEnvironment("MARIADB_ROOT_PASSWORD", "rootpw")
.WithUsername("root") .WithUsername("root")
.WithPassword("rootpw") .WithPassword("rootpw")

View File

@@ -17,8 +17,8 @@ public class MariaDbFixture : IAsyncLifetime
public async ValueTask InitializeAsync() public async ValueTask InitializeAsync()
{ {
MariaDbContainer = new MariaDbBuilder() MariaDbContainer = new MariaDbBuilder($"mariadb:{MajorVersion}.{MinorVersion}.{Build}")
.WithImage($"mariadb:{MajorVersion}.{MinorVersion}.{Build}") //.WithImage($"mariadb:{MajorVersion}.{MinorVersion}.{Build}")
.Build(); .Build();
await MariaDbContainer.StartAsync(); await MariaDbContainer.StartAsync();

View File

@@ -29,6 +29,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.3" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.3" />
<PackageReference Include="Serilog" Version="4.3.1" /> <PackageReference Include="Serilog" Version="4.3.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" />
<PackageReference Include="Spectre.Console" Version="0.54.0" />
<PackageReference Include="System.CommandLine" Version="2.0.3" /> <PackageReference Include="System.CommandLine" Version="2.0.3" />
</ItemGroup> </ItemGroup>

View File

@@ -97,7 +97,7 @@ scan.SetAction(async (parseResult, cancellationToken) =>
ScanOptions options = new() ScanOptions options = new()
{ {
Locale = parseResult.GetValue(localeOption), Locale = parseResult.GetValue(localeOption) ?? default!,
StartPage = parseResult.GetValue(startOption), StartPage = parseResult.GetValue(startOption),
EndPage = parseResult.GetValue(endOption), EndPage = parseResult.GetValue(endOption),
PageSize = parseResult.GetValue(sizeOption), PageSize = parseResult.GetValue(sizeOption),

View File

@@ -6,7 +6,7 @@ using Microsoft.Extensions.Options;
namespace JSMR.Worker.Services; namespace JSMR.Worker.Services;
public sealed class ScanJob(ILogger<ScanJob> log, IOptions<ScanOptions> options, ScanVoiceWorksHandler scanVoiceWorksHandler) public sealed class ScanJob(ILogger<ScanJob> log, IOptions<ScanOptions> options, ScanVoiceWorksHandler handler)
{ {
private readonly ScanOptions _options = options.Value; private readonly ScanOptions _options = options.Value;
@@ -21,7 +21,7 @@ public sealed class ScanJob(ILogger<ScanJob> log, IOptions<ScanOptions> options,
Locale: Enum.Parse<Locale>(_options.Locale, true) Locale: Enum.Parse<Locale>(_options.Locale, true)
); );
await scanVoiceWorksHandler.HandleAsync(request, cancellationToken); await handler.HandleAsync(request, cancellationToken);
log.LogInformation("Scan completed."); log.LogInformation("Scan completed.");
} }

View File

@@ -1,10 +1,13 @@
using JSMR.Application.Enums; using JSMR.Application.Enums;
using JSMR.Application.Scanning; using JSMR.Application.Scanning;
using JSMR.Application.Scanning.Ports; using JSMR.Application.Scanning.Ports;
using JSMR.Domain.Enums;
using JSMR.Infrastructure.Common.Time; using JSMR.Infrastructure.Common.Time;
using JSMR.Worker.Options; using JSMR.Worker.Options;
using JSMR.Worker.UI;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Spectre.Console;
using System.Globalization; using System.Globalization;
namespace JSMR.Worker.Services; namespace JSMR.Worker.Services;
@@ -39,7 +42,17 @@ public sealed class PagedScanRunner(
using var scope = serviceProvider.CreateScope(); using var scope = serviceProvider.CreateScope();
ScanVoiceWorksHandler handler = scope.ServiceProvider.GetRequiredService<ScanVoiceWorksHandler>(); ScanVoiceWorksHandler handler = scope.ServiceProvider.GetRequiredService<ScanVoiceWorksHandler>();
log.LogInformation("Scanning page {Page} (size {Size}, locale {Locale})…", currentPage, pageSize, locale); //log.LogInformation("Scanning page {Page} (size {Size}, locale {Locale})…", currentPage, pageSize, locale);
CliUi.PageHeader(currentPage, end);
//AnsiConsole.Status()
//.Start($"[grey]Scanning page[/] [bold]{currentPage}[/] [grey]of[/] [bold]{end}[/][grey]...[/]", ctx =>
//{
// // Simulate grinding
// Thread.Sleep(3000);
//});
//AnsiConsole.MarkupLine($"[green]✓ Scanning page[/] [bold]{currentPage}[/] [grey]of[/] [bold]{end}[/][grey]... DONE[/]");
ScanVoiceWorksRequest request = new( ScanVoiceWorksRequest request = new(
PageNumber: currentPage, PageNumber: currentPage,
@@ -49,18 +62,21 @@ public sealed class PagedScanRunner(
ScanVoiceWorksResponse response = await handler.HandleAsync(request, cancellationToken); ScanVoiceWorksResponse response = await handler.HandleAsync(request, cancellationToken);
//int newUpcoming = response.Results.Where(x => x.IsNewUpcoming == true).Count(); int newUpcoming = response.Results.Count(x => x.UpdateStatus == VoiceWorkStatus.NewAndUpcoming);
//if (newUpcoming > 0) //if (newUpcoming > 0)
// updatedInfo.Add($"{newUpcoming} new upcoming work(s)"); // AnsiConsole.MarkupLine($" - {newUpcoming} new upcoming work(s)");
//int newOnSale = result.ScannedVoiceWorks.Where(x => x.IsNewOnSale == true).Count(); int newRelease = response.Results.Count(x => x.UpdateStatus == VoiceWorkStatus.NewRelease);
//if (newOnSale > 0) //if (newRelease > 0)
// updatedInfo.Add($"{newOnSale} new work(s) on sale"); // updatedInfo.Add($"{newRelease} new work(s) on sale");
CliUi.PageHighlights(newUpcoming, newRelease);
IEnumerable<VoiceWorkUpsertResult> resultsWithIssues = response.Results.Where(x => x.Issues.Count > 0); IEnumerable<VoiceWorkUpsertResult> resultsWithIssues = response.Results.Where(x => x.Issues.Count > 0);
// TODO: Later
//foreach (VoiceWorkUpsertResult resultWithIssues in resultsWithIssues) //foreach (VoiceWorkUpsertResult resultWithIssues in resultsWithIssues)
//{ //{
// log.LogWarning($"PRoblem with {resultWithIssues.}") // log.LogWarning($"PRoblem with {resultWithIssues.}")

40
JSMR.Worker/UI/CliUi.cs Normal file
View File

@@ -0,0 +1,40 @@
namespace JSMR.Worker.UI;
using Spectre.Console;
public static class CliUi
{
public static void PageHeader(int page, int? endPage)
{
AnsiConsole.MarkupLine($"[grey]Scanning page[/] [bold]{page}[/] [grey]of[/] [bold]{endPage}[/][grey]...[/]");
}
public static void PageHighlights(int newUpcoming, int newRelease)
{
if (newUpcoming == 0 && newRelease == 0)
return;
// Nice little boxed summary
var grid = new Grid().AddColumn().AddColumn();
if (newUpcoming > 0)
grid.AddRow("[yellow]Upcoming[/]", $"[yellow]{newUpcoming}[/]");
if (newRelease > 0)
grid.AddRow("[green]New releases[/]", $"[green]{newRelease}[/]");
var panel = new Panel(grid)
.Header("[bold]Page updates[/]")
.Border(BoxBorder.Rounded)
.Padding(1, 0, 1, 0);
AnsiConsole.Write(panel);
}
public static void Warning(string message) =>
AnsiConsole.MarkupLine($"[yellow]⚠ {Escape(message)}[/]");
public static void Error(string message) =>
AnsiConsole.MarkupLine($"[red]✖ {Escape(message)}[/]");
private static string Escape(string s) => Markup.Escape(s);
}