Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate octokit.NET to the new generated SDK #2

Merged
merged 2 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 6 additions & 46 deletions LoongsonNeuq.Classroom/Program.cs
Original file line number Diff line number Diff line change
@@ -1,58 +1,18 @@
using System.Net.Http.Headers;
using LoongsonNeuq.Classroom;
using LoongsonNeuq.Classroom;
using LoongsonNeuq.Common;
using LoongsonNeuq.Common.GitHub;
using LoongsonNeuq.Common.Auth;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Octokit;

var services = new ServiceCollection();

services.AddSingleton(new ProductInfoHeaderValue("LoongsonClassroom", "1.0"));
services.AddSingleton<ITokenProvider, EnvTokenProvider>();

services.AddSingleton<GitHubApi>();
services.AddSingleton(provider =>
{
var github = provider.GetRequiredService<GitHubApi>();

var classroomJson = github.GetAuthedAsync("https://raw.githubusercontent.com/Loongson-neuq/index/master/classroom.json").Result;

var classroom = JsonConvert.DeserializeObject<Classroom>(classroomJson.Content.ReadAsStringAsync().Result)
?? throw new InvalidOperationException("Failed to get classroom.");

classroom.ServiceProvider = provider;

return classroom;
});

services.AddSingleton<ILogger, Logger>();
services.AddGitHubAuth()
.WithToken<EnvTokenProvider>()
.AddGitHubClient();

services.AddSingleton<StudentsTable>();

services.AddSingleton(new GitHubClient(new Octokit.ProductHeaderValue("LoongsonClassroom")));

services.AddSingleton<StudentsTable>();
services.AddLogging();

var serviceProvider = services.BuildServiceProvider();

// 目前本后端仅用于 Loongson-neuq/Summary,仅会在 GitHub Actions 中运行
// 因此只有冷启动,无需考虑缓存更新问题

// var classroom = serviceProvider.GetRequiredService<Classroom>();

// var assignments = classroom.GetAssignments();

// foreach (var assignment in assignments)
// {
// Console.WriteLine($"{assignment.Title}");

// var accepted = assignment.GetAcceptedAssignments();

// foreach (var aa in accepted)
// {
// Console.WriteLine($" {aa.Students.Single().Login}");
// }
// }
// TODO
82 changes: 46 additions & 36 deletions LoongsonNeuq.Classroom/StudentsTable.cs
Original file line number Diff line number Diff line change
@@ -1,63 +1,73 @@
using System.Collections.Concurrent;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Octokit;
using LoongsonNeuq.Common.GitHub;
using LoongsonNeuq.Common;
using GitHub;
using System.Diagnostics;
using GitHub.Models;
using System.Collections.Frozen;

namespace LoongsonNeuq.Classroom;

public class StudentsTable
{
private readonly GitHubApi _github;
private readonly GitHubClient _github;

private readonly ConcurrentDictionary<string, Student> _students = new();
private FrozenDictionary<string, StoredStudent>? _students = null;

private readonly IServiceProvider _serviceProvider;

public StudentsTable(GitHubApi github, IServiceProvider serviceProvider)
public FrozenDictionary<string, StoredStudent> Students
{
get
{
if (_students is null)
{
PopulateStudents();
}

return _students!;
}
}

public StudentsTable(GitHubClient github, IServiceProvider serviceProvider)
{
_github = github;
_serviceProvider = serviceProvider;
}

public void PopulateUpdateStudents()
private string? ReadContent(ContentFile? contentFile)
{
var response = _github.GetAuthedAsync("https://raw.githubusercontent.com/Loongson-neuq/index/master/student_list.json").Result;
var students = JsonConvert.DeserializeObject<List<StoredStudent>>(response.Content.ReadAsStringAsync().Result)
?? throw new InvalidOperationException("Failed to get students.");

var mappedStudents = students.Select(s => new Student
{
Login = s.GitHubLogin,
ResearchFocus = s.ResearchFocus
}).ToList();

foreach (var student in mappedStudents)
if (contentFile is null)
{
if (_students.ContainsKey(student.Login))
{
_students.TryUpdate(student.Login, student, student);
}
else
{
_students.TryAdd(student.Login, student);
}
return null;
}

var github = _serviceProvider.GetRequiredService<GitHubClient>();
Debug.Assert(contentFile.Encoding == "base64");

foreach (var student in _students.Values)
{
student.FillFields(github);
}
return contentFile.Content;
}

private class StoredStudent
public void PopulateStudents()
{
[JsonProperty("github_id")]
public string GitHubLogin { get; set; } = null!;
const string owner = "Loongson-neuq";
const string repo = "index";

const string path = "student_list.json";

var response = _github.Repos[owner][repo].Contents[path].GetAsync().Result;

Debug.Assert(response is not null);

string? content = ReadContent(response.ContentFile);

if (content is null)
{
throw new InvalidOperationException("Failed to get students.");
}

var students = JsonConvert.DeserializeObject<List<StoredStudent>>(content)
?? throw new InvalidOperationException("Failed to deserialize students.");

[JsonProperty("research_focus")]
public List<string> ResearchFocus { get; set; } = null!;
_students = students.ToDictionary(s => s.GitHubId).ToFrozenDictionary();
}
}
52 changes: 52 additions & 0 deletions LoongsonNeuq.Common/DependencyInjectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using GitHub;
using GitHub.Assignments;
using GitHub.Classrooms;
using GitHub.Classrooms.Item;
using GitHub.Models;
using GitHub.Octokit.Client;
using GitHub.Octokit.Client.Authentication;
using LoongsonNeuq.Common.Auth;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Kiota.Abstractions;
using Microsoft.Kiota.Abstractions.Authentication;

namespace LoongsonNeuq.Common;

public static class DependencyInjectionExtensions
{
public static IServiceCollection AddGitHubAuth(this IServiceCollection services) => services.AddSingleton<IAuthenticationProvider>(p =>
{
string token = p.GetRequiredService<ITokenProvider>().Token;

if (string.IsNullOrWhiteSpace(token))
{
throw new InvalidOperationException("Token is empty.");
}

return new TokenAuthProvider(new TokenProvider(token));
});

public static IServiceCollection WithToken<T>(this IServiceCollection services) where T : class, ITokenProvider
=> services.AddSingleton<ITokenProvider, T>();

public static IServiceCollection AddAnonymousAuth(this IServiceCollection services)
=> services.AddSingleton<IAuthenticationProvider, AnonymousAuthenticationProvider>();

public static IServiceCollection AddGitHubClient(this IServiceCollection services)
=> services.AddSingleton<GitHubClient>();

public static IServiceCollection AddLogging<TServiceCollection>(this TServiceCollection services)
where TServiceCollection : IServiceCollection
// Must be concrete type to hide Microsoft's AddLogging
=> services.AddSingleton<ILogger, Logger>();

public static IServiceCollection AddClassroom(this IServiceCollection services, int id) => services.AddKeyedTransient(id, (p, key) =>
{
int id = (int)key!;

ArgumentNullException.ThrowIfNull(id, nameof(id));

return p.GetRequiredService<GitHubClient>().Classrooms[id];
});
}
29 changes: 0 additions & 29 deletions LoongsonNeuq.Common/GitHub/AcceptedAssignment.cs

This file was deleted.

61 changes: 0 additions & 61 deletions LoongsonNeuq.Common/GitHub/Assignment.cs

This file was deleted.

57 changes: 0 additions & 57 deletions LoongsonNeuq.Common/GitHub/Classroom.cs

This file was deleted.

Loading