Merge pull request 'added lock commands' (#3) from feature/vibecoded-command into main
Reviewed-on: https://codeberg.org/RythonDev/portfolio-roast-bot/pulls/3
This commit is contained in:
commit
7a71fca30d
7 changed files with 331 additions and 23 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
pub mod faq;
|
pub mod faq;
|
||||||
pub mod forum;
|
pub mod forum;
|
||||||
pub mod info;
|
pub mod info;
|
||||||
|
pub mod lock;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::utils::format::format_embed_description;
|
||||||
use crate::{Context, Error};
|
use crate::{Context, Error};
|
||||||
use futures::{Stream, StreamExt};
|
use futures::{Stream, StreamExt};
|
||||||
use poise::CreateReply;
|
use poise::CreateReply;
|
||||||
|
|
@ -10,11 +11,6 @@ struct Faq {
|
||||||
description: String,
|
description: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_embed_description<S: Into<String>>(description: S) -> Result<String, Error> {
|
|
||||||
let string_val = description.into();
|
|
||||||
Ok(str::replace(&string_val, "\\n", "\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn faq_exists(conn: &Connection, faq: &str, guild_id: &u64) -> Result<bool, Error> {
|
fn faq_exists(conn: &Connection, faq: &str, guild_id: &u64) -> Result<bool, Error> {
|
||||||
let guild_id = guild_id.to_string();
|
let guild_id = guild_id.to_string();
|
||||||
let exists: bool = conn.query_row(
|
let exists: bool = conn.query_row(
|
||||||
|
|
@ -94,25 +90,32 @@ pub async fn view(
|
||||||
|
|
||||||
move |conn| {
|
move |conn| {
|
||||||
let mut stmt = conn.prepare(
|
let mut stmt = conn.prepare(
|
||||||
"SELECT id, guild_id, title, description FROM faqs WHERE title = ?1 AND guild_id = ?2"
|
"SELECT title, description FROM faqs WHERE title = ?1 AND guild_id = ?2",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let faqs: Vec<Faq> = stmt
|
let faqs: Vec<Faq> = stmt
|
||||||
.query_map([&faq_title, &guild_id], |row| {
|
.query_map([&faq_title, &guild_id], |row| {
|
||||||
Ok(Faq {
|
Ok(Faq {
|
||||||
// id: row.get(0)?,
|
title: row.get(0)?,
|
||||||
// guild_id: row.get(1)?,
|
description: row.get(1)?,
|
||||||
title: row.get(2)?,
|
|
||||||
description: row.get(3)?,
|
|
||||||
})
|
})
|
||||||
})?
|
})?
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
Ok(faqs)
|
Ok(faqs)
|
||||||
}})
|
}
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let faq = faqs.first().unwrap();
|
let Some(faq) = faqs.first() else {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title("Error 404")
|
||||||
|
.description("FAQ not found");
|
||||||
|
|
||||||
|
ctx.send(CreateReply::default().ephemeral(true).embed(embed))
|
||||||
|
.await?;
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
let embed_description = format_embed_description(&faq.description).expect("Format error");
|
let embed_description = format_embed_description(&faq.description).expect("Format error");
|
||||||
let embed = CreateEmbed::new()
|
let embed = CreateEmbed::new()
|
||||||
|
|
@ -143,6 +146,7 @@ pub async fn preview(
|
||||||
let server_guild_id = ctx.guild_id().expect("Guild ID not found");
|
let server_guild_id = ctx.guild_id().expect("Guild ID not found");
|
||||||
let guild_id = server_guild_id.to_string();
|
let guild_id = server_guild_id.to_string();
|
||||||
|
|
||||||
|
|
||||||
move |conn| {
|
move |conn| {
|
||||||
let mut stmt = conn.prepare(
|
let mut stmt = conn.prepare(
|
||||||
"SELECT id, guild_id, title, description FROM faqs WHERE title = ?1 AND guild_id = ?2"
|
"SELECT id, guild_id, title, description FROM faqs WHERE title = ?1 AND guild_id = ?2"
|
||||||
|
|
@ -163,9 +167,8 @@ pub async fn preview(
|
||||||
}})
|
}})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let faq = faqs.first().unwrap();
|
let faq = faqs.first().expect("FAQ not found");
|
||||||
|
|
||||||
// let embed_description = format_embed_description(&faq.description).expect("Format error");
|
|
||||||
let embed = CreateEmbed::new().title(&faq.title).description(format!(
|
let embed = CreateEmbed::new().title(&faq.title).description(format!(
|
||||||
"```
|
"```
|
||||||
{}
|
{}
|
||||||
|
|
|
||||||
281
src/commands/lock.rs
Normal file
281
src/commands/lock.rs
Normal file
|
|
@ -0,0 +1,281 @@
|
||||||
|
use crate::utils::format::format_embed_description;
|
||||||
|
use crate::{Context, Error};
|
||||||
|
use poise::CreateReply;
|
||||||
|
use rusqlite::Connection;
|
||||||
|
use serenity::all::CreateEmbed;
|
||||||
|
use serenity::builder::EditThread;
|
||||||
|
|
||||||
|
struct LockEmbed {
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lock_message_exists(conn: &Connection, guild_id: &u64) -> Result<bool, Error> {
|
||||||
|
let guild_id = guild_id.to_string();
|
||||||
|
let exists: bool = conn.query_row(
|
||||||
|
"SELECT EXISTS(SELECT 1 FROM lock WHERE guild_id = ?1)",
|
||||||
|
[&guild_id],
|
||||||
|
|row| row.get(0),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(exists)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[poise::command(
|
||||||
|
slash_command,
|
||||||
|
subcommands("vibecoded", "preview", "add", "edit", "delete"),
|
||||||
|
guild_only
|
||||||
|
)]
|
||||||
|
pub async fn lock(_ctx: Context<'_>) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Post the vibe coded slop embed message
|
||||||
|
#[poise::command(
|
||||||
|
prefix_command,
|
||||||
|
slash_command,
|
||||||
|
required_permissions = "MANAGE_MESSAGES" // mod only
|
||||||
|
)]
|
||||||
|
pub async fn vibecoded(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "additional comment"] comment_option: Option<String>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let data = ctx.data();
|
||||||
|
|
||||||
|
// lock thread, if it's a thread in a forum
|
||||||
|
|
||||||
|
// let thread_lock = EditThread::new().locked(true);
|
||||||
|
let mut channel = ctx.guild_channel().await.expect("Not a thread");
|
||||||
|
channel
|
||||||
|
.edit_thread(ctx, EditThread::new().locked(true))
|
||||||
|
.await
|
||||||
|
.expect("Failed to lock thread, check permissions");
|
||||||
|
|
||||||
|
let lock_messages = data
|
||||||
|
.execute_db({
|
||||||
|
let server_guild_id = ctx.guild_id().expect("Guild ID not found");
|
||||||
|
let guild_id = server_guild_id.to_string();
|
||||||
|
|
||||||
|
move |conn| {
|
||||||
|
let mut stmt =
|
||||||
|
conn.prepare("SELECT title, description FROM lock WHERE guild_id = ?1")?;
|
||||||
|
|
||||||
|
let lock_messages: Vec<LockEmbed> = stmt
|
||||||
|
.query_map([&guild_id], |row| {
|
||||||
|
Ok(LockEmbed {
|
||||||
|
title: row.get(0)?,
|
||||||
|
description: row.get(1)?,
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
Ok(lock_messages)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let Some(lock_message) = lock_messages.first() else {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title("Error 404")
|
||||||
|
.description("Lock message not found");
|
||||||
|
|
||||||
|
ctx.send(CreateReply::default().embed(embed).ephemeral(true))
|
||||||
|
.await?;
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut embed_description =
|
||||||
|
format_embed_description(&lock_message.description).expect("Format error");
|
||||||
|
if !comment_option.is_none() {
|
||||||
|
let comment = comment_option.expect("Comment error");
|
||||||
|
let new_description = format!(
|
||||||
|
"{}\n\n**Additional Comment(s)**\n{}",
|
||||||
|
&lock_message.description, comment
|
||||||
|
);
|
||||||
|
embed_description = format_embed_description(new_description).expect("Format error");
|
||||||
|
}
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(&lock_message.title)
|
||||||
|
.description(embed_description)
|
||||||
|
.color(0xff0000);
|
||||||
|
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add vibe coded slop embed message
|
||||||
|
#[poise::command(
|
||||||
|
prefix_command,
|
||||||
|
slash_command,
|
||||||
|
required_permissions = "MANAGE_MESSAGES" // mod only
|
||||||
|
)]
|
||||||
|
pub async fn add(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "Lock message title"] title: String,
|
||||||
|
#[description = "Lock message description"] description: String,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let data: &crate::Data = ctx.data();
|
||||||
|
|
||||||
|
let result = data
|
||||||
|
.execute_db({
|
||||||
|
let title = title.clone();
|
||||||
|
let description = description.clone();
|
||||||
|
|
||||||
|
let server_guild_id = ctx.guild_id().expect("Guild ID not found");
|
||||||
|
let guild_id = server_guild_id.get();
|
||||||
|
move |conn| {
|
||||||
|
let exists = lock_message_exists(conn, &guild_id).unwrap_or(false);
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
conn.execute(
|
||||||
|
"INSERT INTO lock (guild_id, title, description) VALUES (?1, ?2, ?3)",
|
||||||
|
[guild_id.to_string(), title, description],
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if result == 1 {
|
||||||
|
let embed_description = format_embed_description(description).expect("Format error");
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Added Lock Message: {}", &title))
|
||||||
|
.description(embed_description);
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
} else {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Error adding lock message: {}", &title))
|
||||||
|
.description("Lock message already exists!");
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Preview lock message
|
||||||
|
#[poise::command(
|
||||||
|
prefix_command,
|
||||||
|
slash_command,
|
||||||
|
required_permissions = "MANAGE_MESSAGES" // mod only
|
||||||
|
)]
|
||||||
|
pub async fn preview(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
|
let data = ctx.data();
|
||||||
|
|
||||||
|
let lock_messages = data
|
||||||
|
.execute_db({
|
||||||
|
let server_guild_id = ctx.guild_id().expect("Guild ID not found");
|
||||||
|
let guild_id = server_guild_id.to_string();
|
||||||
|
|
||||||
|
move |conn| {
|
||||||
|
let mut stmt =
|
||||||
|
conn.prepare("SELECT title, description FROM lock WHERE guild_id = ?1")?;
|
||||||
|
|
||||||
|
let lock_messages: Vec<LockEmbed> = stmt
|
||||||
|
.query_map([&guild_id], |row| {
|
||||||
|
Ok(LockEmbed {
|
||||||
|
title: row.get(0)?,
|
||||||
|
description: row.get(1)?,
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
Ok(lock_messages)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let lock_message = lock_messages.first().expect("Lock message not found");
|
||||||
|
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(&lock_message.title)
|
||||||
|
.description(format!(
|
||||||
|
"```
|
||||||
|
{}
|
||||||
|
```",
|
||||||
|
&lock_message.description
|
||||||
|
));
|
||||||
|
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Edit lock message
|
||||||
|
#[poise::command(
|
||||||
|
prefix_command,
|
||||||
|
slash_command,
|
||||||
|
required_permissions = "MANAGE_MESSAGES"
|
||||||
|
)]
|
||||||
|
pub async fn edit(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "Title"] title: String,
|
||||||
|
#[description = "Description"] description: String,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let data = ctx.data();
|
||||||
|
|
||||||
|
let result = data
|
||||||
|
.execute_db({
|
||||||
|
let title = title.clone();
|
||||||
|
let description = description.clone();
|
||||||
|
|
||||||
|
let server_guild_id = ctx.guild_id().expect("Guild ID not found");
|
||||||
|
let guild_id = server_guild_id.get();
|
||||||
|
|
||||||
|
move |conn| {
|
||||||
|
conn.execute(
|
||||||
|
"UPDATE lock SET description = ?3, title = ?2 WHERE guild_id = ?1",
|
||||||
|
[guild_id.to_string(), title, description],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let embed_description = format_embed_description(description).expect("Format error");
|
||||||
|
|
||||||
|
if result == 1 {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Edited lock message: {}", &title))
|
||||||
|
.description(&embed_description);
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
} else {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Error editing lock message: {}", &title))
|
||||||
|
.description(format!("{} rows were affected", result));
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete lock message
|
||||||
|
#[poise::command(
|
||||||
|
prefix_command,
|
||||||
|
slash_command,
|
||||||
|
required_permissions = "MANAGE_MESSAGES"
|
||||||
|
)]
|
||||||
|
pub async fn delete(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
|
let data = ctx.data();
|
||||||
|
let server_guild_id = ctx.guild_id().expect("Guild ID not found");
|
||||||
|
let guild_id = server_guild_id.to_string();
|
||||||
|
|
||||||
|
let result = data
|
||||||
|
.execute_db({
|
||||||
|
move |conn| conn.execute("DELETE FROM lock WHERE guild_id = ?1", [guild_id])
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if result == 1 {
|
||||||
|
let embed = CreateEmbed::new().title(format!("Deleted lock message for this server"));
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
} else {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Error deleting lock message, ask Ryan"))
|
||||||
|
.description(format!("{} rows were affected", result));
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -62,6 +62,20 @@ pub fn init_tables(conn: &Connection) -> Result<()> {
|
||||||
.expect("Forum Channels Table Creation error");
|
.expect("Forum Channels Table Creation error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lock_table_exists = table_exists(conn, "lock").expect("Lock table exists error");
|
||||||
|
if !lock_table_exists {
|
||||||
|
conn.execute(
|
||||||
|
"CREATE TABLE lock (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
guild_id TEXT NOT NULL UNIQUE,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
description TEXT NOT NULL
|
||||||
|
)",
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
.expect("Lock Table Creation error");
|
||||||
|
}
|
||||||
|
|
||||||
// if we need to create more tables we'll use this function
|
// if we need to create more tables we'll use this function
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use tokio::sync::Mutex;
|
||||||
mod commands;
|
mod commands;
|
||||||
mod database;
|
mod database;
|
||||||
mod events;
|
mod events;
|
||||||
|
mod utils;
|
||||||
use crate::database::database::{init_db, init_tables};
|
use crate::database::database::{init_db, init_tables};
|
||||||
|
|
||||||
// Types used by all command functions
|
// Types used by all command functions
|
||||||
|
|
@ -89,6 +90,7 @@ async fn main() {
|
||||||
commands::info::help(),
|
commands::info::help(),
|
||||||
commands::faq::faq(),
|
commands::faq::faq(),
|
||||||
commands::forum::forum(),
|
commands::forum::forum(),
|
||||||
|
commands::lock::lock(),
|
||||||
],
|
],
|
||||||
event_handler: |ctx, event, framework, data| {
|
event_handler: |ctx, event, framework, data| {
|
||||||
Box::pin(event_handler(ctx, event, framework, data))
|
Box::pin(event_handler(ctx, event, framework, data))
|
||||||
|
|
|
||||||
1
src/utils.rs
Normal file
1
src/utils.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod format;
|
||||||
6
src/utils/format.rs
Normal file
6
src/utils/format.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
use crate::Error;
|
||||||
|
|
||||||
|
pub fn format_embed_description<S: Into<String>>(description: S) -> Result<String, Error> {
|
||||||
|
let string_val = description.into();
|
||||||
|
Ok(str::replace(&string_val, "\\n", "\n"))
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue