smol bot
| -rw-r--r-- | src/bot/mod.rs | 42 | ||||
| -rw-r--r-- | src/bot/schematic.rs | 13 | ||||
| -rw-r--r-- | src/bot/search.rs | 30 |
3 files changed, 59 insertions, 26 deletions
diff --git a/src/bot/mod.rs b/src/bot/mod.rs index d2ca85b..a426c38 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -5,6 +5,7 @@ mod search; use anyhow::Result; use dashmap::DashMap; +use mindus::data::DataWrite; use mindus::Serializable; use poise::serenity_prelude::*; use serenity::futures::StreamExt; @@ -129,6 +130,32 @@ fn sep(x: Option<&Ch>) -> (Option<&'static str>, Option<String>) { (x.map(|x| x.d), x.map(|x| tags(x.labels))) } +#[poise::command(slash_command)] +pub async fn tag(c: Context<'_>) -> Result<()> { + if c.author().id != OWNER { + poise::say_reply(c, "access denied. this incident will be reported").await?; + return Ok(()); + } + c.defer().await?; + for (tags, schem) in SPECIAL.keys().filter_map(|&x| search::dir(x).map(move |y| y.map(move |y| (tags(SPECIAL[&x].labels), y)))).flatten() { + let mut s = search::load(&schem); + let mut v = DataWrite::default(); + s.tags.insert("labels".into(), tags); + s.serialize(&mut v)?; + std::fs::write(schem, v.consume())?; + } + send(&c, |x| { + x.avatar_url(CAT.to_string()).username("bendn <3").embed( + CreateEmbed::new() + .color(RM) + .description(format!("fixed tags :heart:")), + ) + }) + .await; + c.reply("fin").await?; + Ok(()) +} + const OWNER: u64 = 696196765564534825; #[poise::command(slash_command)] pub async fn scour(c: Context<'_>, ch: ChannelId) -> Result<()> { @@ -146,7 +173,9 @@ pub async fn scour(c: Context<'_>, ch: ChannelId) -> Result<()> { continue; }; if let Ok(Some(x)) = schematic::from((&msg.content, &msg.attachments)).await { - _ = std::fs::write(format!("repo/{d}/{:x}.msch", msg.id.get()), x.data); + let mut v = DataWrite::default(); + x.serialize(&mut v).unwrap(); + _ = std::fs::write(format!("repo/{d}/{:x}.msch", msg.id.get()), v.consume()); msg.react(c, emojis::get!(MERGE)).await?; n += 1; } @@ -190,6 +219,8 @@ where } mod git { + use mindus::data::DataWrite; + use self::schematic::Schem; use super::*; @@ -264,7 +295,9 @@ mod git { pub fn write(dir: &str, x: MessageId, s: Schem) { _ = std::fs::create_dir(format!("repo/{dir}")); - std::fs::write(path(dir, x), s.data).unwrap(); + let mut v = DataWrite::default(); + s.serialize(&mut v).unwrap(); + std::fs::write(path(dir, x), v.consume()).unwrap(); add(); } @@ -283,6 +316,7 @@ const RM: (u8, u8, u8) = (242, 121, 131); const AD: (u8, u8, u8) = (128, 191, 255); const CAT: &str = "https://cdn.discordapp.com/avatars/696196765564534825/6f3c605329ffb5cfb790343f59ed355d.webp"; + pub struct Bot; impl Bot { pub async fn spawn() { @@ -292,7 +326,7 @@ impl Bot { std::env::var("TOKEN").unwrap_or_else(|_| read_to_string("token").expect("wher token")); let f = poise::Framework::builder() .options(poise::FrameworkOptions { - commands: vec![logic::run(), help(), scour(), search::search() ,search::find(), search::file()], + commands: vec![logic::run(), help(), scour(), search::search(), search::find(), search::file(), tag()], event_handler: |c, e, _, d| { Box::pin(async move { match e { @@ -482,7 +516,7 @@ impl Bot { .setup(|ctx, _ready, _| { Box::pin(async move { poise::builtins::register_globally(ctx, &[logic::run(), help()]).await?; - poise::builtins::register_in_guild(ctx, &[search::search(), scour(), search::find(), search::file()], 925674713429184564.into()).await?; + poise::builtins::register_in_guild(ctx, &[tag(), search::search(), scour(), search::find(), search::file()], 925674713429184564.into()).await?; println!("registered"); let tracker = Arc::new(DashMap::new()); let tc = Arc::clone(&tracker); diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs index 1450b91..8e809e5 100644 --- a/src/bot/schematic.rs +++ b/src/bot/schematic.rs @@ -16,7 +16,6 @@ static RE: LazyLock<Regex> = pub struct Schem { schem: Schematic, - pub data: Vec<u8>, // work around bugs } impl Deref for Schem { @@ -36,7 +35,7 @@ pub async fn from_attachments(attchments: &[Attachment]) -> Result<Option<Schem> println!("failed to read {}", a.filename); continue; }; - return Ok(Some(Schem { schem: s, data: sd })); + return Ok(Some(Schem { schem: s })); // discord uploads base64 as a file when its too long } else if a.filename == "message.txt" { let Ok(s) = String::from_utf8(a.download().await?) else { @@ -54,10 +53,7 @@ pub async fn from_attachments(attchments: &[Attachment]) -> Result<Option<Schem> println!("failed to read msg.txt"); continue; }; - return Ok(Some(Schem { - schem: s, - data: buff, - })); + return Ok(Some(Schem { schem: s })); } } Ok(None) @@ -157,10 +153,7 @@ pub fn from_msg(msg: &str) -> Result<Option<Schem>> { buff.truncate(n_out); Schematic::deserialize(&mut DataRead::new(&buff)).map_err(anyhow::Error::from) })?; - Ok(Some(Schem { - schem: s, - data: buff, - })) + Ok(Some(Schem { schem: s })) } fn decode_tags(tags: &str) -> Vec<String> { diff --git a/src/bot/search.rs b/src/bot/search.rs index 28dac9a..4d0582d 100644 --- a/src/bot/search.rs +++ b/src/bot/search.rs @@ -116,27 +116,33 @@ pub async fn find( #[derive(Copy, Clone)] pub struct Data { - channel: u64, - message: u64, + pub channel: u64, + pub message: u64, +} + +pub fn dir(x: u64) -> Option<impl Iterator<Item = PathBuf>> { + std::fs::read_dir(Path::new("repo").join(super::SPECIAL[&x].d)) + .ok() + .map(|x| x.filter_map(Result::ok).map(move |f| f.path())) } pub fn files() -> impl Iterator<Item = (PathBuf, u64)> { super::SPECIAL - .entries() - .filter_map(|(&ch, &super::Ch { d: dir, .. })| { - std::fs::read_dir(Path::new("repo").join(dir)) - .ok() - .map(|x| (x, ch)) - }) - .map(|(fs, channel)| fs.filter_map(Result::ok).map(move |f| (f.path(), channel))) + .keys() + .filter_map(|&ch| dir(ch).map(|x| (x, ch))) + .map(|(fs, channel)| fs.map(move |f| (f, channel))) .flatten() } +pub fn load(f: &Path) -> Schematic { + let dat = std::fs::read(f).unwrap(); + let mut dat = DataRead::new(&dat); + Schematic::deserialize(&mut dat).unwrap() +} + pub fn schems() -> impl Iterator<Item = (Schematic, Data)> { files().map(|(f, channel)| { - let dat = std::fs::read(&f).unwrap(); - let mut dat = DataRead::new(&dat); - let ts = Schematic::deserialize(&mut dat).unwrap(); + let ts = load(&f); let x = f.file_name().unwrap().to_string_lossy(); ( ts, |