From 6edf0fd93abf7e58b4c0974e3d3e54bcf8517946 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 8 Dec 2025 19:53:12 +0100 Subject: human-readable cache keys --- server/src/helper/asset.rs | 37 +++++++++++++++++++++++++++++++++++++ server/src/helper/mod.rs | 2 +- server/src/helper/picture.rs | 32 -------------------------------- server/src/ui/assets.rs | 17 ++++++++--------- 4 files changed, 46 insertions(+), 42 deletions(-) create mode 100644 server/src/helper/asset.rs delete mode 100644 server/src/helper/picture.rs (limited to 'server') diff --git a/server/src/helper/asset.rs b/server/src/helper/asset.rs new file mode 100644 index 0000000..244aa70 --- /dev/null +++ b/server/src/helper/asset.rs @@ -0,0 +1,37 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2025 metamuffin +*/ + +use crate::helper::A; +use jellycommon::Asset; +use rocket::{ + http::uri::fmt::{FromUriParam, Path, UriDisplay}, + request::{FromParam, FromSegments}, +}; +use std::fmt::Write; + +impl<'a> FromParam<'a> for A { + type Error = (); + fn from_param(param: &'a str) -> Result { + Ok(A(Asset(param.to_owned()))) + } +} +impl UriDisplay for A { + fn fmt(&self, f: &mut rocket::http::uri::fmt::Formatter<'_, Path>) -> std::fmt::Result { + write!(f, "{}", self.0 .0) + } +} +impl FromUriParam for A { + type Target = A; + fn from_uri_param(param: Asset) -> Self::Target { + A(param) + } +} +impl<'r> FromSegments<'r> for A { + type Error = (); + fn from_segments(segments: rocket::http::uri::Segments<'r, Path>) -> Result { + Ok(A(Asset(segments.collect::>().join("/")))) + } +} diff --git a/server/src/helper/mod.rs b/server/src/helper/mod.rs index 6d1c834..cf592d7 100644 --- a/server/src/helper/mod.rs +++ b/server/src/helper/mod.rs @@ -10,7 +10,7 @@ pub mod filter_sort; pub mod language; pub mod node_id; pub mod session; -pub mod picture; +pub mod asset; use crate::ui::error::{MyError, MyResult}; use accept::Accept; diff --git a/server/src/helper/picture.rs b/server/src/helper/picture.rs deleted file mode 100644 index d5887e3..0000000 --- a/server/src/helper/picture.rs +++ /dev/null @@ -1,32 +0,0 @@ -/* - This file is part of jellything (https://codeberg.org/metamuffin/jellything) - which is licensed under the GNU Affero General Public License (version 3); see /COPYING. - Copyright (C) 2025 metamuffin -*/ - -use crate::helper::A; -use jellycommon::Picture; -use rocket::{ - http::uri::fmt::{FromUriParam, Path, UriDisplay}, - request::FromParam, -}; -use std::fmt::Write; -use std::str::FromStr; - -impl<'a> FromParam<'a> for A { - type Error = (); - fn from_param(param: &'a str) -> Result { - Picture::from_str(param).map_err(|_| ()).map(A) - } -} -impl UriDisplay for A { - fn fmt(&self, f: &mut rocket::http::uri::fmt::Formatter<'_, Path>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} -impl FromUriParam for A { - type Target = A; - fn from_uri_param(param: Picture) -> Self::Target { - A(param) - } -} diff --git a/server/src/ui/assets.rs b/server/src/ui/assets.rs index d7663c3..6bc92ef 100644 --- a/server/src/ui/assets.rs +++ b/server/src/ui/assets.rs @@ -6,31 +6,29 @@ use super::error::MyResult; use crate::helper::{cache::CacheControlImage, A}; use anyhow::{anyhow, Context}; -use jellycache::{CacheContentType, CacheKey}; -use jellycommon::{api::NodeFilterSort, NodeID, Picture, PictureSlot}; +use jellycommon::{api::NodeFilterSort, Asset, NodeID, PictureSlot}; use jellylogic::{assets::get_node_thumbnail, node::get_node, session::Session}; use rocket::{get, http::ContentType, response::Redirect}; use std::str::FromStr; -pub const AVIF_QUALITY: f32 = 50.; +pub const AVIF_QUALITY: u32 = 50; pub const AVIF_SPEED: u8 = 5; -#[get("/image/?")] +#[get("/image/?")] pub async fn r_image( _session: A, - key: A, + key: A, size: Option, ) -> MyResult<(ContentType, CacheControlImage)> { let size = size.unwrap_or(2048); - let key = CacheKey(key.0 .0); - if !matches!(key.content_type(), CacheContentType::Image) { + if !key.0 .0.ends_with(".image") { Err(anyhow!("request to non-image"))? } // fit the resolution into a finite set so the maximum cache is finite too. let width = 2usize.pow(size.clamp(128, 2048).ilog2()); - let encoded = jellytranscoder::image::transcode(key, AVIF_QUALITY, AVIF_SPEED, width) + let encoded = jellytranscoder::image::transcode(&key.0 .0, AVIF_QUALITY, AVIF_SPEED, width) .context("transcoding asset")?; Ok((ContentType::AVIF, CacheControlImage(encoded))) @@ -49,8 +47,9 @@ pub async fn r_item_poster( .node .pictures .get(&slot) + .cloned() .ok_or(anyhow!("no pic todo"))?; - Ok(Redirect::permanent(rocket::uri!(r_image(*picture, size)))) + Ok(Redirect::permanent(rocket::uri!(r_image(picture, size)))) } #[get("/n//thumbnail?&")] -- cgit v1.3