aboutsummaryrefslogtreecommitdiff
path: root/docker
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-11-26 17:21:33 +0800
committercrupest <crupest@outlook.com>2022-11-26 17:21:33 +0800
commit80bb178ab3234fb7b883c6489ff3c5e2631e208e (patch)
tree588d8efd20f1e427a9c72ce8fadd8a5dcb0b4879 /docker
parent63e43d1a9b880c92d73b7ec97b596c38d3e758e2 (diff)
downloadcrupest-80bb178ab3234fb7b883c6489ff3c5e2631e208e.tar.gz
crupest-80bb178ab3234fb7b883c6489ff3c5e2631e208e.tar.bz2
crupest-80bb178ab3234fb7b883c6489ff3c5e2631e208e.zip
Add crupest-api.
Diffstat (limited to 'docker')
-rw-r--r--docker/auto-backup/AutoBackup/.dockerignore2
-rw-r--r--docker/crupest-api/CrupestApi/.dockerignore2
-rw-r--r--docker/crupest-api/CrupestApi/.gitignore2
-rw-r--r--docker/crupest-api/CrupestApi/Config/TodosConfiguration.cs15
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.csproj8
-rw-r--r--docker/crupest-api/CrupestApi/Program.cs160
-rw-r--r--docker/crupest-api/CrupestApi/Properties/launchSettings.json13
-rw-r--r--docker/crupest-api/CrupestApi/appsettings.json8
-rw-r--r--docker/crupest-api/Dockerfile13
9 files changed, 223 insertions, 0 deletions
diff --git a/docker/auto-backup/AutoBackup/.dockerignore b/docker/auto-backup/AutoBackup/.dockerignore
new file mode 100644
index 0000000..7de5508
--- /dev/null
+++ b/docker/auto-backup/AutoBackup/.dockerignore
@@ -0,0 +1,2 @@
+obj
+bin
diff --git a/docker/crupest-api/CrupestApi/.dockerignore b/docker/crupest-api/CrupestApi/.dockerignore
new file mode 100644
index 0000000..7de5508
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/.dockerignore
@@ -0,0 +1,2 @@
+obj
+bin
diff --git a/docker/crupest-api/CrupestApi/.gitignore b/docker/crupest-api/CrupestApi/.gitignore
new file mode 100644
index 0000000..7de5508
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/.gitignore
@@ -0,0 +1,2 @@
+obj
+bin
diff --git a/docker/crupest-api/CrupestApi/Config/TodosConfiguration.cs b/docker/crupest-api/CrupestApi/Config/TodosConfiguration.cs
new file mode 100644
index 0000000..68f893a
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/Config/TodosConfiguration.cs
@@ -0,0 +1,15 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace CrupestApi.Config
+{
+ public class TodoConfiguration
+ {
+ [Required]
+ public string Username { get; set; } = default!;
+ [Required]
+ public int ProjectNumber { get; set; } = default!;
+ [Required]
+ public string Token { get; set; } = default!;
+ public int? Count { get; set; }
+ }
+} \ No newline at end of file
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.csproj b/docker/crupest-api/CrupestApi/CrupestApi.csproj
new file mode 100644
index 0000000..4348979
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/CrupestApi.csproj
@@ -0,0 +1,8 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+ <PropertyGroup>
+ <TargetFramework>net7.0</TargetFramework>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+
+</Project>
diff --git a/docker/crupest-api/CrupestApi/Program.cs b/docker/crupest-api/CrupestApi/Program.cs
new file mode 100644
index 0000000..c62bf4d
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/Program.cs
@@ -0,0 +1,160 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Mime;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Console;
+using Microsoft.AspNetCore.Http;
+using CrupestApi.Config;
+
+public class TodoItem
+{
+ public string Status { get; set; } = default!;
+ public string Title { get; set; } = default!;
+}
+
+internal class Program
+{
+ private static void Main(string[] args)
+ {
+ using var httpClient = new HttpClient();
+
+ var builder = WebApplication.CreateBuilder(args);
+
+ string configFilePath = Environment.GetEnvironmentVariable("CRUPEST_API_CONFIG_FILE") ?? "/config.json";
+
+ builder.Configuration.AddJsonFile(configFilePath, optional: false, reloadOnChange: true);
+
+ string? logFilePath = Environment.GetEnvironmentVariable("CRUPEST_API_LOG_FILE");
+ if (logFilePath is not null)
+ {
+ // TODO: Log to file.
+ builder.Logging.AddSimpleConsole(logger =>
+ {
+ logger.ColorBehavior = LoggerColorBehavior.Disabled;
+ });
+ }
+
+ var app = builder.Build();
+
+ app.MapGet("/api/todos", async ([FromServices] IConfiguration configuration, [FromServices] ILoggerFactory loggerFactory) =>
+ {
+ var logger = loggerFactory.CreateLogger("CrupestApi.Todos");
+
+ static string CreateGraphQLQuery(TodoConfiguration todoConfiguration)
+ {
+ return $$"""
+{
+ user(login: "{{todoConfiguration.Username}}") {
+ projectV2(number: {{todoConfiguration.ProjectNumber}}) {
+ items(last: {{todoConfiguration.Count ?? 20}}) {
+ nodes {
+ __typename
+ content {
+ __typename
+ ... on Issue {
+ title
+ closed
+ }
+ ... on PullRequest {
+ title
+ closed
+ }
+ ... on DraftIssue {
+ title
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+""";
+ }
+
+ var todoConfiguration = configuration.GetSection("Todos").Get<TodoConfiguration>();
+ if (todoConfiguration is null)
+ {
+ throw new Exception("Fail to get todos configuration.");
+ }
+
+ using var requestContent = new StringContent(JsonSerializer.Serialize(new
+ {
+ query = CreateGraphQLQuery(todoConfiguration)
+ }));
+ requestContent.Headers.ContentType = new MediaTypeHeaderValue(MediaTypeNames.Application.Json, Encoding.UTF8.WebName);
+
+ using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.github.com/graphql");
+ request.Content = requestContent;
+ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", todoConfiguration.Token);
+
+ using var response = await httpClient.SendAsync(request);
+ var responseBody = await response.Content.ReadAsStringAsync();
+ logger.LogInformation(response.StatusCode.ToString());
+ logger.LogInformation(responseBody);
+
+
+ if (response.IsSuccessStatusCode)
+ {
+ using var responseJson = JsonSerializer.Deserialize<JsonDocument>(responseBody);
+ if (responseJson is null)
+ {
+ throw new Exception("Fail to deserialize response body.");
+ }
+
+ var nodes = responseJson.RootElement.GetProperty("data").GetProperty("user").GetProperty("projectV2").GetProperty("items").GetProperty("nodes").EnumerateArray();
+
+ var result = new List<TodoItem>();
+
+ foreach (var node in nodes)
+ {
+ var content = node.GetProperty("content");
+ var title = content.GetProperty("title").GetString();
+ if (title is null)
+ {
+ throw new Exception("Fail to get title.");
+ }
+ JsonElement closedElement;
+ bool closed;
+ if (content.TryGetProperty("closed", out closedElement))
+ {
+ closed = closedElement.GetBoolean();
+ }
+ else
+ {
+ closed = false;
+ }
+
+ result.Add(new TodoItem
+ {
+ Title = title,
+ Status = closed ? "Done" : "Todo"
+ });
+ }
+
+ return Results.Json(result, new JsonSerializerOptions
+ {
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase
+ }, statusCode: 200);
+ }
+ else
+ {
+ const string message = "Fail to get todos from GitHub.";
+ logger.LogError(message);
+
+ return Results.Json(new
+ {
+ message
+ }, statusCode: StatusCodes.Status503ServiceUnavailable);
+ }
+ });
+
+ app.Run();
+ }
+} \ No newline at end of file
diff --git a/docker/crupest-api/CrupestApi/Properties/launchSettings.json b/docker/crupest-api/CrupestApi/Properties/launchSettings.json
new file mode 100644
index 0000000..01f2a12
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/Properties/launchSettings.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "dev": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "applicationUrl": "http://localhost:5188",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/docker/crupest-api/CrupestApi/appsettings.json b/docker/crupest-api/CrupestApi/appsettings.json
new file mode 100644
index 0000000..53753bd
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/appsettings.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+} \ No newline at end of file
diff --git a/docker/crupest-api/Dockerfile b/docker/crupest-api/Dockerfile
new file mode 100644
index 0000000..ba7d75b
--- /dev/null
+++ b/docker/crupest-api/Dockerfile
@@ -0,0 +1,13 @@
+FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine AS build
+COPY CrupestApi /CrupestApi
+WORKDIR /CrupestApi
+RUN dotnet publish CrupestApi.csproj --configuration Release --output ./publish/ -r linux-x64 --self-contained false
+
+FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine
+ENV ASPNETCORE_URLS=http://0.0.0.0:5000
+ENV ASPNETCORE_FORWARDEDHEADERS_ENABLED=true
+COPY --from=build /CrupestApi/publish /CrupestApi
+WORKDIR /CrupestApi
+VOLUME [ "/config.json" ]
+EXPOSE 5000
+ENTRYPOINT ["dotnet", "CrupestApi.dll"]