fix media_links cdn/env

This commit is contained in:
Brandon Thomas committed 2025-08-27 00:54:20 -04:00
1 parent 8250162d8f
commit 540a3ff06f
7 files changed
+53 -30

No files matched your search

@@ -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
}
@@ -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");
@@ -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<GenericInferenceJobStatus>,
server_environment: ServerEnvironment,
media_domain: MediaDomain,
) -> Json<BatchGetInferenceJobStatusSuccessResponse> {
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::<Vec<_>>(),
})
@@ -269,6 +275,7 @@ fn records_to_response(
fn db_record_to_response_payload(
record: GenericInferenceJobStatus,
maybe_extra_status_description: Option<String>,
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,
}
@@ -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<String>,
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());
@@ -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<GenericInferenceJobStatus>,
server_environment: ServerEnvironment,
media_domain: MediaDomain,
) -> Result<Json<ListSessionJobsSuccessResponse>, 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::<Vec<_>>();
@@ -240,6 +242,7 @@ fn records_to_response(
fn db_record_to_response_payload(
record: GenericInferenceJobStatus,
maybe_extra_status_description: Option<String>,
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,
}
@@ -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,
@@ -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,