diff --git a/crates/lib/mysql_queries/src/queries/media_files/get_media_file.rs b/crates/lib/mysql_queries/src/queries/media_files/get_media_file.rs index 8dc215e82f..b2c38b6e1c 100644 --- a/crates/lib/mysql_queries/src/queries/media_files/get_media_file.rs +++ b/crates/lib/mysql_queries/src/queries/media_files/get_media_file.rs @@ -8,9 +8,12 @@ use chrono::{DateTime, Utc}; use sqlx::MySqlPool; 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::common::visibility::Visibility; use errors::AnyhowResult; use tokens::tokens::media_files::MediaFileToken; +use tokens::tokens::model_weights::ModelWeightToken; use tokens::tokens::users::UserToken; #[derive(Serialize, Debug)] @@ -31,6 +34,11 @@ pub struct MediaFile { pub creator_set_visibility: Visibility, + pub maybe_model_weights_token: Option, + pub maybe_model_weights_title: Option, + pub maybe_model_weights_type: Option, + pub maybe_model_weights_category: Option, + pub public_bucket_directory_hash: String, pub maybe_public_bucket_prefix: Option, pub maybe_public_bucket_extension: Option, @@ -68,6 +76,11 @@ pub struct MediaFileRaw { pub creator_set_visibility: Visibility, + pub maybe_model_weights_token: Option, + pub maybe_model_weights_title: Option, + pub maybe_model_weights_type: Option, + pub maybe_model_weights_category: Option, + pub public_bucket_directory_hash: String, pub maybe_public_bucket_prefix: Option, pub maybe_public_bucket_extension: Option, @@ -109,6 +122,10 @@ pub async fn get_media_file( maybe_creator_display_name: record.maybe_creator_display_name, maybe_creator_gravatar_hash: record.maybe_creator_gravatar_hash, creator_set_visibility: record.creator_set_visibility, + maybe_model_weights_token: record.maybe_model_weights_token, + maybe_model_weights_title: record.maybe_model_weights_title, + maybe_model_weights_type: record.maybe_model_weights_type, + maybe_model_weights_category: record.maybe_model_weights_category, public_bucket_directory_hash: record.public_bucket_directory_hash, maybe_public_bucket_prefix: record.maybe_public_bucket_prefix, maybe_public_bucket_extension: record.maybe_public_bucket_extension, @@ -136,6 +153,11 @@ SELECT m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`, + model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`, + model_weights.title as maybe_model_weights_title, + model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`, + model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`, + m.public_bucket_directory_hash, m.maybe_public_bucket_prefix, m.maybe_public_bucket_extension, @@ -146,6 +168,8 @@ SELECT FROM media_files AS m LEFT OUTER JOIN users ON m.maybe_creator_user_token = users.token +LEFT OUTER JOIN model_weights + ON m.maybe_origin_model_token = model_weights.token WHERE m.token = ? "#, @@ -174,6 +198,11 @@ SELECT m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`, + model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`, + model_weights.title as maybe_model_weights_title, + model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`, + model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`, + m.public_bucket_directory_hash, m.maybe_public_bucket_prefix, m.maybe_public_bucket_extension, @@ -184,6 +213,8 @@ SELECT FROM media_files AS m LEFT OUTER JOIN users ON m.maybe_creator_user_token = users.token +LEFT OUTER JOIN model_weights + ON m.maybe_origin_model_token = model_weights.token WHERE m.token = ? AND m.user_deleted_at IS NULL diff --git a/crates/service/web/storyteller_web/src/api_doc.rs b/crates/service/web/storyteller_web/src/api_doc.rs index d3be7c0799..7adcf868de 100644 --- a/crates/service/web/storyteller_web/src/api_doc.rs +++ b/crates/service/web/storyteller_web/src/api_doc.rs @@ -19,6 +19,7 @@ use crate::http_server::common_responses::media_file_social_meta_lite::MediaFile use crate::http_server::common_responses::pagination_cursors::PaginationCursors; use crate::http_server::common_responses::pagination_page::PaginationPage; use crate::http_server::common_responses::user_details_lite::{DefaultAvatarInfo, UserDetailsLight}; +use crate::http_server::endpoints::media_files::get_media_file::*; use crate::http_server::endpoints::media_files::list_featured_media_files::*; use crate::http_server::endpoints::media_files::list_media_files::*; use crate::http_server::endpoints::media_files::list_media_files_for_user::*; @@ -42,6 +43,7 @@ use crate::http_server::web_utils::response_success_helpers::*; #[derive(OpenApi)] #[openapi( paths( + crate::http_server::endpoints::media_files::get_media_file::get_media_file_handler, crate::http_server::endpoints::media_files::list_featured_media_files::list_featured_media_files_handler, crate::http_server::endpoints::media_files::list_media_files::list_media_files_handler, crate::http_server::endpoints::media_files::list_media_files_for_user::list_media_files_for_user_handler, @@ -70,6 +72,7 @@ use crate::http_server::web_utils::response_success_helpers::*; EnqueueTTSRequest,EnqueueTTSRequestSuccessResponse,EnqueueTTSRequestError,InferenceJobToken, // Media Files WeightsData, + GetMediaFilePathInfo,GetMediaFileError,GetMediaFileSuccessResponse,GetMediaFileModelInfo,MediaFileInfo, // Model Weights ModelWeightToken,WeightsCategory,WeightsType, GetWeightPathInfo,GetWeightResponse,GetWeightError, diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/get_media_file.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/get_media_file.rs index b18f8af8da..bf9b7826aa 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/get_media_file.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/get_media_file.rs @@ -7,32 +7,36 @@ use actix_web::http::StatusCode; use actix_web::web::Path; use chrono::{DateTime, Utc}; use log::warn; +use utoipa::ToSchema; use buckets::public::media_files::bucket_file_path::MediaFileBucketPath; 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::common::visibility::Visibility; use mysql_queries::queries::media_files::get_media_file::get_media_file; use mysql_queries::queries::tts::tts_results::query_tts_result::select_tts_result_by_token; use tokens::tokens::media_files::MediaFileToken; +use tokens::tokens::model_weights::ModelWeightToken; use crate::http_server::common_responses::user_details_lite::UserDetailsLight; use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; use crate::server_state::ServerState; /// For the URL PathInfo -#[derive(Deserialize)] +#[derive(Deserialize, ToSchema)] pub struct GetMediaFilePathInfo { token: MediaFileToken, } -#[derive(Serialize)] +#[derive(Serialize, ToSchema)] pub struct GetMediaFileSuccessResponse { pub success: bool, - pub media_file: MediaFile, + pub media_file: MediaFileInfo, } -#[derive(Serialize)] -pub struct MediaFile { +#[derive(Serialize, ToSchema)] +pub struct MediaFileInfo { pub token: MediaFileToken, /// Type of media will dictate which fields are populated and what @@ -49,6 +53,10 @@ pub struct MediaFile { //pub maybe_origin_model_token: Option, //pub maybe_origin_filename: Option, + /// Possible model info (if generated by inference) + pub maybe_model_weight_info: Option, + + /// User info pub maybe_creator_user: Option, @@ -74,7 +82,15 @@ pub struct MediaFile { // pub maybe_mod_deleted_at: Option>, //} -#[derive(Debug)] +#[derive(Serialize, ToSchema)] +pub struct GetMediaFileModelInfo { + pub token: ModelWeightToken, + pub weight_type: WeightsType, + pub weight_category: WeightsCategory, + pub title: String, +} + +#[derive(Debug, ToSchema)] pub enum GetMediaFileError { ServerError, NotFound, @@ -83,8 +99,8 @@ pub enum GetMediaFileError { impl ResponseError for GetMediaFileError { fn status_code(&self) -> StatusCode { match *self { - GetMediaFileError::ServerError=> StatusCode::INTERNAL_SERVER_ERROR, - GetMediaFileError::NotFound=> StatusCode::NOT_FOUND, + GetMediaFileError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, + GetMediaFileError::NotFound => StatusCode::NOT_FOUND, } } @@ -105,6 +121,18 @@ impl fmt::Display for GetMediaFileError { } } +#[utoipa::path( + get, + path = "/v1/media_files/file/{token}", + responses( + (status = 200, description = "Found", body = GetMediaFileSuccessResponse), + (status = 404, description = "Not found", body = GetMediaFileError), + (status = 500, description = "Server error", body = GetMediaFileError), + ), + params( + ("path" = GetMediaFilePathInfo, description = "Path for Request") + ) +)] pub async fn get_media_file_handler( http_request: HttpRequest, path: Path, @@ -194,10 +222,21 @@ async fn modern_media_file_lookup( Ok(GetMediaFileSuccessResponse { success: true, - media_file: MediaFile { + media_file: MediaFileInfo { token: result.token, media_type: result.media_type, public_bucket_path, + maybe_model_weight_info: match result.maybe_model_weights_token { + None => None, + Some(weight_token) => Some(GetMediaFileModelInfo { + token: weight_token, + // TODO(bt,2023-12-28): Instead of giving bogus defaults on None, make these optional or return + // None for *everything* on any field being absent. + weight_type: result.maybe_model_weights_type.unwrap_or(WeightsType::Tacotron2), + weight_category: result.maybe_model_weights_category.unwrap_or(WeightsCategory::TextToSpeech), + title: result.maybe_model_weights_title.unwrap_or_else(|| "model".to_string()), + }) + }, maybe_creator_user: UserDetailsLight::from_optional_db_fields_owned( result.maybe_creator_user_token, result.maybe_creator_username, @@ -255,10 +294,17 @@ async fn emulate_media_file_with_legacy_tts_result_lookup( Ok(GetMediaFileSuccessResponse { success: true, - media_file: MediaFile { + media_file: MediaFileInfo { token, media_type: MediaFileType::Audio, // NB: Always audio public_bucket_path, + maybe_model_weight_info: Some(GetMediaFileModelInfo { + // NB: These should be reasonable synthetic defaults for emulated TT2 results, even the "ModelWeightToken". + token: ModelWeightToken::new_from_str(&result.tts_model_token), + weight_type: WeightsType::Tacotron2, + weight_category: WeightsCategory::TextToSpeech, + title: result.tts_model_title.unwrap_or_else(|| "tacotron2 model".to_string()), + }), maybe_creator_user: UserDetailsLight::from_optional_db_fields_owned( result.maybe_creator_user_token, result.maybe_creator_username, diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/create_user_bookmark_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/create_user_bookmark_handler.rs index f720c601c7..62709c8fae 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/create_user_bookmark_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/create_user_bookmark_handler.rs @@ -76,13 +76,13 @@ impl fmt::Display for CreateUserBookmarkError { } #[utoipa::path( -post, -path = "/v1/user_bookmarks/create", -request_body = CreateUserBookmarkRequest, -responses( -(status = 200, body = CreateUserBookmarkSuccessResponse), -(status = 400, body = CreateUserBookmarkError), -) + post, + path = "/v1/user_bookmarks/create", + request_body = CreateUserBookmarkRequest, + responses( + (status = 200, body = CreateUserBookmarkSuccessResponse), + (status = 400, body = CreateUserBookmarkError), + ) )] pub async fn create_user_bookmark_handler( http_request: HttpRequest, diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/list_user_bookmarks_for_user_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/list_user_bookmarks_for_user_handler.rs index 875f1b7d5a..77c53bb158 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/list_user_bookmarks_for_user_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/user_bookmarks/list_user_bookmarks_for_user_handler.rs @@ -142,8 +142,8 @@ pub async fn list_user_bookmarks_for_user_handler( ) -> Result { let sort_ascending = query.sort_ascending.unwrap_or(false); - let page_size = query.page_size.unwrap_or_else(|| 25); - let page_index = query.page_index.unwrap_or_else(|| 0); + let page_size = query.page_size.unwrap_or(25); + let page_index = query.page_index.unwrap_or(0); let query_results = list_user_bookmarks_by_maybe_entity_type(ListUserBookmarksForUserArgs{ @@ -177,7 +177,7 @@ pub async fn list_user_bookmarks_for_user_handler( maybe_weights_data: match user_bookmark.entity_type { UserBookmarkEntityType::ModelWeight => Some(WeightsData { // TODO(bt,2023-12-28): Proper default, optional, or "unknown" values would be better. - title: user_bookmark.maybe_entity_descriptive_text.clone().unwrap_or("weight".to_string()), + title: user_bookmark.maybe_entity_descriptive_text.clone().unwrap_or_else(|| "weight".to_string()), weights_type: user_bookmark.maybe_model_weight_type.unwrap_or(WeightsType::Tacotron2), weights_category: user_bookmark.maybe_model_weight_category.unwrap_or(WeightsCategory::TextToSpeech), }),