From 670d6c33a66321f2a22fffc24f87feffb01f9679 Mon Sep 17 00:00:00 2001 From: Jackz Date: Mon, 14 Apr 2025 17:32:08 -0500 Subject: [PATCH] reorganized routes --- server/Cargo.lock | 1 + server/Cargo.toml | 3 +- server/src/main.rs | 6 ++- server/src/routes.rs | 68 +----------------------- server/src/routes/api.rs | 1 + server/src/routes/api/library.rs | 88 ++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 69 deletions(-) create mode 100644 server/src/routes/api.rs create mode 100644 server/src/routes/api/library.rs diff --git a/server/Cargo.lock b/server/Cargo.lock index 9d0f1af..956cc4b 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -2042,6 +2042,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", + "dotenvy", "int-enum", "log", "rocket", diff --git a/server/Cargo.toml b/server/Cargo.toml index acc55a6..731aef6 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -13,4 +13,5 @@ chrono = { version = "0.4.40", features = ["serde"] } anyhow = "1.0.98" serde = "1.0.219" serde_json = "1.0.140" -int-enum = "1.2.0" \ No newline at end of file +int-enum = "1.2.0" +dotenvy = "0.15.7" \ No newline at end of file diff --git a/server/src/main.rs b/server/src/main.rs index a5a482d..cb5b345 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -10,6 +10,7 @@ use crate::managers::libraries::LibraryManager; use crate::managers::repos::RepoManager; use crate::objs::library::Library; use crate::util::{setup_logger, JsonErrorResponse, ResponseError}; +use routes::api; mod routes; mod util; @@ -27,6 +28,7 @@ const MAX_UPLOAD_SIZE: ByteUnit = ByteUnit::Mebibyte(100_000); #[launch] async fn rocket() -> _ { setup_logger(); + dotenvy::dotenv().ok(); debug!("{}", std::env::var("DATABASE_URL").unwrap().as_str()); let pool = PgPoolOptions::new() .max_connections(5) @@ -52,7 +54,9 @@ async fn rocket() -> _ { .manage(pool) .manage(repo_manager) .manage(libraries_manager) - .mount("/api", routes![routes::index, routes::get_library, routes::list_library_files, routes::get_library_file, routes::upload_library_file, routes::move_library_file]) + .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, + ]) } #[catch(404)] diff --git a/server/src/routes.rs b/server/src/routes.rs index 55868e3..5050ca9 100644 --- a/server/src/routes.rs +++ b/server/src/routes.rs @@ -18,70 +18,4 @@ use crate::models::user; use crate::storage::FileEntry; use crate::util::{JsonErrorResponse, ResponseError}; -#[get("/")] -pub(crate) fn index() -> &'static str { - "Hello, world!" -} - - -#[get("/library/")] -pub(crate) async fn get_library(pool: &State, library_id: &str) -> Result>, ResponseError> { - let library = models::library::get_library_with_repo(pool, library_id).await - .map_err(|e| ResponseError::GenericError)?; - debug!("{:?}", library); - Ok(library.map(|lib| Json(lib))) -} - -#[get("/library//files?")] -pub(crate) async fn list_library_files(pool: &State, libraries: &State>>, library_id: &str, path: &str) -> Result>, ResponseError> { - let libs = libraries.lock().await; - let library = libs.get(library_id).await?; - library.list_files(&PathBuf::from(path)).await - .map(|files| Json(files)) - .map_err(|e| ResponseError::InternalServerError(JsonErrorResponse { - code: "STORAGE_ERROR".to_string(), - message: e.to_string(), - })) -} - -#[get("/library//files/download?")] -pub(crate) async fn get_library_file(pool: &State, libraries: &State>>, library_id: &str, path: &str) -> Result, ResponseError> { - let libs = libraries.lock().await; - let library = libs.get(library_id).await?; - match library.read_file(&PathBuf::from(path)).await - .map_err(|e| ResponseError::GenericError)? - { - None => { - Err(ResponseError::NotFound(JsonErrorResponse { - code: "FILE_NOT_FOUND".to_string(), - message: "Requested file does not exist".to_string() - })) - } - Some(contents) => { - // TODO: headers? - Ok(contents) - } - } -} - -#[post("/library//files/move?&")] -pub(crate) async fn move_library_file(pool: &State, libraries: &State>>, library_id: &str, from: &str, to: &str) -> Result<(), ResponseError> { - let libs = libraries.lock().await; - let library = libs.get(library_id).await?; - library.move_file(&PathBuf::from(from), &PathBuf::from(to)).await - .map_err(|e| ResponseError::GenericError) -} - -#[post("/library//files?", data = "")] -pub(crate) async fn upload_library_file(pool: &State, libraries: &State>>, library_id: &str, path: &str, data: Data<'_>) -> Result { - let libs = libraries.lock().await; - let library = libs.get(library_id).await?; - let mut stream = data.open(MAX_UPLOAD_SIZE); - // TODO: don't just copy all to memory - let mut buf = Vec::new(); - stream.read_to_end(&mut buf).await.unwrap(); - - library.write_file(&PathBuf::from(path), &buf).await - .map_err(|e| ResponseError::GenericError)?; - Ok(status::NoContent) -} \ No newline at end of file +pub mod api; diff --git a/server/src/routes/api.rs b/server/src/routes/api.rs new file mode 100644 index 0000000..e7d496c --- /dev/null +++ b/server/src/routes/api.rs @@ -0,0 +1 @@ +pub mod library; \ No newline at end of file diff --git a/server/src/routes/api/library.rs b/server/src/routes/api/library.rs new file mode 100644 index 0000000..f50bb18 --- /dev/null +++ b/server/src/routes/api/library.rs @@ -0,0 +1,88 @@ +use std::path::PathBuf; +use std::sync::Arc; +use log::debug; +use rocket::{delete, get, post, Data, Route, State}; +use rocket::fs::TempFile; +use rocket::http::Status; +use rocket::response::status; +use rocket::serde::json::Json; +use sqlx::{query, Postgres}; +use sqlx::types::{Uuid}; +use tokio::io::AsyncReadExt; +use tokio::sync::Mutex; +use crate::{library, models, DB, MAX_UPLOAD_SIZE}; +use crate::managers::libraries::LibraryManager; +use crate::managers::repos::RepoManager; +use crate::models::library::{LibraryModel, LibraryWithRepoModel}; +use crate::models::user; +use crate::storage::FileEntry; +use crate::util::{JsonErrorResponse, ResponseError}; +#[get("/")] +pub(crate) async fn get_file(pool: &State, library_id: &str) -> Result>, ResponseError> { + let library = models::library::get_library_with_repo(pool, library_id).await + .map_err(|e| ResponseError::GenericError)?; + Ok(library.map(|lib| Json(lib))) +} + +#[get("//files?")] +pub(crate) async fn list_files(libraries: &State>>, library_id: &str, path: &str) -> Result>, ResponseError> { + let libs = libraries.lock().await; + let library = libs.get(library_id).await?; + library.list_files(&PathBuf::from(path)).await + .map(|files| Json(files)) + .map_err(|e| ResponseError::InternalServerError(JsonErrorResponse { + code: "STORAGE_ERROR".to_string(), + message: e.to_string(), + })) +} + +#[get("//files/download?")] +pub(crate) async fn download_file(libraries: &State>>, library_id: &str, path: &str) -> Result, ResponseError> { + let libs = libraries.lock().await; + let library = libs.get(library_id).await?; + match library.read_file(&PathBuf::from(path)).await + .map_err(|e| ResponseError::GenericError)? + { + None => { + Err(ResponseError::NotFound(JsonErrorResponse { + code: "FILE_NOT_FOUND".to_string(), + message: "Requested file does not exist".to_string() + })) + } + Some(contents) => { + // TODO: headers? + Ok(contents) + } + } +} + +#[post("//files/move?&")] +pub(crate) async fn move_file(libraries: &State>>, library_id: &str, from: &str, to: &str) -> Result<(), ResponseError> { + let libs = libraries.lock().await; + let library = libs.get(library_id).await?; + library.move_file(&PathBuf::from(from), &PathBuf::from(to)).await + .map_err(|e| ResponseError::GenericError) +} + +#[post("//files?", data = "")] +pub(crate) async fn upload_file(libraries: &State>>, library_id: &str, path: &str, data: Data<'_>) -> Result { + let libs = libraries.lock().await; + let library = libs.get(library_id).await?; + let mut stream = data.open(MAX_UPLOAD_SIZE); + // TODO: don't just copy all to memory + let mut buf = Vec::new(); + stream.read_to_end(&mut buf).await.unwrap(); + + library.write_file(&PathBuf::from(path), &buf).await + .map_err(|e| ResponseError::GenericError)?; + Ok(status::NoContent) +} + +#[delete("//files/move?")] +pub(crate) async fn delete_file(libraries: &State>>, library_id: &str, path: &str) -> Result<(), ResponseError> { + let libs = libraries.lock().await; + let library = libs.get(library_id).await?; + library.delete_file(&PathBuf::from(path)).await + .map_err(|e| ResponseError::GenericError) +} +