diff options
| author | ivar <i@oiee.no> | 2025-10-06 12:06:46 +0200 |
|---|---|---|
| committer | ivar <i@oiee.no> | 2025-10-06 12:06:46 +0200 |
| commit | f18f3fee8844df98a30c2d248dfca04643dd4365 (patch) | |
| tree | 599c1b6a97777a84cdcd7fe8333f4718d2e55c85 /VegaData/Program.cs | |
| download | vegadata-f18f3fee8844df98a30c2d248dfca04643dd4365.tar.xz vegadata-f18f3fee8844df98a30c2d248dfca04643dd4365.zip | |
Initial
Diffstat (limited to 'VegaData/Program.cs')
| -rw-r--r-- | VegaData/Program.cs | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/VegaData/Program.cs b/VegaData/Program.cs new file mode 100644 index 0000000..ac15e62 --- /dev/null +++ b/VegaData/Program.cs @@ -0,0 +1,133 @@ +using System.Text.Json.Serialization; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddHttpClient(); +builder.Services.AddDbContext<Database>(o => o.UseSqlite("Data Source=data/main.db")); +builder.Services.AddHostedService<DataWorker>(); + +var app = builder.Build(); +using var scope = app.Services.CreateScope(); +scope.ServiceProvider.GetRequiredService<Database>().Database.EnsureCreated(); +app.MapStaticAssets(); +app.MapGet("shows", (Database db) => db.Shows); +app.MapGet("/", () => Results.Redirect("/index.html")); +app.Run(); + +class Database(DbContextOptions<Database> options) : DbContext(options) +{ + public DbSet<Show> Shows { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) { + modelBuilder.Entity<Show>().HasIndex(p => new { + p.Title, + p.StartDateTime + }) + .IsUnique(); + base.OnModelCreating(modelBuilder); + } +} + +class Show +{ + public int Id { get; set; } + public string Title { get; set; } + public string Scene { get; set; } + public DateTimeOffset StartDateTime { get; set; } + public string TicketUrl { get; set; } + public string Type { get; set; } + public string MovieVersion { get; set; } + public string MovieMainVersion { get; set; } + public string[] Tags { get; set; } +} + +class DataWorker(IServiceScopeFactory serviceScopeFactory) : BackgroundService +{ + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { + const int hour = 3600 * 60; + while (!stoppingToken.IsCancellationRequested) { + await Work(stoppingToken); + await Task.Delay(hour, stoppingToken); + } + } + + async Task Work(CancellationToken ct) { + using var scope = serviceScopeFactory.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService<Database>(); + var http = scope.ServiceProvider.GetRequiredService<HttpClient>(); + var logger = scope.ServiceProvider.GetRequiredService<ILogger<DataWorker>>(); + var refreshData = Environment.GetEnvironmentVariable("VEGADATA_REFRESH_DATA") == "1"; + logger.LogInformation("Syncing data. refresh:{refreshData}", refreshData); + var shows = await http.GetFromJsonAsync<ShowsResponse>("https://www.vegascene.no/api/program", ct); + var addedCount = 0; + + if (refreshData) { + db.Shows.RemoveRange(db.Shows); + await db.SaveChangesAsync(ct); + File.Copy("data/main.db", $"data/main-{DateTime.UnixEpoch}.db"); + } + + var count = await db.Shows.CountAsync(ct); + + foreach (var show in shows?.Shows ?? []) { + var existing = await db.Shows.AnyAsync(s => + s.Title == show.MovieTitle && s.StartDateTime == show.ShowStart, ct); + if (existing) continue; + db.Shows.Add(new Show() { + Title = show.MovieTitle, + Scene = show.ScreenName, + StartDateTime = show.ShowStart, + MovieMainVersion = show.MovieMainVersionId, + MovieVersion = show.MovieVersionId, + TicketUrl = show.TicketSaleUrl, + Type = show.ShowType, + Tags = show.VersionTags.Select(t => t.Tag).ToArray() + }); + addedCount++; + } + await db.SaveChangesAsync(ct); + logger.LogInformation("Synced data, old count:{count}, new count:{addedCount}", count, addedCount); + } + + class ShowsResponse + { + public List<VegaShow> Shows { get; set; } + } + + class VegaShow + { + [JsonPropertyName("screenName")] + public string ScreenName { get; set; } + + [JsonPropertyName("ticketSaleUrl")] + public string TicketSaleUrl { get; set; } + + [JsonPropertyName("showType")] + public string ShowType { get; set; } + + [JsonPropertyName("showStart")] + public DateTimeOffset ShowStart { get; set; } + + [JsonPropertyName("movieVersionId")] + public string MovieVersionId { get; set; } + + [JsonPropertyName("movieMainVersionId")] + public string MovieMainVersionId { get; set; } + + [JsonPropertyName("movieTitle")] + public string MovieTitle { get; set; } + + [JsonPropertyName("versionTags")] + public VersionTag[] VersionTags { get; set; } + } + + public class VersionTag + { + [JsonPropertyName("tag")] + public string Tag { get; set; } + + [JsonPropertyName("type")] + public string Type { get; set; } + } +}
\ No newline at end of file |
