From cd8ed8bc5793985df2c1692072a932ceee517b95 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 8 Jul 2026 02:13:35 +0200 Subject: OPEN THE RUST GATES Signed-off-by: salmonik --- src/commands/qr.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/commands/qr.rs (limited to 'src/commands/qr.rs') diff --git a/src/commands/qr.rs b/src/commands/qr.rs new file mode 100644 index 0000000..26232ee --- /dev/null +++ b/src/commands/qr.rs @@ -0,0 +1,87 @@ +use poise::serenity_prelude as serenity; + +use crate::Data; +use crate::error::{Error, Result}; +use crate::lang; + +type Context<'a> = poise::Context<'a, Data, Error>; + +/// QR group +#[poise::command(slash_command, subcommands("dekodowanie", "generowanie",))] +pub async fn qr(_ctx: Context<'_>) -> Result<()> { + Ok(()) +} + +/// Generate a QR code from text +#[poise::command(slash_command)] +pub async fn generowanie( + ctx: Context<'_>, + #[description = "Zawartość kodu QR"] text: String, +) -> Result<()> { + ctx.defer().await?; + + let code = qrcode::QrCode::new(text.as_bytes())?; + let image = code.render::>().build(); + + let scaled = image::imageops::resize( + &image, + image.width() * 10, + image.height() * 10, + image::imageops::Nearest, + ); + + let mut buf = std::io::Cursor::new(Vec::new()); + scaled.write_to(&mut buf, image::ImageFormat::Png)?; + + ctx.send( + poise::CreateReply::default() + .content(lang::L_QR_GENERATED) + .attachment(serenity::CreateAttachment::bytes( + buf.into_inner(), + "qrcode.png", + )), + ) + .await?; + Ok(()) +} + +/// Decode a QR code from an uploaded image +#[poise::command(slash_command)] +pub async fn dekodowanie( + ctx: Context<'_>, + #[description = "Obraz zawierający kod QR"] image: serenity::Attachment, +) -> Result<()> { + ctx.defer().await?; + + let img_data = ctx + .data() + .http_client + .get(&image.url) + .send() + .await? + .bytes() + .await?; + let img = image::load_from_memory(&img_data)?; + let gray = img.to_luma8(); + + let decoded = decode_qr_simple(&gray); + match decoded { + Some(text) => { + ctx.say(lang::fmt_qr_decoded(&text)).await?; + } + None => { + ctx.say(lang::L_QR_DECODE_FAILED).await?; + } + } + Ok(()) +} + +fn decode_qr_simple(img: &image::ImageBuffer, Vec>) -> Option { + rxing::helpers::detect_in_luma(img.as_raw().to_vec(), img.width(), img.height(), None) + .ok() + .map(|r| r.getText().to_owned()) +} + +pub fn commands() -> Vec> { + vec![qr()] +} -- cgit v1.2.3