diff options
author | metamuffin <metamuffin@disroot.org> | 2023-07-31 19:53:01 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-07-31 19:53:01 +0200 |
commit | aeafba7847e189313df3025e6d6f291999b57350 (patch) | |
tree | bf7affdca28208695648bc9b18856cbb7049d1e8 /server/src/routes/ui/node.rs | |
parent | 0c651f11920350a4aa96aa24f8fe15b28390aed2 (diff) | |
download | jellything-aeafba7847e189313df3025e6d6f291999b57350.tar jellything-aeafba7847e189313df3025e6d6f291999b57350.tar.bz2 jellything-aeafba7847e189313df3025e6d6f291999b57350.tar.zst |
update server to new schema
Diffstat (limited to 'server/src/routes/ui/node.rs')
-rw-r--r-- | server/src/routes/ui/node.rs | 172 |
1 files changed, 75 insertions, 97 deletions
diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs index 4d599dc..0ae0d9e 100644 --- a/server/src/routes/ui/node.rs +++ b/server/src/routes/ui/node.rs @@ -1,163 +1,141 @@ /* -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) 2023 metamuffin <metamuffin.org> + 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) 2023 metamuffin <metamuffin.org> */ -use super::error::MyError; -use super::player::player_uri; -use super::CacheControlFile; -use crate::uri; +use super::{assets::rocket_uri_macro_r_item_assets, error::MyError, player::player_uri}; use crate::{ - library::{Directory, Item, Library, Node}, + database::Database, routes::ui::{ account::session::Session, + assets::AssetRole, layout::{DynLayoutPage, LayoutPage}, }, + uri, }; -use anyhow::Context; -use jellycommon::DirectoryKind; -use log::info; -use rocket::{get, http::ContentType, State}; -use rocket::{FromFormField, UriDisplayQuery}; -use std::{path::PathBuf, sync::Arc}; -use tokio::fs::File; +use anyhow::{anyhow, Context}; +use jellycommon::{Node, NodeKind}; +use rocket::{get, State}; -#[get("/library/<path..>")] +#[get("/library/<id>")] pub async fn r_library_node( _sess: Session, - path: PathBuf, - library: &State<Library>, + id: String, + db: &State<Database>, ) -> Result<DynLayoutPage<'_>, MyError> { - let node = library - .nested_path(&path) - .context("retrieving library node")?; + let node = db + .node + .get(&id) + .context("retrieving library node")? + .ok_or(anyhow!("node does not exist"))?; + + let children = node + .public + .children + .iter() + .map(|c| { + Ok(( + c.to_owned(), + db.node.get(c)?.ok_or(anyhow!("child does not exist"))?, + )) + }) + .collect::<anyhow::Result<Vec<_>>>()? + .into_iter() + .collect(); + Ok(LayoutPage { - title: node.common().title.to_string(), - show_back: node.get_item().is_ok(), + title: node.public.title.to_string(), + show_back: matches!(node.public.kind, NodeKind::Movie | NodeKind::Episode), content: markup::new! { - @NodePage { node: &node } + @NodePage { node: &node, id: &id, children: &children } }, ..Default::default() }) } markup::define! { - NodePage<'a>(node: &'a Arc<Node>) { - @match node.as_ref() { - Node::Directory(dir) => { @match dir.info.kind { - DirectoryKind::Series => { @SeriesPage { dir } } - _ => { @DirectoryPage { dir } } - } } - Node::Item(item) => { @ItemPage { item } } + NodePage<'a>(id: &'a str, node: &'a Node, children: &'a Vec<(String,Node)>) { + @match node.public.kind { + NodeKind::Collection | NodeKind::Show | NodeKind::Season => { @DirectoryPage { node, id, children } } + NodeKind::Series => { @SeriesPage { node, children, id } } + NodeKind::Movie | NodeKind::Episode => { @ItemPage { node, id } } } } - NodeCard<'a>(node: &'a Arc<Node>) { - @match node.as_ref() { - Node::Directory(dir) => {@PosterCard { - wide: !matches!(dir.info.kind, DirectoryKind::Series | DirectoryKind::Season), - dir: true, - path: dir.lib_path.clone(), - title: &dir.info.title - }} - Node::Item(item) => {@PosterCard { - wide: false, dir: false, - path: item.lib_path.clone(), - title: &item.info.title - }} + NodeCard<'a>(id: &'a str, node: &'a Node) { + @PosterCard { + wide: matches!(node.public.kind, NodeKind::Collection), + dir: !matches!(node.public.kind, NodeKind::Movie | NodeKind::Episode), + id, + title: &node.public.title } } - DirectoryPage<'a>(dir: &'a Arc<Directory>) { + DirectoryPage<'a>(id: &'a str, node: &'a Node, children: &'a Vec<(String,Node)>) { div.page.dir { - h1 { @dir.info.title } - @if let Some(parent) = dir.lib_path.parent() { - a.dirup[href=uri!(r_library_node(&parent))] { "Go up" } - } + h1 { @node.public.title } + // @if let Some(parent) = node.lib_path.parent() { + // a.dirup[href=uri!(r_library_node(&parent))] { "Go up" } + // } ul.directorylisting { - @for node in &dir.children { - li { @NodeCard { node } } + @for (id, node) in children.iter() { + li { @NodeCard { id, node } } } } } } - PosterCard<'a>(path: PathBuf, title: &'a str, wide: bool, dir: bool) { + PosterCard<'a>(id: &'a str, title: &'a str, wide: bool, dir: bool) { div[class=if *wide {"card wide poster"} else {"card poster"}] { div.banner { - a[href=uri!(r_library_node(path))] { - img[src=uri!(r_item_assets(path, AssetRole::Poster))]; + a[href=uri!(r_library_node(id))] { + img[src=uri!(r_item_assets(id, AssetRole::Poster))]; } @if *dir { - div.hoverdir { a[href=&uri!(r_library_node(path))] { "Open" } } + div.hoverdir { a[href=&uri!(r_library_node(id))] { "Open" } } } else { - div.hoveritem { a[href=&player_uri(path)] { "▶" } } + div.hoveritem { a[href=&player_uri(id)] { "▶" } } } } p.title { - a[href=uri!(r_library_node(path))] { + a[href=uri!(r_library_node(id))] { @title } } } } - ItemPage<'a>(item: &'a Arc<Item>) { + ItemPage<'a>(id: &'a str, node: &'a Node) { // TODO different image here - img.backdrop[src=uri!(r_item_assets(&item.lib_path, AssetRole::Backdrop))]; + img.backdrop[src=uri!(r_item_assets(id, AssetRole::Backdrop))]; div.page.item { div.banner { - img[src=uri!(r_item_assets(&item.lib_path, AssetRole::Poster))]; + img[src=uri!(r_item_assets(id, AssetRole::Poster))]; } div.title { - h1 { @item.info.title } + h1 { @node.public.title } // TODO release date, duration, ratings - a.play[href=&player_uri(&item.lib_path)] { "Watch now" } + a.play[href=&player_uri(id)] { "Watch now" } } div.details { - h3 { @item.info.tagline } - p { @item.info.description } + h3 { @node.public.tagline } + p { @node.public.description } } } } - SeriesPage<'a>(dir: &'a Arc<Directory>) { + SeriesPage<'a>(id: &'a str, node: &'a Node, children: &'a Vec<(String,Node)>) { // TODO different image here - img.backdrop[src=uri!(r_item_assets(&dir.lib_path, AssetRole::Backdrop))]; + img.backdrop[src=uri!(r_item_assets(id, AssetRole::Backdrop))]; div.page.item { div.banner { - img[src=uri!(r_item_assets(&dir.lib_path, AssetRole::Poster))]; + img[src=uri!(r_item_assets(id, AssetRole::Poster))]; } div.title { - h1 { @dir.info.title } + h1 { @node.public.title } } div.details { - h3 { @dir.info.tagline } - p { @dir.info.description } + h3 { @node.public.tagline } + p { @node.public.description } } - ol { @for ep in &dir.children { - li { a[href=uri!(r_library_node(ep.lib_path()))] { @ep.common().title } } + ol { @for (id, c) in children.iter() { + li { a[href=uri!(r_library_node(id))] { @c.public.title } } } } } } } - -#[derive(FromFormField, UriDisplayQuery)] -pub enum AssetRole { - Poster, - Backdrop, -} - -#[get("/item_assets/<path..>?<role>")] -pub async fn r_item_assets( - _sess: Session, - path: PathBuf, - role: AssetRole, - library: &State<Library>, -) -> Result<(ContentType, CacheControlFile), MyError> { - let node = library - .nested_path(&path) - .context("retrieving library node")?; - let path = node.get_asset(library, role); - info!("loading asset from {path:?}"); - let ext = path.extension().unwrap().to_str().unwrap(); - Ok(( - ContentType::from_extension(ext).unwrap(), - CacheControlFile::new(File::open(path).await?).await, - )) -} |