Extensible_Portfolio_Site/GithubPlugin/GithubProvider.cs
2022-09-06 22:29:40 -07:00

147 lines
5.5 KiB
C#

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<string, GithubUser> Users = new();
public Dictionary<string, GithubRepo> 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<GithubRepo>(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<GithubUser>(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;
}
}
}