Compare commits

...
Author SHA1 Message Date
Brandon Thomas 3998a0d18b fixup docs 2025-07-15 01:08:04 -04:00
Brandon Thomas 073d7a6573 remove old MediaLinks type 2025-07-15 01:05:21 -04:00
Brandon Thomas 9a4be8a142 refactor out API types so we can use it in a client 2025-07-15 00:18:08 -04:00
39 changed files with 404 additions and 377 deletions
Generated
+2
View File
@@ -698,11 +698,13 @@ dependencies = [
name = "artcraft_api_defs"
version = "0.0.1"
dependencies = [
"chrono",
"enums",
"serde",
"serde_derive",
"serde_json",
"tokens",
"url",
"utoipa",
"workspace-build-acceleration",
]
@@ -8,25 +8,29 @@ authors = [
]
publish = false
[package.metadata.cargo-udeps.ignore]
normal = ["workspace-build-acceleration"]
[lib]
name = "artcraft_api_defs"
path = "src/lib.rs"
[package.metadata.cargo-udeps.ignore]
normal = ["workspace-build-acceleration"]
[dependencies]
# Hackari workspace (faster compile times)
workspace-build-acceleration = { workspace = true }
workspace-build-acceleration.workspace = true
# Internal
enums = { workspace = true }
tokens = { workspace = true }
enums.workspace = true
tokens.workspace = true
# External
chrono.workspace = true
url.workspace = true
# Serialization
serde = { workspace = true }
serde_derive = { workspace = true }
serde_json = { workspace = true }
serde.workspace = true
serde_derive.workspace = true
serde_json.workspace = true
utoipa = { version = "4", features = ["chrono", "actix_extras"] }
@@ -0,0 +1 @@
pub mod responses;
@@ -1,6 +1,6 @@
use utoipa::ToSchema;
use serde::Serialize;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
/// Details about submitted live portrait jobs (request arguments only)
#[derive(Serialize, ToSchema)]
@@ -18,3 +18,15 @@ pub struct JobDetailsLivePortraitRequest {
/// This video must contain a face.
pub face_driver_media_file_token: MediaFileToken,
}
/// Details about submitted lipsync jobs (request arguments only)
#[derive(Serialize, ToSchema)]
pub struct JobDetailsLipsyncRequest {
/// Media file token for the source audio.
/// This is probably an audio file, but in the future we might pull audio from video.
pub audio_source_token: MediaFileToken,
/// Media file token for the source visuals.
/// This is either an image or video.
pub image_or_video_source_token: MediaFileToken,
}
@@ -0,0 +1,38 @@
use serde::Serialize;
use utoipa::ToSchema;
use url::Url;
/// Links to media file locations (bucket, CDN, etc.)
#[derive(Serialize, ToSchema, Debug, Clone, Eq, PartialEq)]
pub struct MediaLinks {
/// Primary link to the asset via the CDN.
pub cdn_url: Url,
/// Template to construct thumbnail URLs.
/// Replace the string `{WIDTH}` with the desired width.
/// Only relevant for image media files. (Video media files instead have
/// video previews, which, in turn, have their own thumbnail templates.)
pub maybe_thumbnail_template: Option<String>,
/// Video preview images (still and animated gif) for mp4 video files.
/// These are only set for video media files.
/// These are not set for "cover images" that are gif or webms, but rather video files.
pub maybe_video_previews: Option<VideoPreviews>,
}
#[derive(Serialize, ToSchema, Debug, Clone, Eq, PartialEq)]
pub struct VideoPreviews {
/// A static single frame preview image of the video.
pub still: Url,
/// An animated gif preview of the video.
pub animated: Url,
/// A template used to construct the still thumbnail URL.
/// Replace the string `{WIDTH}` with the desired width.
pub still_thumbnail_template: String,
/// A template used to construct the animated thumbnail URL.
/// Replace the string `{WIDTH}` with the desired width.
pub animated_thumbnail_template: String,
}
@@ -0,0 +1,2 @@
pub mod job_details;
pub mod media_links;
@@ -0,0 +1,124 @@
use crate::common::responses::job_details::{JobDetailsLipsyncRequest, JobDetailsLivePortraitRequest};
use crate::common::responses::media_links::MediaLinks;
use chrono::{DateTime, Utc};
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::common::job_status_plus::JobStatusPlus;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use serde::Deserialize;
use serde::Serialize;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use utoipa::{IntoParams, ToSchema};
pub const LIST_SESSION_JOBS_URL_PATH: &str = "/v1/jobs/session";
#[derive(Deserialize, ToSchema, IntoParams)]
pub struct ListSessionJobsQueryParams {
//pub sort_ascending: Option<bool>,
//pub page_size: Option<usize>, // TODO(bt,2024-04-23): One page for now.
//pub page_index: Option<usize>, // TODO(bt,2024-04-23): One page for now.
/// NB: This can be one (or more comma-separated values) from `JobStatusPlus`.
/// ?include_states=pending or ?include_states=pending,started,complete_success (etc.)
pub include_states: Option<String>,
/// The opposite of include_states, this filters out states from view.
pub exclude_states: Option<String>,
// TODO(bt,2024-04-23): Add the ability for users to dismiss completed/dead jobs from view.
}
#[derive(Serialize, ToSchema)]
pub struct ListSessionJobsSuccessResponse {
pub success: bool,
/// This is not paginated and is limited to showing 100 jobs.
pub jobs: Vec<ListSessionJobsItem>,
}
#[derive(Serialize, ToSchema)]
pub struct ListSessionJobsItem {
pub job_token: InferenceJobToken,
pub request: ListSessionRequestDetailsResponse,
pub status: ListSessionStatusDetailsResponse,
pub maybe_result: Option<ListSessionResultDetailsResponse>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
/// Details about what the user requested for generation
#[derive(Serialize, ToSchema)]
pub struct ListSessionRequestDetailsResponse {
pub inference_category: InferenceCategory,
pub maybe_model_type: Option<String>,
pub maybe_model_token: Option<String>,
/// OPTIONAL. Title of the model, if it has one
pub maybe_model_title: Option<String>,
/// OPTIONAL. If the result was TTS, this is the raw inference text.
pub maybe_raw_inference_text: Option<String>,
/// OPTIONAL. For Comfy / Video Style Transfer jobs, this might include
/// the name of the selected style.
pub maybe_style_name: Option<StyleTransferName>,
/// OPTIONAL. For Live Portrait jobs, this is additional information on the request.
pub maybe_live_portrait_details: Option<JobDetailsLivePortraitRequest>,
/// OPTIONAL. For lipsync jobs (face fusion and sad talker), this is additional
/// information on the request.
pub maybe_lipsync_details: Option<JobDetailsLipsyncRequest>,
}
/// Details about the ongoing job status
#[derive(Serialize, ToSchema)]
pub struct ListSessionStatusDetailsResponse {
/// Primary status from the database (a state machine).
pub status: JobStatusPlus,
/// Extra, temporary status from Redis.
/// This can denote inference progress, and the Python code can write to it.
pub maybe_extra_status_description: Option<String>,
pub maybe_assigned_worker: Option<String>,
pub maybe_assigned_cluster: Option<String>,
pub maybe_first_started_at: Option<DateTime<Utc>>,
/// If the job is currently running, this is how long it has been running in seconds.
/// This is heuristic estimate since we don't record the precise start time across runs.
pub maybe_current_execution_duration_seconds: Option<u64>,
pub attempt_count: u8,
/// Whether the frontend needs to maintain a keepalive check.
/// This is typically only for non-premium users.
pub requires_keepalive: bool,
/// An enum the frontend can use to display localized/I18N error
/// messages. These pertain to both transient and permanent failures.
pub maybe_failure_category: Option<FrontendFailureCategory>,
/// This is an integer number between 0 and 100 (both inclusive) that
/// reports the completeness.
pub progress_percentage: u8,
}
/// Details about the completed result (if any)
#[derive(Serialize, ToSchema)]
pub struct ListSessionResultDetailsResponse {
pub entity_type: String,
pub entity_token: String,
/// (DEPRECATED) URL path to the media file
#[deprecated(note="This field doesn't point to the full URL. Use media_links instead to leverage the CDN.")]
pub maybe_public_bucket_media_path: Option<String>,
/// Rich CDN links to the media, including thumbnails, previews, and more.
pub media_links: MediaLinks,
pub maybe_successfully_completed_at: Option<DateTime<Utc>>,
}
@@ -0,0 +1 @@
pub mod list_session_jobs;
@@ -1 +1,3 @@
pub mod generate;
pub mod common;
pub mod generate;
pub mod jobs;
@@ -1,5 +1,8 @@
use utoipa::OpenApi;
use artcraft_api_defs::common::responses::job_details::JobDetailsLipsyncRequest;
use artcraft_api_defs::common::responses::job_details::JobDetailsLivePortraitRequest;
use artcraft_api_defs::common::responses::media_links::*;
use artcraft_api_defs::generate::image::edit::gpt_image_1_edit_image::*;
use artcraft_api_defs::generate::image::generate_flux_1_dev_text_to_image::GenerateFlux1DevTextToImageAspectRatio;
use artcraft_api_defs::generate::image::generate_flux_1_dev_text_to_image::GenerateFlux1DevTextToImageNumImages;
@@ -43,50 +46,15 @@ use artcraft_api_defs::generate::video::generate_veo_2_image_to_video::GenerateV
use artcraft_api_defs::generate::video::generate_veo_2_image_to_video::GenerateVeo2Duration;
use artcraft_api_defs::generate::video::generate_veo_2_image_to_video::GenerateVeo2ImageToVideoRequest;
use artcraft_api_defs::generate::video::generate_veo_2_image_to_video::GenerateVeo2ImageToVideoResponse;
use artcraft_api_defs::jobs::list_session_jobs::*;
use billing_component::stripe::http_endpoints::checkout::create::stripe_create_checkout_session_error::CreateCheckoutSessionError;
use billing_component::stripe::http_endpoints::checkout::create::stripe_create_checkout_session_json_handler::*;
use billing_component::users::http_endpoints::list_active_user_subscriptions_handler::*;
use enums::by_table::beta_keys::beta_key_product::BetaKeyProduct;
use enums::by_table::comments::comment_entity_type::CommentEntityType;
use enums::by_table::featured_items::featured_item_entity_type::FeaturedItemEntityType;
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory;
use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory;
use enums::by_table::media_files::media_file_subtype::MediaFileSubtype;
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::by_table::model_weights::{weights_category::WeightsCategory, weights_types::WeightsType};
use enums::by_table::prompts::prompt_type::PromptType;
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
use enums::by_table::user_ratings::entity_type::UserRatingEntityType;
use enums::by_table::user_ratings::rating_value::UserRatingValue;
use enums::by_table::users::user_feature_flag::UserFeatureFlag;
use enums::common::job_status_plus::JobStatusPlus;
use enums::common::visibility::Visibility;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::media_files::public_media_file_model_type::PublicMediaFileModelType;
use enums_public::by_table::model_weights::public_weights_types::PublicWeightsType;
use tokens::tokens::batch_generations::*;
use tokens::tokens::beta_keys::*;
use tokens::tokens::browser_session_logs::*;
use tokens::tokens::comments::*;
use tokens::tokens::generic_inference_jobs::*;
use tokens::tokens::media_files::*;
use tokens::tokens::model_weights::*;
use tokens::tokens::prompts::*;
use tokens::tokens::user_bookmarks::*;
use tokens::tokens::users::*;
use tokens::tokens::zs_voice_datasets::*;
use crate::http_server::common_requests::auto_product_category::AutoProductCategory;
use crate::http_server::common_requests::media_file_token_path_info::MediaFileTokenPathInfo;
use crate::http_server::common_responses::media::cover_image_links::CoverImageLinks;
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileDefaultCover;
use crate::http_server::common_responses::media::media_links::*;
use crate::http_server::common_responses::media::weights_cover_image_details::*;
use crate::http_server::common_responses::media_file_origin_details::*;
use crate::http_server::common_responses::media_file_social_meta_lite::MediaFileSocialMetaLight;
@@ -128,7 +96,40 @@ use crate::http_server::endpoints::featured_items::delete_featured_item_handler:
use crate::http_server::endpoints::featured_items::get_is_featured_item_handler::*;
use crate::http_server::endpoints::image_studio::prompt::enqueue_studio_image_generation_handler::*;
use crate::http_server::endpoints::image_studio::upload::upload_snapshot_media_file_handler::*;
use crate::http_server::endpoints::inference_job::common_responses::live_portrait::JobDetailsLivePortraitRequest;
use enums::by_table::beta_keys::beta_key_product::BetaKeyProduct;
use enums::by_table::comments::comment_entity_type::CommentEntityType;
use enums::by_table::featured_items::featured_item_entity_type::FeaturedItemEntityType;
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory;
use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory;
use enums::by_table::media_files::media_file_subtype::MediaFileSubtype;
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::by_table::model_weights::{weights_category::WeightsCategory, weights_types::WeightsType};
use enums::by_table::prompts::prompt_type::PromptType;
use enums::by_table::users::user_feature_flag::UserFeatureFlag;
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
use enums::by_table::user_ratings::entity_type::UserRatingEntityType;
use enums::by_table::user_ratings::rating_value::UserRatingValue;
use enums::common::job_status_plus::JobStatusPlus;
use enums::common::visibility::Visibility;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::media_files::public_media_file_model_type::PublicMediaFileModelType;
use enums_public::by_table::model_weights::public_weights_types::PublicWeightsType;
use tokens::tokens::batch_generations::*;
use tokens::tokens::beta_keys::*;
use tokens::tokens::browser_session_logs::*;
use tokens::tokens::comments::*;
use tokens::tokens::generic_inference_jobs::*;
use tokens::tokens::media_files::*;
use tokens::tokens::model_weights::*;
use tokens::tokens::prompts::*;
use tokens::tokens::users::*;
use tokens::tokens::user_bookmarks::*;
use tokens::tokens::zs_voice_datasets::*;
use crate::http_server::endpoints::inference_job::delete::dismiss_finished_session_jobs_handler::*;
use crate::http_server::endpoints::inference_job::delete::terminate_inference_job_handler::*;
use crate::http_server::endpoints::inference_job::get::batch_get_inference_job_status_handler::*;
@@ -363,6 +364,7 @@ use crate::http_server::web_utils::response_success_helpers::*;
// Common response structs
JobDetailsLivePortraitRequest,
JobDetailsLipsyncRequest,
MediaFileLivePortraitDetails,
MediaFileModelDetails,
MediaFileOriginDetails,
@@ -1,48 +1,21 @@
use url::Url;
use utoipa::ToSchema;
use crate::http_server::common_responses::media::cdn_link::{get_cdn_host, new_cdn_url};
use crate::http_server::common_responses::media::media_domain::MediaDomain;
use artcraft_api_defs::common::responses::media_links::{MediaLinks, VideoPreviews};
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use server_environment::ServerEnvironment;
use url::Url;
use utoipa::ToSchema;
// TODO(bt,2024-09-05): Worth reducing the quality at all?
const QUALITY : u8 = 95;
/// Links to media file locations (bucket, CDN, etc.)
#[derive(Serialize, ToSchema, Debug, Clone, Eq, PartialEq)]
pub struct MediaLinks {
/// Primary link to the asset via the CDN.
pub cdn_url: Url,
///
/// This migrates the constructors to the `artcraft_api_defs` crate
pub struct MediaLinksBuilder {}
/// Template to construct thumbnail URLs.
/// Replace the string `{WIDTH}` with the desired width.
/// Only relevant for image media files. (Video media files instead have
/// video previews, which, in turn, have their own thumbnail templates.)
pub maybe_thumbnail_template: Option<String>,
/// Video preview images (still and animated gif) for mp4 video files.
/// These are only set for video media files.
/// These are not set for "cover images" that are gif or webms, but rather video files.
pub maybe_video_previews: Option<VideoPreviews>,
}
#[derive(Serialize, ToSchema, Debug, Clone, Eq, PartialEq)]
pub struct VideoPreviews {
/// A static single frame preview image of the video.
pub still: Url,
/// An animated gif preview of the video.
pub animated: Url,
/// A template used to construct the still thumbnail URL.
/// Replace the string `{WIDTH}` with the desired width.
pub still_thumbnail_template: String,
/// A template used to construct the animated thumbnail URL.
/// Replace the string `{WIDTH}` with the desired width.
pub animated_thumbnail_template: String,
}
impl MediaLinks {
impl MediaLinksBuilder {
#[deprecated(note = "we need to start passing the domain and the server environment to generate the CDN")]
pub fn from_media_path(
domain: MediaDomain,
@@ -78,20 +51,22 @@ impl MediaLinks {
MediaLinks {
cdn_url,
maybe_thumbnail_template: thumbnail_template(domain, server_environment, rooted_path),
maybe_video_previews: VideoPreviews::from_rooted_path(domain, rooted_path),
maybe_video_previews: VideoPreviewsBuilder::from_rooted_path(domain, rooted_path),
}
}
}
impl VideoPreviews {
pub struct VideoPreviewsBuilder {}
impl VideoPreviewsBuilder {
fn from_rooted_path(
domain: MediaDomain,
rooted_path: &str,
) -> Option<Self> {
) -> Option<VideoPreviews> {
if !rooted_path.ends_with(".mp4") {
return None;
}
Some(Self {
Some(VideoPreviews {
still: video_preview(domain, rooted_path, PreviewType::Jpg),
animated: video_preview(domain, rooted_path, PreviewType::Gif),
still_thumbnail_template: video_preview_thumbnail_template(domain, rooted_path, PreviewType::Jpg),
@@ -150,7 +125,7 @@ mod tests {
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use crate::http_server::common_responses::media::media_domain::MediaDomain;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
mod fakeyou {
use super::*;
@@ -161,10 +136,10 @@ mod tests {
// TODO(bt,2025-01-31): Write robust tests for this.
#[test]
fn spot_check_new_case() {
let links = MediaLinks::from_rooted_path_and_env(MediaDomain::FakeYou, ServerEnvironment::Production, "/foo/bar.wav");
let links = MediaLinksBuilder::from_rooted_path_and_env(MediaDomain::FakeYou, ServerEnvironment::Production, "/foo/bar.wav");
assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/foo/bar.wav");
let links = MediaLinks::from_rooted_path_and_env(MediaDomain::Storyteller, ServerEnvironment::Development, "/foo/bar.wav");
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;let links = MediaLinksBuilder::from_rooted_path_and_env(MediaDomain::Storyteller, ServerEnvironment::Development, "/foo/bar.wav");
assert_eq!(links.cdn_url.as_str(), "https://pub-c8a4a5bdbdb048f286b77bdf9f786ff2.r2.dev/foo/bar.wav");
}
@@ -173,7 +148,7 @@ mod tests {
#[test]
fn wav_file() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.wav");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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);
@@ -181,7 +156,7 @@ mod tests {
#[test]
fn glb_file() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.glb");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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);
@@ -189,7 +164,7 @@ mod tests {
#[test]
fn jpg_image() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.jpg");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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);
@@ -197,7 +172,7 @@ mod tests {
#[test]
fn mp4_video() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.mp4");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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");
@@ -215,7 +190,7 @@ mod tests {
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 = MediaLinks::from_media_path(DOMAIN, &media_path);
let links = MediaLinksBuilder::from_media_path(DOMAIN, &media_path);
assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/media/9/4/a/2/7/94a27nmbd0bqmd10tg0pp3hz45zytf67/fakeyou_94a27nmbd0bqmd10tg0pp3hz45zytf67.wav");
assert_eq!(links.maybe_thumbnail_template, None);
assert_eq!(links.maybe_video_previews, None);
@@ -225,7 +200,7 @@ mod tests {
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 = MediaLinks::from_media_path(DOMAIN, &media_path);
let links = MediaLinksBuilder::from_media_path(DOMAIN, &media_path);
assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/media/3/7/m/b/3/37mb3gh8fmj85y21thvbv08bzv24atjt/upload_37mb3gh8fmj85y21thvbv08bzv24atjt.png");
assert_eq!(links.maybe_thumbnail_template, Some("https://cdn-2.fakeyou.com/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);
@@ -235,7 +210,7 @@ mod tests {
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 = MediaLinks::from_media_path(DOMAIN, &media_path);
let links = MediaLinksBuilder::from_media_path(DOMAIN, &media_path);
assert_eq!(links.cdn_url.as_str(), "https://cdn-2.fakeyou.com/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");
@@ -257,7 +232,7 @@ mod tests {
#[test]
fn wav_file() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.wav");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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);
@@ -265,7 +240,7 @@ mod tests {
#[test]
fn glb_file() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.glb");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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);
@@ -273,7 +248,7 @@ mod tests {
#[test]
fn jpg_image() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.jpg");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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);
@@ -281,7 +256,7 @@ mod tests {
#[test]
fn mp4_video() {
let links = MediaLinks::from_rooted_path(DOMAIN, "/foo/bar.mp4");
let links = MediaLinksBuilder::from_rooted_path(DOMAIN, "/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");
@@ -299,7 +274,7 @@ mod tests {
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 = MediaLinks::from_media_path(DOMAIN, &media_path);
let links = MediaLinksBuilder::from_media_path(DOMAIN, &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);
@@ -309,7 +284,7 @@ mod tests {
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 = MediaLinks::from_media_path(DOMAIN, &media_path);
let links = MediaLinksBuilder::from_media_path(DOMAIN, &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);
@@ -319,7 +294,7 @@ mod tests {
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 = MediaLinks::from_media_path(DOMAIN, &media_path);
let links = MediaLinksBuilder::from_media_path(DOMAIN, &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");
@@ -2,5 +2,5 @@ pub mod cdn_link;
pub mod cover_image_links;
pub mod media_domain;
pub mod media_file_cover_image_details;
pub mod media_links;
pub mod media_links_builder;
pub mod weights_cover_image_details;
@@ -1,11 +1,14 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
use actix_web::web::Json;
use actix_web::{web, HttpRequest};
use artcraft_api_defs::generate::image::edit::gpt_image_1_edit_image::{GptImage1EditImageImageQuality, GptImage1EditImageImageSize, GptImage1EditImageNumImages, GptImage1EditImageRequest, GptImage1EditImageResponse};
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use enums::common::visibility::Visibility;
use fal_client::creds::open_ai_api_key::OpenAiApiKey;
use fal_client::requests::webhook::image::enqueue_gpt_image_1_edit_image_webhook::enqueue_gpt_image_1_edit_image_webhook;
@@ -17,11 +20,8 @@ use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::InsertGenericInferenceForFalArgs;
use mysql_queries::queries::idepotency_tokens::insert_idempotency_token::insert_idempotency_token;
use utoipa::ToSchema;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use mysql_queries::queries::media_files::get::batch_get_media_files_by_tokens::batch_get_media_files_by_tokens;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use utoipa::ToSchema;
/// Gpt Image 1 Image Editing
#[utoipa::path(
@@ -107,7 +107,7 @@ pub async fn gpt_image_1_edit_image_handler(
file.maybe_public_bucket_prefix.as_deref(),
file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&public_bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -68,7 +68,7 @@ pub async fn remove_image_background_handler(
return Err(CommonWebError::BadInputWithSimpleMessage("No media file token provided".to_string()));
}
};
if let Err(reason) = validate_idempotency_token_format(&request.uuid_idempotency_token) {
return Err(CommonWebError::BadInputWithSimpleMessage(reason));
}
@@ -110,7 +110,7 @@ pub async fn remove_image_background_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -111,7 +111,7 @@ pub async fn generate_hunyuan_2_0_image_to_3d_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -111,7 +111,7 @@ pub async fn generate_hunyuan_2_1_image_to_3d_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -135,7 +135,7 @@ pub async fn generate_kling_1_6_pro_video_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -136,7 +136,7 @@ pub async fn generate_kling_2_1_master_video_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -136,7 +136,7 @@ pub async fn generate_kling_2_1_pro_video_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -114,7 +114,7 @@ pub async fn generate_seedance_1_0_lite_image_to_video_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::validations::validate_idempotency_token_format::validate_idempotency_token_format;
use crate::state::server_state::ServerState;
@@ -115,7 +115,7 @@ pub async fn generate_veo_2_image_to_video_handler(
media_file.maybe_public_bucket_prefix.as_deref(),
media_file.maybe_public_bucket_extension.as_deref());
let media_links = MediaLinks::from_media_path_and_env(
let media_links = MediaLinksBuilder::from_media_path_and_env(
media_domain,
server_state.server_environment,
&bucket_path);
@@ -1,14 +0,0 @@
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
/// Details about submitted lipsync jobs (request arguments only)
#[derive(Serialize, ToSchema)]
pub struct JobDetailsLipsyncRequest {
/// Media file token for the source audio.
/// This is probably an audio file, but in the future we might pull audio from video.
pub audio_source_token: MediaFileToken,
/// Media file token for the source visuals.
/// This is either an image or video.
pub image_or_video_source_token: MediaFileToken,
}
@@ -1,2 +0,0 @@
pub mod lipsync;
pub mod live_portrait;
@@ -2,20 +2,8 @@ use std::collections::HashSet;
use std::fmt;
use std::sync::Arc;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::Json;
use actix_web::{web, HttpRequest, HttpResponse};
use actix_web_lab::extract::Query;
use chrono::{DateTime, Utc};
use log::error;
use r2d2_redis::redis::Commands;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_domain::MediaDomain;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::endpoints::inference_job::common_responses::lipsync::JobDetailsLipsyncRequest;
use crate::http_server::endpoints::inference_job::common_responses::live_portrait::JobDetailsLivePortraitRequest;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::inference_job::utils::estimates::estimate_job_progress::estimate_job_progress;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_lipsync_details::extract_lipsync_details;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_live_portrait_details::extract_live_portrait_details;
@@ -24,16 +12,27 @@ use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_m
use crate::http_server::web_utils::filter_model_name::maybe_filter_model_name;
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
use crate::state::server_state::ServerState;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::Json;
use actix_web::{web, HttpRequest, HttpResponse};
use actix_web_lab::extract::Query;
use artcraft_api_defs::common::responses::job_details::{JobDetailsLipsyncRequest, JobDetailsLivePortraitRequest};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use bucket_paths::legacy::typified_paths::public::voice_conversion_results::bucket_file_path::VoiceConversionResultOriginalFilePath;
use chrono::{DateTime, Utc};
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::common::job_status_plus::JobStatusPlus;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use log::error;
use mysql_queries::queries::generic_inference::web::batch_get_inference_job_status::batch_get_inference_job_status;
use mysql_queries::queries::generic_inference::web::job_status::GenericInferenceJobStatus;
use r2d2_redis::redis::Commands;
use redis_common::redis_keys::RedisKeys;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use utoipa::{IntoParams, ToSchema};
/// For certain jobs or job classes (eg. non-premium), we kill the jobs if the user hasn't
/// maintained a keepalive. This prevents wasted work when users who are unlikely to return
@@ -41,7 +40,6 @@ use tokens::tokens::generic_inference_jobs::InferenceJobToken;
/// typically do not require keepalive.
const JOB_KEEPALIVE_TTL_SECONDS : usize = 60 * 3;
#[derive(Deserialize, ToSchema, IntoParams)]
pub struct BatchGetInferenceJobStatusQueryParams {
/// A grab bag of tokens of various types.
@@ -376,7 +374,7 @@ fn db_record_to_response_payload(
BatchResultDetailsResponse {
entity_type: result_details.entity_type,
entity_token: result_details.entity_token,
media_links: MediaLinks::from_rooted_path(media_domain, &public_bucket_media_path),
media_links: MediaLinksBuilder::from_rooted_path(media_domain, &public_bucket_media_path),
maybe_public_bucket_media_path: Some(public_bucket_media_path),
maybe_successfully_completed_at: result_details.maybe_successfully_completed_at,
}
@@ -1,19 +1,8 @@
use std::fmt;
use std::sync::Arc;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Path};
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::error;
use r2d2_redis::redis::{Commands, RedisResult};
use utoipa::ToSchema;
use crate::http_server::common_responses::media::media_domain::MediaDomain;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::endpoints::inference_job::common_responses::lipsync::JobDetailsLipsyncRequest;
use crate::http_server::endpoints::inference_job::common_responses::live_portrait::JobDetailsLivePortraitRequest;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::inference_job::utils::estimates::estimate_job_progress::estimate_job_progress;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_lipsync_details::extract_lipsync_details;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_live_portrait_details::extract_live_portrait_details;
@@ -22,16 +11,26 @@ use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_m
use crate::http_server::web_utils::filter_model_name::maybe_filter_model_name;
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
use crate::state::server_state::ServerState;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Path};
use actix_web::{web, HttpRequest, HttpResponse};
use artcraft_api_defs::common::responses::job_details::{JobDetailsLipsyncRequest, JobDetailsLivePortraitRequest};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use bucket_paths::legacy::typified_paths::public::voice_conversion_results::bucket_file_path::VoiceConversionResultOriginalFilePath;
use chrono::{DateTime, Utc};
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::common::job_status_plus::JobStatusPlus;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use log::error;
use mysql_queries::queries::generic_inference::web::get_inference_job_status::get_inference_job_status;
use mysql_queries::queries::generic_inference::web::job_status::GenericInferenceJobStatus;
use r2d2_redis::redis::{Commands, RedisResult};
use redis_common::redis_keys::RedisKeys;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use utoipa::ToSchema;
/// For certain jobs or job classes (eg. non-premium), we kill the jobs if the user hasn't
/// maintained a keepalive. This prevents wasted work when users who are unlikely to return
@@ -369,7 +368,7 @@ fn record_to_payload(
ResultDetailsResponse {
entity_type: result_details.entity_type,
entity_token: result_details.entity_token,
media_links: MediaLinks::from_rooted_path(media_domain, &public_bucket_media_path),
media_links: MediaLinksBuilder::from_rooted_path(media_domain, &public_bucket_media_path),
maybe_public_bucket_media_path: Some(public_bucket_media_path),
maybe_successfully_completed_at: result_details.maybe_successfully_completed_at,
}
@@ -2,20 +2,8 @@ use std::collections::HashSet;
use std::fmt;
use std::sync::Arc;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::Json;
use actix_web::{web, HttpRequest, HttpResponse};
use actix_web_lab::extract::Query;
use chrono::{DateTime, Utc};
use log::{error, warn};
use r2d2_redis::redis::Commands;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_domain::MediaDomain;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::endpoints::inference_job::common_responses::lipsync::JobDetailsLipsyncRequest;
use crate::http_server::endpoints::inference_job::common_responses::live_portrait::JobDetailsLivePortraitRequest;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::inference_job::utils::estimates::estimate_job_progress::estimate_job_progress;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_lipsync_details::extract_lipsync_details;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_live_portrait_details::extract_live_portrait_details;
@@ -24,18 +12,28 @@ use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_m
use crate::http_server::web_utils::filter_model_name::maybe_filter_model_name;
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
use crate::state::server_state::ServerState;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::Json;
use actix_web::{web, HttpRequest, HttpResponse};
use actix_web_lab::extract::Query;
use artcraft_api_defs::jobs::list_session_jobs::{ListSessionJobsItem, ListSessionJobsQueryParams, ListSessionJobsSuccessResponse, ListSessionRequestDetailsResponse, ListSessionResultDetailsResponse, ListSessionStatusDetailsResponse};
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use bucket_paths::legacy::typified_paths::public::voice_conversion_results::bucket_file_path::VoiceConversionResultOriginalFilePath;
use chrono::{DateTime, Utc};
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::common::job_status_plus::JobStatusPlus;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use log::{error, warn};
use mysql_queries::queries::generic_inference::web::job_status::GenericInferenceJobStatus;
use mysql_queries::queries::generic_inference::web::list_session_jobs::{list_session_jobs_from_connection, ListSessionJobsForUserArgs, SessionUser};
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 tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::{IntoParams, ToSchema};
/// For certain jobs or job classes (eg. non-premium), we kill the jobs if the user hasn't
/// maintained a keepalive. This prevents wasted work when users who are unlikely to return
@@ -43,118 +41,6 @@ use tokens::tokens::media_files::MediaFileToken;
/// typically do not require keepalive.
const JOB_KEEPALIVE_TTL_SECONDS : usize = 60 * 3;
#[derive(Deserialize, ToSchema, IntoParams)]
pub struct ListSessionJobsQueryParams {
//pub sort_ascending: Option<bool>,
//pub page_size: Option<usize>, // TODO(bt,2024-04-23): One page for now.
//pub page_index: Option<usize>, // TODO(bt,2024-04-23): One page for now.
/// NB: This can be one (or more comma-separated values) from `JobStatusPlus`.
/// ?include_states=pending or ?include_states=pending,started,complete_success (etc.)
pub include_states: Option<String>,
/// The opposite of include_states, this filters out states from view.
pub exclude_states: Option<String>,
// TODO(bt,2024-04-23): Add the ability for users to dismiss completed/dead jobs from view.
}
#[derive(Serialize, ToSchema)]
pub struct ListSessionJobsSuccessResponse {
pub success: bool,
/// This is not paginated and is limited to showing 100 jobs.
pub jobs: Vec<ListSessionJobsItem>,
}
#[derive(Serialize, ToSchema)]
pub struct ListSessionJobsItem {
pub job_token: InferenceJobToken,
pub request: ListSessionRequestDetailsResponse,
pub status: ListSessionStatusDetailsResponse,
pub maybe_result: Option<ListSessionResultDetailsResponse>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
/// Details about what the user requested for generation
#[derive(Serialize, ToSchema)]
pub struct ListSessionRequestDetailsResponse {
pub inference_category: InferenceCategory,
pub maybe_model_type: Option<String>,
pub maybe_model_token: Option<String>,
/// OPTIONAL. Title of the model, if it has one
pub maybe_model_title: Option<String>,
/// OPTIONAL. If the result was TTS, this is the raw inference text.
pub maybe_raw_inference_text: Option<String>,
/// OPTIONAL. For Comfy / Video Style Transfer jobs, this might include
/// the name of the selected style.
pub maybe_style_name: Option<StyleTransferName>,
/// OPTIONAL. For Live Portrait jobs, this is additional information on the request.
pub maybe_live_portrait_details: Option<JobDetailsLivePortraitRequest>,
/// OPTIONAL. For lipsync jobs (face fusion and sad talker), this is additional
/// information on the request.
pub maybe_lipsync_details: Option<JobDetailsLipsyncRequest>,
}
/// Details about the ongoing job status
#[derive(Serialize, ToSchema)]
pub struct ListSessionStatusDetailsResponse {
/// Primary status from the database (a state machine).
pub status: JobStatusPlus,
/// Extra, temporary status from Redis.
/// This can denote inference progress, and the Python code can write to it.
pub maybe_extra_status_description: Option<String>,
pub maybe_assigned_worker: Option<String>,
pub maybe_assigned_cluster: Option<String>,
pub maybe_first_started_at: Option<DateTime<Utc>>,
/// If the job is currently running, this is how long it has been running in seconds.
/// This is heuristic estimate since we don't record the precise start time across runs.
pub maybe_current_execution_duration_seconds: Option<u64>,
pub attempt_count: u8,
/// Whether the frontend needs to maintain a keepalive check.
/// This is typically only for non-premium users.
pub requires_keepalive: bool,
/// An enum the frontend can use to display localized/I18N error
/// messages. These pertain to both transient and permanent failures.
pub maybe_failure_category: Option<FrontendFailureCategory>,
/// This is an integer number between 0 and 100 (both inclusive) that
/// reports the completeness.
pub progress_percentage: u8,
}
/// Details about the completed result (if any)
#[derive(Serialize, ToSchema)]
pub struct ListSessionResultDetailsResponse {
pub entity_type: String,
pub entity_token: String,
/// (DEPRECATED) URL path to the media file
#[deprecated(note="This field doesn't point to the full URL. Use media_links instead to leverage the CDN.")]
pub maybe_public_bucket_media_path: Option<String>,
/// Rich CDN links to the media, including thumbnails, previews, and more.
pub media_links: MediaLinks,
pub maybe_successfully_completed_at: Option<DateTime<Utc>>,
}
#[derive(Debug, ToSchema)]
pub enum ListSessionJobsError {
ServerError,
@@ -472,7 +358,7 @@ fn db_record_to_response_payload(
ListSessionResultDetailsResponse {
entity_type: result_details.entity_type,
entity_token: result_details.entity_token,
media_links: MediaLinks::from_rooted_path(media_domain, &public_bucket_media_path),
media_links: MediaLinksBuilder::from_rooted_path(media_domain, &public_bucket_media_path),
maybe_public_bucket_media_path: Some(public_bucket_media_path),
maybe_successfully_completed_at: result_details.maybe_successfully_completed_at,
}
@@ -481,4 +367,3 @@ fn db_record_to_response_payload(
updated_at: record.updated_at,
}
}
@@ -1,5 +1,4 @@
pub mod admin;
pub mod common_responses;
pub mod delete;
pub mod get;
pub mod list;
@@ -1,4 +1,4 @@
use crate::http_server::endpoints::inference_job::common_responses::lipsync::JobDetailsLipsyncRequest;
use artcraft_api_defs::common::responses::job_details::JobDetailsLipsyncRequest;
use mysql_queries::payloads::generic_inference_args::generic_inference_args::PolymorphicInferenceArgs;
use mysql_queries::payloads::generic_inference_args::inner_payloads::face_fusion_payload::FaceFusionPayload;
use mysql_queries::payloads::generic_inference_args::inner_payloads::lipsync_payload::{LipsyncAnimationAudioSource, LipsyncAnimationImageSource, LipsyncArgs};
@@ -1,7 +1,6 @@
use artcraft_api_defs::common::responses::job_details::JobDetailsLivePortraitRequest;
use mysql_queries::payloads::generic_inference_args::generic_inference_args::PolymorphicInferenceArgs;
use crate::http_server::endpoints::inference_job::common_responses::live_portrait::JobDetailsLivePortraitRequest;
pub fn extract_live_portrait_details(args: &PolymorphicInferenceArgs) -> Option<JobDetailsLivePortraitRequest> {
let lp =
if let PolymorphicInferenceArgs::Lp(live_portrait_args) = args {
@@ -47,4 +46,4 @@ mod tests {
assert_eq!(details.source_media_file_token.as_str(), "portrait");
assert_eq!(details.face_driver_media_file_token.as_str(), "driver");
}
}
}
@@ -7,11 +7,9 @@ use actix_web::http::StatusCode;
use actix_web::web::Json;
use actix_web::{web, HttpRequest, HttpResponse};
use actix_web_lab::extract::Query;
use chrono::{DateTime, Utc};
use log::warn;
use utoipa::{IntoParams, ToSchema};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
@@ -22,14 +20,16 @@ use enums::by_table::model_weights::weights_types::WeightsType;
use enums::common::visibility::Visibility;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::model_weights::public_weights_types::PublicWeightsType;
use log::warn;
use mysql_queries::queries::media_files::get::batch_get_media_files::batch_get_media_files;
use tokens::tokens::batch_generations::BatchGenerationToken;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::model_weights::ModelWeightToken;
use tokens::tokens::prompts::PromptToken;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
use crate::http_server::common_responses::user_details_lite::UserDetailsLight;
use crate::http_server::endpoints::media_files::common_responses::live_portrait::MediaFileLivePortraitDetails;
@@ -333,7 +333,7 @@ pub async fn batch_get_media_files_handler(
maybe_media_subtype: result.maybe_media_subtype,
maybe_engine_extension,
maybe_batch_token: result.maybe_batch_token,
media_links: MediaLinks::from_media_path(media_domain, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
.to_string(),
@@ -1,18 +1,9 @@
use std::fmt;
use std::sync::Arc;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Path};
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::warn;
use url::Url;
use utoipa::ToSchema;
use crate::http_server::common_responses::media::media_domain::MediaDomain;
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
use crate::http_server::common_responses::user_details_lite::UserDetailsLight;
use crate::http_server::endpoints::media_files::common_responses::live_portrait::MediaFileLivePortraitDetails;
@@ -21,7 +12,13 @@ use crate::http_server::web_utils::bucket_urls::bucket_url_from_media_path::buck
use crate::http_server::web_utils::bucket_urls::bucket_url_from_str_path::bucket_url_from_str_path;
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
use crate::state::server_state::ServerState;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Path};
use actix_web::{web, HttpRequest, HttpResponse};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
@@ -32,12 +29,15 @@ use enums::by_table::model_weights::weights_types::WeightsType;
use enums::common::visibility::Visibility;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::model_weights::public_weights_types::PublicWeightsType;
use log::warn;
use mysql_queries::queries::media_files::get::get_media_file::get_media_file;
use mysql_queries::queries::tts::tts_results::query_tts_result::select_tts_result_by_token;
use tokens::tokens::batch_generations::BatchGenerationToken;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::model_weights::ModelWeightToken;
use tokens::tokens::prompts::PromptToken;
use url::Url;
use utoipa::ToSchema;
/// For the URL PathInfo
#[derive(Deserialize, ToSchema)]
@@ -365,7 +365,7 @@ async fn modern_media_file_lookup(
maybe_engine_extension,
maybe_batch_token: result.maybe_batch_token,
maybe_scene_source_media_file_token: result.maybe_scene_source_media_file_token,
media_links: MediaLinks::from_media_path_and_env(media_domain, server_state.server_environment, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path_and_env(media_domain, server_state.server_environment, &public_bucket_path),
public_bucket_url: bucket_url_from_media_path(&public_bucket_path)
.map_err(|err| {
warn!("error creating URL: {:?}", err);
@@ -502,7 +502,7 @@ async fn emulate_media_file_with_legacy_tts_result_lookup(
maybe_engine_extension: None,
maybe_batch_token: None,
maybe_scene_source_media_file_token: None,
media_links: MediaLinks::from_rooted_path_and_env(media_domain, server_state.server_environment, &public_bucket_path),
media_links: MediaLinksBuilder::from_rooted_path_and_env(media_domain, server_state.server_environment, &public_bucket_path),
public_bucket_url: bucket_url_from_str_path(&public_bucket_path)
.map_err(|err| {
warn!("error creating URL: {:?}", err);
@@ -3,14 +3,9 @@ use actix_web::http::StatusCode;
use actix_web::web::Query;
use actix_web::{web, HttpRequest, HttpResponse};
use actix_web_lab::__reexports::tracing::info;
use chrono::{DateTime, Utc};
use log::{error, warn};
use std::sync::Arc;
use std::time::Instant;
use time::ext::InstantExt;
use utoipa::{IntoParams, ToSchema};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
@@ -20,11 +15,16 @@ use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::common::view_as::ViewAs;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::media_files::public_media_file_model_type::PublicMediaFileModelType;
use log::{error, warn};
use mysql_queries::queries::media_files::list::list_featured_media_files::{list_featured_media_files, FeaturedMediaFileListPage, ListFeaturedMediaFilesArgs};
use std::sync::Arc;
use std::time::Instant;
use time::ext::InstantExt;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::media_file_origin_details::MediaFileOriginDetails;
use crate::http_server::common_responses::pagination_cursors::PaginationCursors;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
@@ -288,7 +288,7 @@ pub async fn list_featured_media_files_handler(
media_type: m.media_type,
maybe_engine_category: m.maybe_engine_category,
maybe_animation_type: m.maybe_animation_type,
media_links: MediaLinks::from_media_path(media_domain, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
.to_string(),
@@ -4,11 +4,9 @@ use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Path, Query};
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::warn;
use utoipa::{IntoParams, ToSchema};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
@@ -19,12 +17,14 @@ use enums::common::view_as::ViewAs;
use enums::common::visibility::Visibility;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::media_files::public_media_file_model_type::PublicMediaFileModelType;
use log::warn;
use mysql_queries::queries::media_files::list::list_media_files_by_batch_token::{list_media_files_by_batch_token, ListMediaFileByBatchArgs};
use tokens::tokens::batch_generations::BatchGenerationToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::media_file_origin_details::MediaFileOriginDetails;
use crate::http_server::common_responses::pagination_page::PaginationPage;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
@@ -277,7 +277,7 @@ pub async fn list_media_files_by_batch_token_handler(
maybe_origin_model_type: record.maybe_origin_model_type
.map(|t| PublicMediaFileModelType::from_enum(t)),
maybe_origin_model_token: record.maybe_origin_model_token,
media_links: MediaLinks::from_media_path(media_domain, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
.to_string(),
@@ -4,11 +4,9 @@ use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Path, Query};
use actix_web::{web, HttpMessage, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::{info, warn};
use utoipa::{IntoParams, ToSchema};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
@@ -19,11 +17,13 @@ use enums::common::view_as::ViewAs;
use enums::common::visibility::Visibility;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::media_files::public_media_file_model_type::PublicMediaFileModelType;
use log::{info, warn};
use mysql_queries::queries::media_files::list::list_media_files_for_user::{list_media_files_for_user, ListMediaFileForUserArgs};
use tokens::tokens::media_files::MediaFileToken;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::media_file_origin_details::MediaFileOriginDetails;
use crate::http_server::common_responses::pagination_page::PaginationPage;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
@@ -339,7 +339,7 @@ pub async fn list_media_files_for_user_handler(
maybe_origin_model_type: record.maybe_origin_model_type
.map(|t| PublicMediaFileModelType::from_enum(t)),
maybe_origin_model_token: record.maybe_origin_model_token,
media_links: MediaLinks::from_media_path_and_env(
media_links: MediaLinksBuilder::from_media_path_and_env(
media_domain, server_state.server_environment, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
@@ -4,11 +4,9 @@ use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::Query;
use actix_web::{web, HttpMessage, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::warn;
use utoipa::{IntoParams, ToSchema};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
@@ -19,11 +17,13 @@ use enums::common::view_as::ViewAs;
use enums::common::visibility::Visibility;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::media_files::public_media_file_model_type::PublicMediaFileModelType;
use log::warn;
use mysql_queries::queries::media_files::list::list_media_files::{list_media_files, ListMediaFilesArgs};
use tokens::tokens::media_files::MediaFileToken;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::media_file_origin_details::MediaFileOriginDetails;
use crate::http_server::common_responses::pagination_cursors::PaginationCursors;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
@@ -345,7 +345,7 @@ pub async fn list_media_files_handler(
maybe_origin_model_type: record.maybe_origin_model_type
.map(|m| PublicMediaFileModelType::from_enum(m)),
maybe_origin_model_token: record.maybe_origin_model_token,
media_links: MediaLinks::from_media_path(media_domain, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
.to_string(),
@@ -3,12 +3,9 @@ use std::sync::Arc;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::{debug, error, warn};
use r2d2_redis::redis::Commands;
use utoipa::ToSchema;
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
@@ -17,11 +14,14 @@ use enums::by_table::media_files::media_file_origin_product_category::MediaFileO
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use enums_public::by_table::media_files::public_media_file_model_type::PublicMediaFileModelType;
use log::{debug, error, warn};
use mysql_queries::queries::media_files::get::batch_get_media_files_by_tokens::batch_get_media_files_by_tokens;
use r2d2_redis::redis::Commands;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::media_file_origin_details::MediaFileOriginDetails;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
use crate::http_server::common_responses::user_details_lite::UserDetailsLight;
@@ -215,7 +215,7 @@ pub async fn list_pinned_media_files_handler(
media_type: m.media_type,
maybe_engine_category: m.maybe_engine_category,
maybe_animation_type: m.maybe_animation_type,
media_links: MediaLinks::from_media_path(media_domain, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
.to_string(),
@@ -4,21 +4,21 @@ use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Query};
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::warn;
use utoipa::{IntoParams, ToSchema};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use elasticsearch_schema::searches::search_media_files::{search_media_files, SearchArgs};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::common::visibility::Visibility;
use log::warn;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::user_details_lite::UserDetailsLight;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::endpoints::media_files::helpers::get_scoped_engine_categories::get_scoped_engine_categories;
@@ -227,7 +227,7 @@ pub async fn search_featured_media_files_handler(
media_type: result.media_type,
maybe_engine_category: result.maybe_engine_category,
maybe_animation_type: result.maybe_animation_type,
media_links: MediaLinks::from_media_path(media_domain, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
.to_string(),
@@ -4,22 +4,22 @@ use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Query};
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::warn;
use utoipa::{IntoParams, ToSchema};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use elasticsearch_schema::searches::search_media_files::{search_media_files, SearchArgs};
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use enums::by_table::media_files::media_file_class::MediaFileClass;
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::common::visibility::Visibility;
use log::warn;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::users::UserToken;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::user_details_lite::UserDetailsLight;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::endpoints::media_files::helpers::get_scoped_engine_categories::get_scoped_engine_categories;
@@ -254,7 +254,7 @@ pub async fn search_session_media_files_handler(
media_type: result.media_type,
maybe_engine_category: result.maybe_engine_category,
maybe_animation_type: result.maybe_animation_type,
media_links: MediaLinks::from_media_path(media_domain, &public_bucket_path),
media_links: MediaLinksBuilder::from_media_path(media_domain, &public_bucket_path),
public_bucket_path: public_bucket_path
.get_full_object_path_str()
.to_string(),
@@ -6,16 +6,8 @@
use std::fmt;
use std::sync::Arc;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Path, Query};
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use log::warn;
use utoipa::{IntoParams, ToSchema};
use crate::http_server::common_responses::media::media_file_cover_image_details::MediaFileCoverImageDetails;
use crate::http_server::common_responses::media::media_links::MediaLinks;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::common_responses::media::weights_cover_image_details::WeightsCoverImageDetails;
use crate::http_server::common_responses::pagination_page::PaginationPage;
use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats;
@@ -23,16 +15,24 @@ use crate::http_server::common_responses::user_details_lite::UserDetailsLight;
use crate::http_server::endpoints::media_files::helpers::get_media_domain::get_media_domain;
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
use crate::state::server_state::ServerState;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Json, Path, Query};
use actix_web::{web, HttpRequest, HttpResponse};
use artcraft_api_defs::common::responses::media_links::MediaLinks;
use bucket_paths::legacy::typified_paths::public::media_files::bucket_file_path::MediaFileBucketPath;
use chrono::{DateTime, Utc};
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::by_table::model_weights::weights_category::WeightsCategory;
use enums::by_table::model_weights::weights_types::WeightsType;
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
use enums_public::by_table::model_weights::public_weights_types::PublicWeightsType;
use log::warn;
use mysql_queries::queries::users::user_bookmarks::list_user_bookmarks::{list_user_bookmarks_by_maybe_entity_type, ListUserBookmarksForUserArgs};
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::model_weights::ModelWeightToken;
use tokens::tokens::user_bookmarks::UserBookmarkToken;
use utoipa::{IntoParams, ToSchema};
#[derive(Deserialize, ToSchema)]
pub struct ListUserBookmarksPathInfo {
@@ -230,7 +230,7 @@ pub async fn list_user_bookmarks_for_user_handler(
});
let maybe_media_file_media_links = maybe_media_file_bucket_path.as_ref()
.map(|bucket_path| MediaLinks::from_media_path(media_domain, bucket_path));
.map(|bucket_path| MediaLinksBuilder::from_media_path(media_domain, bucket_path));
let mut maybe_media_file_cover = None;
let mut maybe_model_weight_cover = None;