diff --git a/server/src/main.rs b/server/src/main.rs index f936cce..3c7e84f 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,5 +1,5 @@ use std::sync::Arc; -use log::debug; +use log::{debug, error, info, trace, warn}; use rocket::{catch, launch, routes, Request, State}; use rocket::data::ByteUnit; use rocket::fs::{relative, FileServer}; @@ -34,7 +34,11 @@ async fn rocket() -> _ { setup_logger(); dotenvy::dotenv().ok(); - let handlebars = Handlebars::new(); + trace!("trace"); + debug!("debug"); + info!("info"); + warn!("warn"); + error!("error"); let pool = PgPoolOptions::new() .max_connections(5) @@ -61,13 +65,16 @@ async fn rocket() -> _ { .manage(repo_manager) .manage(libraries_manager) .mount("/static", FileServer::from(relative!("static"))) + .mount("/api/library", routes![ + api::library::move_file, api::library::upload_file, api::library::download_file, api::library::list_files, api::library::get_file, api::library::delete_file, + ]) .mount("/", routes![ ui::user::index, ui::user::list_library_files ]) - .mount("/api", routes![ - api::library::move_file, api::library::upload_file, api::library::download_file, api::library::list_files, api::library::get_file, api::library::delete_file, - ]) - .attach(Template::fairing()) + .attach(Template::custom(|engines| { + let _ = engines + .handlebars; + })) } diff --git a/server/src/storage.rs b/server/src/storage.rs index 59b958a..75d963e 100644 --- a/server/src/storage.rs +++ b/server/src/storage.rs @@ -17,12 +17,39 @@ pub enum StorageBackendMap { } #[derive(Debug, Serialize, Deserialize)] -pub struct FileEntry { - pub file_name: String, - // last_modified: - pub file_size: u64, +#[serde(rename_all = "lowercase")] +pub enum FileType { + File, + Folder, + Symlink, + Other } +impl From for FileType { + fn from(value: std::fs::FileType) -> Self { + if value.is_file() { + FileType::File + } else if value.is_dir() { + FileType::Folder + } else if value.is_symlink() { + FileType::Symlink + } else { + FileType::Other + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct FileEntry { + pub path: String, + // last_modified: + pub size: u64, + #[serde(rename="type")] + pub _type: FileType, +} + + + pub fn get_backend(storage_type: &str, settings: &JsonValue) -> Result>, anyhow::Error> { Ok(match storage_type { "local" => Some(Box::new(LocalStorage::new(settings)?)), diff --git a/server/src/storage/local.rs b/server/src/storage/local.rs index 77ed57e..769b96d 100644 --- a/server/src/storage/local.rs +++ b/server/src/storage/local.rs @@ -19,7 +19,10 @@ impl LocalStorage { } } -fn get_path(folder_root: &PathBuf, library_id: &str, path: &PathBuf) -> Result { +fn get_path(folder_root: &PathBuf, library_id: &str, mut path: &Path) -> Result { + if path.starts_with("/") { + path = path.strip_prefix("/")? + } let path = folder_root.join(library_id).join(path); // Prevent path traversal debug!("root={:?}", folder_root); @@ -51,9 +54,12 @@ impl StorageBackend for LocalStorage { .map(|entry| entry.unwrap()) .map(|entry| { let meta = entry.metadata().unwrap(); + let file_type = meta.file_type().into(); + // TODO: filter out 'other' FileEntry { - file_name: entry.file_name().into_string().unwrap(), - file_size: meta.size() + _type: file_type, + path: entry.file_name().into_string().unwrap(), + size: meta.size() } }) .collect()) diff --git a/server/src/util.rs b/server/src/util.rs index 3047c5c..e2dfd3a 100644 --- a/server/src/util.rs +++ b/server/src/util.rs @@ -1,8 +1,11 @@ +use std::fs; use std::io::Cursor; use rocket::http::{ContentType, Status}; use rocket::{response, Request, Response}; +use rocket::fs::relative; use rocket::response::Responder; use rocket::serde::Serialize; +use rocket_dyn_templates::handlebars::Handlebars; use sqlx::Error; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; @@ -12,12 +15,32 @@ pub(crate) fn setup_logger() { tracing_subscriber::registry() .with( tracing_subscriber::filter::EnvFilter::try_from_default_env() - .unwrap_or_else(|_| format!("warn,rocket=trace,storage-server=trace").into()), + .unwrap_or_else(|_| format!("warn,rocket=trace,storage_server=trace").into()), ) .with(tracing_subscriber::fmt::layer()) .init(); } +// pub(crate) fn setup_template_engine() -> Handlebars<'static> { +// let mut hb = Handlebars::new(); +// #[cfg(debug_assertions)] +// hb.set_dev_mode(true); +// +// let templates = fs::read_dir(relative!("templates")).unwrap(); +// let mut ok = true; +// for file in templates { +// let file = file.unwrap(); +// if let Err(e) = hb.register_template_file(file.path().to_str().unwrap(), ) { +// error!(template, path = %path.display(), +// "failed to register Handlebars template: {e}"); +// +// ok = false; +// } +// } +// +// hb +// } + #[derive(Debug, Clone, Serialize)] pub struct JsonErrorResponse { pub(crate) code: String, diff --git a/server/static/css/main.css b/server/static/css/main.css index 26f8503..dbd52cb 100644 --- a/server/static/css/main.css +++ b/server/static/css/main.css @@ -26,4 +26,33 @@ } .sidebar-list li button:hover, .sidebar-list li button.is-active { background-color: lightgray; +} + +.sidebar-column { + height: 100%; +} + +html,body { + height: 100%; +} +.sidebar-column { + border-right: 1px solid lightgray; +} +tr.file-list td { + vertical-align: middle; + padding: 0; +} + +tr.file-list td input[type="checkbox"] { + margin: 20px; /** this weirdly makes it look good TODO: fix */ + -ms-transform: scale(1.5); + /* IE */ + -moz-transform: scale(1.5); + /* FF */ + -webkit-transform: scale(1.5); + /* Safari and Chrome */ + -o-transform: scale(1.5); + /* Opera */ + transform: scale(1.5); + padding: 10px; } \ No newline at end of file diff --git a/server/templates/layouts/main.html.hbs b/server/templates/layouts/main.html.hbs index 88dc1c6..806c1d1 100644 --- a/server/templates/layouts/main.html.hbs +++ b/server/templates/layouts/main.html.hbs @@ -10,12 +10,12 @@ - + {{> partials/nav }} -
+
diff --git a/server/templates/libraries.html.hbs b/server/templates/libraries.html.hbs index 02ea67f..6d4729f 100644 --- a/server/templates/libraries.html.hbs +++ b/server/templates/libraries.html.hbs @@ -1,6 +1,14 @@ {{#> layouts/main }} -
-

{{ library.name }} > Files

+
+
@@ -9,12 +17,21 @@
Sort
+
+ Info +
+
+ ... +

- + + + + @@ -23,9 +40,30 @@ {{#each files }} - - + + + + diff --git a/server/templates/partials/breadcrumb.html.hbs b/server/templates/partials/breadcrumb.html.hbs new file mode 100644 index 0000000..d049c80 --- /dev/null +++ b/server/templates/partials/breadcrumb.html.hbs @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/server/templates/partials/nav.html.hbs b/server/templates/partials/nav.html.hbs index 9f835c6..7a8a84c 100644 --- a/server/templates/partials/nav.html.hbs +++ b/server/templates/partials/nav.html.hbs @@ -14,6 +14,16 @@
Name Size Last Updated
- {{ file_name }} +
+ + + + + + + + {{#if (eq type "folder") }} + + {{/if}} + {{#if (eq type "file") }} + + {{/if}} + + + {{ path }} + {{#if (eq type "folder") }} + / + {{/if}}