aboutsummaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-04-10 19:51:37 +0200
committermetamuffin <metamuffin@disroot.org>2024-04-10 19:51:43 +0200
commita820b817bf4bfbf7e8978ffc427ccbf75a74309a (patch)
treea59a5c89f8fe3e62fc39f485ffffe84d02989409 /server/src
parent18e23f2454cc6b3a75165eaafebe6c51bbe1f1d0 (diff)
downloadjellything-a820b817bf4bfbf7e8978ffc427ccbf75a74309a.tar
jellything-a820b817bf4bfbf7e8978ffc427ccbf75a74309a.tar.bz2
jellything-a820b817bf4bfbf7e8978ffc427ccbf75a74309a.tar.zst
pretranscode poster buutton
Diffstat (limited to 'server/src')
-rw-r--r--server/src/routes/mod.rs3
-rw-r--r--server/src/routes/ui/admin/mod.rs62
-rw-r--r--server/src/routes/ui/assets.rs6
3 files changed, 65 insertions, 6 deletions
diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs
index 27fb4f7..2f8946f 100644
--- a/server/src/routes/mod.rs
+++ b/server/src/routes/mod.rs
@@ -31,7 +31,7 @@ use ui::{
admin::{
log::r_admin_log,
r_admin_dashboard, r_admin_delete_cache, r_admin_import, r_admin_invite,
- r_admin_remove_invite,
+ r_admin_remove_invite, r_admin_transcode_posters,
user::{r_admin_remove_user, r_admin_user, r_admin_user_permission, r_admin_users},
},
assets::{r_asset, r_item_assets, r_node_thumbnail, r_person_asset},
@@ -129,6 +129,7 @@ pub fn build_rocket(database: DataAcid, federation: Federation) -> Rocket<Build>
r_admin_user_permission,
r_admin_import,
r_admin_delete_cache,
+ r_admin_transcode_posters,
r_admin_log,
r_account_settings,
r_account_settings_post,
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()
+ ))),
+ )
+}
diff --git a/server/src/routes/ui/assets.rs b/server/src/routes/ui/assets.rs
index 115c02a..c278a31 100644
--- a/server/src/routes/ui/assets.rs
+++ b/server/src/routes/ui/assets.rs
@@ -20,6 +20,9 @@ use log::info;
use rocket::{get, http::ContentType, response::Redirect, State};
use std::path::PathBuf;
+pub const AVIF_QUALITY: f32 = 50.;
+pub const AVIF_SPEED: u8 = 5;
+
#[get("/asset/<token>?<width>")]
pub async fn r_asset(
_session: Session,
@@ -43,8 +46,7 @@ pub async fn r_asset(
// fit the resolution into a finite set so the maximum cache is finite too.
let width = 2usize.pow(width.clamp(128, 2048).ilog2());
- // TODO configure avif quality and speed.
- jellytranscoder::image::transcode(source, 50., 5, width)
+ jellytranscoder::image::transcode(source, AVIF_QUALITY, AVIF_SPEED, width)
.await
.context("transcoding asset")?
};