summaryrefslogtreecommitdiffstats
path: root/VegaData/Program.cs
diff options
context:
space:
mode:
Diffstat (limited to 'VegaData/Program.cs')
-rw-r--r--VegaData/Program.cs133
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