smol bot
-rw-r--r--src/bot/mod.rs93
-rw-r--r--src/bot/schematic.rs46
2 files changed, 58 insertions, 81 deletions
diff --git a/src/bot/mod.rs b/src/bot/mod.rs
index 98a398f..5428969 100644
--- a/src/bot/mod.rs
+++ b/src/bot/mod.rs
@@ -311,20 +311,20 @@ impl Bot {
match e {
FullEvent::Ready { .. } => {
println!("bot ready");
- // pruning
- // while SEEN.lock().await.len() < 5 {
- // tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
- // }
- // let mut x = SEEN.lock().await.clone().into_iter().collect::<Vec<_>>();
- // x.sort_by_key(|(_, x, _,_)|*x);
- // for (g, _, _ ,_ ) in x.iter().take_while(|(_, x, _,_)| *x <= 6).filter(|(_, _, _,x)| *x != OWNER) {
- // g.leave(&c).await.unwrap();
- // };
- // for (i, member_count, name, _) in x {
- // println!(
- // "{name} has {member_count:?} members {i:?}"
- // );
- // }
+ while SEEN.lock().await.len() < 5 {
+ tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
+ }
+ let mut x = SEEN.lock().await.clone().into_iter().collect::<Vec<_>>();
+ x.sort_by_key(|(_, x, _,_)|*x);
+ for (g, _, _ ,_ ) in x.iter().take_while(|(_, x, _,_)| *x <= 10).filter(|(_, _, _,x)| *x != OWNER) {
+ // println!()
+ // g.leave(&c).await.unwrap();
+ };
+ for (i, member_count, name, _) in x {
+ println!(
+ "{name} has {member_count:?} members {i:?}"
+ );
+ }
SEEN.lock().await.clear();
emojis::load(c.http()).await;
hookup(c.http()).await;
@@ -894,25 +894,19 @@ pub async fn ping(c: Context<'_>) -> Result<()> {
)]
/// Renders base64 schematic.
pub async fn render(c: Context<'_>, #[description = "schematic, base64"] s: String) -> Result<()> {
- let Ok(s) = schematic::from_b64(&s) else {
- poise::send_reply(
- c,
+ poise::send_reply(c,
+ match schematic::from_b64(&s) {
+ Ok(s) =>
+ schematic::reply(
+ s,
+ &c.author().name,
+ &c.author().avatar_url().unwrap_or(CAT.to_string()),
+ )
+ .await?,
+ Err(e) =>
CreateReply::default()
- .content("schem broken / not schem")
- .ephemeral(true),
- )
- .await?;
- return Ok(());
- };
- poise::send_reply(
- c,
- schematic::reply(
- s,
- &c.author().name,
- &c.author().avatar_url().unwrap_or(CAT.to_string()),
- )
- .await?,
- )
+ .content(format!("schem broken / not schem: {e}")),
+ })
.await?;
Ok(())
}
@@ -1001,26 +995,25 @@ async fn rename(c: Context<'_>, #[description = "schematic, base64"] s: String,
)]
/// Renders schematic inside a message.
pub async fn render_message(c: Context<'_>, m: Message) -> Result<()> {
- let Some(s) = schematic::from((&m.content, &m.attachments)).await? else {
- poise::send_reply(
- c,
+ poise::send_reply(
+ c, match schematic::from((&m.content, &m.attachments)).await {
+ Ok(Some(s)) =>
+ schematic::reply(
+ s,
+ &m.author_nick(c)
+ .await
+ .unwrap_or_else(|| m.author.name.clone()),
+ &m.author.avatar_url().unwrap_or(CAT.to_string()),
+ )
+ .await?,
+ Err(e) =>
+ CreateReply::default()
+ .content(format!("schematic error {e}")),
+ Ok(None) =>
CreateReply::default()
.content("no schem found")
- .ephemeral(true),
- )
- .await?;
- return Ok(());
- };
- poise::send_reply(
- c,
- schematic::reply(
- s,
- &m.author_nick(c)
- .await
- .unwrap_or_else(|| m.author.name.clone()),
- &m.author.avatar_url().unwrap_or(CAT.to_string()),
- )
- .await?,
+ .ephemeral(true)
+ }
)
.await?;
Ok(())
diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs
index bd61a85..7fc4023 100644
--- a/src/bot/schematic.rs
+++ b/src/bot/schematic.rs
@@ -2,6 +2,7 @@ use crate::emoji;
use anyhow::Result;
use base64::Engine;
use logos::Logos;
+use mindus::data::schematic::R64Error;
use mindus::data::DataRead;
use mindus::*;
use poise::{serenity_prelude::*, CreateReply};
@@ -12,8 +13,9 @@ use std::{fmt::Write, ops::Deref};
use super::{strip_colors, Msg, SUCCESS};
-static RE: LazyLock<Regex> =
- LazyLock::new(|| Regex::new(r"(```)?(\n)?([^`]+)(\n)?(```)?").unwrap());
+static RE: LazyLock<Regex> = LazyLock::new(|| {
+ Regex::new(r"(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?").unwrap()
+});
pub struct Schem {
pub schem: Schematic,
@@ -42,19 +44,8 @@ pub async fn from_attachments(attchments: &[Attachment]) -> Result<Option<Schem>
let Ok(s) = String::from_utf8(a.download().await?) else {
continue;
};
- let mut buff = vec![0; s.len() / 4 * 3 + 1];
- let Ok(s) = base64::engine::general_purpose::STANDARD
- .decode_slice(s.as_bytes(), &mut buff)
- .map_err(|_| ())
- .and_then(|n_out| {
- buff.truncate(n_out);
- Schematic::deserialize(&mut DataRead::new(&buff)).map_err(|_| ())
- })
- else {
- println!("failed to read msg.txt");
- continue;
- };
- return Ok(Some(Schem { schem: s }));
+ let schem = Schematic::deserialize_base64(&s)?;
+ return Ok(Some(Schem { schem }));
}
}
Ok(None)
@@ -170,32 +161,25 @@ pub fn to_png(s: &Schematic) -> Vec<u8> {
pub async fn from(m: (&str, &[Attachment])) -> Result<Option<Schem>> {
match from_msg(m.0) {
x @ Ok(Some(_)) => x,
+ // .or
_ => from_attachments(m.1).await,
}
}
pub fn from_msg(msg: &str) -> Result<Option<Schem>> {
- let schem_text = match RE.captures(msg) {
+ let schem_text = match RE
+ .captures_iter(msg)
+ .map(|x| x.get(0).unwrap().as_str())
+ .find(|x| x.starts_with("bXNjaA"))
+ {
None => return Ok(None),
Some(x) => x,
- }
- .get(3)
- .unwrap()
- .as_str()
- .trim();
+ };
Ok(Some(from_b64(schem_text)?))
}
-pub fn from_b64(schem_text: &str) -> Result<Schem> {
- let mut buff = vec![0; schem_text.len() / 4 * 3 + 1];
- let s = base64::engine::general_purpose::STANDARD
- .decode_slice(schem_text.as_bytes(), &mut buff)
- .map_err(anyhow::Error::from)
- .and_then(|n_out| {
- buff.truncate(n_out);
- Schematic::deserialize(&mut DataRead::new(&buff)).map_err(anyhow::Error::from)
- })?;
- Ok(Schem { schem: s })
+pub fn from_b64(schem_text: &str) -> std::result::Result<Schem, R64Error> {
+ Schematic::deserialize_base64(schem_text).map(|schem| Schem { schem })
}
fn decode_tags(tags: &str) -> Vec<String> {