diff options
Diffstat (limited to 'server/src/routes/ui/admin/mod.rs')
-rw-r--r-- | server/src/routes/ui/admin/mod.rs | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/server/src/routes/ui/admin/mod.rs b/server/src/routes/ui/admin/mod.rs index beb146b..6c206bd 100644 --- a/server/src/routes/ui/admin/mod.rs +++ b/server/src/routes/ui/admin/mod.rs @@ -6,7 +6,10 @@ pub mod log; pub mod user; -use super::account::session::AdminSession; +use super::{ + account::session::AdminSession, + assets::{resolve_asset, AVIF_QUALITY, AVIF_SPEED}, +}; use crate::{ database::DataAcid, routes::ui::{ @@ -16,9 +19,10 @@ use crate::{ }, uri, }; -use anyhow::anyhow; +use anyhow::{anyhow, Context}; use jellybase::{ - database::{ReadableTable, TableExt, T_INVITE}, + assetfed::AssetInner, + database::{ReadableTable, TableExt, T_INVITE, T_NODE}, federation::Federation, CONF, }; @@ -26,6 +30,7 @@ use jellyimport::{import, is_importing}; use rand::Rng; use rocket::{form::Form, get, post, FromForm, State}; use std::time::Instant; +use tokio::sync::Semaphore; use user::rocket_uri_macro_r_admin_users; #[get("/admin/dashboard")] @@ -68,9 +73,15 @@ pub fn admin_dashboard<'a>( @if is_importing() { section.message { p.warn { "An import is currently running." } } } + @if is_transcoding() { + section.message { p.warn { "Currently transcoding posters." } } + } form[method="POST", action=uri!(r_admin_import())] { input[type="submit", disabled=is_importing(), value="(Re-)Import Library"]; } + form[method="POST", action=uri!(r_admin_transcode_posters())] { + input[type="submit", disabled=is_transcoding(), value="Transcode all posters with low resolution"]; + } form[method="POST", action=uri!(r_admin_delete_cache())] { input.danger[type="submit", value="Delete Cache"]; } @@ -159,3 +170,48 @@ pub async fn r_admin_delete_cache( ), ) } + +static SEM_TRANSCODING: Semaphore = Semaphore::const_new(1); +fn is_transcoding() -> bool { + SEM_TRANSCODING.available_permits() == 0 +} + +#[post("/admin/transcode_posters")] +pub async fn r_admin_transcode_posters( + session: AdminSession, + database: &State<DataAcid>, +) -> MyResult<DynLayoutPage<'static>> { + drop(session); + let _permit = SEM_TRANSCODING + .try_acquire() + .context("transcoding in progress")?; + + let t = Instant::now(); + + { + let txn = database.begin_read()?; + let nodes = txn.open_table(T_NODE)?; + for node in nodes.iter()? { + let (_, node) = node?; + if let Some(poster) = &node.value().0.public.poster { + let asset = AssetInner::deser(&poster.0)?; + if asset.is_federated() { + continue; + } + let source = resolve_asset(asset).await.context("resolving asset")?; + jellytranscoder::image::transcode(source, AVIF_QUALITY, AVIF_SPEED, 1024) + .await + .context("transcoding asset")?; + } + } + } + drop(_permit); + + admin_dashboard( + &database, + Some(Ok(format!( + "All posters pre-transcoded; took {:?}", + t.elapsed() + ))), + ) +} |