From 3102f202c3d445c1297eb6a953728ddeb6a8d611 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Mon, 26 May 2025 11:53:10 -0400 Subject: [PATCH] begin adding v2 api --- Controllers/{ => V1}/ProfilerController.cs | 3 +- Controllers/{ => V1}/StatsController.cs | 3 +- Controllers/V2/StatsController.cs | 62 ++++++++++++++++++++++ Program.cs | 7 +++ 4 files changed, 73 insertions(+), 2 deletions(-) rename Controllers/{ => V1}/ProfilerController.cs (98%) rename Controllers/{ => V1}/StatsController.cs (98%) create mode 100644 Controllers/V2/StatsController.cs diff --git a/Controllers/ProfilerController.cs b/Controllers/V1/ProfilerController.cs similarity index 98% rename from Controllers/ProfilerController.cs rename to Controllers/V1/ProfilerController.cs index 34e469b..deab530 100644 --- a/Controllers/ProfilerController.cs +++ b/Controllers/V1/ProfilerController.cs @@ -4,10 +4,11 @@ using ParadisePublicAPI.ProfilerDatabase; using Swashbuckle.AspNetCore.Annotations; -namespace ParadisePublicAPI.Controllers { +namespace ParadisePublicAPI.Controllers.V1 { /// /// Profiler /// + [ApiExplorerSettings(GroupName = "v1")] [SwaggerTag("Query proc times from the profiler. Old data may be cleared with no notice")] [Route("profiler")] public class ProfilerController : Controller { diff --git a/Controllers/StatsController.cs b/Controllers/V1/StatsController.cs similarity index 98% rename from Controllers/StatsController.cs rename to Controllers/V1/StatsController.cs index 314d798..adc9aea 100644 --- a/Controllers/StatsController.cs +++ b/Controllers/V1/StatsController.cs @@ -10,10 +10,11 @@ using ParadisePublicAPI.Models; using Swashbuckle.AspNetCore.Annotations; -namespace ParadisePublicAPI.Controllers { +namespace ParadisePublicAPI.Controllers.V1 { /// /// Controller for querying statistics from game rounds /// + [ApiExplorerSettings(GroupName = "v1")] [SwaggerTag("Query statistics from game rounds")] [Route("stats")] public class StatsController : Controller { diff --git a/Controllers/V2/StatsController.cs b/Controllers/V2/StatsController.cs new file mode 100644 index 0000000..c1c5794 --- /dev/null +++ b/Controllers/V2/StatsController.cs @@ -0,0 +1,62 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using ParadisePublicAPI.Database; +using Swashbuckle.AspNetCore.Annotations; + +namespace ParadisePublicAPI.Controllers.V2 +{ + /// + /// Controller for querying statistics from game rounds + /// + [ApiExplorerSettings(GroupName = "v2")] + [SwaggerTag("Query statistics from game rounds")] + [Route("v2/stats")] + public class StatsController : Controller { + private readonly paradise_gamedbContext _context; + + public StatsController(paradise_gamedbContext context) { + _context = context; + } + + /// + /// Gets the data of a specific feedback key for the specified rounds. + /// + /// The name of the desired feedback key. + /// The start date to retrieve data for. + /// The end date to retrieve data for. + /// A list of key-value objects, where "data" is the feedback data and "round_id" is the round ID the data was recorded. + /// Round data successfully retrieved + /// Rate limited by server + [HttpGet("feedback")] + public IActionResult GetFeedbackRow([FromQuery, Required] string key_name, [FromQuery, Required] DateOnly start_date, [FromQuery, Required] DateOnly end_date) { + if (key_name == null) { + return BadRequest("No feedback key_name specified."); + } + if (start_date > end_date) { + return BadRequest($"start_date {start_date} is later than end_date {end_date}"); + } + if (start_date.AddMonths(2) < end_date) { + return BadRequest("Only two months of data may be requested in one query."); + } + var start_datetime = start_date.ToDateTime(TimeOnly.MinValue); + var end_datetime = end_date.ToDateTime(TimeOnly.MaxValue); + var feedbacks = (from feedback in _context.Feedbacks + join round in _context.Rounds on feedback.RoundId equals round.Id + orderby round.Id + where feedback.KeyName == key_name + && round.ShutdownDatetime != null + && round.InitializeDatetime >= start_datetime + && round.InitializeDatetime <= end_datetime + // feedback.JSON begins with `{"data": ...` so we strip the first curly brace + // in order to interpolate the rest of the JSON data into the resultant string + select $"{{\"round_id\": {round.Id}, {feedback.Json.Substring(1)}"); + + return new ContentResult() + { + Content = "[" + string.Join(", ", feedbacks) + "]", + ContentType = "application/json", + StatusCode = 200 + }; + } + } +} diff --git a/Program.cs b/Program.cs index 22af195..a19750d 100644 --- a/Program.cs +++ b/Program.cs @@ -21,6 +21,12 @@ Title = "Paradise Public API", Description = "Paradise Station public API for data querying. This API may change with no notice.
Source: https://github.com/ParadiseSS13/ParadisePublicAPI
Requests are limited to 500 every minute, and 3600 every hour." }); + options.SwaggerDoc("v2", new OpenApiInfo + { + Version = "v2", + Title = "Paradise Public API", + Description = "Paradise Station public API for data querying. This API may change with no notice.
Source: https://github.com/ParadiseSS13/ParadisePublicAPI
Requests are limited to 500 every minute, and 3600 every hour." + }); }); // Setup Game DB @@ -71,6 +77,7 @@ app.UseSwagger(); app.UseSwaggerUI(options => { options.SwaggerEndpoint("swagger/v1/swagger.json", "v1"); + options.SwaggerEndpoint("swagger/v2/swagger.json", "v2"); options.RoutePrefix = String.Empty; });