html terminal
Diffstat (limited to 'src/bot/schematic.rs')
| -rw-r--r-- | src/bot/schematic.rs | 123 |
1 files changed, 57 insertions, 66 deletions
diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs index 41e6cd8..370e2cb 100644 --- a/src/bot/schematic.rs +++ b/src/bot/schematic.rs @@ -1,48 +1,67 @@ -use super::{strip_colors, Context, SUCCESS}; use anyhow::{anyhow, Result}; -use mindus::data::{DataRead, DataWrite}; +use mindus::data::DataRead; use mindus::*; use oxipng::*; use poise::serenity_prelude::*; use regex::Regex; -use std::borrow::Cow; -use std::path::Path; use std::sync::LazyLock; +use std::{borrow::Cow, ops::ControlFlow}; + +use super::{strip_colors, SUCCESS}; static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(```)?(\n)?([^`]+)(\n)?(```)?").unwrap()); -#[poise::command(context_menu_command = "Render schematic", category = "Info")] -/// draw schematic. -pub async fn context_draw(ctx: Context<'_>, msg: Message) -> Result<()> { - let _ = ctx.defer_or_broadcast().await; - - if let Some(a) = msg.attachments.get(0) - && let Some(e) = Path::new(&a.filename).extension() - && e == "msch" { +pub async fn from_attachments(attchments: &[Attachment]) -> Result<Option<Schematic<'_>>> { + for a in attchments { + if a.filename.ends_with("msch") { let s = a.download().await?; let mut s = DataRead::new(&s); - let s = Schematic::deserialize(&mut s).map_err(|e| anyhow!("invalid schematic: {e} with file {}", a.filename))?; - return send(&ctx, &s, false).await; + let Ok(s) = Schematic::deserialize(&mut s) else { + continue; + }; + return Ok(Some(s)); + } } - draw_impl(ctx, &msg.content, false).await + Ok(None) } -#[poise::command( - prefix_command, - slash_command, - category = "Info", - rename = "draw_schematic", - track_edits -)] -/// draw schematic. -pub async fn draw(ctx: Context<'_>, schematic: String) -> Result<()> { - let _ = ctx.defer_or_broadcast().await; - draw_impl(ctx, &schematic, true).await +pub async fn with(m: &Message, c: &serenity::client::Context) -> Result<ControlFlow<(), ()>> { + let send = |v| async move { + let p = to_png(&v); + let author = m.author_nick(c).await.unwrap_or(m.author.name.clone()); + m.channel_id + .send_message(c, |m| { + m.add_file(AttachmentType::Bytes { + data: Cow::Owned(p), + filename: "image.png".to_string(), + }) + .embed(|e| { + e.attachment("image.png"); + if let Some(d) = v.tags.get("description") { + e.description(d); + } + e.title(strip_colors(v.tags.get("name").unwrap())) + .footer(|f| f.text(format!("requested by {author}",))) + .color(SUCCESS) + }) + }) + .await?; + anyhow::Ok(()) + }; + + if let Ok(Some(v)) = from_attachments(&m.attachments).await { + send(v).await?; + return Ok(ControlFlow::Break(())); + } + if let Ok(v) = from_msg(&m.content) { + send(v).await?; + return Ok(ControlFlow::Break(())); + } + Ok(ControlFlow::Continue(())) } -async fn send(ctx: &Context<'_>, s: &Schematic<'_>, send_schematic: bool) -> Result<()> { - let n = strip_colors(s.tags.get("name").unwrap()); +pub fn to_png(s: &Schematic<'_>) -> Vec<u8> { let p = s.render(); let p = RawImage::new( p.width(), @@ -54,51 +73,23 @@ async fn send(ctx: &Context<'_>, s: &Schematic<'_>, send_schematic: bool) -> Res p.buffer, ) .unwrap(); - let p = p - .create_optimized_png(&oxipng::Options { - filter: indexset! { RowFilter::None }, - bit_depth_reduction: false, - color_type_reduction: false, - palette_reduction: false, - grayscale_reduction: false, - ..oxipng::Options::from_preset(0) - }) - .unwrap(); - poise::send_reply(*ctx, |m| { - if send_schematic { - let mut out = DataWrite::default(); - s.serialize(&mut out).unwrap(); - m.attachment(AttachmentType::Bytes { - data: Cow::Owned(out.consume()), - filename: "schem.msch".to_string(), - }); - } - m.attachment(AttachmentType::Bytes { - data: Cow::Owned(p), - filename: "image.png".to_string(), - }) - .embed(|e| { - if let Some(d) = s.tags.get("description") { - e.description(d); - } - if send_schematic { - e.attachment("schem.msch"); - } - e.title(n).attachment("image.png").color(SUCCESS) - }) + p.create_optimized_png(&oxipng::Options { + filter: indexset! { RowFilter::None }, + bit_depth_reduction: false, + color_type_reduction: false, + palette_reduction: false, + grayscale_reduction: false, + ..oxipng::Options::from_preset(0) }) - .await?; - Ok(()) + .unwrap() } -async fn draw_impl(ctx: Context<'_>, msg: &str, send_schematic: bool) -> Result<()> { +pub fn from_msg<'l>(msg: &str) -> Result<Schematic<'l>> { let schem_text = RE .captures(msg) .ok_or(anyhow!("couldnt find schematic"))? .get(3) .unwrap() .as_str(); - let s = Schematic::deserialize_base64(schem_text) - .map_err(|e| anyhow!("schematic deserializatiion failed: {e}"))?; - send(&ctx, &s, send_schematic).await + Ok(Schematic::deserialize_base64(schem_text)?) } |