migration for $r commands

This commit is contained in:
jude
2022-08-14 16:22:00 +01:00
parent 25b84880a5
commit bb3386c4e8
7 changed files with 307 additions and 119 deletions

View File

@ -2,17 +2,19 @@ use std::collections::hash_map::Entry;
use chrono::offset::Utc;
use chrono_tz::{Tz, TZ_VARIANTS};
use lazy_regex::regex;
use levenshtein::levenshtein;
use poise::CreateReply;
use poise::{serenity_prelude::command::CommandOptionType, CreateReply};
use serde_json::{json, Value};
use crate::{
component_models::pager::{MacroPager, Pager},
consts::{EMBED_DESCRIPTION_MAX_LENGTH, THEME_COLOR},
models::{
command_macro::{guild_command_macro, CommandMacro},
command_macro::{guild_command_macro, CommandMacro, RawCommandMacro},
CtxData,
},
Context, Data, Error,
Context, Data, Error, GuildId,
};
async fn timezone_autocomplete(ctx: Context<'_>, partial: String) -> Vec<String> {
@ -576,3 +578,172 @@ pub fn show_macro_page<U, E>(macros: &[CommandMacro<U, E>], page: usize) -> Crea
reply
}
struct Alias {
id: u32,
guild_id: u32,
name: String,
command: String,
}
/// Migrate old $alias reminder commands to macros. Only macro names that are not taken will be used.
#[poise::command(
slash_command,
rename = "migrate",
guild_only = true,
default_member_permissions = "MANAGE_GUILD",
identifying_name = "migrate_macro"
)]
pub async fn migrate_macro(ctx: Context<'_>) -> Result<(), Error> {
let guild_id = ctx.guild_id().unwrap();
let mut transaction = ctx.data().database.begin().await?;
let aliases = sqlx::query_as!(
Alias,
"SELECT * FROM command_aliases WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)",
guild_id.0
)
.fetch_all(&mut transaction)
.await?;
let mut added_aliases = 0;
for alias in aliases {
match parse_text_command(guild_id, alias.name, &alias.command) {
Some(cmd_macro) => {
sqlx::query!(
"INSERT INTO macro (guild_id, name, description, commands) VALUES ((SELECT id FROM guilds WHERE guild = ?), ?, ?, ?)",
cmd_macro.guild_id.0,
cmd_macro.name,
cmd_macro.description,
cmd_macro.commands
)
.execute(&mut transaction)
.await?;
added_aliases += 1;
}
None => {}
}
}
transaction.commit().await?;
ctx.send(|b| b.content(format!("Added {} macros.", added_aliases))).await?;
Ok(())
}
// const REGEX_REMIND_COMMAND: Regex = RegexBuilder::new(
// r#"(?P<mentions>(?:<@\d+>\s+|<@!\d+>\s+|<#\d+>\s+)*)(?P<time>(?:(?:\d+)(?:s|m|h|d|:|/|-|))+)(?:\s+(?P<interval>(?:(?:\d+)(?:s|m|h|d|))+))?(?:\s+(?P<expires>(?:(?:\d+)(?:s|m|h|d|:|/|-|))+))?\s+(?P<content>.*)"#
// )
// .dot_matches_new_line(true)
// .build()
// .unwrap();
// const REGEX_NATURAL_COMMAND_1: Regex = RegexBuilder::new(
// r#"(?P<time>.*?)(?:\s+)(?:send|say)(?:\s+)(?P<msg>.*?)(?:(?:\s+)to(?:\s+)(?P<mentions>((?:<@\d+>)|(?:<@!\d+>)|(?:<#\d+>)|(?:\s+))+))?$"#
// )
// .dot_matches_new_line(true)
// .build()
// .unwrap();
// static REGEX_NATURAL_COMMAND_2: Regex = RegexBuilder::new(
// r#"(?P<msg>.*)(?:\s+)every(?:\s+)(?P<interval>.*?)(?:(?:\s+)(?:until|for)(?:\s+)(?P<expires>.*?))?$"#
// )
// .dot_matches_new_line(true)
// .build()
// .unwrap();
fn parse_text_command(
guild_id: GuildId,
alias_name: String,
command: &str,
) -> Option<RawCommandMacro> {
match command.split_once(" ") {
Some((command_word, args)) => {
let command_word = command_word.to_lowercase();
if command_word == "r"
|| command_word == "i"
|| command_word == "remind"
|| command_word == "interval"
{
let matcher = regex!(
r#"(?P<mentions>(?:<@\d+>\s+|<@!\d+>\s+|<#\d+>\s+)*)(?P<time>(?:(?:\d+)(?:s|m|h|d|:|/|-|))+)(?:\s+(?P<interval>(?:(?:\d+)(?:s|m|h|d|))+))?(?:\s+(?P<expires>(?:(?:\d+)(?:s|m|h|d|:|/|-|))+))?\s+(?P<content>.*)"#s
);
match matcher.captures(&args) {
Some(captures) => {
let mut args: Vec<Value> = vec![];
if let Some(group) = captures.name("time") {
let content = group.as_str();
args.push(json!({
"name": "time",
"value": content,
"type": CommandOptionType::String,
}));
}
if let Some(group) = captures.name("content") {
let content = group.as_str();
args.push(json!({
"name": "content",
"value": content,
"type": CommandOptionType::String,
}));
}
if let Some(group) = captures.name("interval") {
let content = group.as_str();
args.push(json!({
"name": "interval",
"value": content,
"type": CommandOptionType::String,
}));
}
if let Some(group) = captures.name("expires") {
let content = group.as_str();
args.push(json!({
"name": "expires",
"value": content,
"type": CommandOptionType::String,
}));
}
if let Some(group) = captures.name("mentions") {
let content = group.as_str();
args.push(json!({
"name": "channels",
"value": content,
"type": CommandOptionType::String,
}));
}
Some(RawCommandMacro {
guild_id,
name: alias_name,
description: None,
commands: json!([
{
"command_name": "remind",
"options": args,
}
]),
})
}
None => None,
}
// } else if command_word == "n" || command_word == "natural" {
} else {
None
}
}
None => None,
}
}