diff options
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/library.rs | 19 | ||||
-rw-r--r-- | server/src/main.rs | 50 |
2 files changed, 58 insertions, 11 deletions
diff --git a/server/src/library.rs b/server/src/library.rs index c46937a..4bded8a 100644 --- a/server/src/library.rs +++ b/server/src/library.rs @@ -22,6 +22,7 @@ pub struct Directory { #[derive(Debug, Clone)] pub struct Item { + pub fs_path: PathBuf, pub lib_path: PathBuf, pub identifier: String, pub data: ItemInfo, @@ -49,12 +50,18 @@ impl Library { } impl Node { - pub fn get_directory(&self) -> anyhow::Result<&Directory> { + pub fn get_directory(&self) -> anyhow::Result<Arc<Directory>> { match self { - Node::Directory(d) => Ok(d), + Node::Directory(d) => Ok(d.clone()), Node::Item(_) => bail!("not a directory"), } } + pub fn get_item(&self) -> anyhow::Result<Arc<Item>> { + match self { + Node::Item(i) => Ok(i.clone()), + Node::Directory(_) => bail!("not an item"), + } + } pub fn title(&self) -> &str { match self { Node::Directory(d) => &d.data.name, @@ -86,9 +93,10 @@ impl Node { .read_dir()? .filter_map(|e| { let e = e.unwrap(); - eprintln!("{:?}",e.path()); - eprintln!("{:?}",e.path().extension()); - if e.path().extension() == Some(OsStr::new("json")) + eprintln!("{:?}", e.path()); + eprintln!("{:?}", e.path().extension()); + if (e.path().extension() == Some(OsStr::new("json")) + && e.path().file_name() != Some(OsStr::new("directory.json"))) || e.metadata().unwrap().is_dir() { Some(e.path()) @@ -121,6 +129,7 @@ impl Node { .unwrap() .to_string(); Ok(Node::Item(Arc::new(Item { + fs_path: path.clone(), lib_path: lib_path.join(identifier.clone()), data, identifier, diff --git a/server/src/main.rs b/server/src/main.rs index 36571f0..3f8d241 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,11 +1,14 @@ #![feature(box_syntax)] -use crate::frontend::style::CSS_BUNDLE; +use crate::frontend::{pages::MyError, style::CSS_BUNDLE}; use database::Database; use frontend::pages::{home::page_home, node::page_library_node}; +use jellyremuxer::{RemuxerContext, SendWriter}; use library::Library; -use rocket::{get, http::ContentType, launch, routes}; -use std::fs::read_to_string; +use log::debug; +use rocket::{get, http::ContentType, launch, response::stream::ByteStream, routes, State}; +use std::{fs::read_to_string, sync::Arc}; +use tokio::sync::mpsc; pub mod database; pub mod frontend; @@ -23,9 +26,42 @@ async fn assets_style() -> (ContentType, String) { ) } +#[get("/stream?<selection>")] +fn stream( + selection: String, + state: &State<AppState>, +) -> Result<(ContentType, ByteStream![Vec<u8>]), MyError> { + let (tx, mut rx) = mpsc::channel(16); + let item = state.library.nested("mili-bento-box-bivouac")?.get_item()?; + debug!("generating matroska"); + let remuxer = state.remuxer.clone(); + tokio::task::spawn_blocking(move || { + remuxer + .generate_into( + SendWriter(tx), + // SyncIoBridge() + item.fs_path.parent().unwrap().to_path_buf(), + item.data.clone(), + selection.split(",").map(|e| e.parse().unwrap()).collect(), + ) + .unwrap(); + }); + debug!("starting stream"); + Ok(( + ContentType::WEBM, + ByteStream! { + while let Some(x) = rx.recv().await { + debug!("yield {x:?}"); + yield x + } + }, + )) +} + pub struct AppState { pub database: Database, pub library: Library, + pub remuxer: Arc<RemuxerContext>, } #[launch] @@ -34,11 +70,13 @@ fn rocket() -> _ { 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 { + remuxer: RemuxerContext::new(), 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]) + rocket::build().manage(state).mount( + "/", + routes![page_home, page_library_node, assets_style, stream], + ) } |