added edit faq command
This commit is contained in:
parent
7c3e66f513
commit
56f28d5891
2 changed files with 106 additions and 23 deletions
|
|
@ -1,7 +1,10 @@
|
||||||
|
use std::string;
|
||||||
|
|
||||||
use crate::{Context, Error};
|
use crate::{Context, Error};
|
||||||
use futures::{Stream, StreamExt};
|
use futures::{Stream, StreamExt};
|
||||||
use poise::CreateReply;
|
use poise::CreateReply;
|
||||||
use serenity::all::{CreateEmbed};
|
use rusqlite::Connection;
|
||||||
|
use serenity::all::CreateEmbed;
|
||||||
|
|
||||||
// Define your FAQ struct
|
// Define your FAQ struct
|
||||||
struct Faq {
|
struct Faq {
|
||||||
|
|
@ -10,6 +13,21 @@ 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) -> Result<bool, Error> {
|
||||||
|
let exists: bool = conn.query_row(
|
||||||
|
"SELECT EXISTS(SELECT 1 FROM faqs WHERE title = ?)",
|
||||||
|
[faq],
|
||||||
|
|row| row.get(0),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(exists)
|
||||||
|
}
|
||||||
|
|
||||||
async fn autocomplete_faq_titles<'a>(
|
async fn autocomplete_faq_titles<'a>(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
partial: &'a str,
|
partial: &'a str,
|
||||||
|
|
@ -43,12 +61,12 @@ async fn autocomplete_faq_titles<'a>(
|
||||||
.map(|faq| faq.title)
|
.map(|faq| faq.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[poise::command(slash_command, subcommands("view", "add"))]
|
#[poise::command(slash_command, subcommands("view", "add", "edit"))]
|
||||||
pub async fn faq(_ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn faq(_ctx: Context<'_>) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// View messages
|
/// View FAQ
|
||||||
#[poise::command(prefix_command, slash_command)]
|
#[poise::command(prefix_command, slash_command)]
|
||||||
pub async fn view(
|
pub async fn view(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
|
|
@ -60,7 +78,10 @@ pub async fn view(
|
||||||
|
|
||||||
let faqs = data
|
let faqs = data
|
||||||
.execute_db(move |conn| {
|
.execute_db(move |conn| {
|
||||||
let mut stmt = conn.prepare(&format!("SELECT ID, title, description FROM faqs WHERE title='{}'", &faq_title))?;
|
let mut stmt = conn.prepare(&format!(
|
||||||
|
"SELECT ID, title, description FROM faqs WHERE title='{}'",
|
||||||
|
&faq_title
|
||||||
|
))?;
|
||||||
|
|
||||||
let faqs: Vec<Faq> = stmt
|
let faqs: Vec<Faq> = stmt
|
||||||
.query_map([], |row| {
|
.query_map([], |row| {
|
||||||
|
|
@ -78,18 +99,17 @@ pub async fn view(
|
||||||
|
|
||||||
let faq = faqs.first().unwrap();
|
let faq = faqs.first().unwrap();
|
||||||
|
|
||||||
// Now you can use the faqs Vec
|
let embed_description = format_embed_description(&faq.description).expect("Format error");
|
||||||
// ctx.say(format!("# {}\n{}", faqs[0].title, faqs[0].description )).await?;
|
let embed = CreateEmbed::new()
|
||||||
|
.title(&faq.title)
|
||||||
// #131416 19,20,22
|
.description(embed_description);
|
||||||
let embed = CreateEmbed::new().title(&faq.title).description(&faq.description);
|
|
||||||
|
|
||||||
ctx.send(CreateReply::default().embed(embed)).await?;
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A subcommand of `parent`
|
/// Add FAQ
|
||||||
#[poise::command(
|
#[poise::command(
|
||||||
prefix_command,
|
prefix_command,
|
||||||
slash_command,
|
slash_command,
|
||||||
|
|
@ -100,19 +120,85 @@ pub async fn add(
|
||||||
#[description = "FAQ title"] title: String,
|
#[description = "FAQ title"] title: String,
|
||||||
#[description = "FAQ description"] description: String,
|
#[description = "FAQ description"] description: String,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let data = ctx.data();
|
let data: &crate::Data = ctx.data();
|
||||||
|
|
||||||
let result = data
|
let result = data
|
||||||
.execute_db(|conn| {
|
.execute_db({
|
||||||
conn.execute(
|
let title = title.clone();
|
||||||
"INSERT INTO faqs (title, description) VALUES (?1, ?2)",
|
let description = description.clone();
|
||||||
[title, description],
|
|conn| {
|
||||||
)
|
let exists = faq_exists(conn, &title).unwrap_or(false);
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
conn.execute(
|
||||||
|
"INSERT INTO faqs (title, description) VALUES (?1, ?2)",
|
||||||
|
[title, description],
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Now you can use the faqs Vec
|
let embed_description = format_embed_description(description).expect("Format error");
|
||||||
ctx.say(format!("{} rows affected", result)).await?;
|
|
||||||
|
if result == 1 {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Added FAQ: {}", &title))
|
||||||
|
.description(embed_description);
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
} else {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Error adding FAQ: {}", &title))
|
||||||
|
.description("Title already exists!");
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Edit FAQ
|
||||||
|
#[poise::command(
|
||||||
|
prefix_command,
|
||||||
|
slash_command,
|
||||||
|
required_permissions = "MANAGE_MESSAGES"
|
||||||
|
)]
|
||||||
|
pub async fn edit(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "FAQ Title"]
|
||||||
|
#[autocomplete = "autocomplete_faq_titles"]
|
||||||
|
title: String,
|
||||||
|
#[description = "FAQ description"] description: String,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let data = ctx.data();
|
||||||
|
|
||||||
|
let result = data
|
||||||
|
.execute_db({
|
||||||
|
let title = title.clone();
|
||||||
|
let description = description.clone();
|
||||||
|
move |conn| {
|
||||||
|
conn.execute(
|
||||||
|
"UPDATE faqs SET description = ?2 WHERE title = ?1",
|
||||||
|
[title, description],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let embed_description = format_embed_description(description).expect("Format error");
|
||||||
|
|
||||||
|
if result == 1 {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Edited FAQ: {}", &title))
|
||||||
|
.description(&embed_description);
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
} else {
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(format!("Error editing FAQ: {}", &title))
|
||||||
|
.description(format!("{} rows were affected", result));
|
||||||
|
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,8 @@ pub fn init_db(filename: &str) -> Result<Connection, rusqlite::Error> {
|
||||||
|
|
||||||
fn table_exists(conn: &Connection, table_name: &str) -> Result<bool> {
|
fn table_exists(conn: &Connection, table_name: &str) -> Result<bool> {
|
||||||
let exists: bool = conn.query_row(
|
let exists: bool = conn.query_row(
|
||||||
&format!(
|
"SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type='table' AND name=?1)",
|
||||||
"SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type='table' AND name='{}')",
|
[table_name],
|
||||||
table_name
|
|
||||||
),
|
|
||||||
[],
|
|
||||||
|row| row.get(0),
|
|row| row.get(0),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue