From 540a3ff06ff977c0f19dfc66bf5264a1af99de33 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Wed, 27 Aug 2025 00:54:20 -0400 Subject: [PATCH] fix media_links cdn/env --- ...ybe_handle_text_to_image_complete_event.rs | 1 - .../media/media_links_builder.rs | 32 ++++++++----------- .../batch_get_inference_job_status_handler.rs | 19 ++++++++--- .../get/get_inference_job_status_handler.rs | 11 +++++-- .../list/list_session_jobs_handler.rs | 13 ++++++-- ...tch_generated_redux_media_files_handler.rs | 6 +++- .../app/src/pages/PageImage/TextToImage.tsx | 1 + 7 files changed, 53 insertions(+), 30 deletions(-) diff --git a/crates/desktop/artcraft/src/services/midjourney/threads/events/maybe_handle_text_to_image_complete_event.rs b/crates/desktop/artcraft/src/services/midjourney/threads/events/maybe_handle_text_to_image_complete_event.rs index a081f9b869..6c93fb1eda 100644 --- a/crates/desktop/artcraft/src/services/midjourney/threads/events/maybe_handle_text_to_image_complete_event.rs +++ b/crates/desktop/artcraft/src/services/midjourney/threads/events/maybe_handle_text_to_image_complete_event.rs @@ -40,7 +40,6 @@ pub async fn maybe_handle_text_to_image_complete_event( batch_token, ).await?; - if let Err(err) = event.send(&app) { error!("Failed to send TextToImageGenerationCompleteEvent: {:?}", err); // Fail open } diff --git a/crates/service/web/storyteller_web/src/http_server/common_responses/media/media_links_builder.rs b/crates/service/web/storyteller_web/src/http_server/common_responses/media/media_links_builder.rs index 211dffa92d..118af10811 100644 --- a/crates/service/web/storyteller_web/src/http_server/common_responses/media/media_links_builder.rs +++ b/crates/service/web/storyteller_web/src/http_server/common_responses/media/media_links_builder.rs @@ -24,14 +24,6 @@ impl MediaLinksBuilder { Self::from_media_path_and_env(domain, ServerEnvironment::Production, bucket_path) } - #[deprecated(note = "we need to start passing the domain and the server environment to generate the CDN")] - pub fn from_rooted_path( - domain: MediaDomain, - rooted_path: &str, - ) -> MediaLinks { - Self::from_rooted_path_and_env(domain, ServerEnvironment::Production, rooted_path) - } - pub fn from_media_path_and_env( domain: MediaDomain, server_environment: ServerEnvironment, @@ -148,7 +140,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks #[test] fn wav_file() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.wav"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.wav"); assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/foo/bar.wav"); assert_eq!(links.maybe_thumbnail_template, None); assert_eq!(links.maybe_video_previews, None); @@ -156,7 +148,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks #[test] fn glb_file() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.glb"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.glb"); assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/foo/bar.glb"); assert_eq!(links.maybe_thumbnail_template, None); assert_eq!(links.maybe_video_previews, None); @@ -164,7 +156,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks #[test] fn jpg_image() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.jpg"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.jpg"); assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/foo/bar.jpg"); assert_eq!(links.maybe_thumbnail_template, Some("https://cdn-2.fakeyou.com/cdn-cgi/image/width={WIDTH},quality=95/foo/bar.jpg".to_string())); assert_eq!(links.maybe_video_previews, None); @@ -172,7 +164,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks #[test] fn mp4_video() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.mp4"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.mp4"); assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/foo/bar.mp4"); assert_eq!(links.maybe_thumbnail_template, None); let video_previews = links.maybe_video_previews.expect("should have previews"); @@ -228,11 +220,12 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks const DOMAIN : MediaDomain = MediaDomain::Storyteller; mod rooted_path { + use server_environment::ServerEnvironment; use super::*; #[test] fn wav_file() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.wav"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.wav"); assert_eq!(links.cdn_url.as_str(), "https://cdn.storyteller.ai/foo/bar.wav"); assert_eq!(links.maybe_thumbnail_template, None); assert_eq!(links.maybe_video_previews, None); @@ -240,7 +233,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks #[test] fn glb_file() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.glb"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.glb"); assert_eq!(links.cdn_url.as_str(), "https://cdn.storyteller.ai/foo/bar.glb"); assert_eq!(links.maybe_thumbnail_template, None); assert_eq!(links.maybe_video_previews, None); @@ -248,7 +241,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks #[test] fn jpg_image() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.jpg"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.jpg"); assert_eq!(links.cdn_url.as_str(), "https://cdn.storyteller.ai/foo/bar.jpg"); assert_eq!(links.maybe_thumbnail_template, Some("https://cdn.storyteller.ai/cdn-cgi/image/width={WIDTH},quality=95/foo/bar.jpg".to_string())); assert_eq!(links.maybe_video_previews, None); @@ -256,7 +249,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks #[test] fn mp4_video() { - let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/foo/bar.mp4"); + let links = MediaLinksBuilder::from_rooted_path_and_env(DOMAIN, ServerEnvironment::Production, "/foo/bar.mp4"); assert_eq!(links.cdn_url.as_str(), "https://cdn.storyteller.ai/foo/bar.mp4"); assert_eq!(links.maybe_thumbnail_template, None); let video_previews = links.maybe_video_previews.expect("should have previews"); @@ -268,13 +261,14 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks } mod media_path { + use server_environment::ServerEnvironment; use super::*; #[test] fn wav_file() { // https://storage.googleapis.com/vocodes-public/media/9/4/a/2/7/94a27nmbd0bqmd10tg0pp3hz45zytf67/fakeyou_94a27nmbd0bqmd10tg0pp3hz45zytf67.wav let media_path = MediaFileBucketPath::from_object_hash("94a27nmbd0bqmd10tg0pp3hz45zytf67", Some("fakeyou_"), Some(".wav")); - let links = MediaLinksBuilder::from_media_path(DOMAIN, &media_path); + let links = MediaLinksBuilder::from_media_path_and_env(DOMAIN, ServerEnvironment::Production, &media_path); assert_eq!(links.cdn_url.as_str(), "https://cdn.storyteller.ai/media/9/4/a/2/7/94a27nmbd0bqmd10tg0pp3hz45zytf67/fakeyou_94a27nmbd0bqmd10tg0pp3hz45zytf67.wav"); assert_eq!(links.maybe_thumbnail_template, None); assert_eq!(links.maybe_video_previews, None); @@ -284,7 +278,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks fn png_image() { /// https://storage.googleapis.com/vocodes-public/media/3/7/m/b/3/37mb3gh8fmj85y21thvbv08bzv24atjt/upload_37mb3gh8fmj85y21thvbv08bzv24atjt.png let media_path = MediaFileBucketPath::from_object_hash("37mb3gh8fmj85y21thvbv08bzv24atjt", Some("upload_"), Some(".png")); - let links = MediaLinksBuilder::from_media_path(DOMAIN, &media_path); + let links = MediaLinksBuilder::from_media_path_and_env(DOMAIN, ServerEnvironment::Production, &media_path); assert_eq!(links.cdn_url.as_str(), "https://cdn.storyteller.ai/media/3/7/m/b/3/37mb3gh8fmj85y21thvbv08bzv24atjt/upload_37mb3gh8fmj85y21thvbv08bzv24atjt.png"); assert_eq!(links.maybe_thumbnail_template, Some("https://cdn.storyteller.ai/cdn-cgi/image/width={WIDTH},quality=95/media/3/7/m/b/3/37mb3gh8fmj85y21thvbv08bzv24atjt/upload_37mb3gh8fmj85y21thvbv08bzv24atjt.png".to_string())); assert_eq!(links.maybe_video_previews, None); @@ -294,7 +288,7 @@ use crate::http_server::common_responses::media::media_links_builder::MediaLinks fn mp4_video() { // https://storage.googleapis.com/vocodes-public/media/t/6/c/n/y/t6cnyw4g3e8k7carkk2bvrt6nd3fycjv/storyteller_t6cnyw4g3e8k7carkk2bvrt6nd3fycjv.mp4 let media_path = MediaFileBucketPath::from_object_hash("t6cnyw4g3e8k7carkk2bvrt6nd3fycjv", Some("storyteller_"), Some(".mp4")); - let links = MediaLinksBuilder::from_media_path(DOMAIN, &media_path); + let links = MediaLinksBuilder::from_media_path_and_env(DOMAIN, ServerEnvironment::Production, &media_path); assert_eq!(links.cdn_url.as_str(), "https://cdn.storyteller.ai/media/t/6/c/n/y/t6cnyw4g3e8k7carkk2bvrt6nd3fycjv/storyteller_t6cnyw4g3e8k7carkk2bvrt6nd3fycjv.mp4"); assert_eq!(links.maybe_thumbnail_template, None); let video_previews = links.maybe_video_previews.expect("should have previews"); diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/batch_get_inference_job_status_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/batch_get_inference_job_status_handler.rs index c47051462a..3139943128 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/batch_get_inference_job_status_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/batch_get_inference_job_status_handler.rs @@ -31,6 +31,7 @@ use mysql_queries::queries::generic_inference::web::batch_get_inference_job_stat use mysql_queries::queries::generic_inference::web::job_status::GenericInferenceJobStatus; use r2d2_redis::redis::Commands; use redis_common::redis_keys::RedisKeys; +use server_environment::ServerEnvironment; use tokens::tokens::generic_inference_jobs::InferenceJobToken; use utoipa::{IntoParams, ToSchema}; @@ -203,7 +204,11 @@ pub async fn batch_get_inference_job_status_handler( if tokens.is_empty() { // NB: MediaDomain doesn't matter since it's an empty list. - return Ok(records_to_response(Vec::new(), MediaDomain::Storyteller)); + return Ok(records_to_response( + Vec::new(), + server_state.server_environment, + MediaDomain::Storyteller + )); } // NB: Since this is publicly exposed, we don't query sensitive data. @@ -249,18 +254,19 @@ pub async fn batch_get_inference_job_status_handler( let media_domain = get_media_domain(&http_request); - Ok(records_to_response(records, media_domain)) + Ok(records_to_response(records, server_state.server_environment, media_domain)) } fn records_to_response( records: Vec, + server_environment: ServerEnvironment, media_domain: MediaDomain, ) -> Json { Json(BatchGetInferenceJobStatusSuccessResponse { success: true, job_states: records.into_iter() .map(|record| { - db_record_to_response_payload(record, None, media_domain) + db_record_to_response_payload(record, None, server_environment, media_domain) }) .collect::>(), }) @@ -269,6 +275,7 @@ fn records_to_response( fn db_record_to_response_payload( record: GenericInferenceJobStatus, maybe_extra_status_description: Option, + server_environment: ServerEnvironment, media_domain: MediaDomain, ) -> BatchInferenceJobStatusResponsePayload { let inference_category = record.request_details.inference_category; @@ -374,7 +381,11 @@ fn db_record_to_response_payload( BatchResultDetailsResponse { entity_type: result_details.entity_type, entity_token: result_details.entity_token, - media_links: MediaLinksBuilder::from_rooted_path(media_domain, &public_bucket_media_path), + media_links: MediaLinksBuilder::from_rooted_path_and_env( + media_domain, + server_environment, + &public_bucket_media_path + ), maybe_public_bucket_media_path: Some(public_bucket_media_path), maybe_successfully_completed_at: result_details.maybe_successfully_completed_at, } diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/get_inference_job_status_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/get_inference_job_status_handler.rs index 9c73362bfe..6d63beb4fd 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/get_inference_job_status_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/get/get_inference_job_status_handler.rs @@ -29,6 +29,7 @@ use mysql_queries::queries::generic_inference::web::get_inference_job_status::ge use mysql_queries::queries::generic_inference::web::job_status::GenericInferenceJobStatus; use r2d2_redis::redis::{Commands, RedisResult}; use redis_common::redis_keys::RedisKeys; +use server_environment::ServerEnvironment; use tokens::tokens::generic_inference_jobs::InferenceJobToken; use utoipa::ToSchema; @@ -264,6 +265,7 @@ fn record_to_payload( record: GenericInferenceJobStatus, maybe_extra_status_description: Option, media_domain: MediaDomain, + server_environment: ServerEnvironment, ) -> InferenceJobStatusResponsePayload { let inference_category = record.request_details.inference_category; @@ -368,7 +370,11 @@ fn record_to_payload( ResultDetailsResponse { entity_type: result_details.entity_type, entity_token: result_details.entity_token, - media_links: MediaLinksBuilder::from_rooted_path(media_domain, &public_bucket_media_path), + media_links: MediaLinksBuilder::from_rooted_path_and_env( + media_domain, + server_environment, + &public_bucket_media_path + ), maybe_public_bucket_media_path: Some(public_bucket_media_path), maybe_successfully_completed_at: result_details.maybe_successfully_completed_at, } @@ -385,6 +391,7 @@ mod tests { use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory; use mysql_queries::queries::generic_inference::web::job_status::{GenericInferenceJobStatus, RequestDetails, ResultDetails}; use url::Url; + use server_environment::ServerEnvironment; #[test] fn text_to_speech_as_media_file() { @@ -407,7 +414,7 @@ mod tests { }; let payload = - record_to_payload(status, None, MediaDomain::Storyteller); + record_to_payload(status, None, ServerEnvironment::Production, MediaDomain::Storyteller); assert!(payload.maybe_result.is_some()); diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/list/list_session_jobs_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/list/list_session_jobs_handler.rs index 66e332533c..0a384f4317 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/list/list_session_jobs_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/inference_job/list/list_session_jobs_handler.rs @@ -31,6 +31,7 @@ use mysql_queries::queries::generic_inference::web::list_session_jobs::{list_ses use primitives::numerics::i64_to_u64_zero_clamped::i64_to_u64_zero_clamped; use r2d2_redis::redis::Commands; use redis_common::redis_keys::RedisKeys; +use server_environment::ServerEnvironment; use tokens::tokens::generic_inference_jobs::InferenceJobToken; use tokens::tokens::media_files::MediaFileToken; use utoipa::{IntoParams, ToSchema}; @@ -197,16 +198,17 @@ pub async fn list_session_jobs_handler( let media_domain = get_media_domain(&http_request); - records_to_response(records, media_domain) + records_to_response(records, server_state.server_environment, media_domain) } fn records_to_response( records: Vec, + server_environment: ServerEnvironment, media_domain: MediaDomain, ) -> Result, ListSessionJobsError> { let mut records = records.into_iter() .map(|record| { - db_record_to_response_payload(record, None, media_domain) + db_record_to_response_payload(record, None, server_environment, media_domain) }) .collect::>(); @@ -240,6 +242,7 @@ fn records_to_response( fn db_record_to_response_payload( record: GenericInferenceJobStatus, maybe_extra_status_description: Option, + server_environment: ServerEnvironment, media_domain: MediaDomain, ) -> ListSessionJobsItem { let inference_category = record.request_details.inference_category; @@ -359,7 +362,11 @@ fn db_record_to_response_payload( entity_type: result_details.entity_type, entity_token: result_details.entity_token, maybe_batch_token: result_details.maybe_batch_token, - media_links: MediaLinksBuilder::from_rooted_path(media_domain, &public_bucket_media_path), + media_links: MediaLinksBuilder::from_rooted_path_and_env( + media_domain, + server_environment, + &public_bucket_media_path + ), maybe_public_bucket_media_path: Some(public_bucket_media_path), maybe_successfully_completed_at: result_details.maybe_successfully_completed_at, } diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list/list_batch_generated_redux_media_files_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list/list_batch_generated_redux_media_files_handler.rs index 82e5dbda32..5d6079f21a 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list/list_batch_generated_redux_media_files_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list/list_batch_generated_redux_media_files_handler.rs @@ -112,7 +112,11 @@ pub async fn list_batch_generated_redux_media_files_handler( media_class: result.media_class, media_type: result.media_type, maybe_batch_token: result.maybe_batch_token, - media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path), + media_links: MediaLinksBuilder::from_media_path_and_env( + media_domain, + server_state.server_environment, + &public_bucket_path + ), cover_image: MediaFileCoverImageDetailsBuilder::from_optional_db_fields( &result.token, media_domain, diff --git a/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx b/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx index 011fdfc536..331dd970f3 100644 --- a/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx +++ b/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx @@ -41,6 +41,7 @@ const TextToImage = ({ imageMediaId, imageUrl }: TextToImageProps) => { }; useTextToImageGenerationCompleteEvent(async (event) => { + console.log(">>> Event", event); completeBatch( event.generated_images || [], event.maybe_frontend_subscriber_id,