aboutsummaryrefslogtreecommitdiff
path: root/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos
diff options
context:
space:
mode:
Diffstat (limited to 'dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos')
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/CrupestApi.Todos.csproj15
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosConfiguration.cs14
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs163
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs21
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosWebApplicationExtensions.cs32
5 files changed, 0 insertions, 245 deletions
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/CrupestApi.Todos.csproj b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/CrupestApi.Todos.csproj
deleted file mode 100644
index 86460e3..0000000
--- a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/CrupestApi.Todos.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
-
- <ItemGroup>
- <ProjectReference Include="..\CrupestApi.Commons\CrupestApi.Commons.csproj" />
- </ItemGroup>
-
- <PropertyGroup>
- <TargetFramework>net7.0</TargetFramework>
- <TargetType>library</TargetType>
- <Nullable>enable</Nullable>
- <ImplicitUsings>enable</ImplicitUsings>
- <SelfContained>false</SelfContained>
- </PropertyGroup>
-
-</Project>
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosConfiguration.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosConfiguration.cs
deleted file mode 100644
index e8160d2..0000000
--- a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosConfiguration.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-
-namespace CrupestApi.Todos;
-
-public class TodosConfiguration
-{
- [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/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs
deleted file mode 100644
index 5839086..0000000
--- a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-using System.Net.Http.Headers;
-using System.Net.Mime;
-using System.Text;
-using System.Text.Json;
-using Microsoft.Extensions.Options;
-
-namespace CrupestApi.Todos;
-
-public class TodosItem
-{
- public string Status { get; set; } = default!;
- public string Title { get; set; } = default!;
- public bool Closed { get; set; }
- public string Color { get; set; } = default!;
-}
-
-public class TodosService
-{
- private readonly IOptionsSnapshot<TodosConfiguration> _options;
- private readonly ILogger<TodosService> _logger;
-
- public TodosService(IOptionsSnapshot<TodosConfiguration> options, ILogger<TodosService> logger)
- {
- _options = options;
- _logger = logger;
- }
-
- private static string CreateGraphQLQuery(TodosConfiguration todoConfiguration)
- {
- return $$"""
-{
- user(login: "{{todoConfiguration.Username}}") {
- projectV2(number: {{todoConfiguration.ProjectNumber}}) {
- items(last: {{todoConfiguration.Count}}) {
- nodes {
- fieldValueByName(name: "Status") {
- ... on ProjectV2ItemFieldSingleSelectValue {
- name
- }
- }
- content {
- __typename
- ... on Issue {
- title
- closed
- }
- ... on PullRequest {
- title
- closed
- }
- ... on DraftIssue {
- title
- }
- }
- }
- }
- }
- }
-}
-""";
- }
-
-
- public async Task<List<TodosItem>> GetTodosAsync()
- {
- var todoOptions = _options.Value;
- if (todoOptions is null)
- {
- throw new Exception("Fail to get todos configuration.");
- }
-
- _logger.LogInformation("Username: {}; ProjectNumber: {}; Count: {}", todoOptions.Username, todoOptions.ProjectNumber, todoOptions.Count);
- _logger.LogInformation("Getting todos from GitHub GraphQL API...");
-
- using var httpClient = new HttpClient();
-
- using var requestContent = new StringContent(JsonSerializer.Serialize(new
- {
- query = CreateGraphQLQuery(todoOptions)
- }));
- 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", todoOptions.Token);
- request.Headers.TryAddWithoutValidation("User-Agent", todoOptions.Username);
-
- using var response = await httpClient.SendAsync(request);
- var responseBody = await response.Content.ReadAsStringAsync();
-
- _logger.LogInformation("GitHub server returned status code: {}", response.StatusCode);
- _logger.LogInformation("GitHub server returned body: {}", 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<TodosItem>();
-
- 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.");
- }
-
- bool done = false;
-
- var statusField = node.GetProperty("fieldValueByName");
- if (statusField.ValueKind != JsonValueKind.Null) // if there is a "Status" field
- {
- var statusName = statusField.GetProperty("name").GetString();
- if (statusName is null)
- {
- throw new Exception("Fail to get status.");
- }
-
- // if name is "Done", then it is closed, otherwise we check if the issue is closed
- if (statusName.Equals("Done", StringComparison.OrdinalIgnoreCase))
- {
- done = true;
- }
- }
-
- JsonElement closedElement;
- // if item has a "closed" field, then it is a pull request or an issue, and we check if it is closed
- if (content.TryGetProperty("closed", out closedElement) && closedElement.GetBoolean())
- {
- done = true;
- }
-
- // If item "Status" field is "Done' or item is a pull request or issue and it is closed, then it is done.
- // Otherwise it is not closed. Like:
- // 1. it is a draft issue with no "Status" field or "Status" field is not "Done"
- // 2. it is a pull request or issue with no "Status" field or "Status" field is not "Done" and it is not closed
-
- result.Add(new TodosItem
- {
- Title = title,
- Status = done ? "Done" : "Todo",
- Closed = done,
- Color = done ? "green" : "blue"
- });
- }
-
- return result;
- }
- else
- {
- const string message = "Fail to get todos from GitHub.";
- _logger.LogError(message);
- throw new Exception(message);
- }
- }
-}
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs
deleted file mode 100644
index a49d55d..0000000
--- a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Microsoft.Extensions.DependencyInjection.Extensions;
-
-namespace CrupestApi.Todos;
-
-public static class TodosServiceCollectionExtensions
-{
- public static IServiceCollection AddTodos(this IServiceCollection services)
- {
- services.AddOptions<TodosConfiguration>().BindConfiguration("CrupestApi:Todos");
- services.PostConfigure<TodosConfiguration>(config =>
- {
- if (config.Count == 0)
- {
- config.Count = 20;
- }
- });
- services.TryAddScoped<TodosService>();
- return services;
- }
-}
-
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosWebApplicationExtensions.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosWebApplicationExtensions.cs
deleted file mode 100644
index 0ff05a0..0000000
--- a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosWebApplicationExtensions.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using CrupestApi.Commons;
-
-namespace CrupestApi.Todos;
-
-public static class TodosWebApplicationExtensions
-{
- public static WebApplication MapTodos(this WebApplication app, string path)
- {
- if (app is null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- app.MapGet(path, async (context) =>
- {
- var todosService = context.RequestServices.GetRequiredService<TodosService>();
-
- try
- {
- var todos = await todosService.GetTodosAsync();
- await context.Response.WriteJsonAsync(todos);
-
- }
- catch (Exception e)
- {
- await context.Response.WriteMessageAsync(e.Message, statusCode: StatusCodes.Status503ServiceUnavailable);
- }
- });
-
- return app;
- }
-} \ No newline at end of file