mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 21:38:07 -05:00
Compare commits
248
Commits
bt-ffprobe
..
mdawg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f8d1f113b | ||
|
|
a2c1ae7c9b | ||
|
|
f47b729a46 | ||
|
|
4f506f05cd | ||
|
|
a7d688d750 | ||
|
|
b6344a681f | ||
|
|
0454db0aa7 | ||
|
|
233523c6b5 | ||
|
|
e5e93364ae | ||
|
|
f17a9a034f | ||
|
|
a06b583488 | ||
|
|
96021d4507 | ||
|
|
7686eff0c1 | ||
|
|
705013f5e0 | ||
|
|
3f48bb217c | ||
|
|
f72b4c973e | ||
|
|
5300902939 | ||
|
|
9036f0993a | ||
|
|
783ffef82c | ||
|
|
5153bda209 | ||
|
|
0fdfc3b8fc | ||
|
|
17ce397d09 | ||
|
|
278d821207 | ||
|
|
6352f710e0 | ||
|
|
e76d30caf7 | ||
|
|
576af78b2c | ||
|
|
d88ace6706 | ||
|
|
13fe465740 | ||
|
|
00ad03a819 | ||
|
|
de36342731 | ||
|
|
dafeb616a5 | ||
|
|
9708e91137 | ||
|
|
06ac75a569 | ||
|
|
142519b97f | ||
|
|
8639788706 | ||
|
|
6af2b3f173 | ||
|
|
2bee82f0ae | ||
|
|
7c5ba2542c | ||
|
|
7644c6813c | ||
|
|
84c5ae9d18 | ||
|
|
cc41641b2b | ||
|
|
b573860068 | ||
|
|
c40ffa7346 | ||
|
|
93ce89e060 | ||
|
|
59c4574d4d | ||
|
|
6ad5a39bba | ||
|
|
6f568087c6 | ||
|
|
5111254eaf | ||
|
|
1ae84a406d | ||
|
|
f49e49832b | ||
|
|
0bf9e7b5aa | ||
|
|
92338e5f66 | ||
|
|
e09130a1b5 | ||
|
|
0465f5236f | ||
|
|
12cf9730f8 | ||
|
|
bfa842b123 | ||
|
|
3faf22e9c5 | ||
|
|
d87814bc41 | ||
|
|
cf057d26ec | ||
|
|
2d294ce7ad | ||
|
|
4e6285acd2 | ||
|
|
114cdc10a0 | ||
|
|
53e7ca28c6 | ||
|
|
854fe4b340 | ||
|
|
330712407d | ||
|
|
b708e5f9f6 | ||
|
|
4146e922d8 | ||
|
|
1789918913 | ||
|
|
357691be20 | ||
|
|
8889299cc7 | ||
|
|
a4023278bc | ||
|
|
73119ac9e3 | ||
|
|
ec46833726 | ||
|
|
e63ec3ae34 | ||
|
|
aabaf0a5a5 | ||
|
|
4146261806 | ||
|
|
10cc6198d9 | ||
|
|
b8fb1b9a5e | ||
|
|
ab645cacc6 | ||
|
|
ad4b297b55 | ||
|
|
b1b7f4e0ee | ||
|
|
77bebd4833 | ||
|
|
9383ba42fb | ||
|
|
2e79eb9c3a | ||
|
|
55deba82ae | ||
|
|
e0121dffeb | ||
|
|
62d4e260a0 | ||
|
|
ea1435ad6e | ||
|
|
34d19adc1e | ||
|
|
7e630bf588 | ||
|
|
c1544535df | ||
|
|
e6a18f7974 | ||
|
|
783d73a48b | ||
|
|
3f51515b17 | ||
|
|
c44efc2a18 | ||
|
|
7fcaf61170 | ||
|
|
f31a1bb12e | ||
|
|
113ed359fd | ||
|
|
17a4cf774d | ||
|
|
7bfd38a382 | ||
|
|
970e802f14 | ||
|
|
ce186179ce | ||
|
|
45792890b7 | ||
|
|
776c086470 | ||
|
|
b666858b21 | ||
|
|
4ca8932591 | ||
|
|
004e8c27d4 | ||
|
|
70c2c995ee | ||
|
|
54b7e182b0 | ||
|
|
50807429ad | ||
|
|
1cd3175e13 | ||
|
|
bbaed857d0 | ||
|
|
37ccf0f60d | ||
|
|
c95ad4dd55 | ||
|
|
7609c040cc | ||
|
|
076a865747 | ||
|
|
972e8199e7 | ||
|
|
175035000b | ||
|
|
807c8fd4f8 | ||
|
|
e1370a7b6d | ||
|
|
716aca1e3d | ||
|
|
c1996011b0 | ||
|
|
878c93f34c | ||
|
|
f642a5ac39 | ||
|
|
26c7ac8037 | ||
|
|
26153f46b1 | ||
|
|
ed8d78b127 | ||
|
|
6f4e780c7d | ||
|
|
47a3c7935a | ||
|
|
d8ea5054de | ||
|
|
10b8e29b56 | ||
|
|
38619270ef | ||
|
|
e7134fa84f | ||
|
|
2bb2cdf70a | ||
|
|
1feb21625d | ||
|
|
1a0a71dca4 | ||
|
|
c8127d99fd | ||
|
|
8e1f49a588 | ||
|
|
24f5660d2f | ||
|
|
1b4c70281f | ||
|
|
9dc6676621 | ||
|
|
f02476e916 | ||
|
|
1b3c88e93b | ||
|
|
c8e19250b2 | ||
|
|
8675b78f2d | ||
|
|
25df92c9ff | ||
|
|
805765f302 | ||
|
|
8bea5bebab | ||
|
|
9a938954a0 | ||
|
|
7abf70771c | ||
|
|
409eadbfe5 | ||
|
|
d634fd9e6b | ||
|
|
7afb56519c | ||
|
|
4dde614b15 | ||
|
|
44a26c56ac | ||
|
|
76db576c84 | ||
|
|
a87e19b402 | ||
|
|
3a3e85abd0 | ||
|
|
4def6ebd47 | ||
|
|
1215df5844 | ||
|
|
362afd9d6c | ||
|
|
e0180712f7 | ||
|
|
d81bd219a2 | ||
|
|
4e6f25db83 | ||
|
|
adbf268985 | ||
|
|
80aff2bfff | ||
|
|
6f69a2715a | ||
|
|
5a18c51c11 | ||
|
|
cb98541c54 | ||
|
|
8782c6808c | ||
|
|
032705ac45 | ||
|
|
4c8ad1be04 | ||
|
|
203f4e5998 | ||
|
|
84b7bae839 | ||
|
|
317d56dbd0 | ||
|
|
fc83fcd490 | ||
|
|
1ac50b19b1 | ||
|
|
a56166c6a1 | ||
|
|
f458a26f48 | ||
|
|
1c79e6a062 | ||
|
|
f95c0b355f | ||
|
|
af38e923c7 | ||
|
|
8a6dcb1868 | ||
|
|
e07e0ab349 | ||
|
|
dbd431090f | ||
|
|
ee8596488c | ||
|
|
311252d953 | ||
|
|
dfbd3001f1 | ||
|
|
6e546894b2 | ||
|
|
4f9e23250d | ||
|
|
a5f967d6d5 | ||
|
|
7a17d1f20b | ||
|
|
31733b2063 | ||
|
|
c55ad1f2b3 | ||
|
|
d04458f000 | ||
|
|
cd848319eb | ||
|
|
6a1f4dc3bc | ||
|
|
826d710979 | ||
|
|
a9ec812e82 | ||
|
|
3aca9b9090 | ||
|
|
c0db177d4e | ||
|
|
2cb19357ab | ||
|
|
04a19ec4e3 | ||
|
|
f6f769476f | ||
|
|
b53e93773d | ||
|
|
38d174df83 | ||
|
|
1ddd3e75dc | ||
|
|
c60d8b6115 | ||
|
|
56e6d61a8d | ||
|
|
65b14a6486 | ||
|
|
eadb0eded0 | ||
|
|
eb68ab54c4 | ||
|
|
e947e118e3 | ||
|
|
8cc2e334b9 | ||
|
|
b680dbc895 | ||
|
|
68b1f9851c | ||
|
|
6c62851ab4 | ||
|
|
0d3e2e87bc | ||
|
|
6f62958c12 | ||
|
|
a6f96e019a | ||
|
|
61a84134d4 | ||
|
|
43abb4f4b1 | ||
|
|
1fc62e37b6 | ||
|
|
1455138351 | ||
|
|
aad1dbfbdb | ||
|
|
af326ad6c9 | ||
|
|
678cd391f6 | ||
|
|
2548ab880a | ||
|
|
32d44d7070 | ||
|
|
0f7853314d | ||
|
|
bc48f9c129 | ||
|
|
f12b94752f | ||
|
|
64b1dfb5ec | ||
|
|
9467cc2fe0 | ||
|
|
489aabda3d | ||
|
|
93e413dd88 | ||
|
|
8820e82971 | ||
|
|
9c18e6d1ca | ||
|
|
48949ce4b7 | ||
|
|
cdcb083369 | ||
|
|
858c93e4c3 | ||
|
|
1e1d8ab6ca | ||
|
|
56bffa9297 | ||
|
|
3f1125f59c | ||
|
|
639ace9fd4 | ||
|
|
07e3eed1c7 | ||
|
|
ae7b910671 | ||
|
|
d2fd811e41 |
@@ -26,14 +26,14 @@ MIGRATION_DIRECTORY=_sql/migrations/
|
||||
# Bucket config (non-secret)
|
||||
REGION_NAME=us-east1
|
||||
|
||||
TTS_DOWNLOAD_BUCKET_NAME=dev-vocodes-private-uploads
|
||||
TTS_DOWNLOAD_BUCKET_ROOT=/user_uploaded_tts_models
|
||||
#TTS_DOWNLOAD_BUCKET_NAME=kasisnu-t
|
||||
#TTS_DOWNLOAD_BUCKET_ROOT=/user_uploaded_tts_models
|
||||
|
||||
W2L_PRIVATE_DOWNLOAD_BUCKET_NAME=dev-vocodes-private-uploads
|
||||
W2L_PUBLIC_DOWNLOAD_BUCKET_NAME=dev-vocodes-public
|
||||
#W2L_PRIVATE_DOWNLOAD_BUCKET_NAME=dev-vocodes-private-uploads
|
||||
#W2L_PUBLIC_DOWNLOAD_BUCKET_NAME=dev-vocodes-public
|
||||
|
||||
PRIVATE_BUCKET_NAME=dev-vocodes-private-uploads
|
||||
PUBLIC_BUCKET_NAME=dev-vocodes-public
|
||||
#PRIVATE_BUCKET_NAME=kasisnu-test-area-private
|
||||
#PUBLIC_BUCKET_NAME=kasisnu-test-area-public
|
||||
|
||||
# Bucket roots
|
||||
AUDIO_UPLOADS_BUCKET_ROOT=/user_uploaded_w2l_audio
|
||||
@@ -64,7 +64,7 @@ HIFIGAN_ROOT_CODE_DIRECTORY=/home/bt/dev/storyteller/storyteller-ml/tts
|
||||
HIFIGAN_VIRTUAL_ENV_ACTIVATION_COMMAND="source python/bin/activate"
|
||||
HIFIGAN_MODEL_CHECK_SCRIPT_NAME="vocodes_model_check_hifigan.py"
|
||||
|
||||
DOWNLOAD_SCRIPT="/home/tensor/code/storyteller/web-downloader/.venv/bin/python3.11 /home/tensor/code/storyteller/web-downloader/download_internet_file.py"
|
||||
#; DOWNLOAD_SCRIPT="/home/tensor/code/storyteller/web-downloader/.venv/bin/python3.11 /home/tensor/code/storyteller/web-downloader/download_internet_file.py"
|
||||
|
||||
TTS_INFERENCE_SIDECAR_HOSTNAME=localhost:8000
|
||||
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n maybe_model_type as queue_type,\n count(*) as pending_job_count,\n NOW() as present_time\n FROM (\n SELECT\n token,\n maybe_model_type\n FROM generic_inference_jobs\n WHERE status IN (\"pending\", \"attempt_failed\")\n AND maybe_model_type IS NOT NULL\n UNION\n SELECT\n token,\n maybe_model_type\n FROM generic_inference_jobs\n WHERE status IN (\"started\")\n AND created_at > (CURDATE() - INTERVAL 15 MINUTE)\n AND maybe_model_type IS NOT NULL\n) as generic_inner\nGROUP BY queue_type\nUNION\nSELECT\n \"legacy_tts\" as queue_type,\n count(*) as pending_job_count,\n NOW() as present_time\nFROM (\n SELECT\n token\n FROM tts_inference_jobs\n WHERE status IN (\"pending\", \"attempt_failed\")\n UNION\n SELECT\n token\n FROM tts_inference_jobs\n WHERE status IN (\"started\")\n AND created_at > (CURDATE() - INTERVAL 15 MINUTE)\n) as legacy_inner\nGROUP BY queue_type\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "queue_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "pending_job_count",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 21
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "present_time",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 224,
|
||||
"max_size": 76
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "074307d7cd5c9a6f27e4d5ecce3072dcd13914a6f7f5f27f0f7232ae6c4813b4"
|
||||
}
|
||||
+14
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n token as `token: tokens::tokens::users::UserToken`,\n username,\n email_address,\n password_hash as `password_hash: crate::queries::users::user::lookup_user_for_login_result::VecBytes`,\n password_version,\n is_banned\nFROM users\nWHERE email_address = ?\nLIMIT 1\n ",
|
||||
"query": "\nSELECT\n token as `token: tokens::tokens::users::UserToken`,\n username,\n email_address,\n password_hash as `password_hash: crate::queries::users::user::lookup_user_for_login_result::VecBytes`,\n password_version,\n is_banned,\n maybe_feature_flags\nFROM users\nWHERE email_address = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -62,6 +62,16 @@
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_feature_flags",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -73,8 +83,9 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "e8705ee9b3bc3213e806946fef651e9bb8c2cb5cc2ac8eff3eaed82d9a88f90e"
|
||||
"hash": "48889cc9c9b8dbe482e74687629a6958c1c9bf8a1cd5ae177afea0ad0709736d"
|
||||
}
|
||||
+50
-39
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_media_subtype as `maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype`,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n ",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_media_subtype as `maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype`,\n\n m.maybe_mime_type,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -65,6 +65,16 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_mime_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -74,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -84,7 +94,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -94,7 +104,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -104,7 +114,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 11,
|
||||
"name": "maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -114,7 +124,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 12,
|
||||
"name": "maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +134,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 13,
|
||||
"name": "maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -134,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 14,
|
||||
"name": "maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -144,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 15,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -154,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 16,
|
||||
"name": "maybe_text_transcript",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -164,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 17,
|
||||
"name": "maybe_origin_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -174,7 +184,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"ordinal": 18,
|
||||
"name": "maybe_duration_millis",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -184,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 19,
|
||||
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -194,7 +204,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 20,
|
||||
"name": "maybe_other_prompt_args",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -204,7 +214,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 21,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -214,7 +224,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"ordinal": 22,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -224,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"ordinal": 23,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -234,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"ordinal": 24,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -244,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"ordinal": 25,
|
||||
"name": "maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -254,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 26,
|
||||
"name": "maybe_model_weights_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -264,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 27,
|
||||
"name": "maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -274,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 28,
|
||||
"name": "maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -284,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"ordinal": 29,
|
||||
"name": "maybe_model_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -294,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"ordinal": 30,
|
||||
"name": "maybe_model_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -304,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"ordinal": 31,
|
||||
"name": "maybe_model_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -314,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"ordinal": 32,
|
||||
"name": "maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -324,7 +334,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"ordinal": 33,
|
||||
"name": "maybe_model_weight_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -334,7 +344,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 33,
|
||||
"ordinal": 34,
|
||||
"name": "maybe_model_weight_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -344,7 +354,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 34,
|
||||
"ordinal": 35,
|
||||
"name": "maybe_model_weight_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -354,7 +364,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 35,
|
||||
"ordinal": 36,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -364,7 +374,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 36,
|
||||
"ordinal": 37,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -374,7 +384,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 37,
|
||||
"ordinal": 38,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -384,7 +394,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 38,
|
||||
"ordinal": 39,
|
||||
"name": "maybe_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -394,7 +404,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 39,
|
||||
"ordinal": 40,
|
||||
"name": "maybe_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -404,7 +414,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 40,
|
||||
"ordinal": 41,
|
||||
"name": "maybe_bookmark_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -414,7 +424,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 41,
|
||||
"ordinal": 42,
|
||||
"name": "is_featured",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
@@ -424,7 +434,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 42,
|
||||
"ordinal": 43,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -434,7 +444,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 43,
|
||||
"ordinal": 44,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -471,6 +481,7 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
@@ -494,5 +505,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "beda05b1f3e3f78ca2610c491e682ea1c76fb5effccd5d710761353baf8ce161"
|
||||
"hash": "58cb3fd03fb215b1d323f6aa6a5fd713900b9d931700c4226a1d9713b5e469c7"
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n job_type as queue_type,\n count(*) as pending_job_count,\n NOW() as present_time\n FROM (\n SELECT\n token,\n job_type\n FROM generic_inference_jobs\n WHERE status IN (\"pending\", \"attempt_failed\")\n AND job_type IS NOT NULL\n UNION\n SELECT\n token,\n job_type\n FROM generic_inference_jobs\n WHERE status IN (\"started\")\n AND created_at > (CURDATE() - INTERVAL 15 MINUTE)\n AND job_type IS NOT NULL\n) as generic_inner\nGROUP BY queue_type\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "queue_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "pending_job_count",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 21
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "present_time",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "73dc054488b2fa3efc923d3a90914a1450b73e99a377562484a0498ccce1676f"
|
||||
}
|
||||
+14
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n token as `token: tokens::tokens::users::UserToken`,\n username,\n email_address,\n password_hash as `password_hash: crate::queries::users::user::lookup_user_for_login_result::VecBytes`,\n password_version,\n is_banned\nFROM users\nWHERE username = ?\nLIMIT 1\n ",
|
||||
"query": "\nSELECT\n token as `token: tokens::tokens::users::UserToken`,\n username,\n email_address,\n password_hash as `password_hash: crate::queries::users::user::lookup_user_for_login_result::VecBytes`,\n password_version,\n is_banned,\n maybe_feature_flags\nFROM users\nWHERE username = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -62,6 +62,16 @@
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_feature_flags",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -73,8 +83,9 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "5795b8579a458706077b1fa95e4627b90eac6606bde543b6406233d081fd0eb5"
|
||||
"hash": "8e577db7abde571a0f29fc9d678891349918f0882136d9f7a39b338f66270f11"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nUPDATE media_files\nSET\n maybe_animation_type = ?\nWHERE\n token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "930cfd52f78fa14a86bd1a67c5fe36d8c8961079b2bd684a0d4da315bf3ce16e"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nUPDATE generic_inference_jobs\nSET\n is_dismissed_by_user = TRUE\nWHERE maybe_creator_user_token = ?\nAND status IN (\n 'dead',\n 'cancelled_by_system',\n 'cancelled_by_user',\n 'complete_failure',\n 'complete_success'\n )\nAND created_at > DATE_SUB(NOW(), INTERVAL 36 HOUR)\nLIMIT 1000\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a1d44611ee4a0ecc54548f95719f01341eb242460c79ef75423de96b31ed5385"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO users (\n token,\n username,\n display_name,\n email_address,\n email_gravatar_hash,\n profile_markdown,\n profile_rendered_html,\n user_role_slug,\n password_hash,\n ip_address_creation,\n ip_address_last_login,\n ip_address_last_update,\n can_access_studio\n)\nVALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? , ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 13
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a3066dd68c77b5381104a754b2774506990f659c9a0ed2de1fcb8e6fd953e726"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nUPDATE media_files\nSET\n maybe_engine_category = ?\nWHERE\n token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "b56ee40be840cdec013f3f99eb585e4ac333ccfe563ba3da4c9a80df33dccd57"
|
||||
}
|
||||
+14
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n\n jobs.status as `status: enums::common::job_status_plus::JobStatusPlus`,\n jobs.attempt_count,\n\n jobs.maybe_creator_user_token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n jobs.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n jobs.creator_ip_address,\n\n jobs.inference_category as `inference_category: enums::by_table::generic_inference_jobs::inference_category::InferenceCategory`,\n jobs.maybe_model_type,\n jobs.maybe_model_token,\n jobs.maybe_raw_inference_text,\n jobs.maybe_inference_args,\n\n jobs.frontend_failure_category as `maybe_frontend_failure_category: enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory`,\n\n jobs.on_success_result_entity_type as maybe_result_entity_type,\n jobs.on_success_result_entity_token as maybe_result_entity_token,\n\n model_weights.title as maybe_model_weights_title,\n tts_models.title as maybe_tts_model_title,\n voice_conversion_models.title as maybe_voice_conversion_model_title,\n\n tts_results.public_bucket_wav_audio_path as maybe_tts_public_bucket_path,\n voice_conversion_results.public_bucket_hash as maybe_voice_conversion_public_bucket_hash,\n\n media_files.public_bucket_directory_hash as maybe_media_file_public_bucket_directory_hash,\n media_files.maybe_public_bucket_prefix as maybe_media_file_public_bucket_prefix,\n media_files.maybe_public_bucket_extension as maybe_media_file_public_bucket_extension,\n\n jobs.assigned_worker as maybe_assigned_worker,\n jobs.assigned_cluster as maybe_assigned_cluster,\n\n jobs.is_keepalive_required,\n\n jobs.created_at,\n jobs.updated_at,\n\n jobs.first_started_at as maybe_first_started_at,\n jobs.successfully_completed_at as maybe_successfully_completed_at\n\nFROM generic_inference_jobs as jobs\n\nLEFT OUTER JOIN model_weights ON jobs.maybe_model_token = model_weights.token\nLEFT OUTER JOIN tts_models ON jobs.maybe_model_token = tts_models.token\nLEFT OUTER JOIN voice_conversion_models ON jobs.maybe_model_token = voice_conversion_models.token\n\nLEFT OUTER JOIN tts_results ON jobs.on_success_result_entity_token = tts_results.token\nLEFT OUTER JOIN voice_conversion_results ON jobs.on_success_result_entity_token = voice_conversion_results.token\nLEFT OUTER JOIN media_files ON jobs.on_success_result_entity_token = media_files.token\n\nWHERE jobs.token = ?\n ",
|
||||
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n\n jobs.status as `status: enums::common::job_status_plus::JobStatusPlus`,\n jobs.attempt_count,\n\n jobs.maybe_creator_user_token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n jobs.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n jobs.creator_ip_address,\n\n jobs.inference_category as `inference_category: enums::by_table::generic_inference_jobs::inference_category::InferenceCategory`,\n jobs.maybe_model_type,\n jobs.maybe_model_token,\n jobs.maybe_raw_inference_text,\n jobs.maybe_inference_args,\n\n jobs.frontend_failure_category as `maybe_frontend_failure_category: enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory`,\n\n jobs.on_success_result_entity_type as maybe_result_entity_type,\n jobs.on_success_result_entity_token as maybe_result_entity_token,\n\n model_weights.title as maybe_model_weights_title,\n tts_models.title as maybe_tts_model_title,\n voice_conversion_models.title as maybe_voice_conversion_model_title,\n\n tts_results.public_bucket_wav_audio_path as maybe_tts_public_bucket_path,\n voice_conversion_results.public_bucket_hash as maybe_voice_conversion_public_bucket_hash,\n\n media_files.public_bucket_directory_hash as maybe_media_file_public_bucket_directory_hash,\n media_files.maybe_public_bucket_prefix as maybe_media_file_public_bucket_prefix,\n media_files.maybe_public_bucket_extension as maybe_media_file_public_bucket_extension,\n\n jobs.assigned_worker as maybe_assigned_worker,\n jobs.assigned_cluster as maybe_assigned_cluster,\n\n jobs.is_keepalive_required,\n\n jobs.created_at,\n jobs.updated_at,\n\n jobs.first_started_at as maybe_first_started_at,\n jobs.successfully_completed_at as maybe_successfully_completed_at,\n\n NOW() as database_clock\n\nFROM generic_inference_jobs as jobs\n\nLEFT OUTER JOIN model_weights ON jobs.maybe_model_token = model_weights.token\nLEFT OUTER JOIN tts_models ON jobs.maybe_model_token = tts_models.token\nLEFT OUTER JOIN voice_conversion_models ON jobs.maybe_model_token = voice_conversion_models.token\n\nLEFT OUTER JOIN tts_results ON jobs.on_success_result_entity_token = tts_results.token\nLEFT OUTER JOIN voice_conversion_results ON jobs.on_success_result_entity_token = voice_conversion_results.token\nLEFT OUTER JOIN media_files ON jobs.on_success_result_entity_token = media_files.token\n\nWHERE jobs.token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -292,6 +292,16 @@
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"name": "database_clock",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -326,8 +336,9 @@
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "7d5030b221e9b470ee7af4b73539fd2ef477e6f3c98c56422016449c6775222d"
|
||||
"hash": "e5121d132d93ec43e48197e00b19040a50ff2942224dc70b0faa0ec988aee7cf"
|
||||
}
|
||||
+50
-39
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_media_subtype as `maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype`,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n ",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_media_subtype as `maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype`,\n\n m.maybe_mime_type,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -65,6 +65,16 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_mime_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -74,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -84,7 +94,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -94,7 +104,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -104,7 +114,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 11,
|
||||
"name": "maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -114,7 +124,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 12,
|
||||
"name": "maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +134,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 13,
|
||||
"name": "maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -134,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 14,
|
||||
"name": "maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -144,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 15,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -154,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 16,
|
||||
"name": "maybe_text_transcript",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -164,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 17,
|
||||
"name": "maybe_origin_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -174,7 +184,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"ordinal": 18,
|
||||
"name": "maybe_duration_millis",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -184,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 19,
|
||||
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -194,7 +204,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 20,
|
||||
"name": "maybe_other_prompt_args",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -204,7 +214,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 21,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -214,7 +224,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"ordinal": 22,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -224,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"ordinal": 23,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -234,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"ordinal": 24,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -244,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"ordinal": 25,
|
||||
"name": "maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -254,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 26,
|
||||
"name": "maybe_model_weights_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -264,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 27,
|
||||
"name": "maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -274,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 28,
|
||||
"name": "maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -284,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"ordinal": 29,
|
||||
"name": "maybe_model_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -294,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"ordinal": 30,
|
||||
"name": "maybe_model_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -304,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"ordinal": 31,
|
||||
"name": "maybe_model_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -314,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"ordinal": 32,
|
||||
"name": "maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -324,7 +334,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"ordinal": 33,
|
||||
"name": "maybe_model_weight_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -334,7 +344,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 33,
|
||||
"ordinal": 34,
|
||||
"name": "maybe_model_weight_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -344,7 +354,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 34,
|
||||
"ordinal": 35,
|
||||
"name": "maybe_model_weight_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -354,7 +364,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 35,
|
||||
"ordinal": 36,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -364,7 +374,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 36,
|
||||
"ordinal": 37,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -374,7 +384,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 37,
|
||||
"ordinal": 38,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -384,7 +394,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 38,
|
||||
"ordinal": 39,
|
||||
"name": "maybe_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -394,7 +404,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 39,
|
||||
"ordinal": 40,
|
||||
"name": "maybe_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -404,7 +414,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 40,
|
||||
"ordinal": 41,
|
||||
"name": "maybe_bookmark_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -414,7 +424,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 41,
|
||||
"ordinal": 42,
|
||||
"name": "is_featured",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
@@ -424,7 +434,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 42,
|
||||
"ordinal": 43,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -434,7 +444,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 43,
|
||||
"ordinal": 44,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -471,6 +481,7 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
@@ -494,5 +505,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "bfbe17ad0d993033c1015881f679fc27f5f16fb3edb24e30295c8188ff63d5cd"
|
||||
"hash": "f1861dc84015b5c753cb5c31313c747386bce56983108fd6a01815d02d429630"
|
||||
}
|
||||
Generated
+1513
-1307
File diff suppressed because it is too large
Load Diff
+2
-4
@@ -7,6 +7,7 @@ members = [
|
||||
"crates/_types/buckets",
|
||||
"crates/_types/composite_identifiers",
|
||||
"crates/_types/enums",
|
||||
"crates/_types/enums_public",
|
||||
"crates/_types/reusable_types", # TODO(bt, 2022-12-21): Deprecate
|
||||
"crates/_types/tokens",
|
||||
|
||||
@@ -27,7 +28,6 @@ members = [
|
||||
"crates/lib/api_clients/cloud_storage",
|
||||
"crates/lib/api_clients/google_drive_common",
|
||||
"crates/lib/api_clients/thumbnail_generator",
|
||||
"crates/lib/api_clients/twitch_common",
|
||||
"crates/lib/bootstrap",
|
||||
"crates/lib/caching/memory_caching",
|
||||
"crates/lib/caching/redis_caching",
|
||||
@@ -60,6 +60,7 @@ members = [
|
||||
"crates/lib/password",
|
||||
"crates/lib/prompt_engineering",
|
||||
"crates/lib/redis_common",
|
||||
"crates/lib/redis_schema",
|
||||
"crates/lib/server_environment",
|
||||
"crates/lib/sqlx_mysql_helpers",
|
||||
"crates/lib/storyteller_root",
|
||||
@@ -82,16 +83,13 @@ members = [
|
||||
"crates/service/job/tts_inference_job",
|
||||
"crates/service/job/w2l_download_job",
|
||||
"crates/service/job/w2l_inference_job",
|
||||
"crates/service/other/twitch_pubsub_subscriber",
|
||||
"crates/service/web/dummy_service",
|
||||
"crates/service/web/storyteller_web",
|
||||
"crates/service/web/websocket_gateway",
|
||||
|
||||
# Service Plugins: complete subsystems that can be plugged into services (users, billing, etc.)
|
||||
"crates/service/plugins/billing",
|
||||
"crates/service/plugins/inference_workloads",
|
||||
"crates/service/plugins/user_traits_component",
|
||||
"crates/service/plugins/users",
|
||||
|
||||
# Vendored code
|
||||
"crates/vendor/limitation",
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# -*- mode: Python -*-
|
||||
|
||||
if k8s_context() != 'black1':
|
||||
fail("failing early to avoid overwriting prod")
|
||||
local_resource('storyteller-web-binary',
|
||||
cmd='SQLX_OFFLINE=true cargo build --release --bin storyteller-web --target=x86_64-unknown-linux-musl',
|
||||
)
|
||||
|
||||
allow_k8s_contexts('black1')
|
||||
sync_src_crates = sync('./crates', '/storyteller-rust/source/crates')
|
||||
sync_src_sql = sync('./_sql', '/storyteller-rust/source/_sql')
|
||||
sync_src_cargo_lock = sync('./Cargo.lock', '/storyteller-rust/source/Cargo.lock')
|
||||
sync_src_cargo = sync('./Cargo.toml', '/storyteller-rust/source/Cargo.toml')
|
||||
sync_src_env = sync('./.env', '/storyteller-rust/source/.env')
|
||||
sync_src_startup = sync('./_develop/localdev/startup.sh', '/storyteller-rust/_develop/localdev/startup.sh')
|
||||
sync_src_storyteller_binary = sync('./target/x86_64-unknown-linux-musl/release/storyteller-web', '/storyteller-rust/target/x86_64-unknown-linux-musl/release/storyteller-web')
|
||||
docker_build('storyteller-web',
|
||||
'.',
|
||||
dockerfile='_develop/localdev/Dockerfile',
|
||||
platform='linux/amd64',
|
||||
only=[
|
||||
'./target/x86_64-unknown-linux-musl/release/storyteller-web',
|
||||
'_develop/localdev/Dockerfile',
|
||||
'./_develop/localdev/startup.sh',
|
||||
'crates/service/web/storyteller_web/config/storyteller-web.development.env',
|
||||
'_sql', 'diesel.toml', '.env'],
|
||||
live_update = [
|
||||
sync_src_crates,
|
||||
sync_src_sql,
|
||||
sync_src_cargo_lock,
|
||||
sync_src_cargo,
|
||||
sync_src_env,
|
||||
sync_src_startup,
|
||||
sync_src_storyteller_binary,
|
||||
run('date > /restart.txt')
|
||||
],
|
||||
)
|
||||
k8s_yaml('_develop/localdev/kubernetes.yml',
|
||||
|
||||
)
|
||||
k8s_resource(
|
||||
objects=['ssd-hostpath:storageclass', 'test-pvc:persistentvolumeclaim'],
|
||||
new_name='storyteller-web-pvc',
|
||||
trigger_mode=TRIGGER_MODE_MANUAL,
|
||||
)
|
||||
k8s_resource('mysql', port_forwards='3307:3306')
|
||||
k8s_resource('storyteller-web', port_forwards=12345)
|
||||
@@ -6,9 +6,20 @@ RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
mariadb-client \
|
||||
imagemagick \
|
||||
python3-pip \
|
||||
libmariadb-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN cd /tmp && \
|
||||
wget -O entr.zip https://github.com/eradman/entr/archive/refs/tags/5.6.zip && \
|
||||
unzip entr.zip && \
|
||||
cd entr-5.6 && \
|
||||
./configure && \
|
||||
make test && \
|
||||
make install \
|
||||
&& rm -rf /tmp/entr-5.6
|
||||
|
||||
|
||||
|
||||
RUN cargo install diesel_cli --features mysql && \
|
||||
cargo install sqlx-cli --features mysql
|
||||
@@ -19,5 +30,5 @@ ARG GIT_SHA
|
||||
|
||||
RUN echo -n ${GIT_SHA} > /GIT_SHA
|
||||
|
||||
CMD ["/storyteller-rust/localdev/startup.sh"]
|
||||
CMD ["/storyteller-rust/_develop/localdev/startup.sh"]
|
||||
|
||||
|
||||
@@ -27,6 +27,38 @@ spec:
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
|
||||
---
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: ssd-hostpath
|
||||
provisioner: microk8s.io/hostpath
|
||||
reclaimPolicy: Retain
|
||||
volumeBindingMode: WaitForFirstConsumer
|
||||
parameters:
|
||||
pvDir: /home/kasisnu/microk8s/hostpath-provisioner
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: test-pvc
|
||||
spec:
|
||||
storageClassName: ssd-hostpath
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: storyteller-config
|
||||
data:
|
||||
buckets.vocodes_bucket_region: us-east1
|
||||
buckets.vocodes_private_bucket_name: kasisnu-test-area-private
|
||||
buckets.vocodes_public_bucket_name: kasisnu-test-area-public
|
||||
|
||||
---
|
||||
|
||||
apiVersion: apps/v1
|
||||
@@ -65,29 +97,57 @@ spec:
|
||||
labels:
|
||||
app: storyteller-web
|
||||
spec:
|
||||
runtimeClassName: nvidia
|
||||
containers:
|
||||
- name: gpt-sovitsdir
|
||||
image: localhost:32000/some-gpt-sovits:latest
|
||||
imagePullPolicy: Always
|
||||
command: ["sleep", "infinity"]
|
||||
resources:
|
||||
limits:
|
||||
nvidia.com/gpu: "1"
|
||||
requests:
|
||||
nvidia.com/gpu: "1"
|
||||
volumeMounts:
|
||||
- mountPath: /application-dir
|
||||
name: application-dir
|
||||
- name: storyteller-web
|
||||
image: storyteller-web:latest
|
||||
imagePullPolicy: Never
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: MYSQL_URL
|
||||
value: mysql://storyteller:password@mysql.default/storyteller
|
||||
value: mysql://storyteller:password@mysql/storyteller
|
||||
- name: REDIS_0_URL
|
||||
value: redis://redisd@redis.default/0
|
||||
value: redis://redisd@redis/0
|
||||
- name: REDIS_1_URL
|
||||
value: redis://redisd@redis.default/1
|
||||
value: redis://redisd@redis/1
|
||||
- name: ACCESS_KEY
|
||||
value: garbage
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: bucket-secrets
|
||||
key: access-key
|
||||
- name: SECRET_KEY
|
||||
value: garbage
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: bucket-secrets
|
||||
key: secret-key
|
||||
- name: REGION_NAME
|
||||
value: garbage
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: storyteller-config
|
||||
key: buckets.vocodes_bucket_region
|
||||
- name: W2L_PRIVATE_DOWNLOAD_BUCKET_NAME
|
||||
value: garbage
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: storyteller-config
|
||||
key: buckets.vocodes_private_bucket_name
|
||||
- name: W2L_PUBLIC_DOWNLOAD_BUCKET_NAME
|
||||
value: garbage
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: storyteller-config
|
||||
key: buckets.vocodes_public_bucket_name
|
||||
- name: AUDIO_UPLOADS_BUCKET_ROOT
|
||||
value: garbage
|
||||
value: /user_uploaded_w2l_audio
|
||||
- name: TWITCH_USERNAME
|
||||
value: garbage
|
||||
- name: TWITCH_STREAM_KEY
|
||||
@@ -101,10 +161,14 @@ spec:
|
||||
volumeMounts:
|
||||
- mountPath: /storyteller-rust
|
||||
name: storyteller-rust-folder
|
||||
- mountPath: /application-dir
|
||||
name: application-dir
|
||||
volumes:
|
||||
- name: storyteller-rust-folder
|
||||
hostPath:
|
||||
path: /storyteller-rust
|
||||
persistentVolumeClaim:
|
||||
claimName: test-pvc
|
||||
- name: application-dir
|
||||
emptyDir: {}
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
@@ -116,7 +180,7 @@ spec:
|
||||
ports:
|
||||
- name: mysql
|
||||
port: 3306
|
||||
nodePort: 3306
|
||||
nodePort: 32206
|
||||
selector:
|
||||
app: mysql
|
||||
|
||||
@@ -131,7 +195,7 @@ spec:
|
||||
ports:
|
||||
- name: redis
|
||||
port: 6379
|
||||
nodePort: 6379
|
||||
nodePort: 32379
|
||||
selector:
|
||||
app: redis
|
||||
|
||||
@@ -146,7 +210,7 @@ spec:
|
||||
ports:
|
||||
- name: storyteller-web
|
||||
port: 12345
|
||||
nodePort: 12345
|
||||
nodePort: 32345
|
||||
selector:
|
||||
app: storyteller-web
|
||||
|
||||
|
||||
@@ -2,5 +2,8 @@
|
||||
set +e +o pipefail
|
||||
diesel migration run --database-url="${MYSQL_URL}"
|
||||
set -e -o pipefail
|
||||
./target/x86_64-unknown-linux-musl/release/storyteller-web
|
||||
|
||||
echo 'hello world in startup.sh'
|
||||
#sleep infinity
|
||||
date > /restart.txt
|
||||
echo /restart.txt | entr -nrz /storyteller-rust/target/x86_64-unknown-linux-musl/release/storyteller-web
|
||||
#/storyteller-rust/target/x86_64-unknown-linux-musl/release/storyteller-web
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"settings" : {
|
||||
"index.number_of_shards" : 3,
|
||||
"index.number_of_replicas" : 2
|
||||
},
|
||||
"mappings" : {
|
||||
"properties" : {
|
||||
"token" : { "type" : "keyword" },
|
||||
|
||||
"media_class" : { "type" : "keyword" },
|
||||
"media_type" : { "type" : "keyword" },
|
||||
"maybe_media_subtype" : { "type" : "keyword" },
|
||||
"maybe_engine_category" : { "type" : "keyword" },
|
||||
"maybe_animation_type" : { "type" : "keyword" },
|
||||
|
||||
"maybe_mime_type" : { "type" : "keyword" },
|
||||
|
||||
"public_bucket_hash" : { "type" : "keyword" },
|
||||
"public_bucket_prefix" : { "type" : "keyword" },
|
||||
"public_bucket_extension" : { "type" : "keyword" },
|
||||
|
||||
"creator_set_visibility" : { "type" : "keyword" },
|
||||
|
||||
"maybe_title" : { "type" : "search_as_you_type" },
|
||||
"maybe_title_as_keyword" : { "type" : "keyword" },
|
||||
|
||||
"maybe_cover_image_media_file_token" : { "type" : "keyword" },
|
||||
"maybe_cover_image_public_bucket_hash" : { "type" : "keyword" },
|
||||
"maybe_cover_image_public_bucket_prefix" : { "type" : "keyword" },
|
||||
"maybe_cover_image_public_bucket_extension" : { "type" : "keyword" },
|
||||
|
||||
"maybe_creator_user_token" : { "type" : "keyword" },
|
||||
"maybe_creator_username" : { "type" : "keyword" },
|
||||
"maybe_creator_display_name" : { "type" : "text" },
|
||||
"maybe_creator_gravatar_hash" : { "type" : "text" },
|
||||
|
||||
"created_at" : { "type" : "date" },
|
||||
"updated_at" : { "type" : "date" },
|
||||
"user_deleted_at" : { "type" : "date" },
|
||||
"mod_deleted_at" : { "type" : "date" },
|
||||
|
||||
"is_featured" : {
|
||||
"type": "boolean",
|
||||
"index": true
|
||||
},
|
||||
|
||||
"is_deleted" : {
|
||||
"type": "boolean",
|
||||
"index": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
"weights_category" : { "type" : "keyword" },
|
||||
|
||||
"title" : { "type" : "search_as_you_type" },
|
||||
"title_as_keyword" : { "type" : "keyword" },
|
||||
|
||||
"maybe_cover_image_media_file_token" : { "type" : "keyword" },
|
||||
"maybe_cover_image_public_bucket_hash" : { "type" : "keyword" },
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"bool": {
|
||||
"must" : [
|
||||
{
|
||||
"term": {
|
||||
"is_deleted": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"term": {
|
||||
"media_class": "dimensional"
|
||||
}
|
||||
},
|
||||
{
|
||||
"term": {
|
||||
"media_type": "glb"
|
||||
}
|
||||
},
|
||||
{
|
||||
"bool": {
|
||||
"should": [
|
||||
{ "term": { "maybe_engine_category": "object"} },
|
||||
{ "term": { "maybe_engine_category": "image_plane"} }
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"should": [
|
||||
{
|
||||
"fuzzy": {
|
||||
"maybe_title": {
|
||||
"value": "REPLACE_ME",
|
||||
"fuzziness": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"match": {
|
||||
"maybe_title": {
|
||||
"query": "REPLACE_ME",
|
||||
"boost": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"multi_match": {
|
||||
"query": "REPLACE_ME",
|
||||
"type": "bool_prefix",
|
||||
"fields": [
|
||||
"maybe_title",
|
||||
"maybe_title._2gram",
|
||||
"maybe_title._3gram"
|
||||
],
|
||||
"boost": 50
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"bool": {
|
||||
"should": [
|
||||
{
|
||||
"fuzzy": {
|
||||
"title": {
|
||||
"value": "REPLACE_ME",
|
||||
"fuzziness": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"match": {
|
||||
"title": {
|
||||
"query": "REPLACE_ME",
|
||||
"boost": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"multi_match": {
|
||||
"query": "REPLACE_ME",
|
||||
"type": "bool_prefix",
|
||||
"fields": [
|
||||
"title",
|
||||
"title._2gram",
|
||||
"title._3gram"
|
||||
],
|
||||
"boost": 50
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,3 +19,29 @@ where
|
||||
and m.mod_deleted_at IS NULL
|
||||
order by m.title asc;
|
||||
|
||||
-- Top models within time period
|
||||
-- NB: id threshold is to avoid a full table scan
|
||||
select
|
||||
mw.token,
|
||||
mw.title,
|
||||
mw.weights_type,
|
||||
mw.weights_category,
|
||||
u.username as creator_username,
|
||||
r.use_count,
|
||||
mw.created_at,
|
||||
mw.user_deleted_at,
|
||||
mw.mod_deleted_at
|
||||
from (
|
||||
select maybe_model_token, count(*) as use_count
|
||||
from generic_inference_jobs
|
||||
where maybe_model_token IS NOT NULL
|
||||
and created_at > NOW() - INTERVAL 1 DAY
|
||||
and id > 40000000
|
||||
group by maybe_model_token
|
||||
) as r
|
||||
join model_weights as mw
|
||||
on mw.token = r.maybe_model_token
|
||||
join users as u
|
||||
on u.token = mw.creator_user_token
|
||||
order by r.use_count desc
|
||||
limit 100;
|
||||
|
||||
@@ -94,6 +94,7 @@ SET
|
||||
can_access_studio = false,
|
||||
maybe_feature_flags = 'studio,video_style_transfer'
|
||||
WHERE username IN (
|
||||
'FoxtailStudio',
|
||||
'chechisauri0',
|
||||
'dakrid',
|
||||
'omega7321',
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
select *
|
||||
from generic_inference_jobs
|
||||
where job_type = 'comfy_ui'
|
||||
and status NOT IN (
|
||||
'pending',
|
||||
'started',
|
||||
'complete_success'
|
||||
)
|
||||
order by id desc
|
||||
limit 5\G
|
||||
|
||||
-- List started jobs
|
||||
select *
|
||||
from generic_inference_jobs
|
||||
where job_type = 'comfy_ui'
|
||||
and status IN ('started')
|
||||
order by id desc
|
||||
limit 50\G
|
||||
|
||||
update generic_inference_jobs
|
||||
set inference_category = 'convert_bvh_to_workflow'
|
||||
where inference_category = 'deprecated_field'
|
||||
limit 5;
|
||||
|
||||
[2024-07-16T22:53:07Z ERROR inference_job::job::job_loop::main_loop] Error querying jobs: error: ""
|
||||
@@ -6,3 +6,8 @@
|
||||
select username from users where maybe_feature_flags like '%studio%';
|
||||
|
||||
select username from users where can_access_studio = true;
|
||||
|
||||
-- Who signed up recently and has access?
|
||||
select username, maybe_source
|
||||
from users where can_access_studio = true
|
||||
and created_at > NOW() - interval 20 minute;
|
||||
|
||||
@@ -11,8 +11,72 @@ from media_files as m
|
||||
join users as u
|
||||
on m.maybe_creator_user_token = u.token
|
||||
where u.can_access_studio = true
|
||||
and m.created_at > (CURDATE() - INTERVAL 1 WEEK)
|
||||
and m.created_at > (CURDATE() - INTERVAL 14 DAY)
|
||||
and m.is_intermediate_system_file = false
|
||||
and m.media_class = 'video'
|
||||
group by u.token
|
||||
order by video_count desc;
|
||||
|
||||
-- Without internal users
|
||||
select
|
||||
u.username,
|
||||
count(*) as video_count,
|
||||
u.maybe_source,
|
||||
u.created_at
|
||||
from media_files as m
|
||||
join users as u
|
||||
on m.maybe_creator_user_token = u.token
|
||||
where u.maybe_feature_flags LIKE '%studio%'
|
||||
and m.created_at > (CURDATE() - INTERVAL 1 DAY)
|
||||
and m.is_intermediate_system_file = false
|
||||
and m.media_class = 'video'
|
||||
and u.username NOT IN (
|
||||
'bflat',
|
||||
'candyfoxxx',
|
||||
'crossproduct1',
|
||||
'echelon',
|
||||
'endtimes',
|
||||
'heart_ribbon',
|
||||
'kasisnu',
|
||||
'mechacosm',
|
||||
'moonchamp',
|
||||
'olivicmic',
|
||||
'printrman',
|
||||
'vegito1089',
|
||||
'wilwong',
|
||||
'yae_ph'
|
||||
)
|
||||
group by u.token
|
||||
order by created_at desc;
|
||||
|
||||
-- See videos generated
|
||||
-- and m.is_intermediate_system_file IS TRUE
|
||||
-- where u.maybe_feature_flags LIKE '%studio%'
|
||||
select
|
||||
u.username,
|
||||
u.maybe_source,
|
||||
m.token,
|
||||
m.is_intermediate_system_file as sys_file,
|
||||
m.created_at
|
||||
from media_files as m
|
||||
join users as u
|
||||
on m.maybe_creator_user_token = u.token
|
||||
WHERE m.created_at > (CURDATE() - INTERVAL 1 DAY)
|
||||
and m.media_class = 'video'
|
||||
and u.username NOT IN (
|
||||
'bflat',
|
||||
'candyfoxxx',
|
||||
'crossproduct1',
|
||||
'echelon',
|
||||
'endtimes',
|
||||
'heart_ribbon',
|
||||
'kasisnu',
|
||||
'mechacosm',
|
||||
'moonchamp',
|
||||
'olivicmic',
|
||||
'printrman',
|
||||
'vegito1089',
|
||||
'wilwong',
|
||||
'yae_ph'
|
||||
)
|
||||
order by m.created_at desc;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Enroll internal accounts in studio + loyalty features
|
||||
UPDATE users
|
||||
SET
|
||||
can_access_studio = true,
|
||||
maybe_feature_flags = 'explore_media,studio,video_style_transfer',
|
||||
maybe_loyalty_program_key = 'fakeyou_contributor',
|
||||
user_role_slug = "admin"
|
||||
WHERE username IN (
|
||||
'48hourfilm',
|
||||
'intro_video',
|
||||
'zzz_last_item'
|
||||
)
|
||||
LIMIT 5;
|
||||
@@ -199,7 +199,7 @@ CREATE TABLE generic_inference_jobs (
|
||||
attempt_count SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
|
||||
-- If the user chooses to no longer display or poll the job, we mark this flag true.
|
||||
-- This can only be set for terminal state (completed or failed) jobs.
|
||||
-- This should only be set for terminal state (completed or failed) jobs.
|
||||
-- We use this flag to remove the job from the user's view.
|
||||
is_dismissed_by_user BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- This table contains both user uploads and inference or processing results.
|
||||
--
|
||||
-- The fields in media_files that should be filterable are:
|
||||
-- * media_class ("audio", "video", "image", "dimensional")
|
||||
-- * media_type ("fbx", "glb", "scene_json", "png", "jpg", etc.)
|
||||
-- * engine_category ("scene", "character", "animation", "object", "image_plane", etc.)
|
||||
--
|
||||
CREATE TABLE media_files (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
@@ -109,6 +115,11 @@ CREATE TABLE media_files (
|
||||
-- * `glb` for GLB files
|
||||
-- * `gltf` for GLTF files
|
||||
-- * `scene_ron` for SCN.RON files
|
||||
-- * `scene_json` for scene files for three.js
|
||||
-- * `pmd`
|
||||
-- * `vmd`
|
||||
-- * `pmx`
|
||||
-- * `csv`
|
||||
media_type VARCHAR(16) NOT NULL,
|
||||
|
||||
-- Broad class of media:
|
||||
@@ -117,16 +128,15 @@ CREATE TABLE media_files (
|
||||
-- * 'audio' for wav, mp3, etc.
|
||||
-- * 'image' for a variety of video types.
|
||||
-- * 'video' for a variety of video types.
|
||||
-- * 'animation' for animations (engine)
|
||||
-- * 'character' for characters (engine)
|
||||
-- * 'prop' for props (engine)
|
||||
-- * 'scene' for scenes (engine; internal and external scenes)
|
||||
-- * 'dimensional' for a variety of 3d types
|
||||
media_class VARCHAR(16) NOT NULL DEFAULT "unknown",
|
||||
|
||||
-- A media file's possible subtype. Typically used for Storyteller Studio.
|
||||
-- * 'mixamo' for mixamo animations (eg. for BVH, GLB, FBX, etc. files)
|
||||
-- * 'mocap_net' for mocapnet animations (eg. for BVH files)
|
||||
-- * 'scene' for generic scenes (eg. for BVH, GLB, FBX, etc. files)
|
||||
-- * 'scene'
|
||||
-- * 'character'
|
||||
-- * 'animation'
|
||||
maybe_media_subtype VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- The file's mime type.
|
||||
|
||||
+26
-21
@@ -1,29 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="//unpkg.com/swagger-ui-dist@3/swagger-ui.css">
|
||||
|
||||
<title>Storyteller API</title>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="SwaggerUI" />
|
||||
<title>Storyteller API</title>
|
||||
<link rel="stylesheet" href="//unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app-docs" />
|
||||
|
||||
<script src="//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
|
||||
<script>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
window.onload = function () {
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "api.json",
|
||||
dom_id: "#app-docs",
|
||||
<script src="//unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js" crossorigin></script>
|
||||
<script src="//unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-standalone-preset.js" crossorigin></script>
|
||||
<script>
|
||||
window.onload = () => {
|
||||
window.ui = SwaggerUIBundle({
|
||||
url: 'api.json',
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
tagsSorter: 'alpha', // Sort tags (endpoint groupings) alphabetically
|
||||
defaultModelRendering: 'model', // Show model instead of "example request"
|
||||
defaultModelExpandDepth: 6,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ utoipa = { version = "4", features = ["chrono","actix_extras"] }
|
||||
[dev-dependencies]
|
||||
|
||||
# Enum utilities
|
||||
strum = { version = "0.25", features = ["derive"] }
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
|
||||
# Test serialization
|
||||
serde_json = "1.0.108"
|
||||
toml = "0.5.8"
|
||||
toml = "0.8.14"
|
||||
|
||||
@@ -16,32 +16,50 @@ use utoipa::ToSchema;
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, Default, ToSchema)]
|
||||
pub enum InferenceCategory {
|
||||
/// Eg. SadTalker and possibly Wav2Lip
|
||||
/// Deprecate this field !!!
|
||||
/// We should drain all jobs from using this database field, then remove it.
|
||||
#[serde(rename = "deprecated_field")]
|
||||
DeprecatedField,
|
||||
|
||||
/// Facial lipsync animation (eg. SadTalker, Wav2Lip)
|
||||
#[serde(rename = "lipsync_animation")]
|
||||
#[default]
|
||||
LipsyncAnimation,
|
||||
|
||||
/// FakeYou's text to speech (eg. Tacotron2)
|
||||
#[serde(rename = "text_to_speech")]
|
||||
TextToSpeech,
|
||||
|
||||
/// FakeYou's voice conversion (eg. svc, rvc)
|
||||
#[serde(rename = "voice_conversion")]
|
||||
VoiceConversion,
|
||||
|
||||
#[serde(rename = "video_filter")]
|
||||
VideoFilter,
|
||||
|
||||
/// Image generation (eg. Stable Diffusion 1.5)
|
||||
#[serde(rename = "image_generation")]
|
||||
ImageGeneration,
|
||||
|
||||
/// Turn video into animation data with mocap processing (eg. Mocapnet).
|
||||
#[serde(rename = "mocap")]
|
||||
Mocap,
|
||||
|
||||
/// ComfyUI workflows
|
||||
/// This is what powers Storyteller Studio!
|
||||
#[serde(rename = "workflow")]
|
||||
Workflow,
|
||||
|
||||
/// FBX to GLTF/GLB.
|
||||
/// Still supported, but few people will use it.
|
||||
#[serde(rename = "format_conversion")]
|
||||
FormatConversion,
|
||||
|
||||
/// DEPRECATED. Do not use.
|
||||
/// This was for ReRenderAVideo, which we never productionized.
|
||||
#[deprecated(note = "This was for ReRenderAVideo, which we never productionized.")]
|
||||
#[serde(rename = "video_filter")]
|
||||
VideoFilter,
|
||||
|
||||
/// DEPRECATED. Bevy engine serverside rendering.
|
||||
#[deprecated(note = "This was for Bevy engine's server side rendering.")]
|
||||
#[serde(rename = "convert_bvh_to_workflow")]
|
||||
ConvertBvhToWorkflow,
|
||||
}
|
||||
@@ -55,28 +73,30 @@ impl_mysql_from_row!(InferenceCategory);
|
||||
impl InferenceCategory {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::DeprecatedField => "deprecated_field",
|
||||
Self::LipsyncAnimation => "lipsync_animation",
|
||||
Self::TextToSpeech => "text_to_speech",
|
||||
Self::VoiceConversion => "voice_conversion",
|
||||
Self::VideoFilter => "video_filter",
|
||||
Self::ImageGeneration => "image_generation",
|
||||
Self::Mocap => "mocap",
|
||||
Self::Workflow => "workflow",
|
||||
Self::FormatConversion => "format_conversion",
|
||||
Self::VideoFilter => "video_filter",
|
||||
Self::ConvertBvhToWorkflow => "convert_bvh_to_workflow",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"deprecated_field" => Ok(Self::DeprecatedField),
|
||||
"lipsync_animation" => Ok(Self::LipsyncAnimation),
|
||||
"text_to_speech" => Ok(Self::TextToSpeech),
|
||||
"voice_conversion" => Ok(Self::VoiceConversion),
|
||||
"video_filter" => Ok(Self::VideoFilter),
|
||||
"image_generation" => Ok(Self::ImageGeneration),
|
||||
"mocap" => Ok(Self::Mocap),
|
||||
"workflow" => Ok(Self::Workflow),
|
||||
"format_conversion" => Ok(Self::FormatConversion),
|
||||
"video_filter" => Ok(Self::VideoFilter),
|
||||
"convert_bvh_to_workflow" => Ok(Self::ConvertBvhToWorkflow),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
@@ -86,14 +106,15 @@ impl InferenceCategory {
|
||||
// NB: BTreeSet is sorted
|
||||
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
|
||||
BTreeSet::from([
|
||||
Self::DeprecatedField,
|
||||
Self::LipsyncAnimation,
|
||||
Self::TextToSpeech,
|
||||
Self::VoiceConversion,
|
||||
Self::VideoFilter,
|
||||
Self::ImageGeneration,
|
||||
Self::Mocap,
|
||||
Self::Workflow,
|
||||
Self::FormatConversion,
|
||||
Self::VideoFilter,
|
||||
Self::ConvertBvhToWorkflow,
|
||||
])
|
||||
}
|
||||
@@ -109,40 +130,43 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(InferenceCategory::DeprecatedField, "deprecated_field");
|
||||
assert_serialization(InferenceCategory::LipsyncAnimation, "lipsync_animation");
|
||||
assert_serialization(InferenceCategory::TextToSpeech, "text_to_speech");
|
||||
assert_serialization(InferenceCategory::VoiceConversion, "voice_conversion");
|
||||
assert_serialization(InferenceCategory::VideoFilter, "video_filter");
|
||||
assert_serialization(InferenceCategory::ImageGeneration, "image_generation");
|
||||
assert_serialization(InferenceCategory::Mocap, "mocap");
|
||||
assert_serialization(InferenceCategory::Workflow, "workflow");
|
||||
assert_serialization(InferenceCategory::FormatConversion, "format_conversion");
|
||||
assert_serialization(InferenceCategory::VideoFilter, "video_filter");
|
||||
assert_serialization(InferenceCategory::ConvertBvhToWorkflow, "convert_bvh_to_workflow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(InferenceCategory::DeprecatedField.to_str(), "deprecated_field");
|
||||
assert_eq!(InferenceCategory::LipsyncAnimation.to_str(), "lipsync_animation");
|
||||
assert_eq!(InferenceCategory::TextToSpeech.to_str(), "text_to_speech");
|
||||
assert_eq!(InferenceCategory::VoiceConversion.to_str(), "voice_conversion");
|
||||
assert_eq!(InferenceCategory::VideoFilter.to_str(), "video_filter");
|
||||
assert_eq!(InferenceCategory::ImageGeneration.to_str(), "image_generation");
|
||||
assert_eq!(InferenceCategory::Mocap.to_str(), "mocap");
|
||||
assert_eq!(InferenceCategory::Workflow.to_str(), "workflow");
|
||||
assert_eq!(InferenceCategory::FormatConversion.to_str(), "format_conversion");
|
||||
assert_eq!(InferenceCategory::VideoFilter.to_str(), "video_filter");
|
||||
assert_eq!(InferenceCategory::ConvertBvhToWorkflow.to_str(), "convert_bvh_to_workflow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(InferenceCategory::from_str("deprecated_field").unwrap(), InferenceCategory::DeprecatedField);
|
||||
assert_eq!(InferenceCategory::from_str("lipsync_animation").unwrap(), InferenceCategory::LipsyncAnimation);
|
||||
assert_eq!(InferenceCategory::from_str("text_to_speech").unwrap(), InferenceCategory::TextToSpeech);
|
||||
assert_eq!(InferenceCategory::from_str("voice_conversion").unwrap(), InferenceCategory::VoiceConversion);
|
||||
assert_eq!(InferenceCategory::from_str("video_filter").unwrap(), InferenceCategory::VideoFilter);
|
||||
assert_eq!(InferenceCategory::from_str("image_generation").unwrap(), InferenceCategory::ImageGeneration);
|
||||
assert_eq!(InferenceCategory::from_str("mocap").unwrap(), InferenceCategory::Mocap);
|
||||
assert_eq!(InferenceCategory::from_str("workflow").unwrap(), InferenceCategory::Workflow);
|
||||
assert_eq!(InferenceCategory::from_str("format_conversion").unwrap(), InferenceCategory::FormatConversion);
|
||||
assert_eq!(InferenceCategory::from_str("video_filter").unwrap(), InferenceCategory::VideoFilter);
|
||||
assert_eq!(InferenceCategory::from_str("convert_bvh_to_workflow").unwrap(), InferenceCategory::ConvertBvhToWorkflow);
|
||||
}
|
||||
|
||||
@@ -150,15 +174,16 @@ mod tests {
|
||||
fn all_variants() {
|
||||
// Static check
|
||||
let mut variants = InferenceCategory::all_variants();
|
||||
assert_eq!(variants.len(), 9);
|
||||
assert_eq!(variants.len(), 10);
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::DeprecatedField));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::LipsyncAnimation));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::TextToSpeech));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::VoiceConversion));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::VideoFilter));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::ImageGeneration));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::Mocap));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::Workflow));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::FormatConversion));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::VideoFilter));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::ConvertBvhToWorkflow));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
|
||||
|
||||
@@ -15,11 +15,21 @@ use strum::EnumIter;
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum InferenceJobType {
|
||||
/// Job that converts bevy to workflow files
|
||||
#[serde(rename = "bevy_to_workflow")]
|
||||
BevyToWorkflow,
|
||||
/// Storyteller Studio and Video Style Transfer Jobs (which we may want to split).
|
||||
/// These run in Comfy.
|
||||
/// TODO(bt,2024-07-15): We may segregate these two job types in the future
|
||||
VideoRender,
|
||||
|
||||
/// Live Portrait Jobs.
|
||||
/// These run in Comfy.
|
||||
LivePortrait,
|
||||
|
||||
/// Voice jobs that use GPT-Sovits
|
||||
GptSovits,
|
||||
|
||||
/// Jobs that run ComfyUI workflows
|
||||
/// This is actually just for Video Style Transfer and Storyteller Studio.
|
||||
#[deprecated(note = "Use VideoRender instead.")]
|
||||
ComfyUi,
|
||||
|
||||
/// A job that turns "FBX" game engine files into "GLTF" files (Bevy-compatible).
|
||||
@@ -29,10 +39,6 @@ pub enum InferenceJobType {
|
||||
/// Process a video into BVH mocap animation data for game engines
|
||||
MocapNet,
|
||||
|
||||
/// Re-render a video is a video style transfer algorithm. We developed code
|
||||
/// around it, but chose to develop AnimateDiff / ComfyUI support instead.
|
||||
RerenderAVideo,
|
||||
|
||||
/// RVC is a voice conversion model. RVCv2 is the most popular such model currently.
|
||||
#[serde(rename = "rvc_v2")]
|
||||
RvcV2,
|
||||
@@ -58,6 +64,18 @@ pub enum InferenceJobType {
|
||||
/// (i.e. when we backfill the database column and make it non-nullable)
|
||||
#[default]
|
||||
Unknown,
|
||||
|
||||
/// DEPRECATED. DO NOT USE.
|
||||
/// Job that converts bevy to workflow files
|
||||
#[deprecated(note = "This was for Bevy engine's server side rendering.")]
|
||||
#[serde(rename = "bevy_to_workflow")]
|
||||
BevyToWorkflow,
|
||||
|
||||
#[deprecated(note = "This was for ReRenderAVideo, which we never productionized.")]
|
||||
/// DEPRECATED. DO NOT USE.
|
||||
/// Re-render a video is a video style transfer algorithm. We developed code
|
||||
/// around it, but chose to develop AnimateDiff / ComfyUI support instead.
|
||||
RerenderAVideo,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -68,11 +86,12 @@ impl_mysql_enum_coders!(InferenceJobType);
|
||||
impl InferenceJobType {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::BevyToWorkflow => "bevy_to_workflow",
|
||||
Self::VideoRender => "video_render",
|
||||
Self::LivePortrait => "live_portrait",
|
||||
Self::GptSovits => "gpt_sovits",
|
||||
Self::ComfyUi => "comfy_ui",
|
||||
Self::ConvertFbxToGltf => "convert_fbx_gltf",
|
||||
Self::MocapNet => "mocap_net",
|
||||
Self::RerenderAVideo => "rerender_a_video",
|
||||
Self::RvcV2 => "rvc_v2",
|
||||
Self::SadTalker => "sad_talker",
|
||||
Self::SoVitsSvc => "so_vits_svc",
|
||||
@@ -80,16 +99,19 @@ impl InferenceJobType {
|
||||
Self::StyleTTS2 => "styletts2",
|
||||
Self::Tacotron2 => "tacotron2",
|
||||
Self::Unknown => "unknown",
|
||||
Self::BevyToWorkflow => "bevy_to_workflow",
|
||||
Self::RerenderAVideo => "rerender_a_video",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"bevy_to_workflow" => Ok(Self::BevyToWorkflow),
|
||||
"video_render" => Ok(Self::VideoRender),
|
||||
"live_portrait" => Ok(Self::LivePortrait),
|
||||
"gpt_sovits" => Ok(Self::GptSovits),
|
||||
"comfy_ui" => Ok(Self::ComfyUi),
|
||||
"convert_fbx_gltf" => Ok(Self::ConvertFbxToGltf),
|
||||
"mocap_net" => Ok(Self::MocapNet),
|
||||
"rerender_a_video" => Ok(Self::RerenderAVideo),
|
||||
"rvc_v2" => Ok(Self::RvcV2),
|
||||
"sad_talker" => Ok(Self::SadTalker),
|
||||
"so_vits_svc" => Ok(Self::SoVitsSvc),
|
||||
@@ -97,6 +119,8 @@ impl InferenceJobType {
|
||||
"styletts2" => Ok(Self::StyleTTS2),
|
||||
"tacotron2" => Ok(Self::Tacotron2),
|
||||
"unknown" => Ok(Self::Unknown),
|
||||
"bevy_to_workflow" => Ok(Self::BevyToWorkflow),
|
||||
"rerender_a_video" => Ok(Self::RerenderAVideo),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -105,11 +129,12 @@ impl InferenceJobType {
|
||||
// NB: BTreeSet is sorted
|
||||
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
|
||||
BTreeSet::from([
|
||||
Self::BevyToWorkflow,
|
||||
Self::VideoRender,
|
||||
Self::LivePortrait,
|
||||
Self::GptSovits,
|
||||
Self::ComfyUi,
|
||||
Self::ConvertFbxToGltf,
|
||||
Self::MocapNet,
|
||||
Self::RerenderAVideo,
|
||||
Self::RvcV2,
|
||||
Self::SadTalker,
|
||||
Self::SoVitsSvc,
|
||||
@@ -117,6 +142,8 @@ impl InferenceJobType {
|
||||
Self::StyleTTS2,
|
||||
Self::Tacotron2,
|
||||
Self::Unknown,
|
||||
Self::BevyToWorkflow,
|
||||
Self::RerenderAVideo,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -136,11 +163,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(InferenceJobType::BevyToWorkflow, "bevy_to_workflow");
|
||||
assert_serialization(InferenceJobType::VideoRender, "video_render");
|
||||
assert_serialization(InferenceJobType::LivePortrait, "live_portrait");
|
||||
assert_serialization(InferenceJobType::GptSovits, "gpt_sovits");
|
||||
assert_serialization(InferenceJobType::ComfyUi, "comfy_ui");
|
||||
assert_serialization(InferenceJobType::ConvertFbxToGltf, "convert_fbx_gltf");
|
||||
assert_serialization(InferenceJobType::MocapNet, "mocap_net");
|
||||
assert_serialization(InferenceJobType::RerenderAVideo, "rerender_a_video");
|
||||
assert_serialization(InferenceJobType::RvcV2, "rvc_v2");
|
||||
assert_serialization(InferenceJobType::SadTalker, "sad_talker");
|
||||
assert_serialization(InferenceJobType::SoVitsSvc, "so_vits_svc");
|
||||
@@ -148,15 +176,18 @@ mod tests {
|
||||
assert_serialization(InferenceJobType::StyleTTS2, "styletts2");
|
||||
assert_serialization(InferenceJobType::Tacotron2, "tacotron2");
|
||||
assert_serialization(InferenceJobType::Unknown, "unknown");
|
||||
assert_serialization(InferenceJobType::BevyToWorkflow, "bevy_to_workflow");
|
||||
assert_serialization(InferenceJobType::RerenderAVideo, "rerender_a_video");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(InferenceJobType::BevyToWorkflow.to_str(), "bevy_to_workflow");
|
||||
assert_eq!(InferenceJobType::VideoRender.to_str(), "video_render");
|
||||
assert_eq!(InferenceJobType::LivePortrait.to_str(), "live_portrait");
|
||||
assert_eq!(InferenceJobType::GptSovits.to_str(), "gpt_sovits");
|
||||
assert_eq!(InferenceJobType::ComfyUi.to_str(), "comfy_ui");
|
||||
assert_eq!(InferenceJobType::ConvertFbxToGltf.to_str(), "convert_fbx_gltf");
|
||||
assert_eq!(InferenceJobType::MocapNet.to_str(), "mocap_net");
|
||||
assert_eq!(InferenceJobType::RerenderAVideo.to_str(), "rerender_a_video");
|
||||
assert_eq!(InferenceJobType::RvcV2.to_str(), "rvc_v2");
|
||||
assert_eq!(InferenceJobType::SadTalker.to_str(), "sad_talker");
|
||||
assert_eq!(InferenceJobType::SoVitsSvc.to_str(), "so_vits_svc");
|
||||
@@ -164,15 +195,18 @@ mod tests {
|
||||
assert_eq!(InferenceJobType::StyleTTS2.to_str(), "styletts2");
|
||||
assert_eq!(InferenceJobType::Tacotron2.to_str(), "tacotron2");
|
||||
assert_eq!(InferenceJobType::Unknown.to_str(), "unknown");
|
||||
assert_eq!(InferenceJobType::BevyToWorkflow.to_str(), "bevy_to_workflow");
|
||||
assert_eq!(InferenceJobType::RerenderAVideo.to_str(), "rerender_a_video");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(InferenceJobType::from_str("bevy_to_workflow").unwrap(), InferenceJobType::BevyToWorkflow);
|
||||
assert_eq!(InferenceJobType::from_str("video_render").unwrap(), InferenceJobType::VideoRender);
|
||||
assert_eq!(InferenceJobType::from_str("live_portrait").unwrap(), InferenceJobType::LivePortrait);
|
||||
assert_eq!(InferenceJobType::from_str("gpt_sovits").unwrap(), InferenceJobType::GptSovits);
|
||||
assert_eq!(InferenceJobType::from_str("comfy_ui").unwrap(), InferenceJobType::ComfyUi);
|
||||
assert_eq!(InferenceJobType::from_str("convert_fbx_gltf").unwrap(), InferenceJobType::ConvertFbxToGltf);
|
||||
assert_eq!(InferenceJobType::from_str("mocap_net").unwrap(), InferenceJobType::MocapNet);
|
||||
assert_eq!(InferenceJobType::from_str("rerender_a_video").unwrap(), InferenceJobType::RerenderAVideo);
|
||||
assert_eq!(InferenceJobType::from_str("rvc_v2").unwrap(), InferenceJobType::RvcV2);
|
||||
assert_eq!(InferenceJobType::from_str("sad_talker").unwrap(), InferenceJobType::SadTalker);
|
||||
assert_eq!(InferenceJobType::from_str("so_vits_svc").unwrap(), InferenceJobType::SoVitsSvc);
|
||||
@@ -180,18 +214,21 @@ mod tests {
|
||||
assert_eq!(InferenceJobType::from_str("styletts2").unwrap(), InferenceJobType::StyleTTS2);
|
||||
assert_eq!(InferenceJobType::from_str("tacotron2").unwrap(), InferenceJobType::Tacotron2);
|
||||
assert_eq!(InferenceJobType::from_str("unknown").unwrap(), InferenceJobType::Unknown);
|
||||
assert_eq!(InferenceJobType::from_str("bevy_to_workflow").unwrap(), InferenceJobType::BevyToWorkflow);
|
||||
assert_eq!(InferenceJobType::from_str("rerender_a_video").unwrap(), InferenceJobType::RerenderAVideo);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
// Static check
|
||||
let mut variants = InferenceJobType::all_variants();
|
||||
assert_eq!(variants.len(), 12);
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::BevyToWorkflow));
|
||||
assert_eq!(variants.len(), 15);
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::VideoRender));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::LivePortrait));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::GptSovits));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::ComfyUi));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::ConvertFbxToGltf));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::MocapNet));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::RerenderAVideo));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::RvcV2));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::SadTalker));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::SoVitsSvc));
|
||||
@@ -199,6 +236,8 @@ mod tests {
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::StyleTTS2));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::Tacotron2));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::Unknown));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::BevyToWorkflow));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceJobType::RerenderAVideo));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
|
||||
// Generated check
|
||||
|
||||
@@ -17,6 +17,10 @@ use strum::EnumIter;
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
|
||||
pub enum InferenceModelType {
|
||||
// TODO(bt,2024-07-15): This is too generic. We probably need "StorytellerStudio", "LivePortrait", etc.
|
||||
#[serde(rename = "comfy_ui")]
|
||||
ComfyUi,
|
||||
|
||||
#[serde(rename = "rvc_v2")]
|
||||
RvcV2,
|
||||
// NB: sad_talker does use user-supplied models, so there is no "model token"
|
||||
@@ -37,8 +41,6 @@ pub enum InferenceModelType {
|
||||
StableDiffusion,
|
||||
#[serde(rename = "mocap_net")]
|
||||
MocapNet,
|
||||
#[serde(rename = "comfy_ui")]
|
||||
ComfyUi,
|
||||
#[serde(rename = "styletts2")]
|
||||
StyleTTS2,
|
||||
/// A job that turns "FBX" game engine files into "GLTF" files (Bevy-compatible).
|
||||
|
||||
@@ -21,17 +21,39 @@ pub enum MediaFileEngineCategory {
|
||||
/// A 3D character model.
|
||||
Character,
|
||||
|
||||
/// A 3D animation.
|
||||
/// A 3D non-humanoid model, e.g. dragon, wolf, slime creature, etc.
|
||||
/// These may or may not have a skeleton that can be animated with IK/FK.
|
||||
Creature,
|
||||
|
||||
/// A 3D skeletal animation sequence that can be applied to a character,
|
||||
/// creature, etc. Typically, these use Mixamo or Move.ai.
|
||||
Animation,
|
||||
|
||||
/// A facial blend shape / shape key animation.
|
||||
/// A facial blend shape / shape key animation. Currently, these
|
||||
/// are 100% ARKit.
|
||||
Expression,
|
||||
|
||||
/// A large 3D object that can be used as a backdrop for a scene,
|
||||
/// a.k.a. "set", "stage", etc. These are typically self-contained
|
||||
/// locations, buildings, or environments.
|
||||
Location,
|
||||
|
||||
/// All items used to add atmosphere to a scene, e.g. furniture, plants,
|
||||
/// vehicles, radios, and certain props. (We'll reserve the word props for
|
||||
/// "hand props" later.)
|
||||
SetDressing,
|
||||
|
||||
/// A 3D object that doesn't fit with the other types.
|
||||
Object,
|
||||
|
||||
/// A 3D skybox.
|
||||
Skybox,
|
||||
|
||||
/// An Image Plane (texture that spawns as an object)
|
||||
ImagePlane,
|
||||
|
||||
/// A Video Plane (texture that spawns as an object)
|
||||
VideoPlane,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -45,10 +67,15 @@ impl MediaFileEngineCategory {
|
||||
match self {
|
||||
Self::Scene => "scene",
|
||||
Self::Character => "character",
|
||||
Self::Creature => "creature",
|
||||
Self::Animation => "animation",
|
||||
Self::Expression => "expression",
|
||||
Self::Location => "location",
|
||||
Self::SetDressing => "set_dressing",
|
||||
Self::Object => "object",
|
||||
Self::Skybox => "skybox",
|
||||
Self::ImagePlane => "image_plane",
|
||||
Self::VideoPlane => "video_plane",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,10 +83,15 @@ impl MediaFileEngineCategory {
|
||||
match value {
|
||||
"scene" => Ok(Self::Scene),
|
||||
"character" => Ok(Self::Character),
|
||||
"creature" => Ok(Self::Creature),
|
||||
"animation" => Ok(Self::Animation),
|
||||
"expression" => Ok(Self::Expression),
|
||||
"location" => Ok(Self::Location),
|
||||
"set_dressing" => Ok(Self::SetDressing),
|
||||
"object" => Ok(Self::Object),
|
||||
"skybox" => Ok(Self::Skybox),
|
||||
"image_plane" => Ok(Self::ImagePlane),
|
||||
"video_plane" => Ok(Self::VideoPlane),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -70,10 +102,15 @@ impl MediaFileEngineCategory {
|
||||
BTreeSet::from([
|
||||
Self::Scene,
|
||||
Self::Character,
|
||||
Self::Creature,
|
||||
Self::Animation,
|
||||
Self::Expression,
|
||||
Self::Location,
|
||||
Self::SetDressing,
|
||||
Self::Object,
|
||||
Self::Skybox,
|
||||
Self::ImagePlane,
|
||||
Self::VideoPlane,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -90,43 +127,63 @@ mod tests {
|
||||
fn test_serialization() {
|
||||
assert_serialization(MediaFileEngineCategory::Scene, "scene");
|
||||
assert_serialization(MediaFileEngineCategory::Character, "character");
|
||||
assert_serialization(MediaFileEngineCategory::Creature, "creature");
|
||||
assert_serialization(MediaFileEngineCategory::Animation, "animation");
|
||||
assert_serialization(MediaFileEngineCategory::Expression, "expression");
|
||||
assert_serialization(MediaFileEngineCategory::Location, "location");
|
||||
assert_serialization(MediaFileEngineCategory::SetDressing, "set_dressing");
|
||||
assert_serialization(MediaFileEngineCategory::Object, "object");
|
||||
assert_serialization(MediaFileEngineCategory::Skybox, "skybox");
|
||||
assert_serialization(MediaFileEngineCategory::ImagePlane, "image_plane");
|
||||
assert_serialization(MediaFileEngineCategory::VideoPlane, "video_plane");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_str() {
|
||||
assert_eq!(MediaFileEngineCategory::Scene.to_str(), "scene");
|
||||
assert_eq!(MediaFileEngineCategory::Character.to_str(), "character");
|
||||
assert_eq!(MediaFileEngineCategory::Creature.to_str(), "creature");
|
||||
assert_eq!(MediaFileEngineCategory::Animation.to_str(), "animation");
|
||||
assert_eq!(MediaFileEngineCategory::Expression.to_str(), "expression");
|
||||
assert_eq!(MediaFileEngineCategory::Location.to_str(), "location");
|
||||
assert_eq!(MediaFileEngineCategory::SetDressing.to_str(), "set_dressing");
|
||||
assert_eq!(MediaFileEngineCategory::Object.to_str(), "object");
|
||||
assert_eq!(MediaFileEngineCategory::Skybox.to_str(), "skybox");
|
||||
assert_eq!(MediaFileEngineCategory::ImagePlane.to_str(), "image_plane");
|
||||
assert_eq!(MediaFileEngineCategory::VideoPlane.to_str(), "video_plane");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(MediaFileEngineCategory::from_str("scene").unwrap(), MediaFileEngineCategory::Scene);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("character").unwrap(), MediaFileEngineCategory::Character);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("creature").unwrap(), MediaFileEngineCategory::Creature);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("animation").unwrap(), MediaFileEngineCategory::Animation);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("expression").unwrap(), MediaFileEngineCategory::Expression);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("location").unwrap(), MediaFileEngineCategory::Location);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("set_dressing").unwrap(), MediaFileEngineCategory::SetDressing);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("object").unwrap(), MediaFileEngineCategory::Object);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("skybox").unwrap(), MediaFileEngineCategory::Skybox);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("image_plane").unwrap(), MediaFileEngineCategory::ImagePlane);
|
||||
assert_eq!(MediaFileEngineCategory::from_str("video_plane").unwrap(), MediaFileEngineCategory::VideoPlane);
|
||||
assert!(MediaFileEngineCategory::from_str("foo").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = MediaFileEngineCategory::all_variants();
|
||||
assert_eq!(variants.len(), 6);
|
||||
assert_eq!(variants.len(), 11);
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Scene));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Character));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Creature));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Animation));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Expression));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Location));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::SetDressing));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Object));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::Skybox));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::ImagePlane));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileEngineCategory::VideoPlane));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ pub enum MediaFileOriginModelType {
|
||||
|
||||
#[serde(rename = "stable_diffusion_1_5")]
|
||||
StableDiffusion15,
|
||||
|
||||
#[serde(rename = "gpt_sovits")]
|
||||
GptSovits,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -67,7 +70,8 @@ impl MediaFileOriginModelType {
|
||||
Self::MocapNet => "mocap_net",
|
||||
Self::ComfyUi => "comfy_ui",
|
||||
Self::StyleTTS2 => "styletts2",
|
||||
Self::StableDiffusion15 => "stable_diffusion_1_5"
|
||||
Self::StableDiffusion15 => "stable_diffusion_1_5",
|
||||
Self::GptSovits => "gpt_sovits",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +87,7 @@ impl MediaFileOriginModelType {
|
||||
"comfy_ui" => Ok(Self::ComfyUi),
|
||||
"styletts2" => Ok(Self::StyleTTS2),
|
||||
"stable_diffusion_1_5" => Ok(Self::StableDiffusion15),
|
||||
"gpt_sovits" => Ok(Self::GptSovits),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -100,7 +105,8 @@ impl MediaFileOriginModelType {
|
||||
Self::MocapNet,
|
||||
Self::ComfyUi,
|
||||
Self::StyleTTS2,
|
||||
Self::StableDiffusion15
|
||||
Self::StableDiffusion15,
|
||||
Self::GptSovits,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -130,6 +136,7 @@ mod tests {
|
||||
assert_eq!(MediaFileOriginModelType::ComfyUi.to_str(), "comfy_ui");
|
||||
assert_eq!(MediaFileOriginModelType::StyleTTS2.to_str(), "styletts2");
|
||||
assert_eq!(MediaFileOriginModelType::StableDiffusion15.to_str(), "stable_diffusion_1_5");
|
||||
assert_eq!(MediaFileOriginModelType::GptSovits.to_str(), "gpt_sovits");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -144,13 +151,14 @@ mod tests {
|
||||
assert_eq!(MediaFileOriginModelType::from_str("comfy_ui").unwrap(), MediaFileOriginModelType::ComfyUi);
|
||||
assert_eq!(MediaFileOriginModelType::from_str("styletts2").unwrap(), MediaFileOriginModelType::StyleTTS2);
|
||||
assert_eq!(MediaFileOriginModelType::from_str("stable_diffusion_1_5").unwrap(), MediaFileOriginModelType::StableDiffusion15);
|
||||
assert_eq!(MediaFileOriginModelType::from_str("gpt_sovits").unwrap(), MediaFileOriginModelType::GptSovits);
|
||||
assert!(MediaFileOriginModelType::from_str("foo").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = MediaFileOriginModelType::all_variants();
|
||||
assert_eq!(variants.len(), 10);
|
||||
assert_eq!(variants.len(), 11);
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::RvcV2));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::SadTalker));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::SoVitsSvc));
|
||||
@@ -161,6 +169,7 @@ mod tests {
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::ComfyUi));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::StyleTTS2));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::StableDiffusion15));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::GptSovits));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,17 @@ use utoipa::ToSchema;
|
||||
pub enum MediaFileType {
|
||||
// TODO(bt): Deprecate and split into audio mime types; use media_class to represent broadly
|
||||
/// Audio files: wav, mp3, etc.
|
||||
#[deprecated]
|
||||
Audio,
|
||||
|
||||
// TODO(bt): Deprecate and split into image mime types; use media_class to represent broadly
|
||||
/// Image files: png, jpeg, etc.
|
||||
#[deprecated]
|
||||
Image,
|
||||
|
||||
// TODO(bt): Deprecate and split into video mime types; use media_class to represent broadly
|
||||
/// Video files: mp4, etc.
|
||||
#[deprecated]
|
||||
Video,
|
||||
|
||||
/// BVH files (for Bevy)
|
||||
@@ -61,6 +64,18 @@ pub enum MediaFileType {
|
||||
|
||||
/// CSV format. (We use these for ArKit)
|
||||
Csv,
|
||||
|
||||
/// Jpeg images
|
||||
Jpg,
|
||||
|
||||
/// Png images
|
||||
Png,
|
||||
|
||||
/// Gif images
|
||||
Gif,
|
||||
|
||||
/// Mp4 videos
|
||||
Mp4
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -85,6 +100,10 @@ impl MediaFileType {
|
||||
Self::Vmd => "vmd",
|
||||
Self::Pmx => "pmx",
|
||||
Self::Csv => "csv",
|
||||
Self::Jpg => "jpg",
|
||||
Self::Png => "png",
|
||||
Self::Gif => "gif",
|
||||
Self::Mp4 => "mp4",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +122,10 @@ impl MediaFileType {
|
||||
"vmd" => Ok(Self::Vmd),
|
||||
"pmx" => Ok(Self::Pmx),
|
||||
"csv" => Ok(Self::Csv),
|
||||
"jpg" => Ok(Self::Jpg),
|
||||
"png" => Ok(Self::Png),
|
||||
"gif" => Ok(Self::Gif),
|
||||
"mp4" => Ok(Self::Mp4),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -124,6 +147,10 @@ impl MediaFileType {
|
||||
Self::Vmd,
|
||||
Self::Pmx,
|
||||
Self::Csv,
|
||||
Self::Jpg,
|
||||
Self::Png,
|
||||
Self::Gif,
|
||||
Self::Mp4,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -151,6 +178,10 @@ mod tests {
|
||||
assert_serialization(MediaFileType::Vmd, "vmd");
|
||||
assert_serialization(MediaFileType::Pmx, "pmx");
|
||||
assert_serialization(MediaFileType::Csv, "csv");
|
||||
assert_serialization(MediaFileType::Jpg, "jpg");
|
||||
assert_serialization(MediaFileType::Png, "png");
|
||||
assert_serialization(MediaFileType::Gif, "gif");
|
||||
assert_serialization(MediaFileType::Mp4, "mp4");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +203,10 @@ mod tests {
|
||||
assert_eq!(MediaFileType::Vmd.to_str(), "vmd");
|
||||
assert_eq!(MediaFileType::Pmx.to_str(), "pmx");
|
||||
assert_eq!(MediaFileType::Csv.to_str(), "csv");
|
||||
assert_eq!(MediaFileType::Jpg.to_str(), "jpg");
|
||||
assert_eq!(MediaFileType::Png.to_str(), "png");
|
||||
assert_eq!(MediaFileType::Gif.to_str(), "gif");
|
||||
assert_eq!(MediaFileType::Mp4.to_str(), "mp4");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -189,6 +224,10 @@ mod tests {
|
||||
assert_eq!(MediaFileType::from_str("vmd").unwrap(), MediaFileType::Vmd);
|
||||
assert_eq!(MediaFileType::from_str("pmx").unwrap(), MediaFileType::Pmx);
|
||||
assert_eq!(MediaFileType::from_str("csv").unwrap(), MediaFileType::Csv);
|
||||
assert_eq!(MediaFileType::from_str("jpg").unwrap(), MediaFileType::Jpg);
|
||||
assert_eq!(MediaFileType::from_str("png").unwrap(), MediaFileType::Png);
|
||||
assert_eq!(MediaFileType::from_str("gif").unwrap(), MediaFileType::Gif);
|
||||
assert_eq!(MediaFileType::from_str("mp4").unwrap(), MediaFileType::Mp4);
|
||||
assert!(MediaFileType::from_str("foo").is_err());
|
||||
}
|
||||
}
|
||||
@@ -199,7 +238,7 @@ mod tests {
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = MediaFileType::all_variants();
|
||||
assert_eq!(variants.len(), 13);
|
||||
assert_eq!(variants.len(), 17);
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Audio));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Image));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Video));
|
||||
@@ -213,6 +252,10 @@ mod tests {
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Vmd));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Pmx));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Csv));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Jpg));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Png));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Gif));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileType::Mp4));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,70 +9,77 @@ use utoipa::ToSchema;
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
|
||||
pub enum WeightsType {
|
||||
#[serde(rename = "hifigan_tt2")]
|
||||
HifiganTacotron2,
|
||||
#[serde(rename = "rvc_v2")]
|
||||
RvcV2,
|
||||
#[serde(rename = "sd_1.5")]
|
||||
StableDiffusion15,
|
||||
#[serde(rename = "sdxl")]
|
||||
StableDiffusionXL,
|
||||
#[serde(rename = "so_vits_svc")]
|
||||
SoVitsSvc,
|
||||
#[serde(rename = "tt2")]
|
||||
Tacotron2,
|
||||
#[serde(rename = "loRA")]
|
||||
LoRA,
|
||||
#[serde(rename = "vall_e")]
|
||||
VallE,
|
||||
#[serde(rename = "comfy_ui")]
|
||||
ComfyUi,
|
||||
#[serde(rename = "hifigan_tt2")]
|
||||
HifiganTacotron2,
|
||||
#[serde(rename = "rvc_v2")]
|
||||
RvcV2,
|
||||
#[serde(rename = "sd_1.5")]
|
||||
StableDiffusion15,
|
||||
#[serde(rename = "sdxl")]
|
||||
StableDiffusionXL,
|
||||
#[serde(rename = "so_vits_svc")]
|
||||
SoVitsSvc,
|
||||
#[serde(rename = "tt2")]
|
||||
Tacotron2,
|
||||
#[serde(rename = "loRA")]
|
||||
LoRA,
|
||||
#[serde(rename = "vall_e")]
|
||||
VallE,
|
||||
#[serde(rename = "comfy_ui")]
|
||||
ComfyUi,
|
||||
|
||||
/// NB: IN production these are filtered to `PublicWeightsType::Tacotron25`.
|
||||
#[serde(rename = "gpt_so_vits")]
|
||||
GptSoVits,
|
||||
}
|
||||
|
||||
|
||||
impl WeightsType {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::HifiganTacotron2 => "hifigan_tt2",
|
||||
Self::RvcV2 => "rvc_v2",
|
||||
Self::StableDiffusion15 => "sd_1.5",
|
||||
Self::StableDiffusionXL => "sdxl",
|
||||
Self::SoVitsSvc => "so_vits_svc",
|
||||
Self::Tacotron2 => "tt2",
|
||||
Self::LoRA => "loRA",
|
||||
Self::VallE => "vall_e",
|
||||
Self::ComfyUi => "comfy_ui",
|
||||
}
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::HifiganTacotron2 => "hifigan_tt2",
|
||||
Self::RvcV2 => "rvc_v2",
|
||||
Self::StableDiffusion15 => "sd_1.5",
|
||||
Self::StableDiffusionXL => "sdxl",
|
||||
Self::SoVitsSvc => "so_vits_svc",
|
||||
Self::Tacotron2 => "tt2",
|
||||
Self::LoRA => "loRA",
|
||||
Self::VallE => "vall_e",
|
||||
Self::ComfyUi => "comfy_ui",
|
||||
Self::GptSoVits => "gpt_so_vits",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"hifigan_tt2" => Ok(Self::HifiganTacotron2),
|
||||
"rvc_v2" => Ok(Self::RvcV2),
|
||||
"sd_1.5" => Ok(Self::StableDiffusion15),
|
||||
"sdxl" => Ok(Self::StableDiffusionXL),
|
||||
"so_vits_svc" => Ok(Self::SoVitsSvc),
|
||||
"tt2" => Ok(Self::Tacotron2),
|
||||
"loRA" => Ok(Self::LoRA),
|
||||
"vall_e" => Ok(Self::VallE),
|
||||
"comfy_ui" => Ok(Self::ComfyUi),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"hifigan_tt2" => Ok(Self::HifiganTacotron2),
|
||||
"rvc_v2" => Ok(Self::RvcV2),
|
||||
"sd_1.5" => Ok(Self::StableDiffusion15),
|
||||
"sdxl" => Ok(Self::StableDiffusionXL),
|
||||
"so_vits_svc" => Ok(Self::SoVitsSvc),
|
||||
"tt2" => Ok(Self::Tacotron2),
|
||||
"loRA" => Ok(Self::LoRA),
|
||||
"vall_e" => Ok(Self::VallE),
|
||||
"comfy_ui" => Ok(Self::ComfyUi),
|
||||
"gpt_so_vits" => Ok(Self::GptSoVits),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_variants() -> BTreeSet<Self> {
|
||||
BTreeSet::from([
|
||||
Self::HifiganTacotron2,
|
||||
Self::RvcV2,
|
||||
Self::StableDiffusion15,
|
||||
Self::StableDiffusionXL,
|
||||
Self::SoVitsSvc,
|
||||
Self::Tacotron2,
|
||||
Self::LoRA,
|
||||
Self::VallE,
|
||||
Self::ComfyUi,
|
||||
])
|
||||
}
|
||||
pub fn all_variants() -> BTreeSet<Self> {
|
||||
BTreeSet::from([
|
||||
Self::HifiganTacotron2,
|
||||
Self::RvcV2,
|
||||
Self::StableDiffusion15,
|
||||
Self::StableDiffusionXL,
|
||||
Self::SoVitsSvc,
|
||||
Self::Tacotron2,
|
||||
Self::LoRA,
|
||||
Self::VallE,
|
||||
Self::ComfyUi,
|
||||
Self::GptSoVits,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl_enum_display_and_debug_using_to_str!(WeightsType);
|
||||
@@ -84,44 +91,76 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_to_str() {
|
||||
assert_eq!(WeightsType::HifiganTacotron2.to_str(), "hifigan_tt2");
|
||||
assert_eq!(WeightsType::RvcV2.to_str(), "rvc_v2");
|
||||
assert_eq!(WeightsType::StableDiffusion15.to_str(), "sd_1.5");
|
||||
assert_eq!(WeightsType::StableDiffusionXL.to_str(), "sdxl");
|
||||
assert_eq!(WeightsType::SoVitsSvc.to_str(), "so_vits_svc");
|
||||
assert_eq!(WeightsType::Tacotron2.to_str(), "tt2");
|
||||
assert_eq!(WeightsType::LoRA.to_str(), "loRA");
|
||||
assert_eq!(WeightsType::VallE.to_str(), "vall_e");
|
||||
assert_eq!(WeightsType::ComfyUi.to_str(), "comfy_ui");
|
||||
fn test_to_str() {
|
||||
assert_eq!(WeightsType::HifiganTacotron2.to_str(), "hifigan_tt2");
|
||||
assert_eq!(WeightsType::RvcV2.to_str(), "rvc_v2");
|
||||
assert_eq!(WeightsType::StableDiffusion15.to_str(), "sd_1.5");
|
||||
assert_eq!(WeightsType::StableDiffusionXL.to_str(), "sdxl");
|
||||
assert_eq!(WeightsType::SoVitsSvc.to_str(), "so_vits_svc");
|
||||
assert_eq!(WeightsType::Tacotron2.to_str(), "tt2");
|
||||
assert_eq!(WeightsType::LoRA.to_str(), "loRA");
|
||||
assert_eq!(WeightsType::VallE.to_str(), "vall_e");
|
||||
assert_eq!(WeightsType::ComfyUi.to_str(), "comfy_ui");
|
||||
assert_eq!(WeightsType::GptSoVits.to_str(), "gpt_so_vits");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(WeightsType::from_str("hifigan_tt2").unwrap(), WeightsType::HifiganTacotron2);
|
||||
assert_eq!(WeightsType::from_str("rvc_v2").unwrap(), WeightsType::RvcV2);
|
||||
assert_eq!(WeightsType::from_str("sd_1.5").unwrap(), WeightsType::StableDiffusion15);
|
||||
assert_eq!(WeightsType::from_str("sdxl").unwrap(), WeightsType::StableDiffusionXL);
|
||||
assert_eq!(WeightsType::from_str("so_vits_svc").unwrap(), WeightsType::SoVitsSvc);
|
||||
assert_eq!(WeightsType::from_str("tt2").unwrap(), WeightsType::Tacotron2);
|
||||
assert_eq!(WeightsType::from_str("loRA").unwrap(), WeightsType::LoRA);
|
||||
assert_eq!(WeightsType::from_str("vall_e").unwrap(), WeightsType::VallE);
|
||||
assert_eq!(WeightsType::from_str("comfy_ui").unwrap(), WeightsType::ComfyUi);
|
||||
assert_eq!(WeightsType::from_str("gpt_so_vits").unwrap(), WeightsType::GptSoVits);
|
||||
assert!(WeightsType::from_str("invalid").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_variants() {
|
||||
let variants = WeightsType::all_variants();
|
||||
assert_eq!(variants.len(), 10);
|
||||
assert!(variants.contains(&WeightsType::HifiganTacotron2));
|
||||
assert!(variants.contains(&WeightsType::RvcV2));
|
||||
assert!(variants.contains(&WeightsType::StableDiffusion15));
|
||||
assert!(variants.contains(&WeightsType::StableDiffusionXL));
|
||||
assert!(variants.contains(&WeightsType::SoVitsSvc));
|
||||
assert!(variants.contains(&WeightsType::Tacotron2));
|
||||
assert!(variants.contains(&WeightsType::LoRA));
|
||||
assert!(variants.contains(&WeightsType::VallE));
|
||||
assert!(variants.contains(&WeightsType::ComfyUi));
|
||||
assert!(variants.contains(&WeightsType::GptSoVits));
|
||||
}
|
||||
|
||||
mod mechanical_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn variant_length() {
|
||||
use strum::IntoEnumIterator;
|
||||
assert_eq!(WeightsType::all_variants().len(), WeightsType::iter().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(WeightsType::from_str("hifigan_tt2").unwrap(), WeightsType::HifiganTacotron2);
|
||||
assert_eq!(WeightsType::from_str("rvc_v2").unwrap(), WeightsType::RvcV2);
|
||||
assert_eq!(WeightsType::from_str("sd_1.5").unwrap(), WeightsType::StableDiffusion15);
|
||||
assert_eq!(WeightsType::from_str("sdxl").unwrap(), WeightsType::StableDiffusionXL);
|
||||
assert_eq!(WeightsType::from_str("so_vits_svc").unwrap(), WeightsType::SoVitsSvc);
|
||||
assert_eq!(WeightsType::from_str("tt2").unwrap(), WeightsType::Tacotron2);
|
||||
assert_eq!(WeightsType::from_str("loRA").unwrap(), WeightsType::LoRA);
|
||||
assert_eq!(WeightsType::from_str("vall_e").unwrap(), WeightsType::VallE);
|
||||
assert_eq!(WeightsType::from_str("comfy_ui").unwrap(), WeightsType::ComfyUi);
|
||||
assert!(WeightsType::from_str("invalid").is_err());
|
||||
fn round_trip() {
|
||||
for variant in WeightsType::all_variants() {
|
||||
assert_eq!(variant, WeightsType::from_str(variant.to_str()).unwrap());
|
||||
assert_eq!(variant, WeightsType::from_str(&format!("{}", variant)).unwrap());
|
||||
assert_eq!(variant, WeightsType::from_str(&format!("{:?}", variant)).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_variants() {
|
||||
let variants = WeightsType::all_variants();
|
||||
assert_eq!(variants.len(), 9);
|
||||
assert!(variants.contains(&WeightsType::HifiganTacotron2));
|
||||
assert!(variants.contains(&WeightsType::RvcV2));
|
||||
assert!(variants.contains(&WeightsType::StableDiffusion15));
|
||||
assert!(variants.contains(&WeightsType::StableDiffusionXL));
|
||||
assert!(variants.contains(&WeightsType::SoVitsSvc));
|
||||
assert!(variants.contains(&WeightsType::Tacotron2));
|
||||
assert!(variants.contains(&WeightsType::LoRA));
|
||||
assert!(variants.contains(&WeightsType::VallE));
|
||||
assert!(variants.contains(&WeightsType::ComfyUi));
|
||||
fn serialized_length_ok_for_database() {
|
||||
const MAX_LENGTH : usize = 16;
|
||||
for variant in WeightsType::all_variants() {
|
||||
let serialized = variant.to_str();
|
||||
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
|
||||
assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long", variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,10 +124,10 @@ mod tests {
|
||||
fn serialize() {
|
||||
let expected = "\"positive\"".to_string(); // NB: Quoted
|
||||
|
||||
assert_eq!(expected, toml::to_string(&UserRatingValue::Positive).unwrap());
|
||||
assert_eq!(expected, serde_json::to_string(&UserRatingValue::Positive).unwrap());
|
||||
|
||||
// Just to show this serializes the same as a string
|
||||
assert_eq!(expected, toml::to_string("positive").unwrap());
|
||||
assert_eq!(expected, serde_json::to_string("positive").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -112,10 +112,10 @@ mod tests {
|
||||
fn serialize() {
|
||||
let expected = "\"author\"".to_string(); // NB: Quoted
|
||||
|
||||
assert_eq!(expected, toml::to_string(&ViewAs::Author).unwrap());
|
||||
assert_eq!(expected, serde_json::to_string(&ViewAs::Author).unwrap());
|
||||
|
||||
// Just to show this serializes the same as a string
|
||||
assert_eq!(expected, toml::to_string("author").unwrap());
|
||||
assert_eq!(expected, serde_json::to_string("author").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -153,10 +153,10 @@ mod tests {
|
||||
fn serialize() {
|
||||
let expected = "\"public\"".to_string(); // NB: Quoted
|
||||
|
||||
assert_eq!(expected, toml::to_string(&Visibility::Public).unwrap());
|
||||
assert_eq!(expected, serde_json::to_string(&Visibility::Public).unwrap());
|
||||
|
||||
// Just to show this serializes the same as a string
|
||||
assert_eq!(expected, toml::to_string("public").unwrap());
|
||||
assert_eq!(expected, serde_json::to_string("public").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
pub mod premium_product;
|
||||
pub mod style_transfer;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod premium_product_name;
|
||||
@@ -0,0 +1,134 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// This enum is not backed by a particular database table.
|
||||
/// This is used to count premium product uses for free and paid users.
|
||||
///
|
||||
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PremiumProductName {
|
||||
// NB: These keys are kept short to preserve space
|
||||
#[serde(rename = "fa")]
|
||||
FaceAnimator,
|
||||
// NB: These keys are kept short to preserve space
|
||||
#[serde(rename = "fm")]
|
||||
FaceMirror,
|
||||
// NB: These keys are kept short to preserve space
|
||||
#[serde(rename = "lip")]
|
||||
Lipsync,
|
||||
// NB: These keys are kept short to preserve space
|
||||
#[serde(rename = "vst")]
|
||||
VideoStyleTransfer,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
impl_enum_display_and_debug_using_to_str!(PremiumProductName);
|
||||
//impl_mysql_enum_coders!(PremiumProductName);
|
||||
//impl_mysql_from_row!(PremiumProductName);
|
||||
|
||||
/// NB: Legacy API for older code.
|
||||
impl PremiumProductName {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::FaceAnimator => "fa",
|
||||
Self::FaceMirror => "fm",
|
||||
Self::Lipsync => "lip",
|
||||
Self::VideoStyleTransfer => "vst",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"fa" => Ok(Self::FaceAnimator),
|
||||
"fm" => Ok(Self::FaceMirror),
|
||||
"lip" => Ok(Self::Lipsync),
|
||||
"vst" => Ok(Self::VideoStyleTransfer),
|
||||
_ => Err(format!("Unknown PremiumProductName: {}", value)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_variants() -> BTreeSet<Self> {
|
||||
// NB: BTreeSet is sorted
|
||||
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
|
||||
BTreeSet::from([
|
||||
Self::FaceAnimator,
|
||||
Self::FaceMirror,
|
||||
Self::Lipsync,
|
||||
Self::VideoStyleTransfer,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::no_table::premium_product::premium_product_name::PremiumProductName;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod serde {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(PremiumProductName::FaceAnimator, "fa");
|
||||
assert_serialization(PremiumProductName::FaceMirror, "fm");
|
||||
assert_serialization(PremiumProductName::Lipsync, "lip");
|
||||
assert_serialization(PremiumProductName::VideoStyleTransfer, "vst");
|
||||
}
|
||||
|
||||
mod impl_methods {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(PremiumProductName::FaceAnimator.to_str(), "fa");
|
||||
assert_eq!(PremiumProductName::FaceMirror.to_str(), "fm");
|
||||
assert_eq!(PremiumProductName::Lipsync.to_str(), "lip");
|
||||
assert_eq!(PremiumProductName::VideoStyleTransfer.to_str(), "vst");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(PremiumProductName::from_str("fa").unwrap(), PremiumProductName::FaceAnimator);
|
||||
assert_eq!(PremiumProductName::from_str("fm").unwrap(), PremiumProductName::FaceMirror);
|
||||
assert_eq!(PremiumProductName::from_str("lip").unwrap(), PremiumProductName::Lipsync);
|
||||
assert_eq!(PremiumProductName::from_str("vst").unwrap(), PremiumProductName::VideoStyleTransfer);
|
||||
}
|
||||
}
|
||||
|
||||
mod manual_variant_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let variants = PremiumProductName::all_variants();
|
||||
assert_eq!(variants.len(), 4);
|
||||
}
|
||||
}
|
||||
|
||||
mod mechanical_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn variant_length() {
|
||||
use strum::IntoEnumIterator;
|
||||
assert_eq!(PremiumProductName::all_variants().len(), PremiumProductName::iter().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip() {
|
||||
for variant in PremiumProductName::all_variants() {
|
||||
assert_eq!(variant, PremiumProductName::from_str(variant.to_str()).unwrap());
|
||||
assert_eq!(variant, PremiumProductName::from_str(&format!("{}", variant)).unwrap());
|
||||
assert_eq!(variant, PremiumProductName::from_str(&format!("{:?}", variant)).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,10 @@ pub enum StyleTransferName {
|
||||
#[serde(rename = "realistic_cyberpunk")]
|
||||
RealisticCyberpunk,
|
||||
|
||||
// New Styles (2024-06-27)
|
||||
|
||||
#[serde(rename = "dreamer")] // TODO: Land this in Gitub
|
||||
Dreamer,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -130,6 +134,9 @@ impl StyleTransferName {
|
||||
Self::Dragonball => "dragonball",
|
||||
Self::RealisticMatrix => "realistic_matrix",
|
||||
Self::RealisticCyberpunk => "realistic_cyberpunk",
|
||||
|
||||
// New Styles (2024-06-27)
|
||||
Self::Dreamer => "dreamer",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +176,7 @@ impl StyleTransferName {
|
||||
"dragonball" => Ok(Self::Dragonball),
|
||||
"realistic_matrix" => Ok(Self::RealisticMatrix),
|
||||
"realistic_cyberpunk" => Ok(Self::RealisticCyberpunk),
|
||||
"dreamer" => Ok(Self::Dreamer),
|
||||
_ => Err(format!("Unknown StyleTransferName: {}", value)),
|
||||
}
|
||||
}
|
||||
@@ -209,6 +217,7 @@ impl StyleTransferName {
|
||||
Self::Dragonball => "31_dragonball.json",
|
||||
Self::RealisticMatrix => "32_realistic_matrix.json",
|
||||
Self::RealisticCyberpunk => "33_realistic_cyberpunk.json",
|
||||
Self::Dreamer => "34_dreamer.json",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +259,8 @@ impl StyleTransferName {
|
||||
Self::Dragonball,
|
||||
Self::RealisticMatrix,
|
||||
Self::RealisticCyberpunk,
|
||||
|
||||
Self::Dreamer,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -298,6 +309,8 @@ mod tests {
|
||||
assert_serialization(StyleTransferName::Dragonball, "dragonball");
|
||||
assert_serialization(StyleTransferName::RealisticMatrix, "realistic_matrix");
|
||||
assert_serialization(StyleTransferName::RealisticCyberpunk, "realistic_cyberpunk");
|
||||
|
||||
assert_serialization(StyleTransferName::Dreamer, "dreamer");
|
||||
}
|
||||
|
||||
mod impl_methods {
|
||||
@@ -339,6 +352,8 @@ mod tests {
|
||||
assert_eq!(StyleTransferName::Dragonball.to_str(), "dragonball");
|
||||
assert_eq!(StyleTransferName::RealisticMatrix.to_str(), "realistic_matrix");
|
||||
assert_eq!(StyleTransferName::RealisticCyberpunk.to_str(), "realistic_cyberpunk");
|
||||
|
||||
assert_eq!(StyleTransferName::Dreamer.to_str(), "dreamer");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -378,6 +393,8 @@ mod tests {
|
||||
assert_eq!(StyleTransferName::from_str("realistic_matrix").unwrap(), StyleTransferName::RealisticMatrix);
|
||||
assert_eq!(StyleTransferName::from_str("realistic_cyberpunk").unwrap(), StyleTransferName::RealisticCyberpunk);
|
||||
|
||||
assert_eq!(StyleTransferName::from_str("dreamer").unwrap(), StyleTransferName::Dreamer);
|
||||
|
||||
assert!(StyleTransferName::from_str("foo").is_err());
|
||||
}
|
||||
}
|
||||
@@ -388,7 +405,7 @@ mod tests {
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let variants = StyleTransferName::all_variants();
|
||||
assert_eq!(variants.len(), 33);
|
||||
assert_eq!(variants.len(), 34);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
use serde::Serialize;
|
||||
|
||||
pub fn to_toml<T: Serialize>(t: &T) -> String {
|
||||
toml::to_string(t)
|
||||
.expect("serialization error")
|
||||
.replace("\"", "") // JSON values are quoted, so we remove quotes
|
||||
match toml::to_string(t) {
|
||||
Ok(s) => s.replace("\"", ""), // JSON values are quoted, so we remove quotes
|
||||
Err(err) => {
|
||||
panic!("serialization error: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_json<T: Serialize>(t: &T) -> String {
|
||||
@@ -18,6 +21,7 @@ pub fn to_json<T: Serialize>(t: &T) -> String {
|
||||
/// This is useful for ensuring stability of serialization.
|
||||
pub fn assert_serialization<T: Serialize>(t: T, expected: &str) {
|
||||
// TODO: See if there's a way to check the sqlx serialization
|
||||
assert_eq!(&to_toml(&t), expected);
|
||||
// TODO(bt,2024-06-27): Something broke with serde toml serialization, so we're disabling it
|
||||
// assert_eq!(&to_toml(&t), expected);
|
||||
assert_eq!(&to_json(&t), expected);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
[package]
|
||||
name = "enums_public"
|
||||
edition = "2018"
|
||||
version = "0.0.1"
|
||||
authors = [
|
||||
"Brandon Thomas <bt@brand.io>",
|
||||
"Brandon Thomas <echelon@gmail.com>",
|
||||
]
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "enums_public"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[package.metadata.cargo-udeps.ignore]
|
||||
normal = ["my-workspace-hack"]
|
||||
|
||||
[dependencies]
|
||||
# Internal
|
||||
enums = { path = "../enums" }
|
||||
errors = { path = "../../lib/errors" }
|
||||
|
||||
# Workspace hack (faster compile times)
|
||||
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
|
||||
|
||||
# Serialization
|
||||
serde = "1.0.125"
|
||||
serde_derive = "1.0.125"
|
||||
|
||||
utoipa = { version = "4", features = ["chrono","actix_extras"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
# Enum utilities
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
|
||||
# Test serialization
|
||||
serde_json = "1.0.108"
|
||||
toml = "0.8.14"
|
||||
@@ -0,0 +1 @@
|
||||
pub mod public_inference_job_type;
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::by_table::generic_inference_jobs::inference_job_type::InferenceJobType;
|
||||
|
||||
/// Report certain jobs publicly as different from what we actually run.
|
||||
/// This is so we have an edge against the competition that might try to run
|
||||
/// the same models or workflows. This won't always make sense, but in some cases it will.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, Default, ToSchema, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PublicInferenceJobType {
|
||||
// Renamed enum variants
|
||||
|
||||
/// Instead of `InferenceJobType::LivePortrait` ("live_portrait")
|
||||
ActingFace,
|
||||
|
||||
/// Storyteller Studio and Video Style Transfer Jobs (which we may want to split).
|
||||
/// These run in Comfy.
|
||||
/// TODO(bt,2024-07-15): We may segregate these two job types in the future
|
||||
VideoRender,
|
||||
|
||||
GptSovits,
|
||||
|
||||
// Everything else is the same
|
||||
|
||||
/// Jobs that run ComfyUI workflows
|
||||
/// This is actually just for Video Style Transfer and Storyteller Studio.
|
||||
#[deprecated(note = "Use VideoRender instead.")]
|
||||
ComfyUi,
|
||||
|
||||
/// A job that turns "FBX" game engine files into "GLTF" files (Bevy-compatible).
|
||||
#[serde(rename = "convert_fbx_gltf")]
|
||||
ConvertFbxToGltf,
|
||||
|
||||
/// Process a video into BVH mocap animation data for game engines
|
||||
MocapNet,
|
||||
|
||||
/// RVC is a voice conversion model. RVCv2 is the most popular such model currently.
|
||||
#[serde(rename = "rvc_v2")]
|
||||
RvcV2,
|
||||
|
||||
/// SadTalker does image-to-video lip-syncing when given an audio file and image.
|
||||
SadTalker,
|
||||
|
||||
/// so-vits-svc voice conversion. This predates RVCv2.
|
||||
SoVitsSvc,
|
||||
|
||||
/// Stable diffusion image generation
|
||||
StableDiffusion,
|
||||
|
||||
/// StyleTTS2 is a zero shot multi-speaker TTS model.
|
||||
/// This job type should handle both speaker vector encoding and inference.
|
||||
#[serde(rename = "styletts2")]
|
||||
StyleTTS2,
|
||||
|
||||
/// TT2 Text to speech
|
||||
Tacotron2,
|
||||
|
||||
/// A value we may use in the future for historical jobs
|
||||
/// (i.e. when we backfill the database column and make it non-nullable)
|
||||
#[default]
|
||||
Unknown,
|
||||
|
||||
/// DEPRECATED. DO NOT USE.
|
||||
/// Job that converts bevy to workflow files
|
||||
#[deprecated(note = "This was for Bevy engine's server side rendering.")]
|
||||
#[serde(rename = "bevy_to_workflow")]
|
||||
BevyToWorkflow,
|
||||
|
||||
#[deprecated(note = "This was for ReRenderAVideo, which we never productionized.")]
|
||||
/// DEPRECATED. DO NOT USE.
|
||||
/// Re-render a video is a video style transfer algorithm. We developed code
|
||||
/// around it, but chose to develop AnimateDiff / ComfyUI support instead.
|
||||
RerenderAVideo,
|
||||
}
|
||||
|
||||
/// NB: Legacy API for older code.
|
||||
impl PublicInferenceJobType {
|
||||
|
||||
pub fn from_enum(inference_job_type: InferenceJobType) -> Self {
|
||||
match inference_job_type {
|
||||
// Renamed variants
|
||||
InferenceJobType::LivePortrait => Self::ActingFace,
|
||||
// Conserved variants
|
||||
InferenceJobType::VideoRender => Self::VideoRender,
|
||||
InferenceJobType::GptSovits => Self::GptSovits,
|
||||
InferenceJobType::ComfyUi => Self::ComfyUi,
|
||||
InferenceJobType::ConvertFbxToGltf => Self::ConvertFbxToGltf,
|
||||
InferenceJobType::MocapNet => Self::MocapNet,
|
||||
InferenceJobType::RvcV2 => Self::RvcV2,
|
||||
InferenceJobType::SadTalker => Self::SadTalker,
|
||||
InferenceJobType::SoVitsSvc => Self::SoVitsSvc,
|
||||
InferenceJobType::StableDiffusion => Self::StableDiffusion,
|
||||
InferenceJobType::StyleTTS2 => Self::StyleTTS2,
|
||||
InferenceJobType::Tacotron2 => Self::Tacotron2,
|
||||
InferenceJobType::Unknown => Self::Unknown,
|
||||
InferenceJobType::BevyToWorkflow => Self::BevyToWorkflow,
|
||||
InferenceJobType::RerenderAVideo => Self::RerenderAVideo,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_enum(&self) -> InferenceJobType {
|
||||
match self {
|
||||
// Renamed variants
|
||||
Self::ActingFace => InferenceJobType::LivePortrait,
|
||||
// Conserved variants
|
||||
Self::VideoRender => InferenceJobType::VideoRender,
|
||||
Self::GptSovits => InferenceJobType::GptSovits,
|
||||
Self::ComfyUi => InferenceJobType::ComfyUi,
|
||||
Self::ConvertFbxToGltf => InferenceJobType::ConvertFbxToGltf,
|
||||
Self::MocapNet => InferenceJobType::MocapNet,
|
||||
Self::RvcV2 => InferenceJobType::RvcV2,
|
||||
Self::SadTalker => InferenceJobType::SadTalker,
|
||||
Self::SoVitsSvc => InferenceJobType::SoVitsSvc,
|
||||
Self::StableDiffusion => InferenceJobType::StableDiffusion,
|
||||
Self::StyleTTS2 => InferenceJobType::StyleTTS2,
|
||||
Self::Tacotron2 => InferenceJobType::Tacotron2,
|
||||
Self::Unknown => InferenceJobType::Unknown,
|
||||
Self::BevyToWorkflow => InferenceJobType::BevyToWorkflow,
|
||||
Self::RerenderAVideo => InferenceJobType::RerenderAVideo,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::test_helpers::to_json;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn override_enums() -> &'static [PublicInferenceJobType; 1] {
|
||||
&[
|
||||
PublicInferenceJobType::ActingFace,
|
||||
]
|
||||
}
|
||||
|
||||
mod override_values {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn acting_face() {
|
||||
// Public --> Internal
|
||||
assert_eq!(PublicInferenceJobType::ActingFace.to_enum(), InferenceJobType::LivePortrait);
|
||||
assert_eq!(to_json(&PublicInferenceJobType::ActingFace.to_enum()), "live_portrait");
|
||||
|
||||
// Internal --> Public
|
||||
assert_eq!(PublicInferenceJobType::from_enum(InferenceJobType::LivePortrait), PublicInferenceJobType::ActingFace);
|
||||
assert_eq!(to_json(&PublicInferenceJobType::from_enum(InferenceJobType::LivePortrait)), "acting_face");
|
||||
}
|
||||
}
|
||||
|
||||
mod mechanical_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn public_to_internal() {
|
||||
let mut tested_count = 0;
|
||||
|
||||
for public_variant in PublicInferenceJobType::iter() {
|
||||
if public_variant == PublicInferenceJobType::ActingFace {
|
||||
continue; // Can't compare.
|
||||
}
|
||||
|
||||
// Round trip
|
||||
assert_eq!(public_variant, PublicInferenceJobType::from_enum(public_variant.to_enum()));
|
||||
|
||||
let internal_enum_variant = public_variant.to_enum();
|
||||
let internal_enum_string = to_json(&internal_enum_variant);
|
||||
let public_enum_string = to_json(&public_variant);
|
||||
|
||||
assert_eq!(internal_enum_string, public_enum_string);
|
||||
|
||||
tested_count += 1;
|
||||
}
|
||||
|
||||
assert!(tested_count > 1);
|
||||
assert_eq!(tested_count, PublicInferenceJobType::iter().len() - override_enums().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn internal_to_public() {
|
||||
let mut tested_count = 0;
|
||||
|
||||
for internal_variant in InferenceJobType::all_variants() {
|
||||
if internal_variant == InferenceJobType::LivePortrait {
|
||||
continue; // Can't compare.
|
||||
}
|
||||
|
||||
// Round trip
|
||||
assert_eq!(internal_variant, PublicInferenceJobType::from_enum(internal_variant).to_enum());
|
||||
|
||||
let public_enum_variant = PublicInferenceJobType::from_enum(internal_variant);
|
||||
let public_enum_string = to_json(&public_enum_variant);
|
||||
let internal_enum_string = to_json(&internal_variant);
|
||||
|
||||
// Same serialization
|
||||
assert_eq!(internal_enum_string, public_enum_string);
|
||||
|
||||
tested_count += 1;
|
||||
}
|
||||
|
||||
assert!(tested_count > 1);
|
||||
assert_eq!(tested_count, InferenceJobType::all_variants().len() - override_enums().len());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod generic_inference_jobs;
|
||||
pub mod model_weights;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod public_weights_types;
|
||||
@@ -0,0 +1,162 @@
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
|
||||
/// Report certain models publicly as different from what we actually use.
|
||||
/// This is so we have an edge against the competition that might try to run
|
||||
/// the same models. This won't always make sense, but in some cases it will.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, ToSchema, Debug)]
|
||||
pub enum PublicWeightsType {
|
||||
// Renamed enum variants
|
||||
|
||||
/// Instead of `WeightsType::GptSoVits` ("gpt_so_vits")
|
||||
#[serde(rename = "tacotron2.5")]
|
||||
Tacotron2_5,
|
||||
|
||||
// Everything else is the same
|
||||
|
||||
#[serde(rename = "hifigan_tt2")]
|
||||
HifiganTacotron2,
|
||||
#[serde(rename = "rvc_v2")]
|
||||
RvcV2,
|
||||
#[serde(rename = "sd_1.5")]
|
||||
StableDiffusion15,
|
||||
#[serde(rename = "sdxl")]
|
||||
StableDiffusionXL,
|
||||
#[serde(rename = "so_vits_svc")]
|
||||
SoVitsSvc,
|
||||
#[serde(rename = "tt2")]
|
||||
Tacotron2,
|
||||
#[serde(rename = "loRA")]
|
||||
LoRA,
|
||||
#[serde(rename = "vall_e")]
|
||||
VallE,
|
||||
#[serde(rename = "comfy_ui")]
|
||||
ComfyUi,
|
||||
}
|
||||
|
||||
impl PublicWeightsType {
|
||||
pub fn from_enum(weights_type: WeightsType) -> Self {
|
||||
match weights_type {
|
||||
// Renamed variants
|
||||
WeightsType::GptSoVits => Self::Tacotron2_5,
|
||||
// Conserved variants
|
||||
WeightsType::HifiganTacotron2 => Self::HifiganTacotron2,
|
||||
WeightsType::RvcV2 => Self::RvcV2,
|
||||
WeightsType::StableDiffusion15 => Self::StableDiffusion15,
|
||||
WeightsType::StableDiffusionXL => Self::StableDiffusionXL,
|
||||
WeightsType::SoVitsSvc => Self::SoVitsSvc,
|
||||
WeightsType::Tacotron2 => Self::Tacotron2,
|
||||
WeightsType::LoRA => Self::LoRA,
|
||||
WeightsType::VallE => Self::VallE,
|
||||
WeightsType::ComfyUi => Self::ComfyUi,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_enum(&self) -> WeightsType {
|
||||
match self {
|
||||
// Renamed variants
|
||||
Self::Tacotron2_5 => WeightsType::GptSoVits,
|
||||
// Conserved variants
|
||||
Self::HifiganTacotron2 => WeightsType::HifiganTacotron2,
|
||||
Self::RvcV2 => WeightsType::RvcV2,
|
||||
Self::StableDiffusion15 => WeightsType::StableDiffusion15,
|
||||
Self::StableDiffusionXL => WeightsType::StableDiffusionXL,
|
||||
Self::SoVitsSvc => WeightsType::SoVitsSvc,
|
||||
Self::Tacotron2 => WeightsType::Tacotron2,
|
||||
Self::LoRA => WeightsType::LoRA,
|
||||
Self::VallE => WeightsType::VallE,
|
||||
Self::ComfyUi => WeightsType::ComfyUi,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::test_helpers::to_json;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn override_enums() -> &'static [PublicWeightsType; 1] {
|
||||
&[
|
||||
PublicWeightsType::Tacotron2_5,
|
||||
]
|
||||
}
|
||||
|
||||
mod override_values {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn gpt_so_vits() {
|
||||
// Public --> Internal
|
||||
assert_eq!(PublicWeightsType::Tacotron2_5.to_enum(), WeightsType::GptSoVits);
|
||||
assert_eq!(to_json(&PublicWeightsType::Tacotron2_5.to_enum()), "gpt_so_vits");
|
||||
|
||||
// Internal --> Public
|
||||
assert_eq!(PublicWeightsType::from_enum(WeightsType::GptSoVits), PublicWeightsType::Tacotron2_5);
|
||||
assert_eq!(to_json(&PublicWeightsType::from_enum(WeightsType::GptSoVits)), "tacotron2.5");
|
||||
}
|
||||
}
|
||||
|
||||
mod mechanical_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn public_to_internal() {
|
||||
let mut tested_count = 0;
|
||||
|
||||
for public_variant in PublicWeightsType::iter() {
|
||||
if public_variant == PublicWeightsType::Tacotron2_5 {
|
||||
continue; // Can't compare.
|
||||
}
|
||||
|
||||
// Round trip
|
||||
assert_eq!(public_variant, PublicWeightsType::from_enum(public_variant.to_enum()));
|
||||
|
||||
let internal_enum_variant = public_variant.to_enum();
|
||||
let internal_enum_string = to_json(&internal_enum_variant);
|
||||
let public_enum_string = to_json(&public_variant);
|
||||
|
||||
assert_eq!(internal_enum_string, public_enum_string);
|
||||
|
||||
tested_count += 1;
|
||||
}
|
||||
|
||||
assert!(tested_count > 1);
|
||||
assert_eq!(tested_count, PublicWeightsType::iter().len() - override_enums().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn internal_to_public() {
|
||||
let mut tested_count = 0;
|
||||
|
||||
for internal_variant in WeightsType::all_variants() {
|
||||
if internal_variant == WeightsType::GptSoVits {
|
||||
continue; // Can't compare.
|
||||
}
|
||||
|
||||
// Round trip
|
||||
assert_eq!(internal_variant, PublicWeightsType::from_enum(internal_variant).to_enum());
|
||||
|
||||
let public_enum_variant = PublicWeightsType::from_enum(internal_variant);
|
||||
let public_enum_string = to_json(&public_enum_variant);
|
||||
let internal_enum_string = to_json(&internal_variant);
|
||||
|
||||
// Same serialization
|
||||
assert_eq!(internal_enum_string, public_enum_string);
|
||||
|
||||
tested_count += 1;
|
||||
}
|
||||
|
||||
assert!(tested_count > 1);
|
||||
assert_eq!(tested_count, WeightsType::all_variants().len() - override_enums().len());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//! enums_public
|
||||
//!
|
||||
//! Sometimes we want to hide which enums we allow over the API
|
||||
//! to keep competitors in the dark about what we're doing.
|
||||
//!
|
||||
|
||||
// Never allow these
|
||||
#![forbid(private_bounds)]
|
||||
#![forbid(private_interfaces)]
|
||||
#![forbid(unused_must_use)] // NB: It's unsafe to not close/check some things
|
||||
|
||||
// Okay to toggle
|
||||
#![forbid(unreachable_patterns)]
|
||||
#![forbid(unused_imports)]
|
||||
#![forbid(unused_mut)]
|
||||
#![forbid(unused_variables)]
|
||||
|
||||
// Always allow
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
#[macro_use] extern crate serde_derive;
|
||||
|
||||
#[cfg(test)] pub mod test_helpers;
|
||||
|
||||
pub mod by_table;
|
||||
@@ -0,0 +1,27 @@
|
||||
//! Only imported in tests
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
pub fn to_toml<T: Serialize>(t: &T) -> String {
|
||||
match toml::to_string(t) {
|
||||
Ok(s) => s.replace("\"", ""), // JSON values are quoted, so we remove quotes
|
||||
Err(err) => {
|
||||
panic!("serialization error: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_json<T: Serialize>(t: &T) -> String {
|
||||
serde_json::to_string(t)
|
||||
.expect("serialization error")
|
||||
.replace("\"", "") // JSON values are quoted, so we remove quotes
|
||||
}
|
||||
|
||||
/// Assert that the Serialize is represented by the expected string value.
|
||||
/// This is useful for ensuring stability of serialization.
|
||||
pub fn assert_serialization<T: Serialize>(t: T, expected: &str) {
|
||||
// TODO: See if there's a way to check the sqlx serialization
|
||||
// TODO(bt,2024-06-27): Something broke with serde toml serialization, so we're disabling it
|
||||
// assert_eq!(&to_toml(&t), expected);
|
||||
assert_eq!(&to_json(&t), expected);
|
||||
}
|
||||
@@ -36,4 +36,4 @@ sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls",
|
||||
[dev-dependencies]
|
||||
# Test serialization
|
||||
#serde_json = "1.0.64"
|
||||
toml = "0.5.8"
|
||||
toml = "0.8.14"
|
||||
|
||||
@@ -41,8 +41,8 @@ utoipa = { version = "4", features = ["chrono","actix_extras"] }
|
||||
[dev-dependencies]
|
||||
|
||||
# Enum utilities
|
||||
strum = { version = "0.25", features = ["derive"] }
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
|
||||
# Test serialization
|
||||
serde_json = "1.0.108"
|
||||
toml = "0.5.8"
|
||||
toml = "0.8.14"
|
||||
|
||||
@@ -12,4 +12,5 @@ use crate::prefixes::TokenPrefix;
|
||||
pub struct MediaFileToken(pub String);
|
||||
|
||||
impl_string_token!(MediaFileToken);
|
||||
impl_mysql_token_from_row!(MediaFileToken);
|
||||
impl_crockford_generator!(MediaFileToken, 32usize, TokenPrefix::MediaFile, CrockfordLower);
|
||||
|
||||
@@ -40,7 +40,7 @@ clap = "4.4.8"
|
||||
rand = "0.8.5"
|
||||
# Runtime
|
||||
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
tokio = { version = "1.38.0", features = ["macros"] }
|
||||
|
||||
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ pub fn get_bucket_clients() -> AnyhowResult<BucketClients> {
|
||||
let region_name = easyenv::get_env_string_required("REGION_NAME")?;
|
||||
let public_bucket_name = easyenv::get_env_string_required("PUBLIC_BUCKET_NAME")?;
|
||||
let private_bucket_name = easyenv::get_env_string_required("PRIVATE_BUCKET_NAME")?;
|
||||
let s3_compatible_endpoint_url = easyenv::get_env_string_or_default("S3_COMPATIBLE_ENDPOINT_URL", "https://storage.googleapis.com");
|
||||
|
||||
// NB: Long timeout for dev rust builds to upload to cloud buckets.
|
||||
// Unoptimized binaries sometimes take a lot of time to upload, presumably due to unoptimized code.
|
||||
@@ -29,6 +30,7 @@ pub fn get_bucket_clients() -> AnyhowResult<BucketClients> {
|
||||
&secret_key,
|
||||
®ion_name,
|
||||
&public_bucket_name,
|
||||
&s3_compatible_endpoint_url,
|
||||
None,
|
||||
Some(bucket_timeout),
|
||||
)?;
|
||||
@@ -40,6 +42,7 @@ pub fn get_bucket_clients() -> AnyhowResult<BucketClients> {
|
||||
&secret_key,
|
||||
®ion_name,
|
||||
&private_bucket_name,
|
||||
&s3_compatible_endpoint_url,
|
||||
None,
|
||||
Some(bucket_timeout),
|
||||
)?;
|
||||
|
||||
@@ -37,7 +37,7 @@ log = "0.4.14"
|
||||
|
||||
# Runtime
|
||||
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
tokio = { version = "1.38.0", features = ["macros"] }
|
||||
|
||||
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@ pub async fn main() -> AnyhowResult<()> {
|
||||
let region_name = easyenv::get_env_string_required("REGION_NAME")?;
|
||||
let public_bucket_name = easyenv::get_env_string_required("PUBLIC_BUCKET_NAME")?;
|
||||
|
||||
let s3_compatible_endpoint_url = easyenv::get_env_string_or_default(
|
||||
"S3_COMPATIBLE_ENDPOINT_URL", "");
|
||||
let bucket_timeout = easyenv::get_env_duration_seconds_or_default(
|
||||
"BUCKET_TIMEOUT_SECONDS", Duration::from_secs(60 * 5));
|
||||
|
||||
@@ -53,6 +55,7 @@ pub async fn main() -> AnyhowResult<()> {
|
||||
&secret_key,
|
||||
®ion_name,
|
||||
&public_bucket_name,
|
||||
&s3_compatible_endpoint_url,
|
||||
None,
|
||||
Some(bucket_timeout),
|
||||
)?;
|
||||
|
||||
@@ -26,4 +26,4 @@ my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
|
||||
# External
|
||||
clap = "4.4.8"
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
tokio = { version = "1.38.0", features = ["macros"] }
|
||||
|
||||
@@ -16,10 +16,9 @@ path = "src/main.rs"
|
||||
normal = ["my-workspace-hack"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
# Internal
|
||||
container_common = { path = "../../../lib/deprecated/container_common" }
|
||||
easyenv = { path = "../../../lib/easyenv" }
|
||||
errors = { path = "../../../lib/errors" }
|
||||
|
||||
# Workspace hack (faster compile times)
|
||||
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use log::info;
|
||||
|
||||
use container_common::anyhow_result::AnyhowResult;
|
||||
use easyenv::init_all_with_default_logging;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
fn main() -> AnyhowResult<()> {
|
||||
init_all_with_default_logging(None);
|
||||
|
||||
@@ -18,7 +18,6 @@ normal = ["my-workspace-hack"]
|
||||
[dependencies]
|
||||
# Internal
|
||||
buckets = { path = "../../../_types/buckets" }
|
||||
container_common = { path = "../../../lib/deprecated/container_common" }
|
||||
easyenv = { path = "../../../lib/easyenv" }
|
||||
enums = { path = "../../../_types/enums" }
|
||||
errors = { path = "../../../lib/errors" }
|
||||
@@ -32,11 +31,11 @@ my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
# External
|
||||
clap = "4.4.8"
|
||||
dotenv = "0.15.0"
|
||||
itertools = "0.11.0"
|
||||
itertools = "0.13.0"
|
||||
log = "0.4.14"
|
||||
|
||||
# Bigger pieces
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
tokio = { version = "1.38.0", features = ["macros"] }
|
||||
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
|
||||
|
||||
# Serialization
|
||||
|
||||
@@ -2,8 +2,8 @@ use log::info;
|
||||
use sqlx::{MySql, Pool};
|
||||
use sqlx::mysql::MySqlPoolOptions;
|
||||
|
||||
use container_common::anyhow_result::AnyhowResult;
|
||||
use easyenv::init_all_with_default_logging;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
use crate::cli_args::Action;
|
||||
use crate::operations::delete_all_anonymous_user_images::delete_all_anonymous_user_images::delete_all_anonymous_user_images;
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ use sqlx::{MySql, Pool};
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::common::view_as::ViewAs;
|
||||
use errors::AnyhowResult;
|
||||
use mysql_queries::queries::media_files::delete_media_file::delete_media_file_as_mod;
|
||||
use mysql_queries::queries::media_files::delete::delete_media_file::delete_media_file_as_mod;
|
||||
use mysql_queries::queries::media_files::list::list_media_files::{list_media_files, ListMediaFilesArgs};
|
||||
|
||||
use crate::cli_args::Args;
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ use sqlx::{MySql, Pool};
|
||||
|
||||
use enums::common::view_as::ViewAs;
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use mysql_queries::queries::media_files::delete_media_file::delete_media_file_as_mod;
|
||||
use mysql_queries::queries::media_files::delete::delete_media_file::delete_media_file_as_mod;
|
||||
use mysql_queries::queries::media_files::list::list_media_files_for_user::{list_media_files_for_user, ListMediaFileForUserArgs};
|
||||
use mysql_queries::queries::users::user_profiles::get_user_profile_by_username::get_user_profile_by_username;
|
||||
|
||||
|
||||
@@ -33,10 +33,10 @@ my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
# External
|
||||
clap = "4.4.8"
|
||||
log = "0.4.14"
|
||||
strum = { version = "0.25", features = ["derive"] }
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
|
||||
# Bigger pieces
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
tokio = { version = "1.38.0", features = ["macros"] }
|
||||
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
|
||||
elasticsearch = "8.5.0-alpha.1"
|
||||
|
||||
|
||||
@@ -23,10 +23,17 @@ pub enum Environment {
|
||||
pub enum Action {
|
||||
ReindexTts,
|
||||
SearchTts,
|
||||
|
||||
/// Reindex model_weights into ElasticSearch
|
||||
ReindexModelWeights,
|
||||
|
||||
/// Search the model weights
|
||||
SearchModelWeights,
|
||||
|
||||
/// Reindex media_files into ElasticSearch
|
||||
/// For now, this is just media files that are relevant to the engine.
|
||||
ReindexMediaFiles,
|
||||
SearchMediaFiles,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
|
||||
@@ -20,6 +20,8 @@ use errors::AnyhowResult;
|
||||
use crate::cli_args::{Action, Environment, parse_cli_args};
|
||||
use crate::plans::create_all_model_weight_documents::create_all_model_weight_documents;
|
||||
use crate::plans::create_all_tts_documents::create_all_tts_documents;
|
||||
use crate::plans::media_files::create_dimensional_media_file_documents::create_dimensional_media_file_documents;
|
||||
use crate::plans::media_files::test_search_media_files_documents::test_search_media_files;
|
||||
|
||||
pub mod cli_args;
|
||||
pub mod plans;
|
||||
@@ -62,6 +64,14 @@ pub async fn main() -> AnyhowResult<()> {
|
||||
println!("Result: {:#?}", result);
|
||||
}
|
||||
}
|
||||
Action::ReindexMediaFiles => {
|
||||
info!("Reindexing media files...");
|
||||
create_dimensional_media_file_documents(&mysql, &elasticsearch).await?;
|
||||
}
|
||||
Action::SearchMediaFiles => {
|
||||
info!("Search media files...");
|
||||
test_search_media_files(&elasticsearch).await?;
|
||||
}
|
||||
}
|
||||
|
||||
info!("Done!");
|
||||
|
||||
+7
-2
@@ -13,7 +13,11 @@ use errors::AnyhowResult;
|
||||
use mysql_queries::queries::model_weights::list::list_model_weights_for_elastic_search_backfill_using_cursor::{list_model_weights_for_elastic_search_backfill_using_cursor, ModelWeightForElasticsearchRecord};
|
||||
use storyteller_root::get_storyteller_rust_root;
|
||||
|
||||
pub async fn create_all_model_weight_documents(mysql: &Pool<MySql>, elasticsearch: &Elasticsearch) -> AnyhowResult<()> {
|
||||
pub async fn create_all_model_weight_documents(
|
||||
mysql: &Pool<MySql>,
|
||||
elasticsearch: &Elasticsearch
|
||||
) -> AnyhowResult<()> {
|
||||
|
||||
info!("Create all model weight documents.");
|
||||
|
||||
// TODO(bt, 2024-01-10): expose this as a CLI flag
|
||||
@@ -63,7 +67,8 @@ async fn create_document_from_record(elasticsearch: &Elasticsearch, record: Mode
|
||||
weights_type: record.weights_type,
|
||||
weights_category: record.weights_category,
|
||||
|
||||
title: record.title,
|
||||
title: record.title.clone(),
|
||||
title_as_keyword: record.title,
|
||||
|
||||
maybe_cover_image_media_file_token: record.maybe_cover_image_media_file_token,
|
||||
maybe_cover_image_public_bucket_hash: record.maybe_cover_image_public_bucket_hash,
|
||||
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
use std::collections::HashSet;
|
||||
use std::fs::read_to_string;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use elasticsearch::{BulkOperation, BulkParts, Elasticsearch};
|
||||
use log::{error, info, warn};
|
||||
use serde_json::Value;
|
||||
use sqlx::{MySql, Pool};
|
||||
|
||||
use elasticsearch_schema::documents::media_file_document::{MEDIA_FILE_INDEX, MediaFileDocument};
|
||||
use elasticsearch_schema::traits::document::Document;
|
||||
use elasticsearch_schema::utils::create_index_if_not_exists::{create_index_if_not_exists, CreateIndexArgs};
|
||||
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 errors::AnyhowResult;
|
||||
use mysql_queries::queries::media_files::list::list_media_files_for_elastic_search_backfill_using_cursor::{list_media_files_for_elastic_search_backfill_using_cursor, ListArgs, MediaFileForElasticsearchRecord};
|
||||
use mysql_queries::queries::model_weights::list::list_model_weights_for_elastic_search_backfill_using_cursor::{list_model_weights_for_elastic_search_backfill_using_cursor, ModelWeightForElasticsearchRecord};
|
||||
use storyteller_root::get_storyteller_rust_root;
|
||||
|
||||
pub async fn create_dimensional_media_file_documents(
|
||||
mysql: &Pool<MySql>,
|
||||
elasticsearch: &Elasticsearch
|
||||
) -> AnyhowResult<()> {
|
||||
|
||||
info!("Create dimensional media file documents.");
|
||||
|
||||
// TODO(bt, 2024-01-10): expose this as a CLI flag
|
||||
const DELETE_EXISTING_INDEX : bool = true;
|
||||
const PAGE_SIZE : usize = 1000;
|
||||
|
||||
create_media_file_index(&elasticsearch, DELETE_EXISTING_INDEX).await?;
|
||||
|
||||
let mut cursor = 0;
|
||||
|
||||
loop {
|
||||
info!("Cursor: {cursor}");
|
||||
|
||||
let results = list_media_files_for_elastic_search_backfill_using_cursor(ListArgs {
|
||||
mysql_pool: mysql,
|
||||
page_size: PAGE_SIZE,
|
||||
cursor,
|
||||
maybe_filter_engine_categories: Some(&HashSet::from_iter(vec![
|
||||
MediaFileEngineCategory::Animation,
|
||||
MediaFileEngineCategory::Character,
|
||||
MediaFileEngineCategory::Creature,
|
||||
MediaFileEngineCategory::Expression,
|
||||
MediaFileEngineCategory::ImagePlane,
|
||||
MediaFileEngineCategory::Location,
|
||||
MediaFileEngineCategory::Object,
|
||||
MediaFileEngineCategory::Scene,
|
||||
MediaFileEngineCategory::SetDressing,
|
||||
MediaFileEngineCategory::Skybox,
|
||||
MediaFileEngineCategory::VideoPlane,
|
||||
])),
|
||||
maybe_filter_media_types: Some(&HashSet::from_iter(vec![
|
||||
// Engine types
|
||||
MediaFileType::Csv,
|
||||
MediaFileType::Fbx,
|
||||
MediaFileType::Glb,
|
||||
MediaFileType::SceneJson,
|
||||
// Image types
|
||||
MediaFileType::Gif,
|
||||
MediaFileType::Jpg,
|
||||
MediaFileType::Png,
|
||||
])),
|
||||
maybe_filter_media_classes: Some(&HashSet::from_iter(vec![
|
||||
MediaFileClass::Image,
|
||||
MediaFileClass::Dimensional,
|
||||
])),
|
||||
}).await?;
|
||||
|
||||
info!("Results length: {}", results.len());
|
||||
|
||||
if results.is_empty() {
|
||||
info!("No more results at cursor {cursor}");
|
||||
break;
|
||||
}
|
||||
|
||||
let maybe_last_id = results.last().map(|result| result.id);
|
||||
|
||||
match maybe_last_id {
|
||||
Some(last_id) => cursor = last_id as usize,
|
||||
None => {
|
||||
warn!("No final ID at cursor {cursor}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for result in results {
|
||||
create_document_from_record(elasticsearch, result).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn create_document_from_record(elasticsearch: &Elasticsearch, record: MediaFileForElasticsearchRecord) -> AnyhowResult<()> {
|
||||
info!("Create record for {:?}", record.token);
|
||||
|
||||
let is_deleted = record.user_deleted_at.is_some() || record.mod_deleted_at.is_some();
|
||||
|
||||
let document = MediaFileDocument {
|
||||
token: record.token,
|
||||
|
||||
media_class: record.media_class,
|
||||
media_type: record.media_type,
|
||||
maybe_media_subtype: record.maybe_media_subtype,
|
||||
maybe_engine_category: record.maybe_engine_category,
|
||||
maybe_animation_type: record.maybe_animation_type,
|
||||
|
||||
maybe_mime_type: record.maybe_mime_type,
|
||||
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,
|
||||
creator_set_visibility: record.creator_set_visibility,
|
||||
|
||||
maybe_title: record.maybe_title.clone(),
|
||||
maybe_title_as_keyword: record.maybe_title,
|
||||
|
||||
maybe_cover_image_media_file_token: record.maybe_cover_image_media_file_token,
|
||||
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_creator_user_token: record.maybe_creator_user_token,
|
||||
maybe_creator_username: record.maybe_creator_username,
|
||||
maybe_creator_display_name: record.maybe_creator_display_name,
|
||||
maybe_creator_gravatar_hash: record.maybe_creator_gravatar_hash,
|
||||
|
||||
is_featured: record.is_featured,
|
||||
|
||||
created_at: record.created_at,
|
||||
updated_at: record.updated_at,
|
||||
user_deleted_at: record.user_deleted_at,
|
||||
mod_deleted_at: record.mod_deleted_at,
|
||||
|
||||
is_deleted,
|
||||
};
|
||||
|
||||
let op : BulkOperation<_> = BulkOperation::index(&document)
|
||||
.id(document.get_document_id())
|
||||
.into();
|
||||
|
||||
let response = elasticsearch
|
||||
.bulk(BulkParts::Index(MEDIA_FILE_INDEX))
|
||||
.body(vec![op])
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let json: Value = response.json().await?;
|
||||
|
||||
let had_errors = json["errors"].as_bool().unwrap_or(false);
|
||||
|
||||
if had_errors {
|
||||
let failed: Vec<&Value> = json["items"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|v| !v["error"].is_null())
|
||||
.collect();
|
||||
|
||||
// TODO: retry failures
|
||||
error!("Errors during indexing. Failures: {}", failed.len());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// NB: Adapted from elasticsearch crate examples source
|
||||
async fn create_media_file_index(client: &Elasticsearch, delete_existing: bool) -> AnyhowResult<()> {
|
||||
|
||||
info!("Creating model media file index...");
|
||||
|
||||
let index_path = get_storyteller_rust_root()
|
||||
.join("_elasticsearch/index_definitions/media_files_v1.json");
|
||||
|
||||
info!("Reading index file: {:?}", index_path);
|
||||
|
||||
let index_definition = read_to_string(index_path)?;
|
||||
|
||||
create_index_if_not_exists(CreateIndexArgs {
|
||||
client,
|
||||
index_name: MEDIA_FILE_INDEX,
|
||||
index_definition: &index_definition,
|
||||
delete_existing,
|
||||
}).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod create_dimensional_media_file_documents;
|
||||
pub mod test_search_media_files_documents;
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
use std::collections::HashSet;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use elasticsearch::Elasticsearch;
|
||||
|
||||
use elasticsearch_schema::searches::search_media_files::{search_media_files, SearchArgs};
|
||||
use enums::by_table::media_files::media_file_class::MediaFileClass;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
pub async fn test_search_media_files(client: &Elasticsearch) -> AnyhowResult<()> {
|
||||
|
||||
let results = search_media_files(SearchArgs {
|
||||
search_term: "cac",
|
||||
is_featured: None,
|
||||
maybe_creator_user_token: None,
|
||||
maybe_media_classes: Some(HashSet::from_iter(vec![
|
||||
MediaFileClass::Dimensional,
|
||||
MediaFileClass::Image,
|
||||
])),
|
||||
maybe_media_types: None,
|
||||
maybe_engine_categories: None,
|
||||
client,
|
||||
}).await?;
|
||||
|
||||
for result in results {
|
||||
println!("Result: {:#?}", result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod create_all_model_weight_documents;
|
||||
pub mod create_all_tts_documents;
|
||||
pub mod create_all_tts_documents;
|
||||
pub mod media_files;
|
||||
@@ -35,11 +35,11 @@ my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
# External
|
||||
clap = "4.4.8"
|
||||
log = "0.4.14"
|
||||
strum = { version = "0.25", features = ["derive"] }
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
tempdir = "0.3.7"
|
||||
|
||||
# Async + clients
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
tokio = { version = "1.38.0", features = ["macros"] }
|
||||
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
|
||||
|
||||
# Serialization
|
||||
|
||||
@@ -75,6 +75,8 @@ pub fn get_bucket_client(env_var_suffix: &str) -> AnyhowResult<BucketClient> {
|
||||
let region_name = easyenv::get_env_string_required(&format!("REGION_NAME_{env_var_suffix}"))?;
|
||||
let bucket_name = easyenv::get_env_string_required(&format!("BUCKET_NAME_{env_var_suffix}"))?;
|
||||
|
||||
let s3_compatible_endpoint_url = easyenv::get_env_string_or_default(
|
||||
&format!("S3_COMPATIBLE_ENDPOINT_URL_{env_var_suffix}"), "https://storage.googleapis.com");
|
||||
// NB: Long timeout for dev rust builds to upload to cloud buckets.
|
||||
// Unoptimized binaries sometimes take a lot of time to upload, presumably due to unoptimized code.
|
||||
let bucket_timeout = easyenv::get_env_duration_seconds_or_default(
|
||||
@@ -87,6 +89,7 @@ pub fn get_bucket_client(env_var_suffix: &str) -> AnyhowResult<BucketClient> {
|
||||
&secret_key,
|
||||
®ion_name,
|
||||
&bucket_name,
|
||||
&s3_compatible_endpoint_url,
|
||||
None,
|
||||
Some(bucket_timeout),
|
||||
)?)
|
||||
|
||||
@@ -29,10 +29,10 @@ log = "0.4.14"
|
||||
|
||||
# Actix
|
||||
actix-cors = "0.6.4"
|
||||
actix-http = "3.4.0"
|
||||
actix-web = "4.4.0"
|
||||
actix-http = "3.7.0"
|
||||
actix-web = "4.7.0"
|
||||
url = { version = "2.5.0", features = [] }
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "2.9.0"
|
||||
actix-rt = "2.10.0"
|
||||
speculoos = "0.11.0" # Fluent assertions
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pub (crate) mod development_only;
|
||||
pub (crate) mod fakeyou;
|
||||
pub (crate) mod gottagofast;
|
||||
pub (crate) mod storyteller_studio;
|
||||
pub (crate) mod legacy;
|
||||
pub (crate) mod storyteller;
|
||||
+33
-8
@@ -2,14 +2,17 @@ use actix_cors::Cors;
|
||||
|
||||
use crate::util::netlify_branch_domain_matches::netlify_branch_domain_matches;
|
||||
|
||||
pub fn add_gotta_go_fast_test_branches(cors: Cors, _is_production: bool) -> Cors {
|
||||
cors.allowed_origin("http://localhost:5173")
|
||||
.allowed_origin_fn(|origin, _req_head| {
|
||||
netlify_branch_domain_matches(origin, "pipeline-gottagofast.netlify.app")
|
||||
})
|
||||
pub fn add_storyteller_studio(cors: Cors, _is_production: bool) -> Cors {
|
||||
cors.allowed_origin("https://studio.storyteller.ai")
|
||||
.allowed_origin("https://studio-staging.studio.storyteller.ai")
|
||||
.allowed_origin("https://studio-testing.studio.storyteller.ai")
|
||||
.allowed_origin_fn(|origin, _req_head| {
|
||||
netlify_branch_domain_matches(origin, "storytellerstudio.netlify.app")
|
||||
})
|
||||
.allowed_origin_fn(|origin, _req_head| {
|
||||
netlify_branch_domain_matches(origin, "pipeline-gottagofast.netlify.app")
|
||||
})
|
||||
.allowed_origin("http://localhost:5173")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -54,17 +57,39 @@ mod tests {
|
||||
#[actix_rt::test]
|
||||
async fn studio_main() {
|
||||
let production_cors = build_cors_config(ServerEnvironment::Production);
|
||||
assert_origin_ok(&production_cors, "https://storytellerstudio.netlify.app").await;
|
||||
assert_origin_ok(&production_cors, "https://studio.storyteller.ai").await;
|
||||
assert_origin_invalid(&production_cors, "https://studiofake.storyteller.ai").await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn studio_branch_deploy() {
|
||||
async fn studio_staging() {
|
||||
let production_cors = build_cors_config(ServerEnvironment::Production);
|
||||
assert_origin_ok(&production_cors, "https://studio-staging.studio.storyteller.ai").await;
|
||||
assert_origin_invalid(&production_cors, "https://studio-staging-fake.studio.storyteller.ai").await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn studio_testing() {
|
||||
let production_cors = build_cors_config(ServerEnvironment::Production);
|
||||
assert_origin_ok(&production_cors, "https://studio-testing.studio.storyteller.ai").await;
|
||||
assert_origin_invalid(&production_cors, "https://studio-testing-fake.studio.storyteller.ai").await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn studio_netlify() {
|
||||
let production_cors = build_cors_config(ServerEnvironment::Production);
|
||||
assert_origin_ok(&production_cors, "https://storytellerstudio.netlify.app").await;
|
||||
assert_origin_invalid(&production_cors, "https://storytellerstudiofake.netlify.app").await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn studio_netlify_branch_deploy() {
|
||||
let production_cors = build_cors_config(ServerEnvironment::Production);
|
||||
assert_origin_ok(&production_cors, "https://foo--storytellerstudio.netlify.app").await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn studio_deploy_preview() {
|
||||
async fn studio_netlify_deploy_preview() {
|
||||
let production_cors = build_cors_config(ServerEnvironment::Production);
|
||||
assert_origin_ok(&production_cors, "https://deploy-preview-123--storytellerstudio.netlify.app").await;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ use reusable_types::server_environment::ServerEnvironment;
|
||||
|
||||
use crate::configs::development_only::add_development_only;
|
||||
use crate::configs::fakeyou::{add_fakeyou, add_fakeyou_dev_proxy};
|
||||
use crate::configs::gottagofast::add_gotta_go_fast_test_branches;
|
||||
use crate::configs::storyteller_studio::add_storyteller_studio;
|
||||
use crate::configs::legacy::{add_legacy_storyteller_stream, add_legacy_trumped, add_legacy_vocodes, add_power_stream};
|
||||
use crate::configs::storyteller::{add_storyteller, add_storyteller_dev_proxy};
|
||||
|
||||
@@ -34,7 +34,7 @@ fn do_build_cors_config(is_production: bool) -> Cors {
|
||||
cors = add_fakeyou_dev_proxy(cors, is_production);
|
||||
cors = add_storyteller(cors, is_production);
|
||||
cors = add_storyteller_dev_proxy(cors, is_production);
|
||||
cors = add_gotta_go_fast_test_branches(cors, is_production);
|
||||
cors = add_storyteller_studio(cors, is_production);
|
||||
|
||||
// Legacy
|
||||
cors = add_legacy_trumped(cors, is_production);
|
||||
|
||||
@@ -24,11 +24,11 @@ errors = { path = "../../lib/errors" }
|
||||
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
|
||||
|
||||
# Actix
|
||||
actix-http = "3.4.0"
|
||||
actix-rt = "2.9.0"
|
||||
actix-http = "3.7.0"
|
||||
actix-rt = "2.10.0"
|
||||
actix-service = "2.0.2"
|
||||
actix-utils = "3.0.1"
|
||||
actix-web = "4.4.0"
|
||||
actix-web = "4.7.0"
|
||||
|
||||
# IPv4 and v6 CIDRs (crate has few dependencies)
|
||||
cidr-utils = "0.5.11"
|
||||
|
||||
@@ -32,13 +32,13 @@ my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
# External
|
||||
anyhow = "1.0.86"
|
||||
log = "0.4.14"
|
||||
env_logger = "0.10.1"
|
||||
env_logger = "0.11.3"
|
||||
async-trait = "0.1.75"
|
||||
# The "never-encode-slash" feature seems to have been removed:
|
||||
# https://github.com/durch/rust-s3/pull/254
|
||||
rust-s3 = { version = "0.33.0" }
|
||||
rust-s3 = { version = "0.34.0" }
|
||||
|
||||
# Runtime
|
||||
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
tokio = { version = "1.38.0", features = ["macros"] }
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ impl BucketClient {
|
||||
secret_key: &str,
|
||||
region_name: &str,
|
||||
bucket_name: &str,
|
||||
s3_endpoint: &str,
|
||||
optional_bucket_root: Option<&str>,
|
||||
// See underlying docs for timeout details.
|
||||
bucket_request_timeout: Option<Duration>,
|
||||
@@ -63,14 +64,14 @@ impl BucketClient {
|
||||
// NB: The GCS buckets aren't supported by default.
|
||||
let region = Region::Custom {
|
||||
region: region_name.to_owned(),
|
||||
endpoint: "https://storage.googleapis.com".to_owned(),
|
||||
endpoint: s3_endpoint.to_owned(),
|
||||
};
|
||||
|
||||
let mut bucket = Bucket::new(&bucket_name, region, credentials)?;
|
||||
|
||||
bucket.set_request_timeout(bucket_request_timeout);
|
||||
bucket.set_path_style();
|
||||
bucket.set_subdomain_style();
|
||||
// bucket.set_subdomain_style();
|
||||
|
||||
let optional_bucket_root = optional_bucket_root.map(|s| s.to_string());
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user