using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Json; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Octokit; using Wabbajack.DTOs; using Wabbajack.DTOs.GitHub; using Wabbajack.DTOs.JsonConverters; using Wabbajack.Networking.GitHub.DTOs; namespace Wabbajack.Networking.GitHub; public class Client { private readonly GitHubClient _client; private readonly DTOSerializer _dtos; private readonly ILogger _logger; private readonly GithubAuthTokenProvider _token; private readonly HttpClient _httpClient; public Client(ILogger logger, DTOSerializer dtos, GitHubClient client, HttpClient httpClient) { _httpClient = httpClient; _logger = logger; _client = client; _dtos = dtos; } public async Task<(string Hash, IReadOnlyList Lists)> GetData(List lst) { var content = (await _client.Repository.Content.GetAllContents("wabbajack-tools", "mod-lists", PathNames.FromList[lst])) .First(); return (content.Sha, _dtos.Deserialize(content.Content)!); } private async Task WriteData(List file, string machinenUrl, string dataHash, IReadOnlyList dataLists) { var listData = _dtos.Serialize(dataLists, true); // the website requires all names be in lowercase; listData = GameRegistry.Games.Keys.Aggregate(listData, (current, g) => current.Replace($"\"game\": \"{g}\",", $"\"game\": \"{g.ToString().ToLower()}\",")); var updateRequest = new UpdateFileRequest($"New release of {machinenUrl}", listData, dataHash); await _client.Repository.Content.UpdateFile("wabbajack-tools", "mod-lists", PathNames.FromList[file], updateRequest); } public async Task UpdateList(string maintainer, UpdateRequest newData) { foreach (var file in Enum.GetValues()) { var data = await GetData(file); var found = data.Lists.FirstOrDefault(l => l.NamespacedName == newData.MachineUrl && l.Maintainers.Contains(maintainer)); if (found == null) continue; found.DownloadMetadata = newData.DownloadMetadata; found.Version = newData.Version; found.Links.Download = newData.DownloadUrl.ToString(); await WriteData(file, newData.MachineUrl, data.Hash, data.Lists); return; } throw new Exception("List not found or user not authorized"); } public async Task<(string Sha, string Content)> GetData(string owner, string repo, string path) { var result = (await _client.Repository.Content.GetAllContents(owner, repo, path))[0]; return (result.Sha, result.Content); } public async Task GetUserInfoFromPAT(string pat) { var msg = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/user"); msg.Headers.Add("User-Agent", "wabbajack"); msg.Headers.Add("Authorization", "Token " + pat); var result = await _httpClient.SendAsync(msg); if (!result.IsSuccessStatusCode) return null; return await result.Content.ReadFromJsonAsync(); } public async Task PutData(string owner, string repo, string path, string message, string content, string oldSha) { await _client.Repository.Content.UpdateFile(owner, repo, path, new UpdateFileRequest(message, content, oldSha)); } }