feat: enable script upload

This commit is contained in:
itsscb 2025-05-26 22:15:50 +02:00
parent 001be86948
commit de9500bd16
3 changed files with 37 additions and 5 deletions

View File

@ -6,7 +6,7 @@ description = "PowerShell Scripts for EVERYONE!"
repository = "https://git.itsscb.de/itsscb/BefehlsWerk"
[dependencies]
axum = { version = "0.8.4", features = ["ws"] }
axum = { version = "0.8.4", features = ["multipart", "ws"] }
chrono = "0.4.41"
futures = "0.3.31"
serde = { version = "1.0.219", features = ["derive", "rc"] }

View File

@ -1,5 +1,5 @@
use axum::routing::{delete, get, get_service};
use routes::scripts::{delete_script, get_script_by_id, get_scripts};
use axum::routing::{delete, get, get_service, post};
use routes::scripts::{delete_script, get_script_by_id, get_scripts, upload_script};
use sqlx::SqlitePool;
use tower_http::services::ServeDir;
mod routes;
@ -8,6 +8,7 @@ pub fn new_router(db: SqlitePool) -> axum::Router {
axum::Router::new()
.fallback_service(get_service(ServeDir::new("assets")))
.route("/scripts", get(get_scripts))
.route("/scripts", post(upload_script))
.route("/scripts/{id}", get(get_script_by_id))
.route("/scripts/{id}", delete(delete_script))
.with_state(db)

View File

@ -1,12 +1,38 @@
use axum::{
extract::{Path, State},
extract::{Multipart, Path, State},
http::StatusCode,
response::{Html, IntoResponse, Redirect},
};
use sqlx::SqlitePool;
use std::fmt::Write;
use tokio::io::AsyncWriteExt;
use tracing::{error, info, instrument, warn};
#[allow(clippy::unwrap_used)]
#[instrument(skip_all)]
pub async fn upload_script(
// State(database): State<SqlitePool>,
mut multipart: Multipart,
) -> impl IntoResponse {
while let Some(field) = multipart.next_field().await.unwrap() {
// Borrow file_name as &str
let file_name = field.file_name().map(|name| name.to_string());
// Now you can move or consume `field` safely
let data = field.bytes().await.unwrap();
if let Some(name) = file_name {
let _ = tokio::fs::create_dir("./uploads").await;
// Use `name` (owned String) and `data` here
let path = format!("./uploads/{}", name);
let mut file = tokio::fs::File::create(path).await.unwrap();
file.write_all(&data).await.unwrap();
// tokio::fs::write(path, &data).await.unwrap();
}
}
Html("File uploaded successfully")
}
#[instrument(skip_all, fields(id = ?Path(&id)))]
pub async fn delete_script(
State(database): State<SqlitePool>,
@ -88,7 +114,12 @@ pub async fn get_scripts(State(database): State<SqlitePool>) -> impl IntoRespons
});
let output = format!(
r##"<section id="scripts"><ul>{content}</ul><button hx-get="/scripts" hx-swap="outerHTML" hx-target="#scripts">Refresh</button></section>"##
r##"<section id="scripts"><ul>{content}</ul><button hx-get="/scripts" hx-swap="outerHTML" hx-target="#scripts">Refresh</button><form hx-post="/scripts" hx-target="#upload-status" enctype="multipart/form-data" method="post">
<input type="file" name="file" />
<button type="submit">Upload</button>
</form>
<div id="upload-status"></div>
</section>"##
);
Ok(Html(output))