aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-01-10 22:55:04 +0100
committermetamuffin <metamuffin@disroot.org>2023-01-10 22:55:04 +0100
commit552a3eb82347ee051855016f51ec452906cdc4d6 (patch)
tree18f2f1a53d7edf61a92f83d44893039009094064 /src
parent80e668f9cda3eb7972198dbbc65f6f72eae43c99 (diff)
downloadjellything-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.rs4
-rw-r--r--src/frontend/pages/mod.rs60
-rw-r--r--src/frontend/pages/node.rs26
-rw-r--r--src/library.rs49
-rw-r--r--src/main.rs44
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(&params.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])
}