feat: upload package

This commit is contained in:
Ahmet Kaan GÜMÜŞ 2024-11-20 00:16:31 +03:00
parent 9c64df93fd
commit e5e3bf2de5
7 changed files with 60 additions and 11 deletions

View file

@ -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"

View file

@ -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 {

View file

@ -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 {}

View file

@ -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;

View file

@ -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)]

View file

@ -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
}

View file

@ -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())
}