diff options
author | metamuffin <metamuffin@disroot.org> | 2023-01-10 22:55:04 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-01-10 22:55:04 +0100 |
commit | 552a3eb82347ee051855016f51ec452906cdc4d6 (patch) | |
tree | 18f2f1a53d7edf61a92f83d44893039009094064 /src | |
parent | 80e668f9cda3eb7972198dbbc65f6f72eae43c99 (diff) | |
download | jellything-552a3eb82347ee051855016f51ec452906cdc4d6.tar jellything-552a3eb82347ee051855016f51ec452906cdc4d6.tar.bz2 jellything-552a3eb82347ee051855016f51ec452906cdc4d6.tar.zst |
the rocket is launching! :rocket: :rocket:
Diffstat (limited to 'src')
-rw-r--r-- | src/frontend/pages/home.rs | 4 | ||||
-rw-r--r-- | src/frontend/pages/mod.rs | 60 | ||||
-rw-r--r-- | src/frontend/pages/node.rs | 26 | ||||
-rw-r--r-- | src/library.rs | 49 | ||||
-rw-r--r-- | src/main.rs | 44 |
5 files changed, 91 insertions, 92 deletions
diff --git a/src/frontend/pages/home.rs b/src/frontend/pages/home.rs index bb0eb59..3595c19 100644 --- a/src/frontend/pages/home.rs +++ b/src/frontend/pages/home.rs @@ -2,10 +2,10 @@ use crate::{ frontend::pages::{layout::Layout, HtmlTemplate}, AppState, }; -use actix_web::{get, web::Data, Responder}; +use rocket::{get, State}; #[get("/")] -pub async fn page_home(state: Data<AppState>) -> impl Responder { +pub async fn page_home(state: &State<AppState>) -> HtmlTemplate<impl markup::Render> { HtmlTemplate(Layout { title: String::from("Home"), main: markup::new! { diff --git a/src/frontend/pages/mod.rs b/src/frontend/pages/mod.rs index 0e54a9a..46e2067 100644 --- a/src/frontend/pages/mod.rs +++ b/src/frontend/pages/mod.rs @@ -1,60 +1,40 @@ -use actix_web::{ - body::BoxBody, - http::{ - header::{HeaderName, HeaderValue}, - StatusCode, - }, - HttpResponseBuilder, Responder, +use markup::Render; +use rocket::{ + http::ContentType, + response::{self, Responder}, + Request, Response, }; -use std::fmt::Display; +use std::{fmt::Display, io::Cursor}; pub mod home; pub mod layout; pub mod node; -struct HtmlTemplate<T>(pub T); +pub struct HtmlTemplate<T>(pub T); -impl<T: markup::Render> Responder for HtmlTemplate<T> { - type Body = BoxBody; - - fn respond_to(self, req: &actix_web::HttpRequest) -> actix_web::HttpResponse<Self::Body> { +impl<'r, T: Render> Responder<'r, 'static> for HtmlTemplate<T> { + fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { let mut out = String::new(); self.0.render(&mut out).unwrap(); - - HttpResponseBuilder::new(StatusCode::OK) - .body(out) - .respond_to(req) - } -} - -pub struct ContentType<T>(pub &'static str, pub T); - -impl<T: Responder> Responder for ContentType<T> { - type Body = T::Body; - - fn respond_to(self, req: &actix_web::HttpRequest) -> actix_web::HttpResponse<Self::Body> { - let mut r = self.1.respond_to(req); - r.headers_mut().insert( - HeaderName::from_static("content-type"), - HeaderValue::from_static(self.0), - ); - r + Response::build() + .header(ContentType::HTML) + .streamed_body(Cursor::new(out)) + .ok() } } -pub type MyResult<T> = actix_web::Result<T, MyError>; - #[derive(Debug)] pub struct MyError(anyhow::Error); -impl actix_web::error::ResponseError for MyError { - fn status_code(&self) -> StatusCode { - StatusCode::BAD_REQUEST - } - fn error_response(&self) -> actix_web::HttpResponse<BoxBody> { - HttpResponseBuilder::new(StatusCode::BAD_REQUEST).body(format!("error: {}", self.0)) +impl<'r> Responder<'r, 'static> for MyError { + fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { + Response::build() + .header(ContentType::HTML) + .streamed_body(Cursor::new(format!("{:?}", self.0))) + .ok() } } + impl Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) diff --git a/src/frontend/pages/node.rs b/src/frontend/pages/node.rs index bb8eb6c..cd0b4ec 100644 --- a/src/frontend/pages/node.rs +++ b/src/frontend/pages/node.rs @@ -1,19 +1,20 @@ use crate::{ - frontend::pages::{HtmlTemplate, MyResult, layout::Layout}, + frontend::pages::{layout::Layout, HtmlTemplate}, library::{Directory, Item, Node}, AppState, }; -use actix_web::{get, web, Responder}; -use log::debug; -use std::{ops::Deref, sync::Arc}; +use rocket::{get, uri, State}; +use std::{ops::Deref, path::PathBuf, sync::Arc}; -#[get("/library/{path:.*}")] +use super::MyError; + +#[get("/library/<path..>")] pub async fn page_library_node( - state: web::Data<AppState>, - params: web::Path<(String,)>, -) -> MyResult<impl Responder> { - debug!("request: {:?}", params.0); - let node = state.library.nested(¶ms.0)?; + path: PathBuf, + state: &State<AppState>, +) -> Result<HtmlTemplate<markup::DynRender>, MyError> { + let path = path.to_str().unwrap().to_string(); + let node = state.library.nested(&path)?.clone(); Ok(HtmlTemplate(markup::new! { @match node.deref() { Node::Directory(dir) => { @@ -34,7 +35,7 @@ pub async fn page_library_node( markup::define! { DirectoryCard(dir: Arc<Directory>) { - span { a[href=&dir.identifier] { @dir.data.name } } + span { a[href=&uri!(page_library_node(&dir.lib_path)).to_string()] { @dir.data.name } } } DirectoryPage(dir: Arc<Directory>) { h1 { @dir.data.name } @@ -50,10 +51,9 @@ markup::define! { } } ItemCard(item: Arc<Item>) { - span { a[href=&item.identifier] { @item.data.title } } + span { a[href=&uri!(page_library_node(&item.lib_path)).to_string()] { @item.data.title } } } ItemPage(item: Arc<Item>) { h1 { @item.data.title } } - } diff --git a/src/library.rs b/src/library.rs index ea0b9ed..be75f10 100644 --- a/src/library.rs +++ b/src/library.rs @@ -14,6 +14,7 @@ pub enum Node { #[derive(Debug, Clone)] pub struct Directory { + pub lib_path: PathBuf, pub identifier: String, pub data: DirectoryInfo, pub children: Vec<Arc<Node>>, @@ -21,6 +22,7 @@ pub struct Directory { #[derive(Debug, Clone)] pub struct Item { + pub lib_path: PathBuf, pub identifier: String, pub data: ItemInfo, } @@ -28,7 +30,7 @@ pub struct Item { impl Library { pub fn open(path: &str) -> anyhow::Result<Self> { Ok(Self { - root: Node::from_path(path.into()).context("indexing root")?, + root: Node::from_path(path.into(), PathBuf::new(), true).context("indexing root")?, }) } pub fn nested(&self, path: &str) -> anyhow::Result<Arc<Node>> { @@ -65,23 +67,37 @@ impl Node { Node::Item(i) => &i.identifier, } } - pub fn from_path(path: PathBuf) -> anyhow::Result<Arc<Node>> { + pub fn from_path( + path: PathBuf, + mut lib_path: PathBuf, + root: bool, + ) -> anyhow::Result<Arc<Node>> { if path.is_dir() { let mpath = path.join("directory.json"); let data: DirectoryInfo = serde_json::from_reader(File::open(mpath).context("metadata missing")?)?; + + let identifier = path.file_name().unwrap().to_str().unwrap().to_string(); + if !root { + lib_path = lib_path.join(identifier.clone()); + } + let children = path .read_dir()? .map(|e| e.unwrap().path()) .filter(|e| e.extension() != Some(OsStr::new("json"))) - .map(|e| Node::from_path(e.clone()).context(format!("loading {e:?}"))) + .map(|e| { + Node::from_path(e.clone(), lib_path.clone(), false) + .context(format!("loading {e:?}")) + }) .into_iter() .collect::<anyhow::Result<Vec<_>>>()?; Ok(Node::Directory(Arc::new(Directory { + lib_path, children, data, - identifier: path.file_name().unwrap().to_str().unwrap().to_string(), + identifier, })) .into()) } else if path.is_file() { @@ -89,15 +105,17 @@ impl Node { let datafile = File::open(mpath.clone()) .context(format!("metadata missing, tried path {mpath:?}"))?; let data: ItemInfo = serde_json::from_reader(datafile).context("invalid metadata")?; + let identifier = path + .with_extension("") + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_string(); Ok(Node::Item(Arc::new(Item { + lib_path: lib_path.join(identifier.clone()), data, - identifier: path - .with_extension("") - .file_name() - .unwrap() - .to_str() - .unwrap() - .to_string(), + identifier, })) .into()) } else { @@ -105,8 +123,15 @@ impl Node { } } } - +impl Item { + pub fn path(&self) -> String { + self.lib_path.to_str().unwrap().to_string() + } +} impl Directory { + pub fn path(&self) -> String { + self.lib_path.to_str().unwrap().to_string() + } pub fn child_by_ident(&self, i: &str) -> Option<Arc<Node>> { self.children .iter() diff --git a/src/main.rs b/src/main.rs index 5a0b050..b7a3249 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ #![feature(box_syntax)] -use crate::frontend::{pages::ContentType, style::CSS_BUNDLE}; -use actix_web::{get, web, App, HttpServer, Responder}; +use crate::frontend::style::CSS_BUNDLE; use database::Database; use frontend::pages::{home::page_home, node::page_library_node}; use library::Library; +use rocket::{get, http::ContentType, launch, routes}; use std::fs::read_to_string; pub mod database; @@ -13,15 +13,15 @@ pub mod library; pub mod metadata; #[get("/assets/style.css")] -async fn assets_style() -> impl Responder { - if cfg!(debug_assertions) { - ContentType( - "text/css", - read_to_string("src/frontend/style/layout.css").unwrap(), - ) - } else { - ContentType("text/css", CSS_BUNDLE.to_string()) - } +async fn assets_style() -> (ContentType, String) { + ( + ContentType::CSS, + if cfg!(debug_assertions) { + read_to_string("src/frontend/style/layout.css").unwrap() + } else { + CSS_BUNDLE.to_string() + }, + ) } pub struct AppState { @@ -29,23 +29,17 @@ pub struct AppState { pub library: Library, } -#[actix_web::main] -async fn main() -> std::io::Result<()> { +#[launch] +fn rocket() -> _ { env_logger::init_from_env("LOG"); let db_path = std::env::var("DB_PATH").unwrap_or("data/db".to_string()); let lib_path = std::env::var("LIB_PATH").unwrap_or("data/library".to_string()); - let state = web::Data::new(AppState { + let state = AppState { library: Library::open(&lib_path).unwrap(), database: Database::open(&db_path).unwrap(), - }); - HttpServer::new(move || { - App::new() - .app_data(state.clone()) - .service(page_home) - .service(assets_style) - .service(page_library_node) - }) - .bind(("127.0.0.1", 8080))? - .run() - .await + }; + + rocket::build() + .manage(state) + .mount("/", routes![page_home, page_library_node, assets_style]) } |