Compare commits
No commits in common. "d24cc900d0edcabf07e95cd9413109beae068776" and "46c92f5a5954e205ef24b19c51db427c4748e226" have entirely different histories.
d24cc900d0
...
46c92f5a59
8 changed files with 29 additions and 396 deletions
|
|
@ -1,46 +0,0 @@
|
|||
name: CI
|
||||
|
||||
# pull_request_target always runs this file from the base branch. A pull request
|
||||
# cannot replace these steps, which is what `pull_request` would allow after
|
||||
# someone clicks Approve on a fork.
|
||||
#
|
||||
# Forks still are not compiled until a maintainer adds the `ci` label. `cargo
|
||||
# check` executes build scripts, so review Cargo.toml, Cargo.lock, build.rs,
|
||||
# and .cargo/config.toml before adding it. New commits do not reuse that label;
|
||||
# remove it and add it again after reviewing them.
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
|
||||
jobs:
|
||||
check:
|
||||
if: |
|
||||
forgejo.event.pull_request.head.repo.full_name == forgejo.repository ||
|
||||
(forgejo.event.action == 'label_updated' && forgejo.event.label.name == 'ci')
|
||||
runs-on: native
|
||||
steps:
|
||||
- name: Checkout pull request
|
||||
uses: https://data.forgejo.org/actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ forgejo.event.pull_request.head.repo.full_name }}
|
||||
ref: ${{ forgejo.event.pull_request.head.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Cargo check
|
||||
run: |
|
||||
docker run --rm \
|
||||
--read-only \
|
||||
--network bridge \
|
||||
--cap-drop ALL \
|
||||
--security-opt no-new-privileges \
|
||||
--pids-limit 512 \
|
||||
--memory 4g \
|
||||
--tmpfs /tmp:rw,exec,nosuid,nodev,size=2g \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-e CARGO_HOME=/tmp/cargo \
|
||||
-e CARGO_TARGET_DIR=/tmp/target \
|
||||
-e PATH=/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
-v "$PWD:/src:ro" \
|
||||
-w /src \
|
||||
rust:1.98-bookworm \
|
||||
cargo check --locked --manifest-path /src/Cargo.toml
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
pub mod faq;
|
||||
pub mod forum;
|
||||
pub mod info;
|
||||
pub mod lock;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::format::format_embed_description;
|
||||
use crate::{Context, Error};
|
||||
use futures::{Stream, StreamExt};
|
||||
use poise::CreateReply;
|
||||
|
|
@ -11,6 +10,11 @@ struct Faq {
|
|||
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> {
|
||||
let guild_id = guild_id.to_string();
|
||||
let exists: bool = conn.query_row(
|
||||
|
|
@ -90,32 +94,25 @@ pub async fn view(
|
|||
|
||||
move |conn| {
|
||||
let mut stmt = conn.prepare(
|
||||
"SELECT 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"
|
||||
)?;
|
||||
|
||||
let faqs: Vec<Faq> = stmt
|
||||
.query_map([&faq_title, &guild_id], |row| {
|
||||
Ok(Faq {
|
||||
title: row.get(0)?,
|
||||
description: row.get(1)?,
|
||||
// id: row.get(0)?,
|
||||
// guild_id: row.get(1)?,
|
||||
title: row.get(2)?,
|
||||
description: row.get(3)?,
|
||||
})
|
||||
})?
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(faqs)
|
||||
}
|
||||
})
|
||||
}})
|
||||
.await?;
|
||||
|
||||
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 faq = faqs.first().unwrap();
|
||||
|
||||
let embed_description = format_embed_description(&faq.description).expect("Format error");
|
||||
let embed = CreateEmbed::new()
|
||||
|
|
@ -146,7 +143,6 @@ pub async fn preview(
|
|||
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 id, guild_id, title, description FROM faqs WHERE title = ?1 AND guild_id = ?2"
|
||||
|
|
@ -167,20 +163,14 @@ pub async fn preview(
|
|||
}})
|
||||
.await?;
|
||||
|
||||
let faq = faqs.first().expect("FAQ not found");
|
||||
let embed_description = format_embed_description(&faq.description).expect("Format error");
|
||||
let faq = faqs.first().unwrap();
|
||||
|
||||
let embed = CreateEmbed::new()
|
||||
.title(format!("Title: {}", &faq.title))
|
||||
.description(format!(
|
||||
"\
|
||||
**Raw Text**\n\
|
||||
```\n\
|
||||
{}\
|
||||
```\n\
|
||||
**Preview:**\n\
|
||||
{}",
|
||||
&faq.description, embed_description
|
||||
// let embed_description = format_embed_description(&faq.description).expect("Format error");
|
||||
let embed = CreateEmbed::new().title(&faq.title).description(format!(
|
||||
"```
|
||||
{}
|
||||
```",
|
||||
&faq.description
|
||||
));
|
||||
|
||||
ctx.send(CreateReply::default().embed(embed)).await?;
|
||||
|
|
|
|||
|
|
@ -1,287 +0,0 @@
|
|||
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_description =
|
||||
format_embed_description(&lock_message.description).expect("Format error");
|
||||
|
||||
let embed = CreateEmbed::new()
|
||||
.title(format!("Title: {}", &lock_message.title))
|
||||
.description(format!(
|
||||
"\
|
||||
**Raw Text**\n\
|
||||
```\n\
|
||||
{}\
|
||||
```\n\
|
||||
**Preview:**\n\
|
||||
{}",
|
||||
&lock_message.description, embed_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,20 +62,6 @@ pub fn init_tables(conn: &Connection) -> Result<()> {
|
|||
.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
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use tokio::sync::Mutex;
|
|||
mod commands;
|
||||
mod database;
|
||||
mod events;
|
||||
mod utils;
|
||||
use crate::database::database::{init_db, init_tables};
|
||||
|
||||
// Types used by all command functions
|
||||
|
|
@ -90,7 +89,6 @@ async fn main() {
|
|||
commands::info::help(),
|
||||
commands::faq::faq(),
|
||||
commands::forum::forum(),
|
||||
commands::lock::lock(),
|
||||
],
|
||||
event_handler: |ctx, event, framework, data| {
|
||||
Box::pin(event_handler(ctx, event, framework, data))
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
pub mod format;
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
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