add an ability to set bot configuration dynamically

This commit is contained in:
13xforever 2020-03-10 00:07:26 +05:00
parent 0a9774e89e
commit 14b678072c
4 changed files with 99 additions and 1 deletions

View File

@ -0,0 +1,76 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CompatBot.Commands.Attributes;
using CompatBot.Database;
using CompatBot.Database.Providers;
using CompatBot.Utils;
using DSharpPlus.CommandsNext;
using DSharpPlus.CommandsNext.Attributes;
using Microsoft.EntityFrameworkCore;
namespace CompatBot.Commands
{
internal partial class Sudo
{
public sealed partial class Bot
{
[Group("config"), RequiresBotSudoerRole]
[Description("Commands to set or clear bot configuration variables")]
public sealed partial class Configuration : BaseCommandModule
{
[Command("list"), Aliases("show")]
[Description("Lists set variable names")]
public async Task List(CommandContext ctx)
{
using var db = new BotDb();
var setVars = await db.BotState.AsNoTracking().Where(v => v.Key.StartsWith(SqlConfiguration.ConfigVarPrefix)).ToListAsync().ConfigureAwait(false);
if (setVars.Any())
{
var result = new StringBuilder("Set variables:").AppendLine();
foreach (var v in setVars)
result.AppendLine(v.Key[(SqlConfiguration.ConfigVarPrefix.Length)..]);
await ctx.RespondAsync(result.ToString()).ConfigureAwait(false);
}
else
await ctx.RespondAsync("No variables were set yet").ConfigureAwait(false);
}
[Command("set")]
[Description("Sets configuration variable")]
public async Task Set(CommandContext ctx, string key, [RemainingText] string value)
{
Config.inMemorySettings[key] = value;
key = SqlConfiguration.ConfigVarPrefix + key;
using var db = new BotDb();
var v = await db.BotState.Where(v => v.Key == key).FirstOrDefaultAsync().ConfigureAwait(false);
if (v == null)
{
v = new BotState {Key = key, Value = value};
db.BotState.Add(v);
}
else
v.Value = value;
await db.SaveChangesAsync().ConfigureAwait(false);
await ctx.ReactWithAsync(Config.Reactions.Success, "Set variable successfully").ConfigureAwait(false);
}
[Command("clear"), Aliases("unset", "remove")]
[Description("Removes configuration variable")]
public async Task Clear(CommandContext ctx, string key)
{
Config.inMemorySettings.TryRemove(key, out _);
key = SqlConfiguration.ConfigVarPrefix + key;
using var db = new BotDb();
var v = await db.BotState.Where(v => v.Key == key).FirstOrDefaultAsync().ConfigureAwait(false);
if (v != null)
{
db.BotState.Remove(v);
await db.SaveChangesAsync().ConfigureAwait(false);
}
await ctx.ReactWithAsync(Config.Reactions.Success, "Removed variable successfully").ConfigureAwait(false);
}
}
}
}
}

View File

@ -20,7 +20,7 @@ namespace CompatBot.Commands
[Group("bot"), Aliases("kot")]
[Description("Commands to manage the bot instance")]
public sealed class Bot: BaseCommandModuleCustom
public sealed partial class Bot: BaseCommandModuleCustom
{
[Command("version")]
[Description("Returns currently checked out bot commit")]

View File

@ -0,0 +1,19 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace CompatBot.Database.Providers
{
internal static class SqlConfiguration
{
internal const string ConfigVarPrefix = "ENV-";
public static async Task RestoreAsync()
{
using var db = new BotDb();
var setVars = await db.BotState.AsNoTracking().Where(v => v.Key.StartsWith(ConfigVarPrefix)).ToListAsync().ConfigureAwait(false);
foreach (var v in setVars)
Config.inMemorySettings[v.Key[(ConfigVarPrefix.Length)..]] = v.Value;
}
}
}

View File

@ -99,6 +99,9 @@ namespace CompatBot
if (!await DbImporter.UpgradeAsync(db, Config.Cts.Token))
return;
await SqlConfiguration.RestoreAsync().ConfigureAwait(false);
Config.Log.Debug("Restored configuration variables from persistent storage");
await StatsStorage.RestoreAsync().ConfigureAwait(false);
Config.Log.Debug("Restored stats from persistent storage");