diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/database.rs | 13 | ||||
-rw-r--r-- | src/frontend/mod.rs | 2 | ||||
-rw-r--r-- | src/frontend/pages/home.rs | 14 | ||||
-rw-r--r-- | src/frontend/pages/layout.rs | 20 | ||||
-rw-r--r-- | src/frontend/pages/mod.rs | 69 | ||||
-rw-r--r-- | src/frontend/pages/node.rs | 60 | ||||
-rw-r--r-- | src/frontend/style/layout.css | 42 | ||||
-rw-r--r-- | src/frontend/style/mod.rs | 2 | ||||
-rw-r--r-- | src/library.rs | 141 | ||||
-rw-r--r-- | src/main.rs | 45 | ||||
-rw-r--r-- | src/metadata.rs | 11 |
11 files changed, 0 insertions, 419 deletions
diff --git a/src/database.rs b/src/database.rs deleted file mode 100644 index 3ba8c52..0000000 --- a/src/database.rs +++ /dev/null @@ -1,13 +0,0 @@ -use anyhow::Context; - -#[derive(Debug)] -pub struct Database { - pub db: sled::Db, -} - -impl Database { - pub fn open(path: &str) -> Result<Self, anyhow::Error> { - let db = sled::open(path).context("opening database")?; - Ok(Self { db }) - } -} diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs deleted file mode 100644 index 99c22f8..0000000 --- a/src/frontend/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod style; -pub mod pages; diff --git a/src/frontend/pages/home.rs b/src/frontend/pages/home.rs deleted file mode 100644 index 5076177..0000000 --- a/src/frontend/pages/home.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::frontend::pages::node::NodePage; -use crate::{frontend::pages::HtmlTemplate, AppState}; -use rocket::{get, State}; - -#[get("/")] -pub async fn page_home(state: &State<AppState>) -> HtmlTemplate<markup::DynRender> { - HtmlTemplate( - "Home".to_string(), - markup::new! { - p { "Welcome to Jellything" } - @NodePage { node: state.library.root.clone() } - }, - ) -} diff --git a/src/frontend/pages/layout.rs b/src/frontend/pages/layout.rs deleted file mode 100644 index 5654d3b..0000000 --- a/src/frontend/pages/layout.rs +++ /dev/null @@ -1,20 +0,0 @@ -use markup::Render; - -markup::define! { - Layout<Main: Render>(title: String, main: Main) { - @markup::doctype() - html { - head { - title { @title " - Jellything" } - link[rel="stylesheet", href="/assets/style.css"]; - } - body { - nav { - h1 { "Jellything" } - - } - #main { @main } - } - } - } -} diff --git a/src/frontend/pages/mod.rs b/src/frontend/pages/mod.rs deleted file mode 100644 index a20fa0e..0000000 --- a/src/frontend/pages/mod.rs +++ /dev/null @@ -1,69 +0,0 @@ -use markup::Render; -use rocket::{ - http::ContentType, - response::{self, Responder}, - Request, Response, -}; -use std::{fmt::Display, io::Cursor}; - -use self::layout::Layout; - -pub mod home; -pub mod layout; -pub mod node; - -pub struct HtmlTemplate<T>(pub String, pub T); - -impl<'r, T: Render> Responder<'r, 'static> for HtmlTemplate<T> { - fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { - let mut out = String::new(); - Layout { - title: self.0, - main: self.1, - } - .render(&mut out) - .unwrap(); - Response::build() - .header(ContentType::HTML) - .streamed_body(Cursor::new(out)) - .ok() - } -} - -#[derive(Debug)] -pub struct MyError(anyhow::Error); - -impl<'r> Responder<'r, 'static> for MyError { - fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { - let mut out = String::new(); - Layout { - title: "Error".to_string(), - main: markup::new! { - h2 { "An error occured. Nobody is sorry"} - pre.error { @format!("{:?}", self.0) } - }, - } - .render(&mut out) - .unwrap(); - Response::build() - .header(ContentType::HTML) - .streamed_body(Cursor::new(out)) - .ok() - } -} - -impl Display for MyError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} -impl From<anyhow::Error> for MyError { - fn from(err: anyhow::Error) -> MyError { - MyError(err) - } -} -impl From<std::fmt::Error> for MyError { - fn from(err: std::fmt::Error) -> MyError { - MyError(anyhow::anyhow!("{err}")) - } -} diff --git a/src/frontend/pages/node.rs b/src/frontend/pages/node.rs deleted file mode 100644 index 7ac4332..0000000 --- a/src/frontend/pages/node.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::{ - frontend::pages::HtmlTemplate, - library::{Directory, Item, Node}, - AppState, -}; -use anyhow::Context; -use rocket::{get, uri, State}; -use std::{ops::Deref, path::PathBuf, sync::Arc}; - -use super::MyError; - -#[get("/library/<path..>")] -pub async fn page_library_node( - path: PathBuf, - state: &State<AppState>, -) -> Result<HtmlTemplate<markup::DynRender>, MyError> { - let path = path.to_str().unwrap().to_string(); - let node = state - .library - .nested(&path) - .context("retrieving library node")? - .clone(); - Ok(HtmlTemplate( - format!("{}", node.title()), - markup::new! { - @NodePage { node: node.clone() } - }, - )) -} - -markup::define! { - NodePage(node: Arc<Node>) { - @match node.deref() { - Node::Directory(dir) => { @DirectoryPage { dir: dir.clone() } } - Node::Item(item) => { @ItemPage { item: item.clone() } } - } - } - DirectoryCard(dir: Arc<Directory>) { - span { a[href=&uri!(page_library_node(&dir.lib_path)).to_string()] { @dir.data.name } } - } - DirectoryPage(dir: Arc<Directory>) { - h1 { @dir.data.name } - ul.directorylisting { - @for el in &dir.children { - li { - span.title { @match el.deref().to_owned() { - Node::Directory(dir) => { @DirectoryCard { dir } } - Node::Item(item) => { @ItemCard { item } } - }} - } - } - } - } - ItemCard(item: Arc<Item>) { - 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/frontend/style/layout.css b/src/frontend/style/layout.css deleted file mode 100644 index 4418903..0000000 --- a/src/frontend/style/layout.css +++ /dev/null @@ -1,42 +0,0 @@ -@import url("https://s.metamuffin.org/static/font-ubuntu/include.css"); - -* { - color: white; - font-family: "Ubuntu", sans-serif; - font-weight: 300; - margin: 0px; - padding: 0px; -} - -body { - background-color: #1a1a1a; - width: 100vw; -} - -nav { - position: absolute; - top: 0px; - left: 0px; - padding: 1em; - width: calc(100vw - 2em); - height: 2em; - background-color: #41414144; -} - -nav h1 { - margin: 0px; - font-size: 1.5em; -} - -#main { - margin-top: 5em; - padding: 1em; - padding-left: 3em; - padding-right: 3em; -} - -.error { - padding: 1em; - color: rgb(255, 117, 117); - font-family: monospace; -} diff --git a/src/frontend/style/mod.rs b/src/frontend/style/mod.rs deleted file mode 100644 index 9d0729e..0000000 --- a/src/frontend/style/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ - -pub const CSS_BUNDLE: &'static str = include_str!("layout.css"); diff --git a/src/library.rs b/src/library.rs deleted file mode 100644 index 0c42a73..0000000 --- a/src/library.rs +++ /dev/null @@ -1,141 +0,0 @@ -use crate::metadata::{DirectoryInfo, ItemInfo}; -use anyhow::{anyhow, bail, Context, Ok}; -use std::{ffi::OsStr, fs::File, path::PathBuf, sync::Arc}; - -pub struct Library { - pub root: Arc<Node>, -} - -#[derive(Debug, Clone)] -pub enum Node { - Directory(Arc<Directory>), - Item(Arc<Item>), -} - -#[derive(Debug, Clone)] -pub struct Directory { - pub lib_path: PathBuf, - pub identifier: String, - pub data: DirectoryInfo, - pub children: Vec<Arc<Node>>, -} - -#[derive(Debug, Clone)] -pub struct Item { - pub lib_path: PathBuf, - pub identifier: String, - pub data: ItemInfo, -} - -impl Library { - pub fn open(path: &str) -> anyhow::Result<Self> { - Ok(Self { - root: Node::from_path(path.into(), PathBuf::new(), true).context("indexing root")?, - }) - } - pub fn nested(&self, path: &str) -> anyhow::Result<Arc<Node>> { - let mut n = self.root.clone(); - if path == "" { - return Ok(n); - } - for seg in path.split("/") { - n = n - .get_directory()? - .child_by_ident(seg) - .ok_or(anyhow!("does not exist"))?; - } - Ok(n) - } -} - -impl Node { - pub fn get_directory(&self) -> anyhow::Result<&Directory> { - match self { - Node::Directory(d) => Ok(d), - Node::Item(_) => bail!("not a directory"), - } - } - pub fn title(&self) -> &str { - match self { - Node::Directory(d) => &d.data.name, - Node::Item(i) => &i.data.title, - } - } - pub fn identifier(&self) -> &str { - match self { - Node::Directory(d) => &d.identifier, - Node::Item(i) => &i.identifier, - } - } - 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(), 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, - })) - .into()) - } else if path.is_file() { - let mpath = path.clone().with_extension("metadata.json"); - 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, - })) - .into()) - } else { - bail!("did somebody really put a fifo or socket in the library?!") - } - } -} -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() - .find(|e| e.identifier() == i) - .map(|e| e.to_owned()) - } -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index b7a3249..0000000 --- a/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![feature(box_syntax)] - -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; -pub mod frontend; -pub mod library; -pub mod metadata; - -#[get("/assets/style.css")] -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 { - pub database: Database, - pub library: Library, -} - -#[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 = AppState { - library: Library::open(&lib_path).unwrap(), - database: Database::open(&db_path).unwrap(), - }; - - rocket::build() - .manage(state) - .mount("/", routes![page_home, page_library_node, assets_style]) -} diff --git a/src/metadata.rs b/src/metadata.rs deleted file mode 100644 index ff45af2..0000000 --- a/src/metadata.rs +++ /dev/null @@ -1,11 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct DirectoryInfo { - pub name: String, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct ItemInfo { - pub title: String, -} |