mirror of
https://github.com/Jackzmc/storage.git
synced 2025-05-06 12:03:20 +00:00
reorganized routes
This commit is contained in:
parent
361459d931
commit
670d6c33a6
6 changed files with 98 additions and 69 deletions
1
server/Cargo.lock
generated
1
server/Cargo.lock
generated
|
@ -2042,6 +2042,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"dotenvy",
|
||||||
"int-enum",
|
"int-enum",
|
||||||
"log",
|
"log",
|
||||||
"rocket",
|
"rocket",
|
||||||
|
|
|
@ -13,4 +13,5 @@ chrono = { version = "0.4.40", features = ["serde"] }
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
serde = "1.0.219"
|
serde = "1.0.219"
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
int-enum = "1.2.0"
|
int-enum = "1.2.0"
|
||||||
|
dotenvy = "0.15.7"
|
|
@ -10,6 +10,7 @@ use crate::managers::libraries::LibraryManager;
|
||||||
use crate::managers::repos::RepoManager;
|
use crate::managers::repos::RepoManager;
|
||||||
use crate::objs::library::Library;
|
use crate::objs::library::Library;
|
||||||
use crate::util::{setup_logger, JsonErrorResponse, ResponseError};
|
use crate::util::{setup_logger, JsonErrorResponse, ResponseError};
|
||||||
|
use routes::api;
|
||||||
|
|
||||||
mod routes;
|
mod routes;
|
||||||
mod util;
|
mod util;
|
||||||
|
@ -27,6 +28,7 @@ const MAX_UPLOAD_SIZE: ByteUnit = ByteUnit::Mebibyte(100_000);
|
||||||
#[launch]
|
#[launch]
|
||||||
async fn rocket() -> _ {
|
async fn rocket() -> _ {
|
||||||
setup_logger();
|
setup_logger();
|
||||||
|
dotenvy::dotenv().ok();
|
||||||
debug!("{}", std::env::var("DATABASE_URL").unwrap().as_str());
|
debug!("{}", std::env::var("DATABASE_URL").unwrap().as_str());
|
||||||
let pool = PgPoolOptions::new()
|
let pool = PgPoolOptions::new()
|
||||||
.max_connections(5)
|
.max_connections(5)
|
||||||
|
@ -52,7 +54,9 @@ async fn rocket() -> _ {
|
||||||
.manage(pool)
|
.manage(pool)
|
||||||
.manage(repo_manager)
|
.manage(repo_manager)
|
||||||
.manage(libraries_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)]
|
#[catch(404)]
|
||||||
|
|
|
@ -18,70 +18,4 @@ use crate::models::user;
|
||||||
use crate::storage::FileEntry;
|
use crate::storage::FileEntry;
|
||||||
use crate::util::{JsonErrorResponse, ResponseError};
|
use crate::util::{JsonErrorResponse, ResponseError};
|
||||||
|
|
||||||
#[get("/")]
|
pub mod api;
|
||||||
pub(crate) fn index() -> &'static str {
|
|
||||||
"Hello, world!"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[get("/library/<library_id>")]
|
|
||||||
pub(crate) async fn get_library(pool: &State<DB>, library_id: &str) -> Result<Option<Json<LibraryWithRepoModel>>, 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/<library_id>/files?<path>")]
|
|
||||||
pub(crate) async fn list_library_files(pool: &State<DB>, libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: &str) -> Result<Json<Vec<FileEntry>>, 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/<library_id>/files/download?<path>")]
|
|
||||||
pub(crate) async fn get_library_file(pool: &State<DB>, libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: &str) -> Result<Vec<u8>, 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/<library_id>/files/move?<from>&<to>")]
|
|
||||||
pub(crate) async fn move_library_file(pool: &State<DB>, libraries: &State<Arc<Mutex<LibraryManager>>>, 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/<library_id>/files?<path>", data = "<data>")]
|
|
||||||
pub(crate) async fn upload_library_file(pool: &State<DB>, libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: &str, data: Data<'_>) -> Result<status::NoContent, ResponseError> {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
1
server/src/routes/api.rs
Normal file
1
server/src/routes/api.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod library;
|
88
server/src/routes/api/library.rs
Normal file
88
server/src/routes/api/library.rs
Normal file
|
@ -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("/<library_id>")]
|
||||||
|
pub(crate) async fn get_file(pool: &State<DB>, library_id: &str) -> Result<Option<Json<LibraryWithRepoModel>>, 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("/<library_id>/files?<path>")]
|
||||||
|
pub(crate) async fn list_files(libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: &str) -> Result<Json<Vec<FileEntry>>, 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_id>/files/download?<path>")]
|
||||||
|
pub(crate) async fn download_file(libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: &str) -> Result<Vec<u8>, 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_id>/files/move?<from>&<to>")]
|
||||||
|
pub(crate) async fn move_file(libraries: &State<Arc<Mutex<LibraryManager>>>, 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_id>/files?<path>", data = "<data>")]
|
||||||
|
pub(crate) async fn upload_file(libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: &str, data: Data<'_>) -> Result<status::NoContent, ResponseError> {
|
||||||
|
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("/<library_id>/files/move?<path>")]
|
||||||
|
pub(crate) async fn delete_file(libraries: &State<Arc<Mutex<LibraryManager>>>, 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)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue