diff --git a/cooked/src/routes.rs b/cooked/src/routes.rs index 9a5c066..515f9bf 100644 --- a/cooked/src/routes.rs +++ b/cooked/src/routes.rs @@ -4,13 +4,14 @@ use crate::{entities, entities::prelude::*, filters}; use actix_files::Files; use actix_identity::Identity; use actix_multipart::form::{tempfile::TempFile, MultipartForm}; -use actix_web::http::header::{CONTENT_LENGTH, CONTENT_TYPE}; +use actix_web::http::header::CONTENT_TYPE; use actix_web::web::{Data, Form, Path}; use actix_web::HttpMessage; use actix_web::{get, post, HttpRequest, HttpResponse, Responder}; use askama::Template; use askama_actix::TemplateToResponse; use itertools::Itertools; +use sea_orm::IntoActiveModel; use sea_orm::{ prelude::*, DatabaseTransaction, JoinType, QueryOrder, QuerySelect, TransactionTrait, }; @@ -169,10 +170,6 @@ impl TagsTemplate { } } } -// -// -// -// #[derive(Debug, Template)] #[template(path = "tag.jinja", ext = "html")] @@ -221,10 +218,6 @@ impl TagTemplate { } } } -// -// -// -// #[derive(Debug, Template)] #[template(path = "index.jinja", ext = "html")] @@ -382,6 +375,49 @@ async fn recipe_image_upload(MultipartForm(form): MultipartForm) -> HttpResponse::Ok().body(format!("{{\"url\":\"/assets/recipies/images/{uid}\"}}")) } +#[post("/recipe/{id}/update-image")] +async fn recipe_image_update( + MultipartForm(form): MultipartForm, + path: Path, + db: Data, + admin: Identity, +) -> HttpResponse { + use sea_orm::ActiveValue::Set; + + let Ok(Some(recipe)) = Recipies::find() + .filter(entities::recipies::Column::Id.eq(path.into_inner())) + .one(&**db) + .await + else { + return HttpResponse::BadRequest().finish(); + }; + tracing::debug!("Ensure production assets directory exists"); + let _ = tokio::fs::create_dir_all("./assets/recipies/images").await; + tracing::debug!("Ensure tmp assets directory exists"); + let _ = tokio::fs::create_dir_all("/tmp/assets/recipies/images").await; + tracing::debug!("Storing TempFile"); + let Ok((_file, path)) = form.image.file.keep() else { + tracing::warn!("Storing TempFile failed"); + return HttpResponse::InternalServerError().finish(); + }; + let uid = uuid::Uuid::new_v4(); + tracing::debug!("Copying TempFile to tmp directory"); + let recipe_image_path = format!("/assets/recipies/images/{uid}"); + let Ok(_) = tokio::fs::copy(&path, format!(".{}", recipe_image_path)).await else { + tracing::warn!("Copy TempFile to tmp directory failed"); + return HttpResponse::InternalServerError().finish(); + }; + let mut model = recipe.into_active_model(); + model.image_url = Set(recipe_image_path); + let Ok(_) = Recipies::update(model).exec(&**db).await else { + return HttpResponse::InternalServerError().finish(); + }; + tracing::debug!("Copying TempFile to tmp directory"); + let _ = tokio::fs::remove_file(&path).await; + + HttpResponse::Ok().body(format!("{{\"url\":\"/assets/recipies/images/{uid}\"}}")) +} + #[post("/sign-in")] async fn sign_in( req: HttpRequest, @@ -1202,6 +1238,7 @@ pub fn configure(config: &mut actix_web::web::ServiceConfig) { .service(show) .service(search_page) .service(search_results) + .service(recipe_image_update) .service(update_recipe) .service(edit_recipe) .service(recipe_form) diff --git a/cooked/templates/recipies/update_form.jinja b/cooked/templates/recipies/update_form.jinja index 3ae3178..fbf3a5e 100644 --- a/cooked/templates/recipies/update_form.jinja +++ b/cooked/templates/recipies/update_form.jinja @@ -130,9 +130,8 @@ document.addEventListener("DOMContentLoaded", (event) => { image.addEventListener('change', () => { const f = new FormData(); f.append('image', image.files[0]); - fetch('/recipe-image', { body: f, method: 'post' }) - .then(res => res.json()) - .then(({ url }) => image_url.value = url); + + fetch("/recipe/{{id}}/update-image", { body: f, method: 'post' }); }); const form = body.querySelector('form'); return;