Merge pull request #255 from storytold/brandon-update-weight-cover-image

update weight cover image in update endpoint
This commit is contained in:
Brandon Thomas authored and GitHub committed 2023-12-28 22:26:10 -05:00
commit dbd91dd67f
2 files changed
+55 -21

No files matched your search

@@ -3,26 +3,31 @@ use sqlx::{MySql, MySqlPool, QueryBuilder};
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::model_weights::ModelWeightToken;
pub struct UpdateWeightArgs<'a> {
pub weight_token: &'a ModelWeightToken,
pub title: Option<&'a str>,
pub cover_image: Option<CoverImageOption<'a>>,
pub maybe_description_markdown: Option<&'a str>,
pub maybe_description_rendered_html: Option<&'a str>,
pub creator_set_visibility: Option<&'a Visibility>,
pub weights_type: Option<String>,
pub weights_category: Option<String>,
pub mysql_pool: &'a MySqlPool,
}
pub enum CoverImageOption<'a> {
ClearCoverImage,
SetCoverImage(&'a MediaFileToken),
}
pub async fn update_weights(args: UpdateWeightArgs<'_>) -> AnyhowResult<()> {
if args.title.is_none()
&& args.maybe_description_markdown.is_none()
&& args.maybe_description_rendered_html.is_none()
&& args.creator_set_visibility.is_none()
&& args.weights_type.is_none()
&& args.weights_category.is_none(){
&& args.cover_image.is_none()
{
return Err(anyhow!("No fields to update"));
}
@@ -51,13 +56,16 @@ SET
separated.push("creator_set_visibility = ");
separated.push_bind_unseparated(creator_set_visibility.to_str());
}
if let Some(weights_type) = args.weights_type {
separated.push("weights_type = ");
separated.push_bind_unseparated(weights_type);
}
if let Some(weights_category) = args.weights_category {
separated.push("weights_category = ");
separated.push_bind_unseparated(weights_category);
if let Some(cover_image_option) = args.cover_image {
match cover_image_option {
CoverImageOption::ClearCoverImage => {
separated.push(" maybe_cover_image_media_file_token = NULL ");
}
CoverImageOption::SetCoverImage(media_file_token) => {
separated.push("maybe_cover_image_media_file_token = ");
separated.push_bind_unseparated(media_file_token.as_str());
}
}
}
separated.push("version = version + 1");
@@ -7,28 +7,32 @@ use actix_web::http::StatusCode;
use actix_web::web::Path;
use log::warn;
use utoipa::ToSchema;
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::common::visibility::Visibility;
use http_server_common::response::response_success_helpers::simple_json_success;
use http_server_common::response::serialize_as_json_error::serialize_as_json_error;
use mysql_queries::queries::model_weights::edit::update_weight::{update_weights, UpdateWeightArgs};
use mysql_queries::queries::media_files::get_media_file::get_media_file;
use mysql_queries::queries::model_weights::edit::update_weight::{CoverImageOption, update_weights, UpdateWeightArgs};
use mysql_queries::queries::model_weights::get_weight::get_weight_by_token;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::model_weights::ModelWeightToken;
use user_input_common::check_for_slurs::contains_slurs;
use user_input_common::markdown_to_html::markdown_to_html;
use crate::server_state::ServerState;
/// TODO will eventually be polymorphic
// TODO will eventually be polymorphic
/// **IMPORTANT**: This endpoint handles sparse (by-field) updates rather than wholesale updates.
/// That is, if a field is absent, we do not update it (as opposed to clearing it).
#[derive(Deserialize, ToSchema)]
pub struct UpdateWeightRequest {
pub title: Option<String>,
pub description_markdown: Option<String>,
// KS: We should probably remove this
// Users have to update markdown, not html directly
pub description_rendered_html: Option<String>,
pub weight_type: Option<String>,
pub weight_category: Option<String>,
/// The media file token of the *image* media file.
/// Set to *empty string* to clear the cover image.
pub cover_image_media_file_token: Option<MediaFileToken>,
pub visibility: Option<Visibility>,
}
@@ -144,10 +148,10 @@ pub async fn update_weight_handler(
}
let mut weight_title = None;
let mut cover_image = None;
let mut description_markdown = None;
let mut description_rendered_html = None;
if let Some(title) = &request.title {
if (contains_slurs(title)) {
return Err(UpdateWeightError::BadInput("Title contains slurs".to_string()));
@@ -155,6 +159,29 @@ pub async fn update_weight_handler(
weight_title = Some(title.trim().to_string());
}
if let Some(media_file_token) = &request.cover_image_media_file_token {
if media_file_token.as_str().trim().is_empty() {
cover_image = Some(CoverImageOption::ClearCoverImage);
} else {
let maybe_media_file = get_media_file(
media_file_token,
false, // NB: Even mods shouldn't set deleted media files.
&server_state.mysql_pool
).await.map_err(|err| {
warn!("Error looking up media file: {:?}", err);
UpdateWeightError::ServerError
})?;
let maybe_media_file_type = maybe_media_file.map(|media_file| media_file.media_type);
match maybe_media_file_type {
Some(MediaFileType::Image) => cover_image = Some(CoverImageOption::SetCoverImage(media_file_token)),
None => return Err(UpdateWeightError::BadInput("Media file does not exist".to_string())),
_ => return Err(UpdateWeightError::BadInput("Media file is the wrong type".to_string())),
}
}
}
if let Some(markdown) = &request.description_markdown {
if (contains_slurs(markdown)) {
return Err(UpdateWeightError::BadInput("Description contains slurs".to_string()));
@@ -169,11 +196,10 @@ pub async fn update_weight_handler(
weight_token: &ModelWeightToken::new(path.weight_token.clone()),
mysql_pool: &server_state.mysql_pool,
title: weight_title.as_deref(),
cover_image,
maybe_description_markdown: description_markdown.as_deref(),
maybe_description_rendered_html: description_rendered_html.as_deref(),
creator_set_visibility: request.visibility.as_ref(),
weights_type: request.weight_type.as_deref().map(|s| s.to_string()),
weights_category: request.weight_category.as_deref().map(|s| s.to_string()),
}).await;
match query_result {