Fix nested folders

This commit is contained in:
Jackzie 2025-04-15 14:15:19 -05:00
parent 403cf26426
commit e4870bf88e
5 changed files with 58 additions and 20 deletions

View file

@ -71,7 +71,7 @@ async fn rocket() -> _ {
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, ui::user::get_library_file
ui::user::index, ui::user::redirect_list_library_files, ui::user::list_library_files, ui::user::get_library_file
])
.attach(Template::custom(|engines| {
let hb = &mut engines.handlebars;

View file

@ -1,14 +1,17 @@
use std::io::Cursor;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use rocket::{get, Response, State};
use log::debug;
use rocket::{get, uri, Response, State};
use rocket::fs::NamedFile;
use rocket::http::{ContentType, Header};
use rocket::http::hyper::body::Buf;
use rocket::response::{status, Responder};
use rocket::response::{status, Redirect, Responder};
use rocket::response::stream::ByteStream;
use rocket::serde::json::Json;
use rocket::serde::json::{json, Json};
use rocket_dyn_templates::{context, Template};
use serde::Serialize;
use serde_json::Value;
use tokio::sync::Mutex;
use crate::managers::libraries::LibraryManager;
use crate::util::{JsonErrorResponse, ResponseError};
@ -18,24 +21,61 @@ pub async fn index() -> Template {
Template::render("index", context! { test: "value" })
}
#[get("/libraries/<library_id>/<_>/<path..>")]
#[get("/library/<library_id>")]
pub async fn redirect_list_library_files(libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str)
-> Result<Redirect, ResponseError>
{
let libs = libraries.lock().await;
let library = libs.get(library_id).await?;
// let redirect_to = format!("/library/{}/{}/", library_id, library.model().name);
// debug!("{}", redirect_to);
Ok(Redirect::to(uri!(list_library_files(library_id, library.model().name, ""))))
// Ok(Redirect::to(redirect_to))
}
#[get("/library/<library_id>/<_>/<path..>")]
pub async fn list_library_files(libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: PathBuf)
-> Result<Template, ResponseError>
{
let libs = libraries.lock().await;
let library = libs.get(library_id).await?;
let files = library.list_files(&PathBuf::from(path)).await
let files = library.list_files(&PathBuf::from(&path)).await
.map_err(|e| ResponseError::InternalServerError(JsonErrorResponse {
code: "STORAGE_ERROR".to_string(),
message: e.to_string(),
}))?;
// TODO:
// parent
let parent = path.clone();
let mut seg_path = PathBuf::new();
let segments: Vec<PathSegmentPiece> = path.iter()
.map(|segment| {
seg_path = seg_path.join(segment);
PathSegmentPiece {
path: seg_path.clone(),
segment: segment.to_string_lossy().into_owned(),
}
})
.collect();
debug!("parent={:?}", parent);
debug!("segments={:?}", segments);
Ok(Template::render("libraries", context! {
library: library.model(),
files: files
files: files,
parent,
path_segments: segments
}))
}
#[derive(Debug, Serialize)]
struct PathSegmentPiece {
pub path: PathBuf,
pub segment: String
}
#[derive(Responder)]
#[response(status = 200)]
struct FileAttachment {
@ -61,15 +101,9 @@ pub async fn get_library_file<'a>(libraries: &State<Arc<Mutex<LibraryManager>>>,
}))
}
Some(contents) => {
// TODO: headers?
let file_name = path.file_name().unwrap().to_string_lossy();
let ext = path.extension().unwrap().to_string_lossy();
let file_type = ContentType::from_extension(&ext);
// let res = Response::build()
// .header(file_type.unwrap_or(ContentType::Binary))
// .header(Header::new("Content-Disposition", format!("attachment; filename=\"{}\"", file_name)))
// .sized_body(contents.len(), Cursor::new(contents))
// .finalize();
Ok(FileAttachment {
content: contents,
content_type: file_type.unwrap_or(ContentType::Binary),

View file

@ -15,7 +15,7 @@ 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=warn,storage_server=trace").into()),
)
.with(tracing_subscriber::fmt::layer())
.init();

View file

@ -24,7 +24,7 @@
<tbody>
<tr>
<td class="px-4 py-4">
<a href="/libraries/dbabbf7d-9b63-487b-9908-57c2df11b2d2">My Library</a>
<a href="/library/dbabbf7d-9b63-487b-9908-57c2df11b2d2/My Library/">My Library</a>
</td>
<td></td>
<td></td>

View file

@ -2,8 +2,12 @@
<div class="">
<nav class="breadcrumb is-inline-block is-size-5 mb-0" aria-label="breadcrumbs">
<ul>
<li><a class="has-text-black" href="#">{{ library.name }}</a></li>
<li class="is-active"><a class="has-text-black" href="#" aria-current="page">test</a></li>
<li><a class="has-text-black" href="/library/{{library.id}}/{{library.name}}/">{{ library.name }}</a></li>
{{#each path_segments}}
<li>
<a class="has-text-black" href="/library/{{../library.id}}/{{../library.name}}/{{path}}" aria-current="page"> {{ segment }} </a>
</li>
{{/each}}
<div class="button is-small">
+
</div>
@ -61,10 +65,10 @@
</td>
<td class="filecell-label pl-4">
{{#if (eq type "folder")}}
<a href="{{ path }}">{{ path }}/</a>
<a href="{{../parent}}/{{ path }}">{{ path }}/</a>
{{/if}}
{{#if (eq type "file") }}
<a target="_blank" href="/file/{{../library.id}}/{{ path }}">{{ path }}</a>
<a target="_blank" href="/file/{{../library.id}}/{{../parent}}/{{ path }}">{{ path }}</a>
{{/if}}
</td>
<td>{{ bytes size }}</td>