From 59e6e7a6feafaf1dada3054466d415cca047ca1a Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 2 Aug 2023 11:23:48 +0200 Subject: node api on the same route --- server/src/routes/api/mod.rs | 48 +++++++++++++++++++++++++++++++++++++++++++- server/src/routes/ui/node.rs | 24 ++++++++++++++-------- 2 files changed, 63 insertions(+), 9 deletions(-) (limited to 'server/src') diff --git a/server/src/routes/api/mod.rs b/server/src/routes/api/mod.rs index b39950c..e74b134 100644 --- a/server/src/routes/api/mod.rs +++ b/server/src/routes/api/mod.rs @@ -4,12 +4,23 @@ Copyright (C) 2023 metamuffin */ +use std::ops::Deref; + use super::ui::{ account::{login_logic, LoginForm}, error::MyResult, }; use crate::database::Database; -use rocket::{get, post, response::Redirect, serde::json::Json, State}; +use rocket::{ + get, + http::MediaType, + outcome::Outcome, + post, + request::{self, FromRequest}, + response::Redirect, + serde::json::Json, + Request, State, +}; use serde_json::{json, Value}; #[get("/api")] @@ -27,3 +38,38 @@ pub fn r_api_account_login(database: &State, data: Json) -> let token = login_logic(database, &data.username, &data.password)?; Ok(json!(token)) } + +pub struct AcceptJson(bool); +impl Deref for AcceptJson { + type Target = bool; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl<'r> FromRequest<'r> for AcceptJson { + type Error = (); + + fn from_request<'life0, 'async_trait>( + request: &'r Request<'life0>, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future> + + ::core::marker::Send + + 'async_trait, + >, + > + where + 'r: 'async_trait, + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + Outcome::Success(AcceptJson( + request + .accept() + .map(|a| a.preferred().exact_eq(&MediaType::JSON)) + .unwrap_or(false), + )) + }) + } +} diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs index e4bf329..93186bf 100644 --- a/server/src/routes/ui/node.rs +++ b/server/src/routes/ui/node.rs @@ -6,29 +6,37 @@ use super::{assets::rocket_uri_macro_r_item_assets, error::MyError, player::player_uri}; use crate::{ database::Database, - routes::ui::{ - account::session::Session, - assets::AssetRole, - layout::{DynLayoutPage, LayoutPage}, + routes::{ + api::AcceptJson, + ui::{ + account::session::Session, + assets::AssetRole, + layout::{DynLayoutPage, LayoutPage}, + }, }, uri, }; use anyhow::{anyhow, Context}; use jellycommon::{Node, NodeKind}; -use rocket::{get, State}; +use rocket::{get, serde::json::Json, Either, State}; #[get("/n/")] pub async fn r_library_node( _sess: Session, id: String, db: &State, -) -> Result, MyError> { + aj: AcceptJson, +) -> Result, Json>, MyError> { let node = db .node .get(&id) .context("retrieving library node")? .ok_or(anyhow!("node does not exist"))?; + if *aj { + return Ok(Either::Right(Json(node))); + } + let children = node .public .children @@ -43,14 +51,14 @@ pub async fn r_library_node( .into_iter() .collect(); - Ok(LayoutPage { + Ok(Either::Left(LayoutPage { title: node.public.title.to_string(), show_back: matches!(node.public.kind, NodeKind::Movie | NodeKind::Episode), content: markup::new! { @NodePage { node: &node, id: &id, children: &children } }, ..Default::default() - }) + })) } markup::define! { -- cgit v1.2.3-70-g09d2