feat: reintroduce tag command
Signed-off-by: seth <getchoo@tuta.io>
This commit is contained in:
parent
a8eb4a212a
commit
30cc4a6220
12 changed files with 256 additions and 10 deletions
37
Cargo.lock
generated
37
Cargo.lock
generated
|
@ -548,6 +548,18 @@ version = "0.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gray_matter"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cf2fb99fac0b821a4e61c61abff076324bb0e5c3b4a83815bbc3518a38971ad"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"toml",
|
||||||
|
"yaml-rust",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.22"
|
version = "0.3.22"
|
||||||
|
@ -807,6 +819,12 @@ version = "0.2.150"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
@ -1209,6 +1227,7 @@ dependencies = [
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"gray_matter",
|
||||||
"log",
|
"log",
|
||||||
"octocrab",
|
"octocrab",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -1885,6 +1904,15 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.4.13"
|
version = "0.4.13"
|
||||||
|
@ -2411,6 +2439,15 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
|
|
@ -5,8 +5,14 @@ edition = "2021"
|
||||||
repository = "https://github.com/PrismLauncher/refraction"
|
repository = "https://github.com/PrismLauncher/refraction"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[build-dependencies]
|
||||||
|
gray_matter = "0.2.6"
|
||||||
|
poise = "0.5.7"
|
||||||
|
serde = "1.0.193"
|
||||||
|
serde_json = "1.0.108"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
color-eyre = "0.6.2"
|
color-eyre = "0.6.2"
|
||||||
|
|
121
build.rs
Normal file
121
build.rs
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::{env, fs};
|
||||||
|
|
||||||
|
use gray_matter::{engine, Matter};
|
||||||
|
|
||||||
|
include!("src/tags.rs");
|
||||||
|
|
||||||
|
/// generate the ChoiceParameter enum and tag data we will use in the `tag` command
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn main() {
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
let generated = Path::new(&out_dir).join("generated.rs");
|
||||||
|
|
||||||
|
let tag_files: Vec<String> = fs::read_dir(TAG_DIR)
|
||||||
|
.unwrap()
|
||||||
|
.map(|f| f.unwrap().file_name().to_string_lossy().to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let tags: Vec<Tag> = tag_files
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.map(|name| {
|
||||||
|
let file_name = format!("{TAG_DIR}/{name}");
|
||||||
|
let content = fs::read_to_string(&file_name).unwrap();
|
||||||
|
|
||||||
|
let matter = Matter::<engine::YAML>::new();
|
||||||
|
let frontmatter: TagFrontmatter = matter
|
||||||
|
.parse(&content)
|
||||||
|
.data
|
||||||
|
.unwrap()
|
||||||
|
.deserialize()
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
// actually handling the error since this is the most likely thing to fail -getchoo
|
||||||
|
panic!(
|
||||||
|
"Failed to parse file {file_name}! Here's what it looked like:\n{content}\n\nReported Error:\n{e}\n",
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
Tag {
|
||||||
|
content,
|
||||||
|
file_name: name,
|
||||||
|
frontmatter,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let aliases: HashMap<String, Vec<String>> = tags
|
||||||
|
.iter()
|
||||||
|
.filter_map(|t| {
|
||||||
|
t.frontmatter
|
||||||
|
.aliases
|
||||||
|
.clone()
|
||||||
|
.map(|aliases| (t.file_name.clone(), aliases))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let formatted_names: Vec<String> = tags
|
||||||
|
.iter()
|
||||||
|
.flat_map(|t| {
|
||||||
|
let mut res = Vec::from([t.file_name.replace(".md", "").replace('-', "_")]);
|
||||||
|
if let Some(tag_aliases) = aliases.get(&t.file_name) {
|
||||||
|
res.append(&mut tag_aliases.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let tag_choice = format!(
|
||||||
|
r#"
|
||||||
|
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
|
||||||
|
#[derive(Clone, Debug, poise::ChoiceParameter)]
|
||||||
|
pub enum TagChoice {{
|
||||||
|
{}
|
||||||
|
}}"#,
|
||||||
|
formatted_names.join(",\n")
|
||||||
|
);
|
||||||
|
|
||||||
|
let to_str = format!(
|
||||||
|
r#"
|
||||||
|
impl TagChoice {{
|
||||||
|
fn as_str(&self) -> &str {{
|
||||||
|
match &self {{
|
||||||
|
{}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
"#,
|
||||||
|
formatted_names
|
||||||
|
.iter()
|
||||||
|
.map(|n| {
|
||||||
|
let file_name = n.replace('_', "-") + ".md";
|
||||||
|
|
||||||
|
// assume this is an alias if we can't match the file name
|
||||||
|
let name = if tag_files.contains(&file_name) {
|
||||||
|
file_name
|
||||||
|
} else {
|
||||||
|
aliases
|
||||||
|
.iter()
|
||||||
|
.find(|a| a.1.contains(n))
|
||||||
|
.unwrap()
|
||||||
|
.0
|
||||||
|
.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
format!("Self::{n} => \"{name}\",")
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("\n")
|
||||||
|
);
|
||||||
|
|
||||||
|
let contents = Vec::from([tag_choice, to_str]).join("\n\n");
|
||||||
|
|
||||||
|
fs::write(generated, contents).unwrap();
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-env=TAGS={}",
|
||||||
|
// make sure we can deserialize with env! at runtime
|
||||||
|
serde_json::to_string(&tags).unwrap()
|
||||||
|
);
|
||||||
|
}
|
|
@ -3,9 +3,11 @@ mod members;
|
||||||
mod rory;
|
mod rory;
|
||||||
mod say;
|
mod say;
|
||||||
mod stars;
|
mod stars;
|
||||||
|
mod tag;
|
||||||
|
|
||||||
pub use joke::joke;
|
pub use joke::joke;
|
||||||
pub use members::members;
|
pub use members::members;
|
||||||
pub use rory::rory;
|
pub use rory::rory;
|
||||||
pub use say::say;
|
pub use say::say;
|
||||||
pub use stars::stars;
|
pub use stars::stars;
|
||||||
|
pub use tag::tag;
|
||||||
|
|
57
src/commands/general/tag.rs
Normal file
57
src/commands/general/tag.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#![allow(non_camel_case_types, clippy::upper_case_acronyms)]
|
||||||
|
use crate::tags::Tag;
|
||||||
|
use crate::{consts, Context};
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use color_eyre::eyre::{eyre, Result};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use poise::serenity_prelude::{Color, User};
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/generated.rs"));
|
||||||
|
static TAGS: Lazy<Vec<Tag>> = Lazy::new(|| serde_json::from_str(env!("TAGS")).unwrap());
|
||||||
|
|
||||||
|
/// Send a tag
|
||||||
|
#[poise::command(slash_command)]
|
||||||
|
pub async fn tag(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "the copypasta you want to send"] name: TagChoice,
|
||||||
|
user: Option<User>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let tag_file = name.as_str();
|
||||||
|
let tag = TAGS
|
||||||
|
.iter()
|
||||||
|
.find(|t| t.file_name == tag_file)
|
||||||
|
.ok_or_else(|| eyre!("Tried to get non-existent tag: {tag_file}"))?;
|
||||||
|
|
||||||
|
let frontmatter = &tag.frontmatter;
|
||||||
|
|
||||||
|
ctx.send(|m| {
|
||||||
|
if let Some(user) = user {
|
||||||
|
m.content(format!("<@{}>", user.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
m.embed(|e| {
|
||||||
|
if let Some(color) = &frontmatter.color {
|
||||||
|
let color = *consts::COLORS
|
||||||
|
.get(color.as_str())
|
||||||
|
.unwrap_or(&Color::default());
|
||||||
|
e.color(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(image) = &frontmatter.image {
|
||||||
|
e.image(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fields) = &frontmatter.fields {
|
||||||
|
for field in fields {
|
||||||
|
e.field(&field.name, &field.value, field.inline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ pub fn to_global_commands() -> Vec<Command<Data, Report>> {
|
||||||
general::rory(),
|
general::rory(),
|
||||||
general::say(),
|
general::say(),
|
||||||
general::stars(),
|
general::stars(),
|
||||||
|
general::tag(),
|
||||||
moderation::ban_user(),
|
moderation::ban_user(),
|
||||||
moderation::kick_user(),
|
moderation::kick_user(),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use poise::serenity_prelude::Color;
|
||||||
|
|
||||||
pub static COLORS: Lazy<HashMap<&str, (u8, u8, u8)>> = Lazy::new(|| {
|
pub static COLORS: Lazy<HashMap<&str, Color>> = Lazy::new(|| {
|
||||||
HashMap::from([
|
HashMap::from([
|
||||||
("red", (239, 68, 68)),
|
("red", Color::from((239, 68, 68))),
|
||||||
("green", (34, 197, 94)),
|
("green", Color::from((34, 197, 94))),
|
||||||
("blue", (96, 165, 250)),
|
("blue", Color::from((96, 165, 250))),
|
||||||
("yellow", (253, 224, 71)),
|
("yellow", Color::from((253, 224, 71))),
|
||||||
("orange", (251, 146, 60)),
|
("orange", Color::from((251, 146, 60))),
|
||||||
])
|
])
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ mod eta;
|
||||||
pub async fn handle(
|
pub async fn handle(
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
event: &Event<'_>,
|
event: &Event<'_>,
|
||||||
framework: FrameworkContext<'_, Data, Report>,
|
_framework: FrameworkContext<'_, Data, Report>,
|
||||||
data: &Data,
|
_data: &Data,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match event {
|
match event {
|
||||||
Event::Ready { data_about_bot } => {
|
Event::Ready { data_about_bot } => {
|
||||||
|
|
|
@ -12,6 +12,7 @@ mod commands;
|
||||||
mod config;
|
mod config;
|
||||||
mod consts;
|
mod consts;
|
||||||
mod handlers;
|
mod handlers;
|
||||||
|
mod tags;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
type Context<'a> = poise::Context<'a, Data, Report>;
|
type Context<'a> = poise::Context<'a, Data, Report>;
|
||||||
|
|
21
src/tags.rs
Normal file
21
src/tags.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use poise::serenity_prelude::EmbedField;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const TAG_DIR: &str = "tags";
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct TagFrontmatter {
|
||||||
|
pub title: String,
|
||||||
|
pub aliases: Option<Vec<String>>,
|
||||||
|
pub color: Option<String>,
|
||||||
|
pub image: Option<String>,
|
||||||
|
pub fields: Option<Vec<EmbedField>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Tag {
|
||||||
|
pub content: String,
|
||||||
|
pub file_name: String,
|
||||||
|
pub frontmatter: TagFrontmatter,
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Can I install/download FTB packs directly from Prism?
|
title: Can I install/download FTB packs directly from Prism?
|
||||||
color: orange
|
color: orange
|
||||||
aliases: ['FTB']
|
|
||||||
---
|
---
|
||||||
|
|
||||||
You cannot download FTB packs directly from Prism Launcher.
|
You cannot download FTB packs directly from Prism Launcher.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: Upload Logs
|
title: Upload Logs
|
||||||
color: orange
|
color: orange
|
||||||
aliases: ['sendlog', 'logs', '🪵']
|
aliases: ['sendlog', 'logs']
|
||||||
image: https://cdn.discordapp.com/attachments/1031694870756204566/1156971972232740874/image.png
|
image: https://cdn.discordapp.com/attachments/1031694870756204566/1156971972232740874/image.png
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue