Merge remote-tracking branch 'origin/main' into blazor

This commit is contained in:
Unnoen 2022-01-20 19:35:27 +11:00
commit 3352657911
No known key found for this signature in database
GPG Key ID: 8F8E42252BA20553
8 changed files with 170 additions and 77 deletions

View File

@ -23,14 +23,6 @@ public class CommandLineBuilder
foreach (var verb in _verbs) foreach (var verb in _verbs)
root.Add(verb.MakeCommand()); root.Add(verb.MakeCommand());
/*
foreach (var verb in _verbs)
root.AddCommand(verb.MakeCommand());
var builder = new System.CommandLine.Builder.CommandLineBuilder(root);
var built = builder.Build();
var parsed = built.Parse(args);
return await parsed.InvokeAsync(_console);*/
return await root.InvokeAsync(args); return await root.InvokeAsync(args);
} }
} }

View File

@ -18,6 +18,8 @@ public class AppSettings
public string SpamWebHook { get; set; } = null; public string SpamWebHook { get; set; } = null;
public string HamWebHook { get; set; } = null; public string HamWebHook { get; set; } = null;
public string DiscordKey { get; set; }
public string AuthoredFilesFolder { get; set; } public string AuthoredFilesFolder { get; set; }
public string PatchesFilesFolder { get; set; } public string PatchesFilesFolder { get; set; }

View File

@ -1,73 +1,76 @@
using System; using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace Wabbajack.Server.DTOs; namespace Wabbajack.Server.DTOs;
public class DiscordMessage public class DiscordMessage
{ {
[JsonProperty("username")] public string UserName { get; set; } [JsonPropertyName("username")]
public string? UserName { get; set; }
[JsonProperty("avatar_url")] public Uri AvatarUrl { get; set; } [JsonPropertyName("avatar_url")]
public Uri? AvatarUrl { get; set; }
[JsonProperty("content")] public string Content { get; set; } [JsonPropertyName("content")]
public string? Content { get; set; }
[JsonProperty("embeds")] public DiscordEmbed[] Embeds { get; set; } [JsonPropertyName("embeds")]
public DiscordEmbed[]? Embeds { get; set; }
} }
public class DiscordEmbed public class DiscordEmbed
{ {
[JsonProperty("title")] public string Title { get; set; } [JsonPropertyName("title")] public string Title { get; set; }
[JsonProperty("color")] public int Color { get; set; } [JsonPropertyName("color")] public int Color { get; set; }
[JsonProperty("author")] public DiscordAuthor Author { get; set; } [JsonPropertyName("author")] public DiscordAuthor Author { get; set; }
[JsonProperty("url")] public Uri Url { get; set; } [JsonPropertyName("url")] public Uri Url { get; set; }
[JsonProperty("description")] public string Description { get; set; } [JsonPropertyName("description")] public string Description { get; set; }
[JsonProperty("fields")] public DiscordField Field { get; set; } [JsonPropertyName("fields")] public DiscordField Field { get; set; }
[JsonProperty("thumbnail")] public DiscordNumbnail Thumbnail { get; set; } [JsonPropertyName("thumbnail")] public DiscordThumbnail Thumbnail { get; set; }
[JsonProperty("image")] public DiscordImage Image { get; set; } [JsonPropertyName("image")] public DiscordImage Image { get; set; }
[JsonProperty("footer")] public DiscordFooter Footer { get; set; } [JsonPropertyName("footer")] public DiscordFooter Footer { get; set; }
[JsonProperty("timestamp")] public DateTime Timestamp { get; set; } = DateTime.UtcNow; [JsonPropertyName("timestamp")] public DateTime Timestamp { get; set; } = DateTime.UtcNow;
} }
public class DiscordAuthor public class DiscordAuthor
{ {
[JsonProperty("name")] public string Name { get; set; } [JsonPropertyName("name")] public string Name { get; set; }
[JsonProperty("url")] public Uri Url { get; set; } [JsonPropertyName("url")] public Uri Url { get; set; }
[JsonProperty("icon_url")] public Uri IconUrl { get; set; } [JsonPropertyName("icon_url")] public Uri IconUrl { get; set; }
} }
public class DiscordField public class DiscordField
{ {
[JsonProperty("name")] public string Name { get; set; } [JsonPropertyName("name")] public string Name { get; set; }
[JsonProperty("value")] public string Value { get; set; } [JsonPropertyName("value")] public string Value { get; set; }
[JsonProperty("inline")] public bool Inline { get; set; } [JsonPropertyName("inline")] public bool Inline { get; set; }
} }
public class DiscordNumbnail public class DiscordThumbnail
{ {
[JsonProperty("Url")] public Uri Url { get; set; } [JsonPropertyName("Url")] public Uri Url { get; set; }
} }
public class DiscordImage public class DiscordImage
{ {
[JsonProperty("Url")] public Uri Url { get; set; } [JsonPropertyName("Url")] public Uri Url { get; set; }
} }
public class DiscordFooter public class DiscordFooter
{ {
[JsonProperty("text")] public string Text { get; set; } [JsonPropertyName("text")] public string Text { get; set; }
[JsonProperty("icon_url")] public Uri icon_url { get; set; } [JsonPropertyName("icon_url")] public Uri icon_url { get; set; }
} }

View File

@ -0,0 +1,104 @@
using Discord;
using Discord.WebSocket;
using Microsoft.Extensions.Logging;
using Wabbajack.BuildServer;
namespace Wabbajack.Server.Services;
public class DiscordBackend
{
private readonly AppSettings _settings;
private readonly ILogger<DiscordBackend> _logger;
private readonly DiscordSocketClient _client;
private readonly NexusCacheManager _nexusCacheManager;
public DiscordBackend(ILogger<DiscordBackend> logger, AppSettings settings, NexusCacheManager nexusCacheManager)
{
_settings = settings;
_logger = logger;
_nexusCacheManager = nexusCacheManager;
_client = new DiscordSocketClient(new DiscordSocketConfig()
{
});
_client.Log += LogAsync;
_client.Ready += ReadyAsync;
_client.MessageReceived += MessageReceivedAsync;
Task.Run(async () =>
{
await _client.LoginAsync(TokenType.Bot, settings.DiscordKey);
await _client.StartAsync();
});
}
private async Task MessageReceivedAsync(SocketMessage arg)
{
_logger.LogInformation(arg.Content);
if (arg.Content.StartsWith("!dervenin"))
{
var parts = arg.Content.Split(" ", StringSplitOptions.RemoveEmptyEntries);
if (parts[0] != "!dervenin")
return;
if (parts.Length == 1)
{
await ReplyTo(arg, "Wat?");
}
if (parts[1] == "purge-nexus-cache")
{
if (parts.Length != 3)
{
await ReplyTo(arg, "Welp you did that wrong, gotta give me a mod-id or url");
return;
}
var rows = await _nexusCacheManager.Purge(parts[2]);
await ReplyTo(arg, $"Purged {rows} rows");
}
if (parts[1] == "nft")
{
await ReplyTo(arg, "No Fucking Thanks.");
}
}
}
private async Task ReplyTo(SocketMessage socketMessage, string message)
{
await socketMessage.Channel.SendMessageAsync(message);
}
private async Task ReadyAsync()
{
}
private async Task LogAsync(LogMessage arg)
{
switch (arg.Severity)
{
case LogSeverity.Info:
_logger.LogInformation(arg.Message);
break;
case LogSeverity.Warning:
_logger.LogWarning(arg.Message);
break;
case LogSeverity.Critical:
_logger.LogCritical(arg.Message);
break;
case LogSeverity.Error:
_logger.LogError(arg.Exception, arg.Message);
break;
case LogSeverity.Verbose:
_logger.LogTrace(arg.Message);
break;
case LogSeverity.Debug:
_logger.LogDebug(arg.Message);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}

View File

@ -34,12 +34,16 @@ public class DiscordWebHook : AbstractService<DiscordWebHook, int>
_client = client; _client = client;
_dtos = dtos; _dtos = dtos;
var message = new DiscordMessage Task.Run(async () =>
{ {
Content = $"\"{GetQuote()}\" - Sheogorath (as he brings the server online)"
}; var message = new DiscordMessage
var a = Send(Channel.Ham, message); {
var b = Send(Channel.Spam, message); Content = $"\"{await GetQuote()}\" - Sheogorath (as he brings the server online)"
};
await Send(Channel.Ham, message);
await Send(Channel.Spam, message);
});
} }
public async Task Send(Channel channel, DiscordMessage message) public async Task Send(Channel channel, DiscordMessage message)

View File

@ -145,4 +145,25 @@ public class NexusCacheManager
_lockObject.Release(); _lockObject.Release();
} }
} }
public async Task<int> Purge(string mod)
{
if (Uri.TryCreate(mod, UriKind.Absolute, out var url))
{
mod = Enumerable.Last(url.AbsolutePath.Split("/", StringSplitOptions.RemoveEmptyEntries));
}
var count = 0;
if (!int.TryParse(mod, out var mod_id)) return count;
foreach (var file in _cacheFolder.EnumerateFiles())
{
if (!file.FileName.ToString().Contains($"_{mod_id}")) continue;
await PurgeCacheEntry(file);
count++;
}
return count;
}
} }

View File

@ -1,33 +0,0 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Wabbajack.BuildServer;
using Wabbajack.Server.DTOs;
namespace Wabbajack.Server.Services;
public class Watchdog : AbstractService<Watchdog, int>
{
private readonly DiscordWebHook _discord;
public Watchdog(ILogger<Watchdog> logger, AppSettings settings, QuickSync quickSync, DiscordWebHook discordWebHook)
: base(logger, settings, quickSync, TimeSpan.FromMinutes(5))
{
_discord = discordWebHook;
}
public override async Task<int> Execute()
{
var report = await _quickSync.Report();
foreach (var service in report)
if (service.Value.LastRunTime != default && service.Value.LastRunTime >= service.Value.Delay * 4)
await _discord.Send(Channel.Spam,
new DiscordMessage
{
Content =
$"Service {service.Key.Name} has missed it's scheduled execution window. \n Current work: \n {string.Join("\n", service.Value.ActiveWork)}"
});
return report.Count;
}
}

View File

@ -68,7 +68,6 @@ public class Startup
services.AddSingleton<QuickSync>(); services.AddSingleton<QuickSync>();
services.AddSingleton<GlobalInformation>(); services.AddSingleton<GlobalInformation>();
services.AddSingleton<DiscordWebHook>(); services.AddSingleton<DiscordWebHook>();
services.AddSingleton<Watchdog>();
services.AddSingleton<Metrics>(); services.AddSingleton<Metrics>();
services.AddSingleton<HttpClient>(); services.AddSingleton<HttpClient>();
services.AddSingleton<AuthorFiles>(); services.AddSingleton<AuthorFiles>();
@ -76,6 +75,7 @@ public class Startup
services.AddSingleton<Client>(); services.AddSingleton<Client>();
services.AddSingleton<NexusCacheManager>(); services.AddSingleton<NexusCacheManager>();
services.AddSingleton<NexusApi>(); services.AddSingleton<NexusApi>();
services.AddSingleton<DiscordBackend>();
services.AddAllSingleton<ITokenProvider<NexusApiState>, NexusApiTokenProvider>(); services.AddAllSingleton<ITokenProvider<NexusApiState>, NexusApiTokenProvider>();
services.AddAllSingleton<IResource, IResource<HttpClient>>(s => new Resource<HttpClient>("Web Requests", 12)); services.AddAllSingleton<IResource, IResource<HttpClient>>(s => new Resource<HttpClient>("Web Requests", 12));
// Application Info // Application Info
@ -142,7 +142,6 @@ public class Startup
app.UseResponseCompression(); app.UseResponseCompression();
app.UseService<DiscordWebHook>(); app.UseService<DiscordWebHook>();
app.UseService<Watchdog>();
app.UseResponseCaching(); app.UseResponseCaching();
@ -178,6 +177,7 @@ public class Startup
app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
// Trigger the internal update code // Trigger the internal update code
var _ = app.ApplicationServices.GetRequiredService<NexusCacheManager>(); app.ApplicationServices.GetRequiredService<NexusCacheManager>();
app.ApplicationServices.GetRequiredService<DiscordBackend>();
} }
} }