feat: api and html ingress routes

This commit is contained in:
Per Stark
2025-01-03 15:33:08 +01:00
parent 4366c88b42
commit a7eb5105e5
4 changed files with 29 additions and 58 deletions

View File

@@ -20,8 +20,7 @@ use zettle_db::{
middleware_api_auth::api_auth,
routes::{
api::{
file::upload_handler, ingress::ingress_data, query::query_handler,
queue_length::queue_length_handler,
ingress::ingress_data, query::query_handler, queue_length::queue_length_handler,
},
html::{
account::{delete_account, set_api_key, show_account_page},
@@ -134,8 +133,6 @@ fn api_routes_v1(app_state: &AppState) -> Router<AppState> {
// Ingress routes
.route("/ingress", post(ingress_data))
.route("/message_count", get(queue_length_handler))
// File routes
.route("/file", post(upload_handler))
.layer(DefaultBodyLimit::max(1024 * 1024 * 1024))
// Query routes
.route("/query", post(query_handler))

View File

@@ -1,44 +0,0 @@
use crate::{
error::{ApiError, AppError},
server::AppState,
storage::types::file_info::FileInfo,
};
use axum::{extract::State, response::IntoResponse, Json};
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
use serde_json::json;
use tempfile::NamedTempFile;
use tracing::info;
#[derive(Debug, TryFromMultipart)]
pub struct FileUploadRequest {
#[form_data(limit = "1000000")] // Example limit: ~1000 KB
pub file: FieldData<NamedTempFile>,
}
/// Handler to upload a new file.
///
/// Route: POST /file
pub async fn upload_handler(
State(state): State<AppState>,
TypedMultipart(input): TypedMultipart<FileUploadRequest>,
) -> Result<impl IntoResponse, ApiError> {
info!("Received an upload request");
// Process the file upload
let file_info = FileInfo::new(input.file, &state.surreal_db_client)
.await
.map_err(AppError::from)?;
// Prepare the response JSON
let response = json!({
"id": file_info.id,
"sha256": file_info.sha256,
"path": file_info.path,
"mime_type": file_info.mime_type,
});
info!("File uploaded successfully: {:?}", file_info);
// Return the response with HTTP 200
Ok((axum::http::StatusCode::OK, Json(response)))
}

View File

@@ -1,4 +1,3 @@
pub mod file;
pub mod ingress;
pub mod query;
pub mod queue_length;

View File

@@ -5,6 +5,7 @@ use axum::{
use axum_session_auth::AuthSession;
use axum_session_surreal::SessionSurrealPool;
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
use futures::{future::try_join_all, TryFutureExt};
use serde::Serialize;
use surrealdb::{engine::any::Any, Surreal};
use tempfile::NamedTempFile;
@@ -12,6 +13,7 @@ use tracing::info;
use crate::{
error::{AppError, HtmlError},
ingress::types::ingress_input::{create_ingress_objects, IngressInput},
server::AppState,
storage::types::{file_info::FileInfo, user::User},
};
@@ -52,22 +54,39 @@ pub async fn process_ingress_form(
auth: AuthSession<User, String, SessionSurrealPool<Any>, Surreal<Any>>,
TypedMultipart(input): TypedMultipart<IngressParams>,
) -> Result<impl IntoResponse, HtmlError> {
let _user = match auth.current_user {
let user = match auth.current_user {
Some(user) => user,
None => return Ok(Redirect::to("/").into_response()),
};
info!("{:?}", input);
// Process files and create FileInfo objects
let mut file_infos = Vec::new();
for file in input.files {
let file_info = FileInfo::new(file, &state.surreal_db_client)
.await
.map_err(|e| HtmlError::new(AppError::from(e), state.templates.clone()))?;
file_infos.push(file_info);
}
let file_infos = try_join_all(input.files.into_iter().map(|file| {
FileInfo::new(file, &state.surreal_db_client, &user.id)
.map_err(|e| HtmlError::new(AppError::from(e), state.templates.clone()))
}))
.await?;
let ingress_objects = create_ingress_objects(
IngressInput {
content: input.content,
instructions: input.instructions,
category: input.category,
files: file_infos,
},
user.id.as_str(),
)
.map_err(|e| HtmlError::new(AppError::from(e), state.templates.clone()))?;
let futures: Vec<_> = ingress_objects
.into_iter()
.map(|object| state.rabbitmq_producer.publish(object))
.collect();
try_join_all(futures)
.await
.map_err(AppError::from)
.map_err(|e| HtmlError::new(AppError::from(e), state.templates.clone()))?;
// Process the ingress (implement your logic here)
Ok(Html("SuccessBRO!").into_response())