Added .qimport and .qexport commands, fixed some response strings

This commit is contained in:
Kwoth
2021-12-11 15:27:32 +01:00
parent 02eb6e172b
commit 36c013fbb5
7 changed files with 164 additions and 5 deletions

View File

@@ -7,10 +7,13 @@ using NadekoBot.Db.Models;
using NadekoBot.Extensions;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using NadekoBot.Common.Yml;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using NadekoBot.Db;
using YamlDotNet.Serialization;
namespace NadekoBot.Modules.Utility
{
@@ -20,10 +23,12 @@ namespace NadekoBot.Modules.Utility
public class QuoteCommands : NadekoSubmodule
{
private readonly DbService _db;
private readonly IHttpClientFactory _http;
public QuoteCommands(DbService db)
public QuoteCommands(DbService db, IHttpClientFactory http)
{
_db = db;
_http = http;
}
[NadekoCommand, Aliases]
@@ -248,6 +253,140 @@ namespace NadekoBot.Modules.Utility
await ReplyConfirmLocalizedAsync(strs.quotes_deleted(Format.Bold(keyword.SanitizeAllMentions()))).ConfigureAwait(false);
}
public class ExportedQuote
{
public static ExportedQuote FromModel(Quote quote)
=> new ExportedQuote()
{
Id = ((kwum)quote.Id).ToString(),
An = quote.AuthorName,
Aid = quote.AuthorId,
Txt = quote.Text
};
public string Id { get; set; }
public string An { get; set; }
public ulong Aid { get; set; }
public string Txt { get; set; }
}
private const string _prependExport =
@"# Keys are keywords, Each key has a LIST of quotes in the following format:
# - id: Alphanumeric id used for commands related to the quote. (Note, when using .quotesimport, a new id will be generated.)
# an: Author name
# aid: Author id
# txt: Quote text
";
private static readonly ISerializer _exportSerializer = new SerializerBuilder()
.WithEventEmitter(args => new MultilineScalarFlowStyleEmitter(args))
.WithNamingConvention(YamlDotNet.Serialization.NamingConventions.CamelCaseNamingConvention.Instance)
.WithIndentedSequences()
.ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults)
.DisableAliases()
.Build();
[NadekoCommand, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.Administrator)]
public async Task QuotesExport()
{
IEnumerable<Quote> quotes;
using (var uow = _db.GetDbContext())
{
quotes = uow.Quotes
.GetForGuild(ctx.Guild.Id)
.ToList();
}
var crsDict = quotes
.GroupBy(x => x.Keyword)
.ToDictionary(x => x.Key, x => x.Select(ExportedQuote.FromModel));
var text = _prependExport + _exportSerializer
.Serialize(crsDict)
.UnescapeUnicodeCodePoints();
await using var stream = await text.ToStream();
await ctx.Channel.SendFileAsync(stream, "quote-export.yml", text: null);
}
[NadekoCommand, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.Administrator)]
[Ratelimit(300)]
#if GLOBAL_NADEKO
[OwnerOnly]
#endif
public async Task QuotesImport([Leftover]string input = null)
{
input = input?.Trim();
_ = ctx.Channel.TriggerTypingAsync();
if (input is null)
{
var attachment = ctx.Message.Attachments.FirstOrDefault();
if (attachment is null)
{
await ReplyErrorLocalizedAsync(strs.expr_import_no_input);
return;
}
using var client = _http.CreateClient();
input = await client.GetStringAsync(attachment.Url);
if (string.IsNullOrWhiteSpace(input))
{
await ReplyErrorLocalizedAsync(strs.expr_import_no_input);
return;
}
}
var succ = await ImportCrsAsync(ctx.Guild.Id, input);
if (!succ)
{
await ReplyErrorLocalizedAsync(strs.expr_import_invalid_data);
return;
}
await ctx.OkAsync();
}
public async Task<bool> ImportCrsAsync(ulong guildId, string input)
{
Dictionary<string, List<ExportedQuote>> data;
try
{
data = Yaml.Deserializer.Deserialize<Dictionary<string, List<ExportedQuote>>>(input);
if (data.Sum(x => x.Value.Count) == 0)
return false;
}
catch
{
return false;
}
await using var uow = _db.GetDbContext();
foreach (var entry in data)
{
var keyword = entry.Key;
await uow.Quotes
.AddRangeAsync(entry.Value
.Where(quote => !string.IsNullOrWhiteSpace(quote.Txt))
.Select(quote => new Quote()
{
GuildId = guildId,
Keyword = keyword,
Text = quote.Txt,
AuthorId = quote.Aid,
AuthorName = quote.An,
}));
}
await uow.SaveChangesAsync();
return true;
}
}
}
}