using Microsoft.EntityFrameworkCore; using System.Text.Json.Serialization; namespace PagerParser; public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(); builder.Services.AddRazorPages(); // This is necessary if we don't want enum values sent as integers in JSON objects builder.Services.AddControllers().AddJsonOptions(o => { var converter = new JsonStringEnumConverter(); o.JsonSerializerOptions.Converters.Add(converter); }); builder.Services.AddCors(); // Add our custom services builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(p => p.GetRequiredService()); builder.Services.AddSingleton(p => p.GetRequiredService()); builder.Services.AddHostedService(); var app = builder.Build(); // Create a temporary scope so that we can access services during startup using var scope = app.Services.CreateScope(); var logger = scope.ServiceProvider.GetRequiredService>(); var config = scope.ServiceProvider.GetRequiredService(); var parser = scope.ServiceProvider.GetRequiredService(); // Ensure the database is created and the correct schema is used // If we did update the database schema, attempt to re-parse all // messages. using var db = scope.ServiceProvider.GetRequiredService(); var needsMigration = db.Database.GetPendingMigrations().Any(); db.Database.Migrate(); int c = 0; if(needsMigration || config.GetValue("PagerParser:ReparseAllOnStartup")) { logger.LogInformation("Reparsing all messages..."); db.ParsedPagerMessages.RemoveRange( db.ParsedPagerMessages.ToArray()); db.SaveChanges(); foreach(var message in db.PagerMessages) { message.ParsedMessage = parser.TryParse(message.Message); if(message.ParsedMessage is not null) { c++; message.ParsedMessage.GpsPosition = PositionCalculator.GetGpsPosition(message.ParsedMessage); } } db.SaveChanges(); logger.LogInformation($"Successfully reparsed {c}/{db.PagerMessages.Count()} messages"); } else if(config.GetValue("PagerParser:ReparseFailedOnStartup")) { logger.LogInformation("Reparsing non-parsed messages..."); foreach(var message in db.PagerMessages.Where(m => m.ParsedMessage == null)) { message.ParsedMessage = parser.TryParse(message.Message); if(message.ParsedMessage is not null) { c++; if(message.ParsedMessage.GpsPosition is null) message.ParsedMessage.GpsPosition = PositionCalculator.GetGpsPosition(message.ParsedMessage); } } db.SaveChanges(); logger.LogInformation($"Successfully reparsed {c}/{db.PagerMessages.Count()} messages"); } if(!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } // Start the server app.UseCors(p => p .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); app.UseHttpsRedirection(); app.UseHsts(); app.MapControllers(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run(); } }