Refactor macros
This commit is contained in:
@ -17,7 +17,13 @@ pub async fn delete_macro(
|
||||
) -> Result<(), Error> {
|
||||
match sqlx::query!(
|
||||
"
|
||||
SELECT id FROM macro WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ?",
|
||||
SELECT m.id
|
||||
FROM macro m
|
||||
INNER JOIN guilds
|
||||
ON guilds.guild = m.guild_id
|
||||
WHERE guild = ?
|
||||
AND m.name = ?
|
||||
",
|
||||
ctx.guild_id().unwrap().get(),
|
||||
name
|
||||
)
|
||||
|
@ -28,11 +28,11 @@ pub async fn list_macro(ctx: Context<'_>) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn max_macro_page<U, E>(macros: &[CommandMacro<U, E>]) -> usize {
|
||||
pub fn max_macro_page(macros: &[CommandMacro]) -> usize {
|
||||
((macros.len() as f64) / 25.0).ceil() as usize
|
||||
}
|
||||
|
||||
pub fn show_macro_page<U, E>(macros: &[CommandMacro<U, E>], page: usize) -> CreateReply {
|
||||
pub fn show_macro_page(macros: &[CommandMacro], page: usize) -> CreateReply {
|
||||
let pager = MacroPager::new(page);
|
||||
|
||||
if macros.is_empty() {
|
||||
|
@ -1,229 +0,0 @@
|
||||
use lazy_regex::regex;
|
||||
use poise::{serenity_prelude::CommandOptionType, CreateReply};
|
||||
use regex::Captures;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use crate::{models::command_macro::RawCommandMacro, Context, Error, GuildId};
|
||||
|
||||
struct Alias {
|
||||
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 name, command FROM command_aliases WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)",
|
||||
guild_id.get()
|
||||
)
|
||||
.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.get(),
|
||||
cmd_macro.name,
|
||||
cmd_macro.description,
|
||||
cmd_macro.commands
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
|
||||
added_aliases += 1;
|
||||
}
|
||||
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
ctx.send(CreateReply::default().content(format!("Added {} macros.", added_aliases))).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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" {
|
||||
let matcher_primary = regex!(
|
||||
r#"(?P<time>.*?)(?:\s+)(?:send|say)(?:\s+)(?P<content>.*?)(?:(?:\s+)to(?:\s+)(?P<mentions>((?:<@\d+>)|(?:<@!\d+>)|(?:<#\d+>)|(?:\s+))+))?$"#s
|
||||
);
|
||||
let matcher_secondary = regex!(
|
||||
r#"(?P<msg>.*)(?:\s+)every(?:\s+)(?P<interval>.*?)(?:(?:\s+)(?:until|for)(?:\s+)(?P<expires>.*?))?$"#s
|
||||
);
|
||||
|
||||
match matcher_primary.captures(&args) {
|
||||
Some(captures) => {
|
||||
let captures_secondary = matcher_secondary.captures(&args);
|
||||
|
||||
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_secondary.as_ref().and_then(|c: &Captures| c.name("interval"))
|
||||
{
|
||||
let content = group.as_str();
|
||||
args.push(json!({
|
||||
"name": "interval",
|
||||
"value": content,
|
||||
"type": CommandOptionType::String,
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(group) =
|
||||
captures_secondary.and_then(|c: Captures| c.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 {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
None => None,
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ use crate::{Context, Error};
|
||||
|
||||
pub mod delete;
|
||||
pub mod list;
|
||||
pub mod migrate;
|
||||
pub mod record;
|
||||
pub mod run;
|
||||
|
||||
|
@ -112,7 +112,7 @@ pub async fn finish_macro(ctx: Context<'_>) -> Result<(), Error> {
|
||||
let lock = ctx.data().recording_macros.read().await;
|
||||
let contained = lock.get(&key);
|
||||
|
||||
if contained.map_or(true, |cmacro| cmacro.commands.is_empty()) {
|
||||
if contained.map_or(true, |r#macro| r#macro.commands.is_empty()) {
|
||||
ctx.send(
|
||||
CreateReply::default().embed(
|
||||
CreateEmbed::new()
|
||||
|
@ -1,7 +1,4 @@
|
||||
use poise::{
|
||||
serenity_prelude::{CommandOption, CreateEmbed},
|
||||
CreateReply,
|
||||
};
|
||||
use poise::{serenity_prelude::CreateEmbed, CreateReply};
|
||||
|
||||
use super::super::autocomplete::macro_name_autocomplete;
|
||||
use crate::{models::command_macro::guild_command_macro, Context, Data, Error, THEME_COLOR};
|
||||
@ -35,20 +32,7 @@ pub async fn run_macro(
|
||||
.await?;
|
||||
|
||||
for command in command_macro.commands {
|
||||
if let Some(action) = command.action {
|
||||
match (action)(poise::ApplicationContext { args: &command.options, ..ctx })
|
||||
.await
|
||||
{
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
println!("{:?}", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Context::Application(ctx)
|
||||
.say(format!("Command \"{}\" not found", command.command_name))
|
||||
.await?;
|
||||
}
|
||||
command.execute(poise::ApplicationContext { ..ctx }).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,15 +125,15 @@ pub async fn offset(
|
||||
if combined_time == 0 {
|
||||
ctx.say("Please specify one of `hours`, `minutes` or `seconds`").await?;
|
||||
} else {
|
||||
if let Some(guild) = ctx.guild() {
|
||||
let channels = guild
|
||||
if let Some(channels) = ctx.guild().map(|guild| {
|
||||
guild
|
||||
.channels
|
||||
.iter()
|
||||
.filter(|(_, channel)| channel.is_text_based())
|
||||
.map(|(id, _)| id.get().to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
|
||||
.join(",")
|
||||
}) {
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE reminders
|
||||
@ -224,9 +224,7 @@ pub async fn look(
|
||||
}),
|
||||
};
|
||||
|
||||
let channel_opt = ctx.channel_id().to_channel_cached(&ctx.cache());
|
||||
|
||||
let channel_id = if let Some(channel) = channel_opt {
|
||||
let channel_id = if let Some(channel) = ctx.channel_id().to_channel_cached(&ctx.cache()) {
|
||||
if Some(channel.guild_id) == ctx.guild_id() {
|
||||
flags.channel_id.unwrap_or_else(|| ctx.channel_id())
|
||||
} else {
|
||||
@ -795,17 +793,14 @@ fn create_response(
|
||||
),
|
||||
};
|
||||
|
||||
let mut embed = CreateEmbed::default();
|
||||
embed
|
||||
CreateEmbed::default()
|
||||
.title(format!(
|
||||
"{n} Reminder{s} Set",
|
||||
n = successes.len(),
|
||||
s = if successes.len() > 1 { "s" } else { "" }
|
||||
))
|
||||
.description(format!("{}\n\n{}", success_part, error_part))
|
||||
.color(*THEME_COLOR);
|
||||
|
||||
embed
|
||||
.color(*THEME_COLOR)
|
||||
}
|
||||
|
||||
fn parse_mention_list(mentions: &str) -> Vec<ReminderScope> {
|
||||
|
Reference in New Issue
Block a user