feat: ✨ upload package
This commit is contained in:
parent
9c64df93fd
commit
e5e3bf2de5
7 changed files with 60 additions and 11 deletions
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
axum = "0.7.7"
|
||||
axum = { version = "0.7.7", features = ["multipart"] }
|
||||
futures = "0.3.31"
|
||||
serde = { version = "1.0.210", features = ["derive"] }
|
||||
serde_json = "1.0.128"
|
||||
|
|
|
@ -11,7 +11,9 @@ use crate::package::package::Package;
|
|||
static DB: LazyLock<Surreal<Client>> = LazyLock::new(Surreal::init);
|
||||
|
||||
pub async fn establish_connection() -> Result<(), surrealdb::Error> {
|
||||
DB.connect::<Ws>("localhost:8000").await
|
||||
DB.connect::<Ws>("localhost:8000").await?;
|
||||
DB.use_ns("Packages").await?;
|
||||
DB.use_db("Packages").await
|
||||
}
|
||||
|
||||
pub async fn is_alive() -> bool {
|
||||
|
|
|
@ -3,5 +3,7 @@ pub mod http;
|
|||
pub mod package;
|
||||
pub mod routing;
|
||||
|
||||
pub const PACKAGE_PATH: &str = "/packages";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppState {}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
use rust_package_manager::{database, routing, AppState};
|
||||
// use axum::routing::{self};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
println!("Hello, world!");
|
||||
|
||||
let listener = TcpListener::bind("192.168.1.2:2345").await.unwrap();
|
||||
let listener = TcpListener::bind("localhost:2345").await.unwrap();
|
||||
database::establish_connection().await.unwrap();
|
||||
let app_state = AppState {};
|
||||
let router = routing::route(axum::extract::State(app_state)).await;
|
||||
|
|
|
@ -68,6 +68,9 @@ impl Package {
|
|||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
pub fn set_location(&mut self, location: &String) {
|
||||
self.location = location.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use crate::{database, routing};
|
||||
use axum::extract::Multipart;
|
||||
use tokio::{fs::File, io::AsyncWriteExt};
|
||||
use tokio_util::io::ReaderStream;
|
||||
|
||||
use crate::{database, routing, PACKAGE_PATH};
|
||||
|
||||
use super::package::Package;
|
||||
|
||||
|
@ -19,3 +23,36 @@ pub async fn update_package(package_name: String, package: routing::Package) ->
|
|||
pub async fn delete_package(package_name: String) -> Option<Package> {
|
||||
database::delete_package(package_name).await
|
||||
}
|
||||
|
||||
pub async fn download_package(package_name: String) -> Option<ReaderStream<File>> {
|
||||
if let Some(package) = crate::package::utils::read_package(package_name).await {
|
||||
if let Some(package_file_stream) = package.serve().await {
|
||||
return Some(package_file_stream);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub async fn upload_package(mut package_file: Multipart) -> Option<Package> {
|
||||
if let Ok(package_file_part_unchecked) = package_file.next_field().await {
|
||||
if let Some(package_file_part) = package_file_part_unchecked {
|
||||
if let Some(package_file_name) = package_file_part.file_name() {
|
||||
let package_file_name = package_file_name.to_owned();
|
||||
let file_location = format!("./{}/{}", PACKAGE_PATH, package_file_name);
|
||||
if let Ok(package_file_data) = package_file_part.bytes().await {
|
||||
if let Some(mut package) =
|
||||
crate::package::utils::read_package(package_file_name.to_owned()).await
|
||||
{
|
||||
if let Ok(mut file_descriptor) = File::create_new(&file_location).await {
|
||||
if let Ok(_) = file_descriptor.write_all(&package_file_data).await {
|
||||
package.set_location(&file_location);
|
||||
return Some(package);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use axum::{
|
||||
body::Body,
|
||||
extract::{Path, State},
|
||||
extract::{Multipart, Path, State},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, get, patch, post},
|
||||
|
@ -30,6 +30,7 @@ pub async fn route(State(app_state): State<AppState>) -> Router {
|
|||
.route("/package/:package_name", patch(update_package))
|
||||
.route("/package/:package_name", delete(delete_package))
|
||||
.route("/package/download/:package_name", get(download_package))
|
||||
.route("/package/upload", post(upload_package))
|
||||
.layer(CorsLayer::permissive())
|
||||
.with_state(app_state)
|
||||
}
|
||||
|
@ -79,10 +80,15 @@ async fn delete_package(Path(package_name): Path<String>) -> impl IntoResponse {
|
|||
}
|
||||
|
||||
async fn download_package(Path(package_name): Path<String>) -> impl IntoResponse {
|
||||
if let Some(package) = crate::package::utils::read_package(package_name).await {
|
||||
if let Some(package_file_stream) = package.serve().await {
|
||||
return (StatusCode::OK, Body::from_stream(package_file_stream));
|
||||
}
|
||||
match crate::package::utils::download_package(package_name).await {
|
||||
Some(package_file_stream) => (StatusCode::OK, Body::from_stream(package_file_stream)),
|
||||
None => (StatusCode::BAD_REQUEST, Body::empty()),
|
||||
}
|
||||
}
|
||||
|
||||
async fn upload_package(package_file: Multipart) -> impl IntoResponse {
|
||||
match crate::package::utils::upload_package(package_file).await {
|
||||
Some(package) => (StatusCode::ACCEPTED, Json(serde_json::json!(package))),
|
||||
None => (StatusCode::BAD_REQUEST, Json(serde_json::json!(""))),
|
||||
}
|
||||
(StatusCode::BAD_REQUEST, Body::empty())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue