Files
bom-local-service/Services/Scraping/Steps/Map/WaitForMapReadyStep.cs
T
alex b30d76ddec Refactor configuration system and remove OpenAPI
- Remove OpenAPI/Swagger support and all related code
- Standardize configuration: remove hardcoded defaults, all defaults from appsettings.json
- Configuration values throw exceptions if missing (except Debug:Enabled defaults to false)
- Refactor CacheManagementService: extract ProcessLocationsAsync helper, remove duplicate code
- Combine UpdateStaggerSeconds and LocationStaggerSeconds into single LocationStaggerSeconds config
- Move config reads to constructors for better performance
- Update README and docker-compose.yml to reflect configuration changes
2025-12-23 21:03:21 +10:00

79 lines
3.3 KiB
C#

using BomLocalService.Services.Interfaces;
using BomLocalService.Services.Scraping;
using Microsoft.Playwright;
namespace BomLocalService.Services.Scraping.Steps.Map;
public class WaitForMapReadyStep : BaseScrapingStep
{
private readonly int _tileRenderWaitMs;
public override string Name => "WaitForMapReady";
public override string[] Prerequisites => new[] { "ClickRadarLink" };
public WaitForMapReadyStep(
ILogger<WaitForMapReadyStep> logger,
ISelectorService selectorService,
IDebugService debugService,
IConfiguration configuration)
: base(logger, selectorService, debugService, configuration)
{
var tileRenderWaitMsConfig = configuration.GetValue<int?>("Screenshot:TileRenderWaitMs");
if (!tileRenderWaitMsConfig.HasValue)
{
throw new InvalidOperationException("Screenshot:TileRenderWaitMs configuration is required. Set it in appsettings.json or via SCREENSHOT__TILERENDERWAITMS environment variable.");
}
_tileRenderWaitMs = tileRenderWaitMsConfig.Value;
}
public override bool CanExecute(ScrapingContext context)
{
return context.IsRadarPageLoaded;
}
public override async Task<ScrapingStepResult> ExecuteAsync(ScrapingContext context, CancellationToken cancellationToken)
{
try
{
Logger.LogInformation("Step {Step}: Waiting for weather map page to load", Name);
await context.Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded, new PageWaitForLoadStateOptions { Timeout = 15000 });
Logger.LogInformation("Step {Step}: Waiting for map canvas element to render", Name);
var mapCanvas = SelectorService.GetLocator(context.Page, Selectors.MapCanvas);
await mapCanvas.WaitForAsync(new LocatorWaitForOptions { Timeout = 15000 });
await context.Page.WaitForFunctionAsync(
JavaScriptTemplates.WaitForMapCanvas,
new PageWaitForFunctionOptions { Timeout = 15000 });
Logger.LogInformation("Step {Step}: Map canvas is ready - waiting for map to render", Name);
try
{
await context.Page.WaitForFunctionAsync(
JavaScriptTemplates.WaitForEsriView,
new PageWaitForFunctionOptions { Timeout = 30000 });
Logger.LogInformation("Step {Step}: Esri map view is ready", Name);
}
catch
{
Logger.LogInformation("Step {Step}: Esri view ready check timed out, continuing with fixed wait", Name);
}
await context.Page.WaitForTimeoutAsync(_tileRenderWaitMs);
await SaveDebugAsync(context, 7, "weather_map_ready", cancellationToken);
context.CurrentState = PageState.MapReady;
return ScrapingStepResult.Successful();
}
catch (Exception ex)
{
Logger.LogError(ex, "Step {Step} failed", Name);
await SaveErrorDebugAsync(context, $"Failed to wait for map ready: {ex.Message}", cancellationToken);
return ScrapingStepResult.Failed($"Failed to wait for map ready: {ex.Message}");
}
}
}