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"
|
||||
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]]
|
||||
name = "h2"
|
||||
version = "0.3.22"
|
||||
|
@ -807,6 +819,12 @@ version = "0.2.150"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.12"
|
||||
|
@ -1209,6 +1227,7 @@ dependencies = [
|
|||
"color-eyre",
|
||||
"dotenvy",
|
||||
"env_logger",
|
||||
"gray_matter",
|
||||
"log",
|
||||
"octocrab",
|
||||
"once_cell",
|
||||
|
@ -1885,6 +1904,15 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
|
@ -2411,6 +2439,15 @@ dependencies = [
|
|||
"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]]
|
||||
name = "zeroize"
|
||||
version = "1.7.0"
|
||||
|
|
|
@ -5,8 +5,14 @@ edition = "2021"
|
|||
repository = "https://github.com/PrismLauncher/refraction"
|
||||
license = "GPL-3.0-or-later"
|
||||
readme = "README.md"
|
||||
build = "build.rs"
|
||||
|
||||
# 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]
|
||||
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 say;
|
||||
mod stars;
|
||||
mod tag;
|
||||
|
||||
pub use joke::joke;
|
||||
pub use members::members;
|
||||
pub use rory::rory;
|
||||
pub use say::say;
|
||||
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::say(),
|
||||
general::stars(),
|
||||
general::tag(),
|
||||
moderation::ban_user(),
|
||||
moderation::kick_user(),
|
||||
]
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
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([
|
||||
("red", (239, 68, 68)),
|
||||
("green", (34, 197, 94)),
|
||||
("blue", (96, 165, 250)),
|
||||
("yellow", (253, 224, 71)),
|
||||
("orange", (251, 146, 60)),
|
||||
("red", Color::from((239, 68, 68))),
|
||||
("green", Color::from((34, 197, 94))),
|
||||
("blue", Color::from((96, 165, 250))),
|
||||
("yellow", Color::from((253, 224, 71))),
|
||||
("orange", Color::from((251, 146, 60))),
|
||||
])
|
||||
});
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ mod eta;
|
|||
pub async fn handle(
|
||||
ctx: &Context,
|
||||
event: &Event<'_>,
|
||||
framework: FrameworkContext<'_, Data, Report>,
|
||||
data: &Data,
|
||||
_framework: FrameworkContext<'_, Data, Report>,
|
||||
_data: &Data,
|
||||
) -> Result<()> {
|
||||
match event {
|
||||
Event::Ready { data_about_bot } => {
|
||||
|
|
|
@ -12,6 +12,7 @@ mod commands;
|
|||
mod config;
|
||||
mod consts;
|
||||
mod handlers;
|
||||
mod tags;
|
||||
mod utils;
|
||||
|
||||
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?
|
||||
color: orange
|
||||
aliases: ['FTB']
|
||||
---
|
||||
|
||||
You cannot download FTB packs directly from Prism Launcher.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Upload Logs
|
||||
color: orange
|
||||
aliases: ['sendlog', 'logs', '🪵']
|
||||
aliases: ['sendlog', 'logs']
|
||||
image: https://cdn.discordapp.com/attachments/1031694870756204566/1156971972232740874/image.png
|
||||
---
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue