using ExtensiblePortfolioSite.SDK.Git; using System.Text.Json; using System.Text.RegularExpressions; namespace GithubPlugin { [GitProvider("github.com")] public class GithubProvider : IGitProvider { private HttpClient httpClient = new HttpClient(); private Regex userPattern = new Regex("^(http(s)*:\\/\\/)(www\\.)*(github\\.com\\/[A-z]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); private Regex repoPattern = new Regex("^(http(s)*:\\/\\/)(www\\.)*(github\\.com\\/[A-z]+\\/[A-z]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); public Dictionary Users = new(); public Dictionary Repositories = new(); public GithubProvider() { this.httpClient.BaseAddress = new("https://api.github.com/"); this.httpClient.DefaultRequestHeaders.Add("User-Agent", "KoromaruKoruko"); this.httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer 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"); } public IGitObject GetByReference(GitReference Reference) { switch(Reference.Kind) { case GitReferenceKind.User: if(TryGetUserByName(Reference.ReferenceString, out IUser? user)) return user!; else return null; case GitReferenceKind.Repository: { if (TryGetRepositoryByName( Reference.ReferenceString.Split('/')[0], Reference.ReferenceString.Split('/')[1], out IRepository? repo)) return repo!; else return null; } case GitReferenceKind.Commit: { if (TryGetRepositoryByName( Reference.ReferenceString.Split('/')[0], Reference.ReferenceString.Split('/')[1], out IRepository? repo)) { if (repo!.TryGetCommitByRef(Reference.ReferenceString.Split('/')[2], out ICommit? commit)) return commit!; else return null; } else return null; } } return null; } public bool TryGetRepositoryByName(string Username, string RepositoryName, out IRepository? Repository) { if (TryGetUserByName(Username, out IUser? User)) return TryGetRepositoryByName(User!, RepositoryName, out Repository); Repository = null; return false; } public bool TryGetRepositoryByName(IUser User, string RepositoryName, out IRepository? Repository) { if(User.GetType() == typeof(GithubUser)) { if (Repositories.TryGetValue(RepositoryName, out GithubRepo? _repo)) { Repository = _repo; return true; } else { var response = httpClient.GetAsync($"repos/{User.Name}/{RepositoryName}").Result; if (!response.IsSuccessStatusCode) { Repository = null; return false; } GithubRepo tempRepo = JsonSerializer.Deserialize(response.Content.ReadAsStream())!; tempRepo.Provider = this; tempRepo.Owner = User; Repository = tempRepo; return true; } } Repository = null; return false; } public bool TryGetUserByName(string Username, out IUser? User) { if(Users.TryGetValue(Username, out GithubUser? _user)) { User = _user; return true; } else { var response = httpClient.GetAsync($"users/{Username}").Result; if(!response.IsSuccessStatusCode) { User = null; return false; } GithubUser tempUser = JsonSerializer.Deserialize(response.Content.ReadAsStream())!; tempUser.Provider = this; User = tempUser; return true; } } public bool TryGetRepositoryByURL(Uri RepoUrl, out IRepository? Repository) { if (repoPattern.IsMatch(RepoUrl.OriginalString)) { var split = RepoUrl.OriginalString.Split("://")[1].Split('/'); return TryGetRepositoryByName(split[1], split[2], out Repository); } else { Repository = null; return false; } } public bool TryGetUserByURL(Uri UserProfile, out IUser? User) { if (userPattern.IsMatch(UserProfile.OriginalString)) { var split = UserProfile.OriginalString.Split("://")[1].Split('/'); return TryGetUserByName(split[1], out User); } else { User = null; return false; } } public HttpResponseMessage GetAPIResource(string resourceLocation) { return httpClient.GetAsync(resourceLocation).Result; } } }