From c767a17da789a7e59ee680abe3f7ae68780f612e Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 3 Oct 2024 00:45:07 -0400 Subject: [PATCH] fix api --- .../src/queries/tags/select_matching_tags.rs | 1 - .../web/storyteller_web/src/docs/api_doc.rs | 14 +++--- .../src/http_server/common_responses/mod.rs | 1 + .../http_server/common_responses/tag_info.rs | 8 ++++ .../tags/list_tags_for_entity_handler.rs | 8 +++- .../tags/set_tags_for_entity_handler.rs | 47 ++++++++++++------- 6 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 crates/service/web/storyteller_web/src/http_server/common_responses/tag_info.rs diff --git a/crates/lib/mysql_queries/src/queries/tags/select_matching_tags.rs b/crates/lib/mysql_queries/src/queries/tags/select_matching_tags.rs index 27e8a0c332..75cdf8d0a3 100644 --- a/crates/lib/mysql_queries/src/queries/tags/select_matching_tags.rs +++ b/crates/lib/mysql_queries/src/queries/tags/select_matching_tags.rs @@ -1,4 +1,3 @@ -use log::info; use crate::utils::transactor::Transactor; use errors::AnyhowResult; use sqlx::mysql::MySqlRow; diff --git a/crates/service/web/storyteller_web/src/docs/api_doc.rs b/crates/service/web/storyteller_web/src/docs/api_doc.rs index caf8d0bf4a..759927b3dd 100644 --- a/crates/service/web/storyteller_web/src/docs/api_doc.rs +++ b/crates/service/web/storyteller_web/src/docs/api_doc.rs @@ -43,14 +43,15 @@ use crate::http_server::common_requests::media_file_token_path_info::MediaFileTo 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; -use crate::http_server::common_responses::media::media_links::*; use crate::http_server::common_responses::pagination_cursors::PaginationCursors; use crate::http_server::common_responses::pagination_page::PaginationPage; use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats; use crate::http_server::common_responses::simple_response::SimpleResponse; +use crate::http_server::common_responses::tag_info::TagInfo; use crate::http_server::common_responses::user_details_lite::{UserDefaultAvatarInfo, UserDetailsLight}; use crate::http_server::endpoints::analytics::log_browser_session_handler::*; use crate::http_server::endpoints::app_state::components::get_permissions::AppStateLegacyPermissionFlags; @@ -119,6 +120,8 @@ use crate::http_server::endpoints::moderation::user_feature_flags::edit_user_fea use crate::http_server::endpoints::prompts::get_prompt_handler::*; use crate::http_server::endpoints::service::status_alert_handler::*; use crate::http_server::endpoints::stats::get_unified_queue_stats_handler::*; +use crate::http_server::endpoints::tags::list_tags_for_entity_handler::*; +use crate::http_server::endpoints::tags::set_tags_for_entity_handler::*; use crate::http_server::endpoints::tts::enqueue_infer_tts_handler::enqueue_infer_tts_handler::*; use crate::http_server::endpoints::user_bookmarks::batch_get_user_bookmarks_handler::*; use crate::http_server::endpoints::user_bookmarks::create_user_bookmark_handler::*; @@ -128,15 +131,13 @@ use crate::http_server::endpoints::user_bookmarks::list_user_bookmarks_for_user_ use crate::http_server::endpoints::user_ratings::batch_get_user_rating_handler::*; use crate::http_server::endpoints::user_ratings::get_user_rating_handler::*; use crate::http_server::endpoints::user_ratings::set_user_rating_handler::*; -use crate::http_server::endpoints::tags::list_tags_for_entity_handler::*; -use crate::http_server::endpoints::tags::set_tags_for_entity_handler::*; +use crate::http_server::endpoints::users::create_account_handler::*; +use crate::http_server::endpoints::users::edit_username_handler::*; use crate::http_server::endpoints::users::get_profile_handler::*; +use crate::http_server::endpoints::users::google_sso::google_sso_handler::*; use crate::http_server::endpoints::users::login_handler::*; use crate::http_server::endpoints::users::logout_handler::*; use crate::http_server::endpoints::users::session_info_handler::*; -use crate::http_server::endpoints::users::edit_username_handler::*; -use crate::http_server::endpoints::users::google_sso::google_sso_handler::*; -use crate::http_server::endpoints::users::create_account_handler::*; use crate::http_server::endpoints::users::session_token_info_handler::*; use crate::http_server::endpoints::voice_conversion::enqueue_voice_conversion_inference_handler::*; use crate::http_server::endpoints::voice_designer::inference::enqueue_tts_request::*; @@ -311,6 +312,7 @@ use crate::http_server::web_utils::response_success_helpers::*; SimpleEntityStats, SimpleGenericJsonSuccess, SimpleResponse, + TagInfo, UserDetailsLight, VideoPreviews, Visibility, diff --git a/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs b/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs index d3b009bd43..d45b5053e9 100644 --- a/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs @@ -5,5 +5,6 @@ pub mod pagination_cursors; pub mod pagination_page; pub mod simple_entity_stats; pub mod simple_response; +pub mod tag_info; pub mod user_avatars; pub mod user_details_lite; diff --git a/crates/service/web/storyteller_web/src/http_server/common_responses/tag_info.rs b/crates/service/web/storyteller_web/src/http_server/common_responses/tag_info.rs new file mode 100644 index 0000000000..7f82972fbf --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/common_responses/tag_info.rs @@ -0,0 +1,8 @@ +use tokens::tokens::tags::TagToken; +use utoipa::ToSchema; + +#[derive(Serialize, ToSchema)] +pub struct TagInfo { + pub token: TagToken, + pub value: String, +} diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/tags/list_tags_for_entity_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/tags/list_tags_for_entity_handler.rs index cae68a30e6..d8460c2686 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/tags/list_tags_for_entity_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/tags/list_tags_for_entity_handler.rs @@ -6,6 +6,7 @@ use std::fmt; use std::sync::Arc; +use crate::http_server::common_responses::tag_info::TagInfo; use crate::http_server::endpoints::comments::list_comments_handler::ListCommentsPathInfo; use crate::http_server::endpoints::media_files::edit::set_media_file_cover_image_handler::SetMediaFileCoverImageError; use crate::http_server::endpoints::users::edit_username_handler::EditUsernameError; @@ -54,7 +55,7 @@ pub struct ListTagsForEntityPathInfo { #[derive(Serialize, ToSchema)] pub struct ListTagsForEntitySuccessResponse { pub success: bool, - pub tags: Vec, + pub tags: Vec, } #[derive(Debug, ToSchema)] @@ -145,7 +146,10 @@ pub async fn list_tags_for_entity_handler( success: true, tags: tags .into_iter() - .map(|tag| tag.tag_value) + .map(|tag| TagInfo { + token: tag.token, + value: tag.tag_value, + }) .collect(), })) } diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/tags/set_tags_for_entity_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/tags/set_tags_for_entity_handler.rs index da80cccdc1..8097d79a70 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/tags/set_tags_for_entity_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/tags/set_tags_for_entity_handler.rs @@ -6,6 +6,7 @@ use std::fmt; use std::sync::Arc; +use crate::http_server::common_responses::tag_info::TagInfo; use crate::http_server::endpoints::comments::list_comments_handler::ListCommentsPathInfo; use crate::http_server::endpoints::media_files::edit::set_media_file_cover_image_handler::SetMediaFileCoverImageError; use crate::http_server::endpoints::users::edit_username_handler::EditUsernameError; @@ -43,6 +44,9 @@ use tokens::tokens::w2l_templates::W2lTemplateToken; use user_input_common::check_for_slurs::contains_slurs; use utoipa::ToSchema; +/// Maximum number of tags allowed per item. +const MAX_TAGS : usize = 30; + /// For the URL PathInfo #[derive(Deserialize, ToSchema)] pub struct SetTagsForEntityPathInfo { @@ -59,7 +63,7 @@ pub struct SetTagsForEntityRequest { #[derive(Serialize, ToSchema)] pub struct SetTagsForEntitySuccessResponse { pub success: bool, - pub tag_tokens: Vec, + pub tags: Vec, } #[derive(Debug, ToSchema)] @@ -171,6 +175,12 @@ pub async fn set_tags_for_entity_handler( let matching_tags = select_matching_tags(&request_tags, Transactor::for_connection(&mut *mysql_connection)) .await + .map(|tags| tags.into_iter() + .map(|tag| TagInfo { + token: tag.token, + value: tag.tag_value.to_string(), + }) + .collect::>()) .map_err(|e| { warn!("error selecting tags: {:?}", e); SetTagsForEntityError::ServerError @@ -178,7 +188,7 @@ pub async fn set_tags_for_entity_handler( let matching_tag_values = matching_tags .iter() - .map(|tag| tag.tag_value.to_string()) + .map(|tag| tag.value.to_string()) .collect::>(); let new_tag_values = request_tags.iter() @@ -186,7 +196,7 @@ pub async fn set_tags_for_entity_handler( .map(|tag| tag.as_str()) .collect::>(); - let mut new_tag_tokens = Vec::new(); + let mut new_tags = Vec::new(); // TODO(bt): Bulk insert instead of insert per tag. @@ -197,24 +207,26 @@ pub async fn set_tags_for_entity_handler( warn!("error creating tag: {:?}", e); SetTagsForEntityError::ServerError })?; - new_tag_tokens.push(token); + new_tags.push(TagInfo { + token, + value: new_tag_value.to_string(), + }); } - let existing_tag_tokens = matching_tags.iter() - .map(|tag| tag.token.clone()) - .collect::>(); + let final_tag_set = matching_tags.into_iter() + .chain(new_tags.into_iter()) + .collect::>(); - let final_tag_set = existing_tag_tokens.iter() - .chain(new_tag_tokens.iter()) - .map(|token| token.clone()) - .collect::>(); + let final_tag_tokens = final_tag_set.iter() + .map(|tag_info| tag_info.token.clone()) + .collect::>(); let entity = TagUseEntity::from_entity_type_and_token( path.entity_type, &path.entity_token); update_tags_for_entity( entity, - &final_tag_set, + &final_tag_tokens, &mut mysql_connection) .await .map_err(|e| { @@ -224,8 +236,7 @@ pub async fn set_tags_for_entity_handler( Ok(Json(SetTagsForEntitySuccessResponse { success: true, - tag_tokens: final_tag_set - , + tags: final_tag_set, })) } @@ -277,8 +288,12 @@ async fn get_is_creator( } fn to_normalized_tags(tags: &str) -> Vec { - tags.split(',') + let mut tags : Vec = tags.split(',') .map(|tag| tag.trim().to_lowercase()) .filter(|tag| !tag.is_empty()) - .collect() + .collect(); + + tags.truncate(MAX_TAGS); + + tags }