From 02bbb2741f2c463aadf9d07493ebaeac1d73c11a Mon Sep 17 00:00:00 2001 From: metamuffin Date: Thu, 30 Jan 2025 14:39:20 +0100 Subject: import channel and children --- server/src/routes/ui/admin/mod.rs | 42 +++++++++++++++--------------- server/src/routes/ui/node.rs | 54 +++++++++++++++------------------------ server/src/routes/ui/sort.rs | 3 ++- 3 files changed, 44 insertions(+), 55 deletions(-) (limited to 'server/src') diff --git a/server/src/routes/ui/admin/mod.rs b/server/src/routes/ui/admin/mod.rs index 5c2c48f..50faa2e 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::Database, routes::ui::{ @@ -17,7 +20,7 @@ use crate::{ uri, }; use anyhow::{anyhow, Context}; -use jellybase::{federation::Federation, CONF}; +use jellybase::{assetfed::AssetInner, federation::Federation, CONF}; use jellyimport::{import_wrap, is_importing, IMPORT_ERRORS}; use markup::DynRender; use rand::Rng; @@ -196,25 +199,22 @@ pub async fn r_admin_transcode_posters( let t = Instant::now(); - // TODO - // { - // 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.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); + { + let nodes = database.list_nodes_with_udata("")?; + for (node, _) in nodes { + if let Some(poster) = &node.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, diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs index 3332483..121896e 100644 --- a/server/src/routes/ui/node.rs +++ b/server/src/routes/ui/node.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; - /* 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. @@ -37,6 +35,7 @@ use jellycommon::{ Chapter, MediaInfo, Node, NodeID, NodeKind, PeopleGroup, Rating, SourceTrackKind, }; use rocket::{get, serde::json::Json, Either, State}; +use std::sync::Arc; /// This function is a stub and only useful for use in the uri! macro. #[get("/n/")] @@ -44,43 +43,32 @@ pub fn r_library_node(id: String) { drop(id) } -#[get("/n/?")] +#[get("/n/?")] pub async fn r_library_node_filter<'a>( session: Session, - id: &'a str, + slug: &'a str, db: &'a State, aj: AcceptJson, filter: NodeFilterSort, ) -> MyResult, Json>> { - let (node, udata) = db.get_node_with_userdata(NodeID::from_slug(id), &session)?; + let id = NodeID::from_slug(slug); + let (node, udata) = db.get_node_with_userdata(id, &session)?; if *aj { return Ok(Either::Right(Json((*node).clone()))); } - // let mut children = node - // .children - // .iter() - // .map(|c| db.get_node_with_userdata(c, &session)) - // .collect::>>()? - // .into_iter() - // .collect(); + let mut children = db + .get_node_children(id)? + .into_iter() + .map(|c| db.get_node_with_userdata(c, &session)) + .collect::>>()?; - // let path = node - // .path - // .iter() - // .map(|c| { - // Ok(( - // c.to_owned(), - // T_NODE - // .get(db, c.as_str())? - // .ok_or(anyhow!("parent node missing"))? - // .public, - // )) - // }) - // .collect::>>()? - // .into_iter() - // .collect::>(); + let parents = node + .parents + .iter() + .flat_map(|pid| db.get_node(*pid).transpose()) + .collect::, _>>()?; filter_and_sort_nodes( &filter, @@ -89,13 +77,13 @@ pub async fn r_library_node_filter<'a>( _ => (SortProperty::Title, SortOrder::Ascending), }, // TODO - &mut Vec::new(), + &mut children, ); Ok(Either::Left(LayoutPage { title: node.title.clone().unwrap_or_default(), content: markup::new! { - @NodePage { node: &node, id, udata: &udata, children: &[], path: &[], filter: &filter } + @NodePage { node: &node, id: slug, udata: &udata, children: &children, parents: &parents, filter: &filter } }, ..Default::default() })) @@ -128,7 +116,7 @@ markup::define! { } } } - NodePage<'a>(id: &'a str, node: &'a Node, udata: &'a NodeUserData, children: &'a [(Arc, NodeUserData)], path: &'a [(String, Node)], filter: &'a NodeFilterSort) { + NodePage<'a>(id: &'a str, node: &'a Node, udata: &'a NodeUserData, children: &'a [(Arc, NodeUserData)], parents: &'a [Arc], filter: &'a NodeFilterSort) { @if !matches!(node.kind.unwrap_or_default(), NodeKind::Collection) { img.backdrop[src=uri!(r_item_backdrop(id, Some(2048))), loading="lazy"]; } @@ -139,9 +127,9 @@ markup::define! { } .title { h1 { @node.title } - span.path { @for (cid, cnode) in *path { - " / " a.component[href=uri!(r_library_node(cid))] { @cnode.title } - }} + ul.parents { @for node in *parents { li { + a.component[href=uri!(r_library_node(&node.slug))] { @node.title } + }}} @if node.media.is_some() { a.play[href=&uri!(r_player(id, PlayerConfig::default()))] { "Watch now" }} @if !matches!(node.kind.unwrap_or_default(), NodeKind::Collection | NodeKind::Channel) { @if matches!(udata.watched, WatchedState::None | WatchedState::Pending | WatchedState::Progress(_)) { diff --git a/server/src/routes/ui/sort.rs b/server/src/routes/ui/sort.rs index 705b616..68bd588 100644 --- a/server/src/routes/ui/sort.rs +++ b/server/src/routes/ui/sort.rs @@ -8,6 +8,7 @@ use rocket::{ http::uri::fmt::{Query, UriDisplay}, FromForm, FromFormField, UriDisplayQuery, }; +use std::sync::Arc; #[derive(FromForm, UriDisplayQuery, Default, Clone)] pub struct NodeFilterSort { @@ -134,7 +135,7 @@ pub enum SortOrder { pub fn filter_and_sort_nodes( f: &NodeFilterSort, default_sort: (SortProperty, SortOrder), - nodes: &mut Vec<(Node, NodeUserData)>, + nodes: &mut Vec<(Arc, NodeUserData)>, ) { let sort_prop = f.sort_by.unwrap_or(default_sort.0); nodes.retain(|(node, udata)| { -- cgit v1.2.3-70-g09d2