Start of code to push updates to GH

This commit is contained in:
Timothy Baldridge 2021-07-19 16:15:27 -06:00
parent 631ccba553
commit 04347bbd06
8 changed files with 170 additions and 9 deletions

View File

@ -272,7 +272,7 @@ namespace Compression.BSA
case VersionType.SSE:
{
var r = new MemoryStream();
await using (var w = LZ4Stream.Encode(r, new LZ4EncoderSettings {CompressionLevel = LZ4Level.L08_HC}, true))
await using (var w = LZ4Stream.Encode(r, new LZ4EncoderSettings {CompressionLevel = LZ4Level.L12_MAX}, true))
{
await _srcData.CopyToWithStatusAsync(_srcData.Length, w, $"Compressing {_path}");
}

View File

@ -65,27 +65,32 @@ namespace Wabbajack.Common
using var tw = new StreamWriter(stream, new UTF8Encoding(false), bufferSize: 1024, leaveOpen: true);
using var writer = new JsonTextWriter(tw);
JsonSerializerSettings settings = (useGenericSettings, prettyPrint) switch
JsonSerializerSettings settings = SettingsForOptions(useGenericSettings, prettyPrint);
var ser = JsonSerializer.Create(settings);
ser.Serialize(writer, obj);
}
private static JsonSerializerSettings SettingsForOptions(bool useGenericSettings, bool prettyPrint)
{
return (useGenericSettings, prettyPrint) switch
{
(true, true) => GenericJsonSettings,
(false, true) => JsonSettingsPretty,
(false, false) => JsonSettings,
(true, false) => GenericJsonSettings
};
var ser = JsonSerializer.Create(settings);
ser.Serialize(writer, obj);
}
public static async ValueTask ToJsonAsync<T>(this T obj, AbsolutePath path, bool useGenericSettings = false, bool prettyPrint = false)
{
await using var fs = await path.Create();
obj.ToJson(fs, useGenericSettings, prettyPrint: prettyPrint);
}
public static string ToJson<T>(this T obj, bool useGenericSettings = false)
public static string ToJson<T>(this T obj, bool useGenericSettings = false, bool prettyPrint = false)
{
return JsonConvert.SerializeObject(obj, useGenericSettings ? GenericJsonSettings : JsonSettings);
return JsonConvert.SerializeObject(obj, SettingsForOptions(useGenericSettings, prettyPrint));
}
public static T FromJson<T>(this AbsolutePath filename)

View File

@ -307,7 +307,7 @@ namespace Wabbajack.Lib
await ModListOutputFolder.Combine("sig")
.WriteAllBytesAsync(((await ModListOutputFolder.Combine("modlist").FileHashAsync()) ?? Hash.Empty).ToArray());
await ClientAPI.SendModListDefinition(ModList);
//await ClientAPI.SendModListDefinition(ModList);
await ModListOutputFile.DeleteAsync();

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Octokit;
using Wabbajack.Common;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack.Lib.GitHub
{
public class Client
{
private readonly GitHubClient _client;
private Client(GitHubClient client)
{
_client = client;
}
public static async Task<Client> Get()
{
var key = Encoding.UTF8.GetString(await Utils.FromEncryptedData("github-key"));
var creds = new Credentials(key);
return new Client(new GitHubClient(ProductHeaderValue.Parse("wabbajack_build_server")){Credentials = creds});
}
public enum List
{
CI,
Unlisted,
Utility,
Published
}
public Dictionary<List, string> PathNames = new()
{
{List.CI, "ci_lists.json"},
{List.Unlisted, "unlisted_modlists.json"},
{List.Utility, "utility_modlists.json"},
{List.Published, "modlists.json"}
};
public async Task<(string Hash, IReadOnlyList<ModlistMetadata> Lists)> GetData(List lst)
{
var content =
(await _client.Repository.Content.GetAllContents("wabbajack-tools", "mod-lists", PathNames[lst])).First();
return (content.Sha, content.Content.FromJsonString<ModlistMetadata[]>());
}
private async Task WriteData(List file, string machinenUrl, string dataHash, IReadOnlyList<ModlistMetadata> dataLists)
{
var updateRequest = new UpdateFileRequest($"New release of {machinenUrl}", dataLists.ToJson(prettyPrint:true), dataHash);
await _client.Repository.Content.UpdateFile("wabbajack-tools", "mod-lists", PathNames[file], updateRequest);
}
public async Task UpdateList(string maintainer, string machineUrl, DownloadMetadata newData)
{
foreach (var file in Enum.GetValues<List>())
{
var data = await GetData(file);
var found = data.Lists.FirstOrDefault(l => l.Links.MachineURL == machineUrl && l.Maintainers.Contains(maintainer));
if (found == null) continue;
found.DownloadMetadata = newData;
await WriteData(file, machineUrl, data.Hash, data.Lists);
return;
}
throw new Exception("List not found or user not authorized");
}
}
}

View File

@ -21,6 +21,9 @@ namespace Wabbajack.Lib.ModListRegistry
[JsonProperty("author")]
public string Author { get; set; } = string.Empty;
[JsonProperty("maintainers")] public string[]
Maintainers { get; set; } = Array.Empty<string>();
[JsonProperty("game")]
public Game Game { get; set; }

View File

@ -37,6 +37,9 @@
<PackageReference Include="ModuleInit.Fody">
<Version>2.1.1</Version>
</PackageReference>
<PackageReference Include="Octokit">
<Version>0.50.0</Version>
</PackageReference>
<PackageReference Include="ReactiveUI">
<Version>14.1.1</Version>
</PackageReference>

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
@ -12,6 +13,8 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Nettle;
using Wabbajack.Common;
using Wabbajack.Lib.GitHub;
using Wabbajack.Lib.ModListRegistry;
using Wabbajack.Server.DataLayer;
namespace Wabbajack.BuildServer.Controllers
@ -36,6 +39,40 @@ namespace Wabbajack.BuildServer.Controllers
Response.Cookies.Append(ApiKeyAuthenticationHandler.ApiKeyHeaderName, authorKey);
return Redirect($"{Consts.WabbajackBuildServerUri}author_controls/home");
}
[Route("lists")]
[HttpGet]
public async Task<IActionResult> AuthorLists()
{
var user = User.FindFirstValue(ClaimTypes.Name);
List<string> lists = new();
var client = await Client.Get();
foreach (var file in Enum.GetValues<Client.List>())
{
lists.AddRange((await client.GetData(file)).Lists.Where(l => l.Maintainers.Contains(user))
.Select(lst => lst.Links.MachineURL));
}
return Ok(lists);
}
[Route("lists/{machineUrl}/download_metadata")]
[HttpPost]
public async Task<IActionResult> AuthorLists(string machineUrl)
{
var user = User.FindFirstValue(ClaimTypes.Name);
var data = (await Request.Body.ReadAllTextAsync()).FromJsonString<DownloadMetadata>();
var client = await Client.Get();
try
{
await client.UpdateList(user, machineUrl, data);
}
catch (Exception ex)
{
return BadRequest(ex);
}
return Ok(data);
}
private static async Task<string> HomePageTemplate(object o)
{

View File

@ -0,0 +1,38 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Documents;
using Octokit;
using Wabbajack.Common;
using Wabbajack.Lib.GitHub;
using Wabbajack.Lib.ModListRegistry;
using Xunit;
namespace Wabbajack.Test
{
public class GitHubTests
{
[Fact]
public async Task CanLogIntoGithub()
{
var client = await Wabbajack.Lib.GitHub.Client.Get();
var rnd = new Random();
var meta = new DownloadMetadata
{
Hash = Hash.FromLong(rnd.Next()),
NumberOfArchives = rnd.Next(100),
NumberOfInstalledFiles = rnd.Next(1000),
SizeOfInstalledFiles = rnd.Next(1000000)
};
await client.UpdateList("ci_tester", "ci_test", meta);
var updated = await client.GetData(Client.List.CI);
var lst = updated.Lists.FirstOrDefault(l => l.Links.MachineURL == "ci_test");
var newMeta = lst!.DownloadMetadata!;
Assert.Equal(meta.Hash, newMeta.Hash);
Assert.Equal(meta.NumberOfArchives, newMeta.NumberOfArchives);
Assert.Equal(meta.NumberOfInstalledFiles, newMeta.NumberOfInstalledFiles);
Assert.Equal(meta.SizeOfInstalledFiles, newMeta.SizeOfInstalledFiles);
}
}
}