port legacy GET TTS endpoint to model weights

This commit is contained in:
Brandon Thomas committed 2024-01-21 01:10:20 -05:00
1 parent 65c5138533
commit 0811e12c0b
7 files changed
+660 -69

No files matched your search

@@ -43,6 +43,7 @@ CREATE TABLE tts_models (
has_self_contained_pitch_model BOOLEAN NOT NULL DEFAULT FALSE,
-- NB(2022-07-05): THIS IS NOW MEANINGLESS AND SUPERSEDED BY `TEXT_PIPELINE_TYPE`.
-- NB(2024-01-20): All 8720 records in the database are "basic".
-- NB: DO NOT CHANGE ORDER; APPEND ONLY!
-- How text should be handled.
text_preprocessing_algorithm ENUM(
@@ -0,0 +1,250 @@
use chrono::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};
use sqlx::MySql;
use sqlx::pool::PoolConnection;
use enums::by_table::tts_models::tts_model_type::TtsModelType;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use mysql_queries::column_types::vocoder_type::VocoderType;
use mysql_queries::queries::model_weights::get::get_weight_for_legacy_tts_info::{get_weight_for_legacy_tts_info_with_connection, ModelWeightForLegacyTtsInfo};
use mysql_queries::queries::tts::tts_models::get_tts_model::{get_tts_model_by_token_using_connection, TtsModelRecord};
use tokens::tokens::model_weights::ModelWeightToken;
/// Get TTS model
/// This is for the tts model info page
pub async fn get_tts_model_info_migration(
token: &str,
mysql_connection: &mut PoolConnection<MySql>,
can_see_deleted: bool,
use_weights_table: bool,
) -> AnyhowResult<Option<TtsModelInfoMigration>> {
// NB: This is temporary migration code as we switch from the `tts_models` table to the `model_weights` table.
if use_weights_table {
let token = ModelWeightToken::new_from_str(token);
let maybe_model = get_weight_for_legacy_tts_info_with_connection(
&token,
can_see_deleted,
mysql_connection
).await?;
Ok(maybe_model.map(|model| TtsModelInfoMigration::ModelWeight(model)))
} else {
let maybe_model = get_tts_model_by_token_using_connection(
&token,
true,
mysql_connection
).await?;
Ok(maybe_model.map(|model| TtsModelInfoMigration::LegacyTts(model)))
}
}
/// Union over the legacy table and the new table to support an easier migration.
/// This enum can hold a record of either type and present a unified accessor interface.
#[derive(Clone, Serialize, Deserialize)]
pub enum TtsModelInfoMigration {
/// Old type from the `tts_models` table, on the way out
LegacyTts(TtsModelRecord),
/// New type, replacing the `tts_models` table.
ModelWeight(ModelWeightForLegacyTtsInfo),
}
impl TtsModelInfoMigration {
pub fn token(&self) -> &str {
match self {
Self::LegacyTts(ref model) => model.model_token.as_str(),
Self::ModelWeight(ref model) => model.token.as_str(),
}
}
pub fn title(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.title,
Self::ModelWeight(ref model) => &model.title,
}
}
pub fn ietf_language_tag(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.ietf_language_tag,
Self::ModelWeight(ref model) => model.maybe_ietf_language_tag.as_deref().unwrap_or("en"),
}
}
pub fn ietf_primary_language_subtag(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.ietf_primary_language_subtag,
Self::ModelWeight(ref model) => model.maybe_ietf_primary_language_subtag.as_deref().unwrap_or("en"),
}
}
pub fn creator_user_token(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_user_token,
Self::ModelWeight(ref model) => model.creator_user_token.as_str(),
}
}
pub fn creator_username(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_username,
Self::ModelWeight(ref model) => &model.creator_username,
}
}
pub fn creator_display_name(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_display_name,
Self::ModelWeight(ref model) => &model.creator_display_name,
}
}
pub fn creator_gravatar_hash(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_gravatar_hash,
Self::ModelWeight(ref model) => &model.creator_gravatar_hash,
}
}
pub fn creator_set_visibility(&self) -> Visibility{
match self {
Self::LegacyTts(ref model) => model.creator_set_visibility,
Self::ModelWeight(ref model) => model.creator_set_visibility,
}
}
pub fn created_at(&self) -> &DateTime<Utc> {
match self {
Self::LegacyTts(ref model) => &model.created_at,
Self::ModelWeight(ref model) => &model.created_at,
}
}
pub fn updated_at(&self) -> &DateTime<Utc> {
match self {
Self::LegacyTts(ref model) => &model.updated_at,
Self::ModelWeight(ref model) => &model.updated_at,
}
}
// Not supported in the new table
pub fn is_front_page_featured(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_front_page_featured,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn is_twitch_featured(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_twitch_featured,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn is_locked_from_use(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_locked_from_use,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn is_locked_from_user_modification(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_locked_from_user_modification,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn user_ratings_positive_count(&self) -> u32 {
match self {
Self::LegacyTts(ref model) => model.user_ratings_positive_count,
Self::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn user_ratings_negative_count(&self) -> u32 {
match self {
Self::LegacyTts(ref model) => model.user_ratings_negative_count,
Self::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn user_ratings_total_count(&self) -> u32 {
match self {
Self::LegacyTts(ref model) => model.user_ratings_total_count,
Self::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn maybe_suggested_unique_bot_command(&self) -> Option<&str> {
match self {
Self::LegacyTts(ref model) => model.maybe_suggested_unique_bot_command.as_deref(),
Self::ModelWeight(ref _model) => None,
}
}
pub fn tts_model_type(&self) -> TtsModelType {
match self {
Self::LegacyTts(ref model) => model.tts_model_type,
Self::ModelWeight(ref _model) => TtsModelType::Tacotron2, // NB: Always TT2
}
}
pub fn description_markdown(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.description_markdown,
Self::ModelWeight(ref model) => &model.maybe_description_markdown.as_deref().unwrap_or(""),
}
}
pub fn description_rendered_html(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.description_rendered_html,
Self::ModelWeight(ref model) => &model.maybe_description_rendered_html.as_deref().unwrap_or(""),
}
}
pub fn maybe_default_pretrained_vocoder(&self) -> Option<VocoderType> {
match self {
Self::LegacyTts(ref model) => model.maybe_default_pretrained_vocoder,
Self::ModelWeight(ref model) => model.maybe_default_pretrained_vocoder,
}
}
pub fn text_preprocessing_algorithm(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.text_preprocessing_algorithm,
Self::ModelWeight(ref _model) => "basic", // NB: All records in the DB are "basic"
}
}
/* NB(bt, 2024-01-20): Breakdown of the text_pipeline_type values in the DB:
mysql> select text_pipeline_type , count(*) from tts_models group by text_pipeline_type ;
+--------------------+----------+
| text_pipeline_type | count(*) |
+--------------------+----------+
| NULL | 4406 |
| legacy_fakeyou | 2572 |
| english_v1 | 1548 |
| spanish_v2 | 194 |
+--------------------+----------+
*/
pub fn text_pipeline_type(&self) -> Option<&str> {
match self {
Self::LegacyTts(ref model) => model.text_pipeline_type.as_deref(),
Self::ModelWeight(ref model) => model.maybe_text_pipeline_type.as_deref(),
}
}
}
@@ -1,2 +1,3 @@
pub mod list_tts_models_for_migration;
pub mod get_tts_model_for_inference_migration;
pub mod get_tts_model_for_inference_migration;
pub mod get_tts_model_info_migration;
pub mod list_tts_models_for_migration;
@@ -0,0 +1,325 @@
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::error;
use sqlx::{MySql, MySqlPool};
use sqlx::pool::PoolConnection;
use container_common::anyhow_result::AnyhowResult;
use enums::by_table::model_weights::weights_category::WeightsCategory;
use enums::by_table::model_weights::weights_types::WeightsType;
use enums::common::visibility::Visibility;
use tokens::tokens::{model_weights::ModelWeightToken, users::UserToken};
use crate::column_types::vocoder_type::VocoderType;
#[derive(Serialize, Deserialize, Clone)]
pub struct ModelWeightForLegacyTtsInfo {
pub token: ModelWeightToken,
pub title: String,
pub weights_type: WeightsType,
pub weights_category: WeightsCategory,
pub maybe_description_markdown: Option<String>,
pub maybe_description_rendered_html: Option<String>,
pub creator_user_token: UserToken,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub creator_ip_address: String,
pub creator_set_visibility: Visibility,
pub maybe_last_update_user_token: Option<UserToken>,
pub original_download_url: Option<String>,
pub original_filename: Option<String>,
pub file_size_bytes: i32,
pub file_checksum_sha2: String,
pub public_bucket_hash: String,
pub maybe_public_bucket_prefix: Option<String>,
pub maybe_public_bucket_extension: Option<String>,
pub maybe_cover_image_public_bucket_hash: Option<String>,
pub maybe_cover_image_public_bucket_prefix: Option<String>,
pub maybe_cover_image_public_bucket_extension: Option<String>,
pub maybe_ratings_positive_count: Option<u32>,
pub maybe_ratings_negative_count: Option<u32>,
pub maybe_bookmark_count: Option<u32>,
pub maybe_ietf_language_tag: Option<String>,
pub maybe_ietf_primary_language_subtag: Option<String>,
pub maybe_default_pretrained_vocoder: Option<VocoderType>,
pub maybe_text_pipeline_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
pub async fn get_weight_for_legacy_tts_info(
weight_token: &ModelWeightToken,
can_see_deleted: bool,
mysql_pool: &MySqlPool
) -> AnyhowResult<Option<ModelWeightForLegacyTtsInfo>> {
let mut connection = mysql_pool.acquire().await?;
get_weight_for_legacy_tts_info_with_connection(weight_token, can_see_deleted, &mut connection).await
}
pub async fn get_weight_for_legacy_tts_info_with_connection(
weight_token: &ModelWeightToken,
can_see_deleted: bool,
mysql_connection: &mut PoolConnection<MySql>
) -> AnyhowResult<Option<ModelWeightForLegacyTtsInfo>> {
let maybe_result = if can_see_deleted {
select_include_deleted(weight_token, mysql_connection).await
} else {
select_without_deleted(weight_token, mysql_connection).await
};
let record: RawWeight = match maybe_result {
Ok(record) => record,
Err(sqlx::Error::RowNotFound) => {
return Ok(None);
}
Err(err) => {
error!("Error fetching weights by token: {:?}", err);
return Err(anyhow!("Error fetching weights by token: {:?}", err));
}
};
// unwrap the result
Ok(
Some(ModelWeightForLegacyTtsInfo {
token: record.token,
title: record.title,
weights_type: record.weights_type,
weights_category: record.weights_category,
maybe_description_markdown: record.maybe_description_markdown,
maybe_description_rendered_html: record.maybe_description_rendered_html,
creator_user_token: record.creator_user_token,
creator_username: record.creator_username,
creator_display_name: record.creator_display_name,
creator_gravatar_hash: record.creator_gravatar_hash,
creator_ip_address: record.creator_ip_address,
creator_set_visibility: record.creator_set_visibility,
maybe_last_update_user_token: record.maybe_last_update_user_token,
original_download_url: record.original_download_url,
original_filename: record.original_filename,
file_size_bytes: record.file_size_bytes,
file_checksum_sha2: record.file_checksum_sha2,
public_bucket_hash: record.public_bucket_hash,
maybe_public_bucket_prefix: record.maybe_public_bucket_prefix,
maybe_public_bucket_extension: record.maybe_public_bucket_extension,
maybe_cover_image_public_bucket_hash: record.maybe_cover_image_public_bucket_hash,
maybe_cover_image_public_bucket_prefix: record.maybe_cover_image_public_bucket_prefix,
maybe_cover_image_public_bucket_extension: record.maybe_cover_image_public_bucket_extension,
maybe_ratings_positive_count: record.maybe_ratings_positive_count,
maybe_ratings_negative_count: record.maybe_ratings_negative_count,
maybe_bookmark_count: record.maybe_bookmark_count,
maybe_ietf_language_tag: record.maybe_ietf_language_tag,
maybe_ietf_primary_language_subtag: record.maybe_ietf_primary_language_subtag,
maybe_default_pretrained_vocoder: record.maybe_default_pretrained_vocoder,
maybe_text_pipeline_type: record.maybe_text_pipeline_type,
version: record.version,
created_at: record.created_at,
updated_at: record.updated_at,
user_deleted_at: record.user_deleted_at,
mod_deleted_at: record.mod_deleted_at,
})
)
}
async fn select_include_deleted(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<RawWeight, sqlx::Error> {
sqlx
::query_as!(
RawWeight,
r#"
SELECT
wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,
wt.title,
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
wt.maybe_description_markdown,
wt.maybe_description_rendered_html,
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
users.username as creator_username,
users.display_name as creator_display_name,
users.email_gravatar_hash AS creator_gravatar_hash,
wt.creator_ip_address,
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,
wt.original_download_url,
wt.original_filename,
wt.file_size_bytes,
wt.file_checksum_sha2,
wt.public_bucket_hash,
wt.maybe_public_bucket_prefix,
wt.maybe_public_bucket_extension,
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
entity_stats.ratings_positive_count as maybe_ratings_positive_count,
entity_stats.ratings_negative_count as maybe_ratings_negative_count,
entity_stats.bookmark_count as maybe_bookmark_count,
w_extension.ietf_language_tag as maybe_ietf_language_tag,
w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,
w_extension.maybe_default_pretrained_vocoder as `maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType`,
w_extension.text_pipeline_type as maybe_text_pipeline_type,
wt.version,
wt.created_at,
wt.updated_at,
wt.user_deleted_at,
wt.mod_deleted_at
FROM model_weights as wt
JOIN users
ON users.token = wt.creator_user_token
LEFT OUTER JOIN media_files as cover_image
ON cover_image.token = wt.maybe_cover_image_media_file_token
LEFT OUTER JOIN entity_stats
ON entity_stats.entity_type = "model_weight"
AND entity_stats.entity_token = wt.token
LEFT OUTER JOIN model_weights_extension_tts_details as w_extension
ON w_extension.model_weights_token = wt.token
WHERE
wt.token = ?
"#,
weight_token.as_str()
)
.fetch_one(&mut **mysql_connection).await
}
async fn select_without_deleted(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<RawWeight, sqlx::Error> {
//as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
//as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`
sqlx
::query_as!(
RawWeight,
r#"
SELECT
wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,
wt.title,
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
wt.maybe_description_markdown,
wt.maybe_description_rendered_html,
wt.creator_ip_address,
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
users.username as creator_username,
users.display_name as creator_display_name,
users.email_gravatar_hash AS creator_gravatar_hash,
wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,
wt.original_download_url,
wt.original_filename,
wt.file_size_bytes,
wt.file_checksum_sha2,
wt.public_bucket_hash,
wt.maybe_public_bucket_prefix,
wt.maybe_public_bucket_extension,
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
entity_stats.ratings_positive_count as maybe_ratings_positive_count,
entity_stats.ratings_negative_count as maybe_ratings_negative_count,
entity_stats.bookmark_count as maybe_bookmark_count,
w_extension.ietf_language_tag as maybe_ietf_language_tag,
w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,
w_extension.maybe_default_pretrained_vocoder as `maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType`,
w_extension.text_pipeline_type as maybe_text_pipeline_type,
wt.version,
wt.created_at,
wt.updated_at,
wt.user_deleted_at,
wt.mod_deleted_at
FROM model_weights as wt
JOIN users
ON users.token = wt.creator_user_token
LEFT OUTER JOIN media_files as cover_image
ON cover_image.token = wt.maybe_cover_image_media_file_token
LEFT OUTER JOIN entity_stats
ON entity_stats.entity_type = "model_weight"
AND entity_stats.entity_token = wt.token
LEFT OUTER JOIN model_weights_extension_tts_details as w_extension
ON w_extension.model_weights_token = wt.token
WHERE
wt.token = ?
AND wt.user_deleted_at IS NULL
AND wt.mod_deleted_at IS NULL
"#,
weight_token.as_str()
)
.fetch_one(&mut **mysql_connection).await
}
// RawWeight is the struct that is returned from the database in raw form.
#[derive(Serialize)]
pub struct RawWeight {
pub token: ModelWeightToken,
pub title: String,
pub weights_type: WeightsType,
pub weights_category: WeightsCategory,
pub maybe_description_markdown: Option<String>,
pub maybe_description_rendered_html: Option<String>,
pub creator_user_token: UserToken,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub creator_ip_address: String,
pub creator_set_visibility: Visibility,
pub maybe_last_update_user_token: Option<UserToken>,
pub original_download_url: Option<String>,
pub original_filename: Option<String>,
pub file_size_bytes: i32,
pub file_checksum_sha2: String,
pub public_bucket_hash: String,
pub maybe_public_bucket_prefix: Option<String>,
pub maybe_public_bucket_extension: Option<String>,
pub maybe_cover_image_public_bucket_hash: Option<String>,
pub maybe_cover_image_public_bucket_prefix: Option<String>,
pub maybe_cover_image_public_bucket_extension: Option<String>,
pub maybe_ratings_positive_count: Option<u32>,
pub maybe_ratings_negative_count: Option<u32>,
pub maybe_bookmark_count: Option<u32>,
pub maybe_ietf_language_tag: Option<String>,
pub maybe_ietf_primary_language_subtag: Option<String>,
pub maybe_default_pretrained_vocoder: Option<VocoderType>,
pub maybe_text_pipeline_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
@@ -1,2 +1,3 @@
pub mod get_weight;
pub mod get_weight_for_legacy_tts_enqueue;
pub mod get_weight_for_legacy_tts_info;
@@ -9,8 +9,12 @@ impl RedisCacheKeys {
format!("get_tts_model:{}", model_token)
}
pub fn get_tts_model_for_info_migration_endpoint(model_token: &str) -> String {
format!("get_tts_inf1:{}", model_token)
}
pub fn get_tts_model_for_inference_migration_endpoint(model_token: &str) -> String {
format!("get_tts_inf:{}", model_token)
format!("get_tts_inf2:{}", model_token)
}
pub fn get_unified_queue_stats_endpoint() -> &'static str {
@@ -16,8 +16,8 @@ use log::warn;
use enums::by_table::tts_models::tts_model_type::TtsModelType;
use enums::common::visibility::Visibility;
use http_server_common::response::serialize_as_json_error::serialize_as_json_error;
use migration::text_to_speech::get_tts_model_info_migration::get_tts_model_info_migration;
use mysql_queries::column_types::vocoder_type::VocoderType;
use mysql_queries::queries::tts::tts_models::get_tts_model::get_tts_model_by_token_using_connection;
use redis_common::redis_cache_keys::RedisCacheKeys;
use tts_common::text_pipelines::guess_pipeline::guess_text_pipeline_heuristic;
use tts_common::text_pipelines::text_pipeline_type::TextPipelineType;
@@ -204,13 +204,16 @@ pub async fn get_tts_model_handler(
let model_token = path.token.clone();
let switch_to_weights_flag = server_state.flags.switch_tts_to_model_weights;
let get_tts_model = move || {
// NB: async closures are not yet stable in Rust, so we include an async block.
async move {
get_tts_model_by_token_using_connection(
get_tts_model_info_migration(
&model_token,
show_deleted_models,
&mut mysql_connection,
show_deleted_models,
switch_to_weights_flag,
).await
}
};
@@ -221,14 +224,14 @@ pub async fn get_tts_model_handler(
get_tts_model().await
}
Ok(mut redis_ttl_cache) => {
let cache_key = RedisCacheKeys::get_tts_model_endpoint(&path.token);
let cache_key = RedisCacheKeys::get_tts_model_for_info_migration_endpoint(&path.token);
redis_ttl_cache.lazy_load_if_not_cached(&cache_key, move || {
get_tts_model()
}).await
}
};
let mut model = match model_query_result {
let model = match model_query_result {
Err(e) => {
warn!("query error: {:?}", e);
return Err(GetTtsModelError::ServerError);
@@ -238,22 +241,24 @@ pub async fn get_tts_model_handler(
};
if let Some(user_session) = &maybe_user_session {
is_original_author = user_session.user_token == model.creator_user_token;
is_original_author = user_session.user_token == model.creator_user_token();
}
if let Some(moderator_fields) = model.maybe_moderator_fields.as_ref() {
// NB: The moderator fields will always be present before removal
// We don't want non-mods seeing stuff made by banned users.
if moderator_fields.creator_is_banned && !is_moderator {
return Err(GetTtsModelError::NotFound);
}
}
// NB(bt, 2024-01-20): Removing to make porting easier.
//if let Some(moderator_fields) = model.maybe_moderator_fields.as_ref() {
// // NB: The moderator fields will always be present before removal
// // We don't want non-mods seeing stuff made by banned users.
// if moderator_fields.creator_is_banned && !is_moderator {
// return Err(GetTtsModelError::NotFound);
// }
//}
if !is_moderator {
model.maybe_moderator_fields = None;
}
// NB(bt, 2024-01-20): Removing to make porting easier.
//if !is_moderator {
// model.maybe_moderator_fields = None;
//}
let text_pipeline_type = model.text_pipeline_type
let text_pipeline_type = model.text_pipeline_type()
.as_deref()
.and_then(|pipeline_type| {
// If there's an error deserializing, turn it to None instead of 500ing. The column is
@@ -273,64 +278,68 @@ pub async fn get_tts_model_handler(
// TODO: Use language to infer as well.
let text_pipeline_type_guess =
guess_text_pipeline_heuristic(Some(model.created_at.clone()));
guess_text_pipeline_heuristic(Some(model.created_at().clone()));
// Map to public response type.
let response = GetTtsModelSuccessResponse {
success: true,
model: TtsModelInfo {
model_token: model.model_token,
tts_model_type: model.tts_model_type,
model_token: model.token().to_string(),
tts_model_type: model.tts_model_type(),
text_pipeline_type,
text_pipeline_type_guess,
maybe_custom_vocoder: match model.maybe_custom_vocoder {
None => None,
Some(vocoder) => Some(CustomVocoderInfo {
vocoder_token: vocoder.vocoder_token,
vocoder_title: vocoder.vocoder_title,
creator_user_token: vocoder.creator_user_token,
creator_username: vocoder.creator_username,
creator_display_name: vocoder.creator_display_name,
creator_gravatar_hash: vocoder.creator_gravatar_hash,
})
},
maybe_default_pretrained_vocoder: model.maybe_default_pretrained_vocoder,
text_preprocessing_algorithm: model.text_preprocessing_algorithm,
creator_user_token: model.creator_user_token,
creator_username: model.creator_username.to_string(), // NB: Cloned because of ref use for avatar below
creator_display_name: model.creator_display_name,
creator_gravatar_hash: model.creator_gravatar_hash,
creator_default_avatar_index: default_avatar_from_username(&model.creator_username),
creator_default_avatar_color_index: default_avatar_color_from_username(&model.creator_username),
title: model.title,
description_markdown: model.description_markdown,
description_rendered_html: model.description_rendered_html,
ietf_language_tag: model.ietf_language_tag,
ietf_primary_language_subtag: model.ietf_primary_language_subtag,
is_front_page_featured: model.is_front_page_featured,
is_twitch_featured: model.is_twitch_featured,
maybe_suggested_unique_bot_command: model.maybe_suggested_unique_bot_command,
// NB(bt, 2024-01-20): We won't be needing these much longer.
maybe_custom_vocoder: None,
//maybe_custom_vocoder: match model.maybe_custom_vocoder {
// None => None,
// Some(vocoder) => Some(CustomVocoderInfo {
// vocoder_token: vocoder.vocoder_token,
// vocoder_title: vocoder.vocoder_title,
// creator_user_token: vocoder.creator_user_token,
// creator_username: vocoder.creator_username,
// creator_display_name: vocoder.creator_display_name,
// creator_gravatar_hash: vocoder.creator_gravatar_hash,
// })
//},
maybe_default_pretrained_vocoder: model.maybe_default_pretrained_vocoder(),
text_preprocessing_algorithm: model.text_preprocessing_algorithm().to_string(),
creator_user_token: model.creator_user_token().to_string(),
creator_username: model.creator_username().to_string(), // NB: Cloned because of ref use for avatar below
creator_display_name: model.creator_display_name().to_string(),
creator_gravatar_hash: model.creator_gravatar_hash().to_string(),
creator_default_avatar_index: default_avatar_from_username(&model.creator_username().to_string()),
creator_default_avatar_color_index: default_avatar_color_from_username(&model.creator_username().to_string()),
title: model.title().to_string(),
description_markdown: model.description_markdown().to_string(),
description_rendered_html: model.description_rendered_html().to_string(),
ietf_language_tag: model.ietf_language_tag().to_string(),
ietf_primary_language_subtag: model.ietf_primary_language_subtag().to_string(),
is_front_page_featured: model.is_front_page_featured(),
is_twitch_featured: model.is_twitch_featured(),
maybe_suggested_unique_bot_command: model.maybe_suggested_unique_bot_command().map(|s| s.to_string()),
user_ratings: UserRatingsStats {
positive_count: model.user_ratings_positive_count,
negative_count: model.user_ratings_negative_count,
total_count: model.user_ratings_total_count,
positive_count: model.user_ratings_positive_count(),
negative_count: model.user_ratings_negative_count(),
total_count: model.user_ratings_total_count(),
},
creator_set_visibility: model.creator_set_visibility,
is_locked_from_use: model.is_locked_from_use,
is_locked_from_user_modification: model.is_locked_from_user_modification,
created_at: model.created_at,
updated_at: model.updated_at,
maybe_moderator_fields: model.maybe_moderator_fields.map(|mod_fields| {
TtsModelModeratorFieldInfo {
use_default_m_factor: mod_fields.use_default_mel_multiply_factor,
maybe_custom_m_factor: mod_fields.maybe_custom_mel_multiply_factor,
creator_is_banned: mod_fields.creator_is_banned,
creator_ip_address_creation: mod_fields.creator_ip_address_creation,
creator_ip_address_last_update: mod_fields.creator_ip_address_last_update,
user_deleted_at: mod_fields.user_deleted_at,
mod_deleted_at: mod_fields.mod_deleted_at,
}
})
creator_set_visibility: model.creator_set_visibility(),
is_locked_from_use: model.is_locked_from_use(),
is_locked_from_user_modification: model.is_locked_from_user_modification(),
created_at: model.created_at().clone(),
updated_at: model.updated_at().clone(),
maybe_moderator_fields: None,
// NB(bt, 2024-01-20): We won't be needing these much longer.
//maybe_moderator_fields: model.maybe_moderator_fields.map(|mod_fields| {
// TtsModelModeratorFieldInfo {
// use_default_m_factor: mod_fields.use_default_mel_multiply_factor,
// maybe_custom_m_factor: mod_fields.maybe_custom_mel_multiply_factor,
// creator_is_banned: mod_fields.creator_is_banned,
// creator_ip_address_creation: mod_fields.creator_ip_address_creation,
// creator_ip_address_last_update: mod_fields.creator_ip_address_last_update,
// user_deleted_at: mod_fields.user_deleted_at,
// mod_deleted_at: mod_fields.mod_deleted_at,
// }
//})
},
};