Merge pull request #502 from wabbajack-tools/more-author-cli-options

And CLI commands for refreshing the build server. Added icon to launc…
This commit is contained in:
Timothy Baldridge 2020-02-11 05:04:16 -07:00 committed by GitHub
commit e80cbf4535
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 142 additions and 32 deletions

View File

@ -5,8 +5,14 @@ namespace Wabbajack.CLI
{
public class OptionsDefinition
{
public static Type[] AllOptions = {
typeof(OptionsDefinition), typeof(Encrypt), typeof(Decrypt), typeof(Validate), typeof(DownloadUrl)
public static readonly Type[] AllOptions = {
typeof(OptionsDefinition),
typeof(Encrypt),
typeof(Decrypt),
typeof(Validate),
typeof(DownloadUrl),
typeof(UpdateModlists),
typeof(UpdateNexusCache)
};
}
}

View File

@ -9,10 +9,12 @@ namespace Wabbajack.CLI
{
return Parser.Default.ParseArguments(args, OptionsDefinition.AllOptions)
.MapResult(
(Encrypt opts) => Encrypt.Run(opts),
(Decrypt opts) => Decrypt.Run(opts),
(Validate opts) => Validate.Run(opts),
(DownloadUrl opts) => DownloadUrl.Run(opts),
(Encrypt opts) => opts.Execute(),
(Decrypt opts) => opts.Execute(),
(Validate opts) => opts.Execute(),
(DownloadUrl opts) => opts.Execute(),
(UpdateModlists opts) => opts.Execute(),
(UpdateNexusCache opts) => opts.Execute(),
errs => 1);
}
}

View File

@ -0,0 +1,17 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Wabbajack.CLI.Verbs
{
public abstract class AVerb
{
public int Execute()
{
return Run().Result;
}
protected abstract Task<int> Run();
}
}

View File

@ -1,11 +1,12 @@
using Alphaleonis.Win32.Filesystem;
using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem;
using CommandLine;
using Wabbajack.Common;
namespace Wabbajack.CLI.Verbs
{
[Verb("decrypt", HelpText = @"Decrypt data from AppData\Local\Wabbajack and store it locally", Hidden = true)]
public class Decrypt
public class Decrypt : AVerb
{
[Option('n', "name", Required = true, HelpText = @"Credential to encrypt and store in AppData\Local\Wabbajack")]
public string Name { get; set; }
@ -14,9 +15,9 @@ namespace Wabbajack.CLI.Verbs
[Option('o', "output", Required = true, HelpText = @"Output file for the decrypted data")]
public string Output { get; set; }
public static int Run(Decrypt opts)
protected override async Task<int> Run()
{
File.WriteAllBytes(opts.Output, Utils.FromEncryptedData(opts.Name));
File.WriteAllBytes(Output, Utils.FromEncryptedData(Name));
return 0;
}
}

View File

@ -11,7 +11,7 @@ using Wabbajack.Lib.Downloaders;
namespace Wabbajack.CLI.Verbs
{
[Verb("download-url", HelpText = "Infer a download state from a URL and download it")]
public class DownloadUrl
public class DownloadUrl : AVerb
{
[Option('u', "url", Required = true, HelpText = "Url to download")]
public Uri Url { get; set; }
@ -19,12 +19,12 @@ namespace Wabbajack.CLI.Verbs
[Option('o', "output", Required = true, HelpText = "Output file name")]
public string Output { get; set; }
public static int Run(DownloadUrl opts)
protected override async Task<int> Run()
{
var state = DownloadDispatcher.Infer(opts.Url);
var state = DownloadDispatcher.Infer(Url);
if (state == null)
{
Console.WriteLine($"Could not find download source for URL {opts.Url}");
Console.WriteLine($"Could not find download source for URL {Url}");
return 1;
}
@ -39,10 +39,10 @@ namespace Wabbajack.CLI.Verbs
new[] {state}
.PMap(queue, async s =>
{
await s.Download(new Archive {Name = Path.GetFileName(opts.Output)}, opts.Output);
await s.Download(new Archive {Name = Path.GetFileName(Output)}, Output);
}).Wait();
File.WriteAllLines(opts.Output + ".meta", state.GetMetaIni());
File.WriteAllLines(Output + ".meta", state.GetMetaIni());
return 0;
}

View File

@ -1,11 +1,12 @@
using Alphaleonis.Win32.Filesystem;
using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem;
using CommandLine;
using Wabbajack.Common;
namespace Wabbajack.CLI.Verbs
{
[Verb("encrypt", HelpText = @"Encrypt local data and store it in AppData\Local\Wabbajack", Hidden = true)]
public class Encrypt
public class Encrypt : AVerb
{
[Option('n', "name", Required = true, HelpText = @"Credential to encrypt and store in AppData\Local\Wabbajack")]
public string Name { get; set; }
@ -13,9 +14,9 @@ namespace Wabbajack.CLI.Verbs
[Option('i', "input", Required = true, HelpText = @"Source data file name")]
public string Input { get; set; }
public static int Run(Encrypt opts)
protected override async Task<int> Run()
{
File.ReadAllBytes(opts.Input).ToEcryptedData(opts.Name);
File.ReadAllBytes(Input).ToEcryptedData(Name);
return 0;
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Threading.Tasks;
using CommandLine;
using Wabbajack.Lib.FileUploader;
namespace Wabbajack.CLI.Verbs
{
[Verb("update-server-modlists", HelpText = "Tell the Build server to update curated modlists (Requires Author API key)")]
public class UpdateModlists : AVerb
{
protected override async Task<int> Run()
{
Console.WriteLine($"Job ID: {await AuthorAPI.UpdateServerModLists()}");
return 0;
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Threading.Tasks;
using CommandLine;
using Wabbajack.Common;
using Wabbajack.Lib.FileUploader;
namespace Wabbajack.CLI.Verbs
{
[Verb("update-nexus-cache", HelpText = "Tell the build server to update the Nexus cache (requires Author API key)")]
public class UpdateNexusCache : AVerb
{
protected override async Task<int> Run()
{
Console.WriteLine($"Job ID: {await AuthorAPI.UpdateNexusCache()}");
return 0;
}
}
}

View File

@ -1,15 +1,17 @@
using System;
using System.Reactive.Linq;
using System.Threading.Tasks;
using CommandLine;
using Wabbajack.Common;
using Wabbajack.Lib;
using Wabbajack.Lib.Validation;
using Wabbajack.VirtualFileSystem;
using File = Alphaleonis.Win32.Filesystem.File;
namespace Wabbajack.CLI.Verbs
{
[Verb("validate", HelpText = @"Validates a Modlist")]
public class Validate
public class Validate : AVerb
{
[Option('i', "input", Required = true, HelpText = @"Modlist file")]
public string Input { get; set; }
@ -25,18 +27,18 @@ namespace Wabbajack.CLI.Verbs
/// <c>1</c> broken modlist
/// </para>
/// </returns>
public static int Run(Validate opts)
protected override async Task<int> Run()
{
if (!File.Exists(opts.Input))
if (!File.Exists(Input))
{
Console.WriteLine($"The file {opts.Input} does not exist!");
Console.WriteLine($"The file {Input} does not exist!");
return -1;
}
if (!opts.Input.EndsWith(Consts.ModListExtension))
if (!Input.EndsWith(Consts.ModListExtension))
{
Console.WriteLine($"The file {opts.Input} does not end with {Consts.ModListExtension}!");
Console.WriteLine($"The file {Input} does not end with {Consts.ModListExtension}!");
return -1;
}
@ -44,7 +46,7 @@ namespace Wabbajack.CLI.Verbs
try
{
modlist = AInstaller.LoadFromFile(opts.Input);
modlist = AInstaller.LoadFromFile(Input);
}
catch (Exception e)
{

View File

@ -37,13 +37,11 @@ namespace Wabbajack.Lib.FileUploader
var tcs = new TaskCompletionSource<string>();
Task.Run(async () =>
{
var handler = new HttpClientHandler {MaxConnectionsPerServer = MAX_CONNECTIONS};
var client = new HttpClient(handler);
var fsize = new FileInfo(filename).Length;
var client = GetAuthorizedClient();
var fsize = new FileInfo(filename).Length;
var hash_task = filename.FileHashAsync();
client.DefaultRequestHeaders.Add("X-API-KEY", AuthorAPI.GetAPIKey());
var response = await client.PutAsync(UploadURL+$"/{Path.GetFileName(filename)}/start", new StringContent(""));
if (!response.IsSuccessStatusCode)
{
@ -118,5 +116,29 @@ namespace Wabbajack.Lib.FileUploader
return tcs.Task;
}
public static HttpClient GetAuthorizedClient()
{
var handler = new HttpClientHandler {MaxConnectionsPerServer = MAX_CONNECTIONS};
var client = new HttpClient(handler);
client.DefaultRequestHeaders.Add("X-API-KEY", AuthorAPI.GetAPIKey());
return client;
}
public static async Task<string> RunJob(string jobtype)
{
var client = GetAuthorizedClient();
return await client.GetStringAsync($"https://{Consts.WabbajackCacheHostname}/jobs/enqueue_job/{jobtype}");
}
public static async Task<string> UpdateNexusCache()
{
return await RunJob("GetNexusUpdatesJob");
}
public static async Task<string> UpdateServerModLists()
{
return await RunJob("UpdateModLists");
}
}
}

View File

@ -10,10 +10,12 @@ using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using Alphaleonis.Win32.Filesystem;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed;
using Wabbajack.Lib;
@ -45,6 +47,7 @@ namespace Wabbajack
public ICommand CopyVersionCommand { get; }
public ICommand ShowLoginManagerVM { get; }
public ICommand OpenSettingsCommand { get; }
public ICommand OpenTerminalCommand { get; }
public string VersionDisplay { get; }
@ -138,6 +141,8 @@ namespace Wabbajack
.Select(active => !SettingsPane.IsValueCreated || !object.ReferenceEquals(active, SettingsPane.Value)),
execute: () => NavigateTo(SettingsPane.Value));
OpenTerminalCommand = ReactiveCommand.Create(() => OpenTerminal());
// Latch onto update events and update GUI
AutoUpdater.CheckForUpdateEvent += (args) =>
{
@ -154,6 +159,16 @@ namespace Wabbajack
});
}
private void OpenTerminal()
{
var process = new ProcessStartInfo
{
FileName = "cmd.exe",
WorkingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
};
Process.Start(process);
}
private static bool IsStartingFromModlist(out string modlistPath)
{
if (CLIArguments.InstallPath == null)

View File

@ -70,6 +70,15 @@
Height="17"
Kind="Settings" />
</Button>
<Button
Grid.Column="1"
Margin="5,0"
Command="{Binding OpenTerminalCommand}">
<icon:PackIconMaterial
Width="17"
Height="17"
Kind="Console" />
</Button>
</mahapps:WindowCommands>
</mahapps:MetroWindow.RightWindowCommands>
</mahapps:MetroWindow>