From e9c8fff7da595fb90b9e74075704e6247f29e740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sun, 22 Sep 2024 12:13:46 +0200 Subject: [PATCH] Show QR code after a burn paste has been created Since one can not visit the actual page (without deleting it) for one-time-pastes, there is no other way to get the QR code for URL of the created paste. --- src/pages.rs | 26 ++++++++++++++++++-------- src/routes/mod.rs | 6 +++--- src/routes/paste.rs | 14 ++++++++++++++ templates/burn.html | 6 ++++++ 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/pages.rs b/src/pages.rs index f610577..a1d9753 100644 --- a/src/pages.rs +++ b/src/pages.rs @@ -177,6 +177,15 @@ impl<'a> Encrypted<'a> { } } +/// Return module coordinates that are dark. +fn dark_modules(code: &qrcodegen::QrCode) -> Vec<(i32, i32)> { + let size = code.size(); + (0..size) + .flat_map(|x| (0..size).map(move |y| (x, y))) + .filter(|(x, y)| code.get_module(*x, *y)) + .collect() +} + /// Paste view showing the formatted paste as well as a bunch of links. #[derive(Template)] #[template(path = "qr.html", escape = "none")] @@ -202,32 +211,33 @@ impl<'a> Qr<'a> { } } - // Return module coordinates that are dark. fn dark_modules(&self) -> Vec<(i32, i32)> { - let size = self.code.size(); - (0..size) - .flat_map(|x| (0..size).map(move |y| (x, y))) - .filter(|(x, y)| self.code.get_module(*x, *y)) - .collect() + dark_modules(&self.code) } } /// Burn page shown if "burn-after-reading" was selected during insertion. #[derive(Template)] -#[template(path = "burn.html")] +#[template(path = "burn.html", escape = "none")] pub struct Burn<'a> { meta: &'a env::Metadata<'a>, base_path: &'static env::BasePath, id: String, + code: qrcodegen::QrCode, } impl<'a> Burn<'a> { /// Construct new burn page linking to `id`. - pub fn new(id: String) -> Self { + pub fn new(code: qrcodegen::QrCode, id: String) -> Self { Self { meta: &env::METADATA, base_path: &env::BASE_PATH, id, + code, } } + + fn dark_modules(&self) -> Vec<(i32, i32)> { + dark_modules(&self.code) + } } diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 1e4e9d8..9dba164 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,6 +1,6 @@ -use crate::pages::{Burn, Index}; +use crate::pages::Index; use crate::AppState; -use axum::extract::{Path, State}; +use axum::extract::State; use axum::routing::{get, Router}; mod assets; @@ -19,7 +19,7 @@ pub fn routes() -> Router { "/:id", get(paste::get).post(paste::get).delete(paste::delete), ) - .route("/burn/:id", get(|Path(id)| async { Burn::new(id) })) + .route("/burn/:id", get(paste::burn_created)) .route("/delete/:id", get(paste::delete)) .merge(assets::routes()) } diff --git a/src/routes/paste.rs b/src/routes/paste.rs index f454045..dd7dc8b 100644 --- a/src/routes/paste.rs +++ b/src/routes/paste.rs @@ -3,6 +3,7 @@ use crate::crypto::Password; use crate::db::read::Entry; use crate::env::BASE_PATH; use crate::highlight::Html; +use crate::pages::Burn; use crate::routes::{form, json}; use crate::{pages, AppState, Error}; use axum::body::Body; @@ -235,3 +236,16 @@ pub async fn delete( Ok(Redirect::to(BASE_PATH.path())) } + +pub async fn burn_created( + Path(id): Path, + headers: HeaderMap, + state: State, +) -> Result> { + let id_clone = id.clone(); + let qr_code = tokio::task::spawn_blocking(move || qr_code_from(state.0, &headers, &id)) + .await + .map_err(Error::from)??; + + Ok(Burn::new(qr_code, id_clone)) +} diff --git a/templates/burn.html b/templates/burn.html index d65e6ad..8e6b5bc 100644 --- a/templates/burn.html +++ b/templates/burn.html @@ -3,5 +3,11 @@

Copy and send this link. After opening it for the first time, it will be deleted.

+

+ + + + +

{% endblock %}