diff --git a/crates/api_clients/storyteller_client/src/media_files/upload_image_media_file_from_file.rs b/crates/api_clients/storyteller_client/src/media_files/upload_image_media_file_from_file.rs index 8cc97063b2..a120ae072b 100644 --- a/crates/api_clients/storyteller_client/src/media_files/upload_image_media_file_from_file.rs +++ b/crates/api_clients/storyteller_client/src/media_files/upload_image_media_file_from_file.rs @@ -33,14 +33,24 @@ use tokens::tokens::model_weights::ModelWeightToken; use tokens::tokens::prompts::PromptToken; use uuid::uuid; +pub struct UploadImageFromFileArgs<'a, P: AsRef> { + pub api_host: &'a ApiHost, + pub maybe_creds: Option<&'a StorytellerCredentialSet>, + + // NB: Path needs to be owned for the request. + pub path: P, + + /// If true, we should hide the image from the user's gallery. + pub is_intermediate_system_file: bool, +} + + /// Upload an image media file from a file. pub async fn upload_image_media_file_from_file>( - api_host: &ApiHost, - maybe_creds: Option<&StorytellerCredentialSet>, - path: P, + args: UploadImageFromFileArgs<'_, P>, ) -> Result { - let url = get_route(api_host); + let url = get_route(args.api_host); debug!("Requesting {:?}", &url); @@ -51,17 +61,21 @@ pub async fn upload_image_media_file_from_file>( .build() .map_err(|err| StorytellerError::Client(ClientError::from(err)))?; - let form = Form::new() + let mut form = Form::new() .text("uuid_idempotency_token", generate_random_uuid()) - .file("file", path) + .file("file", args.path) .await .map_err(|err| StorytellerError::Client(ClientError::from(err)))?; + if args.is_intermediate_system_file { + form = form.text("is_intermediate_system_file", "true"); + } + let mut request_builder = client.post(url) .header("User-Agent", USER_AGENT) .header("Accept", APPLICATION_JSON); - if let Some(creds) = maybe_creds { + if let Some(creds) = args.maybe_creds { if let Some(header) = &creds.maybe_as_cookie_header() { request_builder = request_builder.header("Cookie", header); } diff --git a/crates/api_clients/storyteller_client/src/recipes/upload_media_file_from_file.rs b/crates/api_clients/storyteller_client/src/recipes/upload_media_file_from_file.rs index 75ef1f0827..22089b74d2 100644 --- a/crates/api_clients/storyteller_client/src/recipes/upload_media_file_from_file.rs +++ b/crates/api_clients/storyteller_client/src/recipes/upload_media_file_from_file.rs @@ -1,7 +1,7 @@ use crate::credentials::storyteller_credential_set::StorytellerCredentialSet; use crate::error::client_error::ClientError; use crate::error::storyteller_error::StorytellerError; -use crate::media_files::upload_image_media_file_from_file::upload_image_media_file_from_file; +use crate::media_files::upload_image_media_file_from_file::{upload_image_media_file_from_file, UploadImageFromFileArgs}; use crate::media_files::upload_new_engine_asset_from_file::upload_new_engine_asset_from_file; use crate::media_files::upload_video_media_file_from_file::upload_video_media_file_from_file; use crate::utils::api_host::ApiHost; @@ -49,7 +49,13 @@ pub async fn upload_media_file_from_file>( } } Some(FileExtension::Png) | Some(FileExtension::Jpg) | Some(FileExtension::Gif) | Some(FileExtension::Webp) => { - match upload_image_media_file_from_file(api_host, maybe_creds, path).await { + let result = upload_image_media_file_from_file(UploadImageFromFileArgs { + api_host, + maybe_creds, + path, + is_intermediate_system_file: false, + }).await; + match result { Ok(result) => Ok(UploadMediaFileSuccessResponse { success: result.success, media_file_token: result.media_file_token, diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs index 1dce8894e5..0c1e114abb 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs @@ -39,7 +39,7 @@ use storyteller_client::generate::image::generate_flux_1_schnell_text_to_image:: use storyteller_client::generate::image::generate_flux_pro_11_text_to_image::generate_flux_pro_11_text_to_image; use storyteller_client::generate::image::generate_flux_pro_11_ultra_text_to_image::generate_flux_pro_11_ultra_text_to_image; use storyteller_client::generate::image::remove_image_background::remove_image_background; -use storyteller_client::media_files::upload_image_media_file_from_file::upload_image_media_file_from_file; +use storyteller_client::media_files::upload_image_media_file_from_file::{upload_image_media_file_from_file, UploadImageFromFileArgs}; use tauri::AppHandle; use tokens::tokens::media_files::MediaFileToken; @@ -123,9 +123,13 @@ async fn upload_image_from_base64_bytes( info!("Uploading image media file from temp file: {:?}", temp_file.path()); - let result = - upload_image_media_file_from_file(&app_env_configs.storyteller_host, Some(&creds), temp_file) - .await + let result = + upload_image_media_file_from_file(UploadImageFromFileArgs { + api_host: &app_env_configs.storyteller_host, + maybe_creds: Some(&creds), + path: temp_file, + is_intermediate_system_file: true, // NB: Probably not essential to keep this. + }).await .map_err(|err| { error!("Failed to upload image media file: {:?}", err); InternalBgRemovalError::StorytellerError(err) diff --git a/crates/desktop/artcraft/src/services/fal/commands/fal_background_removal_command.rs b/crates/desktop/artcraft/src/services/fal/commands/fal_background_removal_command.rs index ff51e007ee..b39ff45417 100644 --- a/crates/desktop/artcraft/src/services/fal/commands/fal_background_removal_command.rs +++ b/crates/desktop/artcraft/src/services/fal/commands/fal_background_removal_command.rs @@ -1,4 +1,3 @@ - use crate::core::artcraft_error::ArtcraftError; use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus}; use crate::core::commands::response::shorthand::Response; @@ -30,7 +29,7 @@ use reqwest::Url; use serde_derive::{Deserialize, Serialize}; use storyteller_client::error::storyteller_error::StorytellerError; use storyteller_client::media_files::get_media_file::{get_media_file, GetMediaFileSuccessResponse}; -use storyteller_client::media_files::upload_image_media_file_from_file::upload_image_media_file_from_file; +use storyteller_client::media_files::upload_image_media_file_from_file::{upload_image_media_file_from_file, UploadImageFromFileArgs}; use storyteller_client::utils::api_host::ApiHost; use tauri::{AppHandle, Manager, State}; use tokens::tokens::media_files::MediaFileToken; @@ -257,11 +256,12 @@ pub async fn remove_background( info!("Uploading image media file..."); - let upload_result = upload_image_media_file_from_file( - &app_env_configs.storyteller_host, - Some(&creds), - result_filename, - ).await?; + let upload_result = upload_image_media_file_from_file(UploadImageFromFileArgs { + api_host: &app_env_configs.storyteller_host, + maybe_creds: Some(&creds), + path: result_filename, + is_intermediate_system_file: true, // NB: Probably not essential to keep this. + }).await?; // TODO: Don't re-request to simply build MediaLinks (or CDN URL). Get those from the upload API in one turn. info!("Re-requesting media file..."); diff --git a/crates/desktop/artcraft/src/services/sora/threads/sora_task_polling_thread.rs b/crates/desktop/artcraft/src/services/sora/threads/sora_task_polling_thread.rs index 4f136b8611..f7eae2d199 100644 --- a/crates/desktop/artcraft/src/services/sora/threads/sora_task_polling_thread.rs +++ b/crates/desktop/artcraft/src/services/sora/threads/sora_task_polling_thread.rs @@ -17,7 +17,7 @@ use reqwest::Url; use std::fs::File; use std::io::Write; use std::path::PathBuf; -use storyteller_client::media_files::upload_image_media_file_from_file::upload_image_media_file_from_file; +use storyteller_client::media_files::upload_image_media_file_from_file::{upload_image_media_file_from_file, UploadImageFromFileArgs}; use tauri::AppHandle; use tempdir::TempDir; @@ -134,12 +134,14 @@ async fn polling_loop( let download_path = download_generation(generation, &app_data_root).await?; info!("Uploading to backend..."); - let result = upload_image_media_file_from_file( - &app_env_configs.storyteller_host, - Some(&creds), - download_path - ).await?; - + + let result = upload_image_media_file_from_file(UploadImageFromFileArgs { + api_host: &app_env_configs.storyteller_host, + maybe_creds: Some(&creds), + path: download_path, + is_intermediate_system_file: false, + }).await?; + info!("Uploaded to API backend: {:?}", result.media_file_token); let event = GenerationCompleteEvent {