botserver/src/file/mod.rs

79 lines
2.3 KiB
Rust
Raw Normal View History

2025-10-06 10:30:17 -03:00
use actix_multipart::Multipart;
2025-10-06 20:06:43 -03:00
use actix_web::{get, post, web, HttpResponse, Result};
use futures_util::StreamExt as _;
use log::info;
2025-10-06 10:30:17 -03:00
use std::io::Write;
2025-10-06 20:06:43 -03:00
use tokio::fs;
2025-10-06 10:30:17 -03:00
#[post("/files/upload/{folder_path}")]
pub async fn upload_file(
mut payload: Multipart,
2025-10-06 20:06:43 -03:00
path: web::Path<String>,
) -> Result<HttpResponse> {
let folder_path = path.into_inner();
while let Some(item) = payload.next().await {
let mut field = item?;
2025-10-06 10:30:17 -03:00
let content_disposition = field.content_disposition();
2025-10-06 20:06:43 -03:00
let file_name = if let Some(name) = content_disposition.get_filename() {
name.to_string()
} else {
continue;
};
let file_path = format!("./uploads/{}/{}", folder_path, file_name);
if let Some(parent) = std::path::Path::new(&file_path).parent() {
fs::create_dir_all(parent).await?;
2025-10-06 10:30:17 -03:00
}
2025-10-06 20:06:43 -03:00
let mut f = web::block(|| std::fs::File::create(&file_path))
.await??;
2025-10-06 10:30:17 -03:00
2025-10-06 20:06:43 -03:00
while let Some(chunk) = field.next().await {
let data = chunk?;
f = web::block(move || f.write_all(&data).map(|_| f)).await??;
}
}
2025-10-06 10:30:17 -03:00
2025-10-06 20:06:43 -03:00
info!("File uploaded to folder: {}", folder_path);
Ok(HttpResponse::Ok().json(serde_json::json!({"status": "uploaded"})))
2025-10-06 10:30:17 -03:00
}
#[post("/files/list/{folder_path}")]
pub async fn list_file(
2025-10-06 20:06:43 -03:00
path: web::Path<String>,
) -> Result<HttpResponse> {
let folder_path = path.into_inner();
let dir_path = format!("./uploads/{}", folder_path);
let mut entries = Vec::new();
if let Ok(mut read_dir) = fs::read_dir(&dir_path).await {
while let Ok(Some(entry)) = read_dir.next_entry().await {
if let Ok(file_name) = entry.file_name().into_string() {
entries.push(file_name);
2025-10-06 10:30:17 -03:00
}
}
}
2025-10-06 20:06:43 -03:00
Ok(HttpResponse::Ok().json(entries))
}
#[get("/files/download/{file_path:.*}")]
pub async fn download_file(
path: web::Path<String>,
) -> Result<HttpResponse> {
let file_path = path.into_inner();
let full_path = format!("./uploads/{}", file_path);
if let Ok(content) = fs::read(&full_path).await {
Ok(HttpResponse::Ok()
.content_type("application/octet-stream")
.body(content))
} else {
Ok(HttpResponse::NotFound().body("File not found"))
}
2025-10-06 10:30:17 -03:00
}