mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-01 00:05:54 -04:00
Compare commits
86
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49796c69e3 | ||
|
|
08f59a1989 | ||
|
|
15c218286f | ||
|
|
268346f662 | ||
|
|
7897ef730e | ||
|
|
43da5c91ad | ||
|
|
71360879f3 | ||
|
|
7f80e106bd | ||
|
|
58181b32cf | ||
|
|
0efe2d8177 | ||
|
|
62c5d86584 | ||
|
|
cbb950cb40 | ||
|
|
64be9e49af | ||
|
|
bd688703df | ||
|
|
c627c13e2d | ||
|
|
84104d91ac | ||
|
|
64806135c5 | ||
|
|
5e48a6193a | ||
|
|
11c17f0a1d | ||
|
|
ed97cdbb0d | ||
|
|
cd91a25c3d | ||
|
|
c52d197717 | ||
|
|
79d64c51ad | ||
|
|
3e8d7be00e | ||
|
|
3a5b765e51 | ||
|
|
6df4804e2a | ||
|
|
6b2d4ffdce | ||
|
|
e6ac364622 | ||
|
|
0cff684e97 | ||
|
|
86c80fdf19 | ||
|
|
eca8b01f14 | ||
|
|
1bddb21e9f | ||
|
|
20b950794c | ||
|
|
d698168f9e | ||
|
|
dd41c268e4 | ||
|
|
d5280964bc | ||
|
|
c715d6795c | ||
|
|
4159191d68 | ||
|
|
5e04cc6c2f | ||
|
|
0d58176f0f | ||
|
|
57f383612f | ||
|
|
ab3a312898 | ||
|
|
a2aa71e8a6 | ||
|
|
c49ec5af2f | ||
|
|
44d75baeec | ||
|
|
922e76eeb1 | ||
|
|
3b2f386cdb | ||
|
|
61f30618b0 | ||
|
|
3e02d791af | ||
|
|
70694ce330 | ||
|
|
c116ad90d0 | ||
|
|
5093621995 | ||
|
|
44056ee956 | ||
|
|
70e4af2b4c | ||
|
|
fd28585e13 | ||
|
|
0e8aefce5c | ||
|
|
0549e8eb6a | ||
|
|
0c35dc5068 | ||
|
|
987d983051 | ||
|
|
0144c969bc | ||
|
|
775d867add | ||
|
|
da62443522 | ||
|
|
1ae2df8fa7 | ||
|
|
e63eef03cd | ||
|
|
36c76365bc | ||
|
|
1432c19d3b | ||
|
|
4edea1d68f | ||
|
|
2b186720c1 | ||
|
|
d2faacc796 | ||
|
|
b2555bc756 | ||
|
|
169b45413d | ||
|
|
b0df97b2be | ||
|
|
d03fb5ed0f | ||
|
|
0420605535 | ||
|
|
5454171112 | ||
|
|
d518d54471 | ||
|
|
b17b1f565c | ||
|
|
bacb3ce5b1 | ||
|
|
b124028055 | ||
|
|
2e6d7d96e4 | ||
|
|
382fd8680d | ||
|
|
d68979024e | ||
|
|
25b90c07ce | ||
|
|
39bae02259 | ||
|
|
7755a5683b | ||
|
|
2f971dda60 |
+3
-3
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO voice_conversion_models\nSET\n token = ?,\n model_type = ?,\n title = ?,\n description_markdown = '',\n description_rendered_html = '',\n creator_user_token = ?,\n ip_address_creation = ?,\n ip_address_last_update = ?,\n original_download_url = ?,\n has_index_file = ?,\n private_bucket_hash = ?,\n private_bucket_object_name = ?,\n file_size_bytes = ?\n ",
|
||||
"query": "\nINSERT INTO voice_conversion_models\nSET\n token = ?,\n model_type = ?,\n title = ?,\n description_markdown = '',\n description_rendered_html = '',\n creator_user_token = ?,\n ip_address_creation = ?,\n ip_address_last_update = ?,\n original_download_url = ?,\n has_index_file = ?,\n private_bucket_hash = ?,\n private_bucket_object_name = ?,\n file_size_bytes = ?,\n maybe_migration_new_model_weights_token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 11
|
||||
"Right": 12
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "1e85e546684feffc151a26b0495b9ab8aa4ee5f1627464a9872e9c357ba1dc7a"
|
||||
"hash": "06734395f0a844e59d26c7d1cbc3e4b9a27f44c4bdacb8548d06a9e1dfb3db03"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO model_weights_extension_voice_conversion_details\nSET\n model_weights_token = ?,\n has_index_file = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "34aaedaebab0ea772714f31f42563b7e6b243c34a784e3f66f06aa102af3f1f9"
|
||||
}
|
||||
+94
-28
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_thumbnail_token,\n wt.description_markdown,\n wt.description_rendered_html,\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n wt.private_bucket_hash,\n wt.maybe_private_bucket_prefix,\n wt.maybe_private_bucket_extension,\n wt.cached_user_ratings_negative_count,\n wt.cached_user_ratings_positive_count,\n wt.cached_user_ratings_total_count,\n wt.maybe_cached_user_ratings_ratio,\n wt.cached_user_ratings_last_updated_at,\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n FROM model_weights as wt\n WHERE\n wt.token = ?\n AND wt.user_deleted_at IS NULL\n AND wt.mod_deleted_at IS NULL\n ",
|
||||
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_thumbnail_token,\n wt.description_markdown,\n wt.description_rendered_html,\n\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash AS creator_gravatar_hash,\n\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n wt.public_bucket_hash,\n wt.maybe_public_bucket_prefix,\n wt.maybe_public_bucket_extension,\n\n avatar.public_bucket_directory_hash as maybe_avatar_public_bucket_hash,\n avatar.maybe_public_bucket_prefix as maybe_avatar_public_bucket_prefix,\n avatar.maybe_public_bucket_extension as maybe_avatar_public_bucket_extension,\n\n wt.cached_user_ratings_negative_count,\n wt.cached_user_ratings_positive_count,\n wt.cached_user_ratings_total_count,\n wt.maybe_cached_user_ratings_ratio,\n wt.cached_user_ratings_last_updated_at,\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n FROM model_weights as wt\n JOIN users\n ON users.token = wt.creator_user_token\n LEFT OUTER JOIN media_files as avatar\n ON avatar.token = wt.maybe_avatar_media_file_token\n WHERE\n wt.token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -28,7 +28,7 @@
|
||||
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -78,13 +78,43 @@
|
||||
"name": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "creator_ip_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -94,17 +124,17 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 12,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 13,
|
||||
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -114,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 14,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 15,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -134,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 16,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -144,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 17,
|
||||
"name": "file_checksum_sha2",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -154,8 +184,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "private_bucket_hash",
|
||||
"ordinal": 18,
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
@@ -164,8 +194,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_private_bucket_prefix",
|
||||
"ordinal": 19,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -174,8 +204,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "maybe_private_bucket_extension",
|
||||
"ordinal": 20,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -184,7 +214,37 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 21,
|
||||
"name": "maybe_avatar_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "maybe_avatar_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"name": "maybe_avatar_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"name": "cached_user_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -194,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 25,
|
||||
"name": "cached_user_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -204,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 26,
|
||||
"name": "cached_user_ratings_total_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -214,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"ordinal": 27,
|
||||
"name": "maybe_cached_user_ratings_ratio",
|
||||
"type_info": {
|
||||
"type": "Float",
|
||||
@@ -224,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"ordinal": 28,
|
||||
"name": "cached_user_ratings_last_updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -234,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"ordinal": 29,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -244,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"ordinal": 30,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -254,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 31,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -264,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 32,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -274,7 +334,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 33,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -298,6 +358,9 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@@ -306,6 +369,9 @@
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -318,5 +384,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "f0b5767d52c389660d1859e628c746f6f33a9e1c25f21f66aeeb0784df768c8e"
|
||||
"hash": "4e30e34cdf7a5834a3981d5e634506966bac9f9c420e800d15ce313778272cee"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n w.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n w.weights_type as `weight_type: enums::by_table::model_weights::weights_types::WeightsType`,\n w.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_gravatar_hash,\n w.title,\n w_extension.ietf_language_tag,\n w_extension.ietf_primary_language_subtag,\n w.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n w.created_at,\n w.updated_at\nFROM model_weights as w\nLEFT OUTER JOIN model_weights_extension_voice_conversion_details as w_extension\n ON w_extension.model_weights_token = w.token\nJOIN users\n ON users.token = w.creator_user_token\nWHERE\n w.weights_type IN (\"rvc_v2\", \"so_vits_svc\")\n AND w.user_deleted_at IS NULL\n AND w.mod_deleted_at IS NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "weight_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "ietf_language_tag",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "ietf_primary_language_subtag",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 48
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "57a63d507ccd60824e0cf346a6aa3d69b1e34361294f7e90733a497cb8643908"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO model_weights_extension_voice_conversion_details\nSET\n model_weights_token = ?,\n has_index_file = ?\nON DUPLICATE KEY UPDATE\n has_index_file = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "760f4250fe5fb700c95ba0296b6b06ed89c2399fd1cb03dbae36d6c35143aa30"
|
||||
}
|
||||
+8
-8
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n SELECT\n mw.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n mw.title,\n mw.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n mw.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n mw.maybe_thumbnail_token,\n mw.description_markdown,\n mw.description_rendered_html,\n users.token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_email_gravatar_hash,\n mw.creator_ip_address,\n mw.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n mw.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n mw.original_download_url,\n mw.original_filename,\n mw.file_size_bytes,\n mw.file_checksum_sha2,\n mw.private_bucket_hash,\n mw.maybe_private_bucket_prefix,\n mw.maybe_private_bucket_extension,\n mw.cached_user_ratings_negative_count,\n mw.cached_user_ratings_positive_count,\n mw.cached_user_ratings_total_count,\n mw.maybe_cached_user_ratings_ratio,\n mw.cached_user_ratings_last_updated_at,\n mw.version,\n mw.created_at,\n mw.updated_at,\n mw.user_deleted_at,\n mw.mod_deleted_at\n FROM model_weights as mw\n JOIN users\n ON users.token = mw.creator_user_token\n WHERE\n users.username = ?\n AND mw.user_deleted_at IS NULL\n AND mw.mod_deleted_at IS NULL\n ",
|
||||
"query": "\n SELECT\n mw.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n mw.title,\n mw.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n mw.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n mw.maybe_thumbnail_token,\n mw.description_markdown,\n mw.description_rendered_html,\n users.token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_email_gravatar_hash,\n mw.creator_ip_address,\n mw.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n mw.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n mw.original_download_url,\n mw.original_filename,\n mw.file_size_bytes,\n mw.file_checksum_sha2,\n mw.public_bucket_hash,\n mw.maybe_public_bucket_prefix,\n mw.maybe_public_bucket_extension,\n mw.cached_user_ratings_negative_count,\n mw.cached_user_ratings_positive_count,\n mw.cached_user_ratings_total_count,\n mw.maybe_cached_user_ratings_ratio,\n mw.cached_user_ratings_last_updated_at,\n mw.version,\n mw.created_at,\n mw.updated_at,\n mw.user_deleted_at,\n mw.mod_deleted_at\n FROM model_weights as mw\n JOIN users\n ON users.token = mw.creator_user_token\n WHERE\n users.username = ?\n AND mw.user_deleted_at IS NULL\n AND mw.mod_deleted_at IS NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -28,7 +28,7 @@
|
||||
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -128,7 +128,7 @@
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
@@ -185,7 +185,7 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "private_bucket_hash",
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
@@ -195,7 +195,7 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"name": "maybe_private_bucket_prefix",
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -205,7 +205,7 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"name": "maybe_private_bucket_extension",
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -351,5 +351,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "a6ed8524fb5339fed17bec6611f8f56b6bdee35bac63c9eacbe21eb032a6a831"
|
||||
"hash": "854da1bad28fbcf5a8f82c26c52c25a7727957b52b727831ce62518b3c5fc9bd"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nUPDATE voice_conversion_models\nSET\n maybe_migration_new_model_weights_token = ?\nWHERE token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "898a2f89d1f3efcb87adaef432cc73117057e44766c330caff6ce2c9d48518fd"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO model_weights\nSET\n token = ?,\n weights_type = ?,\n weights_category = ?,\n title = ?,\n\n maybe_thumbnail_token = NULL,\n maybe_avatar_media_file_token = NULL,\n maybe_cover_media_file_token = NULL,\n description_markdown = NULL,\n description_rendered_html = NULL,\n\n maybe_last_update_user_token = NULL,\n original_download_url = ?,\n original_filename = ?,\n file_size_bytes = ?,\n file_checksum_sha2 = ?,\n\n creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n public_bucket_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n cached_user_ratings_total_count = 0,\n cached_user_ratings_positive_count = 0,\n cached_user_ratings_negative_count = 0,\n maybe_cached_user_ratings_ratio = 0.0,\n cached_user_ratings_last_updated_at = NOW(),\n\n maybe_migration_old_model_token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 15
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "8cb3ba5acb8dbef84408370810c98d4b99223761d4547ce7c8a9438ba92e8523"
|
||||
}
|
||||
+102
-36
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_thumbnail_token,\n wt.description_markdown,\n wt.description_rendered_html,\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n wt.private_bucket_hash,\n wt.maybe_private_bucket_prefix,\n wt.maybe_private_bucket_extension,\n wt.cached_user_ratings_negative_count,\n wt.cached_user_ratings_positive_count,\n wt.cached_user_ratings_total_count,\n wt.maybe_cached_user_ratings_ratio,\n wt.cached_user_ratings_last_updated_at,\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n FROM model_weights as wt\n WHERE\n wt.token = ?\n ",
|
||||
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_thumbnail_token,\n wt.description_markdown,\n wt.description_rendered_html,\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash AS creator_gravatar_hash,\n\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n wt.public_bucket_hash,\n wt.maybe_public_bucket_prefix,\n wt.maybe_public_bucket_extension,\n\n avatar.public_bucket_directory_hash as maybe_avatar_public_bucket_hash,\n avatar.maybe_public_bucket_prefix as maybe_avatar_public_bucket_prefix,\n avatar.maybe_public_bucket_extension as maybe_avatar_public_bucket_extension,\n\n wt.cached_user_ratings_negative_count,\n wt.cached_user_ratings_positive_count,\n wt.cached_user_ratings_total_count,\n wt.maybe_cached_user_ratings_ratio,\n wt.cached_user_ratings_last_updated_at,\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n FROM model_weights as wt\n JOIN users\n ON users.token = wt.creator_user_token\n LEFT OUTER JOIN media_files as avatar\n ON avatar.token = wt.maybe_avatar_media_file_token\n WHERE\n wt.token = ?\n AND wt.user_deleted_at IS NULL\n AND wt.mod_deleted_at IS NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -28,7 +28,7 @@
|
||||
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -75,16 +75,6 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "creator_ip_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -94,17 +84,57 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 8,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -114,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 14,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 15,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -134,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 16,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -144,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 17,
|
||||
"name": "file_checksum_sha2",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -154,8 +184,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "private_bucket_hash",
|
||||
"ordinal": 18,
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
@@ -164,8 +194,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_private_bucket_prefix",
|
||||
"ordinal": 19,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -174,8 +204,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "maybe_private_bucket_extension",
|
||||
"ordinal": 20,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -184,7 +214,37 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 21,
|
||||
"name": "maybe_avatar_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "maybe_avatar_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"name": "maybe_avatar_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"name": "cached_user_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -194,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 25,
|
||||
"name": "cached_user_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -204,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 26,
|
||||
"name": "cached_user_ratings_total_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -214,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"ordinal": 27,
|
||||
"name": "maybe_cached_user_ratings_ratio",
|
||||
"type_info": {
|
||||
"type": "Float",
|
||||
@@ -224,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"ordinal": 28,
|
||||
"name": "cached_user_ratings_last_updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -234,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"ordinal": 29,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -244,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"ordinal": 30,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -254,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 31,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -264,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 32,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -274,7 +334,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 33,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -298,6 +358,9 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@@ -306,6 +369,9 @@
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -318,5 +384,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "6a94791c8a8f66ee54bb367a4e8c71106bbcbbb205f54c14e3657279e83dabb6"
|
||||
"hash": "93084dc42ae4ada186dc90bdd470122342586f4f19a3ac961286c1c54a5c32b2"
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n w.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n w.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`\nFROM model_weights as w\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "98d53b1732bf0b0642ac6ebae3a3a2c40f21ec732693b92ad4bda69ae2b8d5bb"
|
||||
}
|
||||
+542
@@ -0,0 +1,542 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n id,\n token as `token: tokens::tokens::tts_models::TtsModelToken`,\n\n tts_model_type as `tts_model_type: enums::by_table::tts_models::tts_model_type::TtsModelType`,\n\n text_pipeline_type,\n has_self_contained_vocoder,\n has_self_contained_duration_model,\n has_self_contained_pitch_model,\n text_preprocessing_algorithm,\n\n use_default_mel_multiply_factor,\n maybe_custom_mel_multiply_factor,\n maybe_default_pretrained_vocoder,\n maybe_custom_vocoder_token as `maybe_custom_vocoder_token: tokens::tokens::vocoder_models::VocoderModelToken`,\n\n ietf_language_tag,\n ietf_primary_language_subtag,\n\n title,\n description_markdown,\n description_rendered_html,\n\n voice_name,\n actor_name,\n characteristic,\n version_string,\n\n is_front_page_featured,\n is_twitch_featured,\n\n maybe_suggested_unique_bot_command,\n\n original_download_url,\n original_filename,\n file_size_bytes,\n\n creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n\n creator_ip_address_creation,\n creator_ip_address_last_update,\n\n creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n private_bucket_hash,\n private_bucket_object_name,\n\n private_bucket_object_is_archive,\n\n user_ratings_total_count,\n user_ratings_positive_count,\n user_ratings_negative_count,\n\n is_public_listing_approved,\n is_locked_from_user_modification,\n is_locked_from_use,\n\n maybe_mod_comments,\n maybe_mod_user_token as `maybe_mod_user_token: tokens::tokens::users::UserToken`,\n\n maybe_migration_new_model_weights_token as `maybe_migration_new_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n\n version,\n\n created_at,\n updated_at,\n\n user_deleted_at,\n mod_deleted_at\n\nFROM tts_models\nWHERE\n id > ?\nORDER BY id ASC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: tokens::tokens::tts_models::TtsModelToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "tts_model_type: enums::by_table::tts_models::tts_model_type::TtsModelType",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 60
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "text_pipeline_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "has_self_contained_vocoder",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "has_self_contained_duration_model",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "has_self_contained_pitch_model",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "text_preprocessing_algorithm",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "use_default_mel_multiply_factor",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_custom_mel_multiply_factor",
|
||||
"type_info": {
|
||||
"type": "Double",
|
||||
"flags": "",
|
||||
"char_set": 63,
|
||||
"max_size": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_default_pretrained_vocoder",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_custom_vocoder_token: tokens::tokens::vocoder_models::VocoderModelToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "ietf_language_tag",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "ietf_primary_language_subtag",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 48
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "description_markdown",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "description_rendered_html",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "voice_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "actor_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"name": "characteristic",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"name": "version_string",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "is_front_page_featured",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "is_twitch_featured",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"name": "maybe_suggested_unique_bot_command",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 2048
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"name": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"name": "creator_ip_address_creation",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"name": "creator_ip_address_last_update",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"name": "private_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"name": "private_bucket_object_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 33,
|
||||
"name": "private_bucket_object_is_archive",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 34,
|
||||
"name": "user_ratings_total_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 35,
|
||||
"name": "user_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 36,
|
||||
"name": "user_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 37,
|
||||
"name": "is_public_listing_approved",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "MULTIPLE_KEY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 38,
|
||||
"name": "is_locked_from_user_modification",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 39,
|
||||
"name": "is_locked_from_use",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 40,
|
||||
"name": "maybe_mod_comments",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 41,
|
||||
"name": "maybe_mod_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 42,
|
||||
"name": "maybe_migration_new_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 43,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 44,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 45,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 46,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 47,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "a44c637e84152864a00f0ba58838c2f3888e3061fc8b44291541840fdb706e44"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO model_weights\nSET\n token = ?,\n weights_type = ?,\n weights_category = ?,\n title = ?,\n maybe_thumbnail_token = NULL,\n maybe_avatar_media_file_token = NULL,\n maybe_cover_media_file_token = NULL,\n description_markdown = ?,\n description_rendered_html = ?,\n creator_user_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n maybe_last_update_user_token = NULL,\n original_download_url = ?,\n original_filename = ?,\n file_size_bytes = ?,\n file_checksum_sha2 = ?,\n\n public_bucket_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n cached_user_ratings_total_count = 0,\n cached_user_ratings_positive_count = 0,\n cached_user_ratings_negative_count = 0,\n maybe_cached_user_ratings_ratio = 0.0,\n cached_user_ratings_last_updated_at = NOW(),\n\n maybe_migration_old_model_token = ?,\n version = ?,\n created_at = ?,\n updated_at = ?,\n user_deleted_at = ?,\n mod_deleted_at = ?\n\nON DUPLICATE KEY UPDATE\n weights_type = ?,\n weights_category = ?,\n title = ?,\n maybe_thumbnail_token = NULL,\n maybe_avatar_media_file_token = NULL,\n maybe_cover_media_file_token = NULL,\n description_markdown = ?,\n description_rendered_html = ?,\n creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n maybe_last_update_user_token = NULL,\n original_download_url = ?,\n original_filename = ?,\n file_size_bytes = ?,\n file_checksum_sha2 = ?,\n public_bucket_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n cached_user_ratings_total_count = 0,\n cached_user_ratings_positive_count = 0,\n cached_user_ratings_negative_count = 0,\n maybe_cached_user_ratings_ratio = 0.0,\n cached_user_ratings_last_updated_at = NOW(),\n maybe_migration_old_model_token = ?,\n version = ?,\n created_at = ?,\n updated_at = ?,\n user_deleted_at = ?,\n mod_deleted_at = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 43
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "aae28dc5fbeff858e4c9dd8b079752ce7892d76b56d2eff95db39c6b6d9f7f11"
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n w.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n w.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n\n w.title,\n vc.has_index_file,\n\n w.public_bucket_hash,\n w.maybe_public_bucket_prefix,\n w.maybe_public_bucket_extension,\n\n w.created_at,\n w.updated_at,\n w.user_deleted_at,\n w.mod_deleted_at\n\nFROM model_weights as w\nJOIN model_weights_extension_voice_conversion_details as vc\nON vc.model_weights_token = w.token\n\nWHERE w.token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "has_index_file",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "ae34c2ce11250786962be50f167f15f6d2d023afe2bb31994d21a1007d81e0a0"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n UPDATE model_weights\n SET\n maybe_avatar_media_file_token = ?\n WHERE token = ?\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "bda002b24b98328f0fb0440cfc82a47faf01e5d16d1030e15a7e2da161dd0d80"
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n INSERT INTO model_weights\n SET\n token = ?,\n weights_type = ?,\n weights_category = ?,\n title = ?,\n maybe_thumbnail_token = ?,\n description_markdown = ?,\n description_rendered_html = ?,\n creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n maybe_last_update_user_token = ?,\n original_download_url = ?,\n original_filename = ?,\n file_size_bytes = ?,\n file_checksum_sha2 = ?,\n private_bucket_hash = ?,\n maybe_private_bucket_prefix = ?,\n maybe_private_bucket_extension = ?,\n cached_user_ratings_total_count = ?,\n cached_user_ratings_positive_count = ?,\n cached_user_ratings_negative_count = ?,\n maybe_cached_user_ratings_ratio = ?,\n version = ?\n ",
|
||||
"query": "\n INSERT INTO model_weights\n SET\n token = ?,\n weights_type = ?,\n weights_category = ?,\n title = ?,\n maybe_thumbnail_token = ?,\n description_markdown = ?,\n description_rendered_html = ?,\n creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n maybe_last_update_user_token = ?,\n original_download_url = ?,\n original_filename = ?,\n file_size_bytes = ?,\n file_checksum_sha2 = ?,\n public_bucket_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n cached_user_ratings_total_count = ?,\n cached_user_ratings_positive_count = ?,\n cached_user_ratings_negative_count = ?,\n maybe_cached_user_ratings_ratio = ?,\n version = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -8,5 +8,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "274cfb1e3caca706e3dbc3d95064e0f4b354c936f8de948070854920f265cc41"
|
||||
"hash": "cb07f1522d0d619e2f364af78250080c99e7930ec095c5600abb80a9d8c5154d"
|
||||
}
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n id,\n token as `token: tokens::tokens::voice_conversion_models::VoiceConversionModelToken`,\n\n model_type as `model_type: enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType`,\n maybe_vocoder_token as `maybe_vocoder_token: tokens::tokens::vocoder_models::VocoderModelToken`,\n\n title,\n description_markdown,\n description_rendered_html,\n\n ietf_language_tag,\n ietf_primary_language_subtag,\n\n has_index_file,\n\n is_front_page_featured,\n\n original_download_url,\n original_filename,\n file_size_bytes,\n\n creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n\n ip_address_creation,\n ip_address_last_update,\n\n maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n\n creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n private_bucket_hash,\n private_bucket_object_name,\n\n is_public_listing_approved,\n is_locked_from_user_modification,\n maybe_mod_comments,\n\n maybe_migration_new_model_weights_token as `maybe_migration_new_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n\n version,\n\n created_at,\n updated_at,\n\n user_deleted_at,\n mod_deleted_at\n\nFROM voice_conversion_models\nWHERE\n id > ?\nORDER BY id ASC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: tokens::tokens::voice_conversion_models::VoiceConversionModelToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "model_type: enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "maybe_vocoder_token: tokens::tokens::vocoder_models::VocoderModelToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "description_markdown",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "description_rendered_html",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "ietf_language_tag",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "ietf_primary_language_subtag",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 48
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "has_index_file",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "is_front_page_featured",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 2048
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "ip_address_creation",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "ip_address_last_update",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"name": "private_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"name": "private_bucket_object_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "is_public_listing_approved",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "MULTIPLE_KEY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "is_locked_from_user_modification",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"name": "maybe_mod_comments",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"name": "maybe_migration_new_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "d1da969247415305e6bff625150b4d2a8b3801fd27999be19cb47f5f86ea279c"
|
||||
}
|
||||
+8
-8
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n SELECT \n mw.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n mw.title,\n mw.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n mw.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n mw.maybe_thumbnail_token,\n mw.description_markdown,\n mw.description_rendered_html,\n users.token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_email_gravatar_hash,\n mw.creator_ip_address,\n mw.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n mw.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n mw.original_download_url,\n mw.original_filename,\n mw.file_size_bytes,\n mw.file_checksum_sha2,\n mw.private_bucket_hash,\n mw.maybe_private_bucket_prefix,\n mw.maybe_private_bucket_extension,\n mw.cached_user_ratings_negative_count,\n mw.cached_user_ratings_positive_count,\n mw.cached_user_ratings_total_count,\n mw.maybe_cached_user_ratings_ratio,\n mw.cached_user_ratings_last_updated_at,\n mw.version,\n mw.created_at,\n mw.updated_at,\n mw.user_deleted_at,\n mw.mod_deleted_at\n FROM model_weights as mw\n JOIN users\n ON users.token = mw.creator_user_token\n WHERE\n users.username = ?\n ",
|
||||
"query": "\n SELECT \n mw.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n mw.title,\n mw.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n mw.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n mw.maybe_thumbnail_token,\n mw.description_markdown,\n mw.description_rendered_html,\n users.token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_email_gravatar_hash,\n mw.creator_ip_address,\n mw.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n mw.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n mw.original_download_url,\n mw.original_filename,\n mw.file_size_bytes,\n mw.file_checksum_sha2,\n mw.public_bucket_hash,\n mw.maybe_public_bucket_prefix,\n mw.maybe_public_bucket_extension,\n mw.cached_user_ratings_negative_count,\n mw.cached_user_ratings_positive_count,\n mw.cached_user_ratings_total_count,\n mw.maybe_cached_user_ratings_ratio,\n mw.cached_user_ratings_last_updated_at,\n mw.version,\n mw.created_at,\n mw.updated_at,\n mw.user_deleted_at,\n mw.mod_deleted_at\n FROM model_weights as mw\n JOIN users\n ON users.token = mw.creator_user_token\n WHERE\n users.username = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -28,7 +28,7 @@
|
||||
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
@@ -128,7 +128,7 @@
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
@@ -185,7 +185,7 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "private_bucket_hash",
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
@@ -195,7 +195,7 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"name": "maybe_private_bucket_prefix",
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -205,7 +205,7 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"name": "maybe_private_bucket_extension",
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -351,5 +351,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "3d586592422727dcc928574966bdf5081ac69fdbb856fffcbd68187fd99c4642"
|
||||
"hash": "ec733ae6705dc03fb785e2299c35fcfef23422142735319c8cd091ca8179f97d"
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n m.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`\nFROM model_weights as m\nWHERE m.token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "f80fb6c91b897bc4a5c24cfd1e16c5975f9438c88421f19a1788531f335e75c2"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO media_files\nSET\n token = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n\n maybe_origin_model_type = NULL,\n maybe_origin_model_token = NULL,\n\n media_type = ?,\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 16
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "fed337e365f0bd36cfa543e0ce9d4076cc0bd7809b6c2cb5740151d6583a6d11"
|
||||
}
|
||||
Generated
+44
-2
@@ -620,9 +620,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.74"
|
||||
version = "0.1.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
||||
checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1124,10 +1124,19 @@ name = "cloud_storage"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"buckets",
|
||||
"crockford",
|
||||
"easyenv",
|
||||
"env_logger",
|
||||
"errors",
|
||||
"filesys",
|
||||
"hashing",
|
||||
"log",
|
||||
"mimetypes",
|
||||
"my-workspace-hack",
|
||||
"rust-s3",
|
||||
"storyteller_root",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -1877,6 +1886,7 @@ version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bootstrap",
|
||||
"buckets",
|
||||
"chrono",
|
||||
"cloud_storage",
|
||||
"concurrency",
|
||||
@@ -1894,6 +1904,7 @@ dependencies = [
|
||||
"hyper",
|
||||
"jobs_common",
|
||||
"log",
|
||||
"migration",
|
||||
"mimetypes",
|
||||
"my-workspace-hack",
|
||||
"mysql_queries",
|
||||
@@ -1906,6 +1917,7 @@ dependencies = [
|
||||
"subprocess",
|
||||
"subprocess_common",
|
||||
"tempdir",
|
||||
"tokens",
|
||||
"tokio",
|
||||
"zip",
|
||||
]
|
||||
@@ -2973,6 +2985,7 @@ dependencies = [
|
||||
"log",
|
||||
"media",
|
||||
"memory_caching",
|
||||
"migration",
|
||||
"mime",
|
||||
"mimetypes",
|
||||
"my-workspace-hack",
|
||||
@@ -3480,16 +3493,43 @@ dependencies = [
|
||||
"my-workspace-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migration"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"buckets",
|
||||
"chrono",
|
||||
"cloud_storage",
|
||||
"enums",
|
||||
"errors",
|
||||
"jobs_common",
|
||||
"my-workspace-hack",
|
||||
"mysql_queries",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serial_test",
|
||||
"sqlx",
|
||||
"tokens",
|
||||
"tokio",
|
||||
"toml 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migration-tool"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"buckets",
|
||||
"clap",
|
||||
"cloud_storage",
|
||||
"config",
|
||||
"easyenv",
|
||||
"enums",
|
||||
"errors",
|
||||
"filesys",
|
||||
"hashing",
|
||||
"log",
|
||||
"my-workspace-hack",
|
||||
"mysql_queries",
|
||||
@@ -3499,6 +3539,7 @@ dependencies = [
|
||||
"sqlx",
|
||||
"storyteller_root",
|
||||
"strum",
|
||||
"tempdir",
|
||||
"tokens",
|
||||
"tokio",
|
||||
]
|
||||
@@ -5900,6 +5941,7 @@ dependencies = [
|
||||
"md-5 0.9.1",
|
||||
"media",
|
||||
"memory_caching",
|
||||
"migration",
|
||||
"mimetypes",
|
||||
"my-workspace-hack",
|
||||
"mysql_queries",
|
||||
|
||||
@@ -49,6 +49,7 @@ members = [
|
||||
"crates/lib/idempotency",
|
||||
"crates/lib/jobs_common",
|
||||
"crates/lib/logging",
|
||||
"crates/lib/migration",
|
||||
"crates/lib/mysql_queries",
|
||||
"crates/lib/password",
|
||||
"crates/lib/redis_common",
|
||||
|
||||
@@ -310,7 +310,7 @@ Secrets:
|
||||
- Put `.env-secrets` in the root `storyteller-rust` directory.
|
||||
|
||||
- Per app secrets (ask Brandon for these):
|
||||
- Put `storteller-web.development-secrets.env` in `crates/service/web/storyteller-web/config`
|
||||
- Put `storteller-web.development-secrets.env` in `crates/service/web/storyteller_web/config`
|
||||
- Put `inference-job.development-secrets.env` in `crates/service/job/inference_job/config`
|
||||
- Put `donwload-job.development-secrets.env` in `crates/service/job/download_job/config`
|
||||
|
||||
@@ -392,4 +392,4 @@ We use this: `https://github.com/juhaku/utoipa`
|
||||
The documentation example is in:
|
||||
`crates/service/web/storyteller_web/src/http_server/endpoints/voice_designer/inference/enqueue_tts_request.rs`
|
||||
Write into the api doc to:
|
||||
`crates/service/web/storyteller_web/src/api_doc.rs`
|
||||
`crates/service/web/storyteller_web/src/api_doc.rs`
|
||||
|
||||
@@ -23,6 +23,27 @@ and success_execution_millis IS NOT NULL
|
||||
order by id desc
|
||||
limit 50;
|
||||
|
||||
-- See how many are using a deleted model
|
||||
select
|
||||
creator_ip_address,
|
||||
count(*)
|
||||
from generic_inference_jobs
|
||||
where maybe_model_token = 'vcm_4x8a30h1r26z'
|
||||
and created_at > NOW() - INTERVAL 24 HOUR
|
||||
group by creator_ip_address
|
||||
|
||||
-- See which deleted models are in use
|
||||
select
|
||||
vm.token,
|
||||
vm.title,
|
||||
count(*)
|
||||
from generic_inference_jobs as j
|
||||
join voice_conversion_models as vm
|
||||
on j.maybe_model_token = vm.token
|
||||
where vm.mod_deleted_at IS NOT NULL
|
||||
and j.created_at > NOW() - INTERVAL 24 HOUR
|
||||
group by vm.token, vm.title
|
||||
|
||||
-- See who is uploading SadTalker jobs
|
||||
select
|
||||
maybe_creator_user_token,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN public_bucket_hash TO private_bucket_hash;
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN maybe_public_bucket_prefix TO maybe_private_bucket_prefix;
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN maybe_public_bucket_extension TO maybe_private_bucket_extension;
|
||||
@@ -0,0 +1,12 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN private_bucket_hash TO public_bucket_hash;
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN maybe_private_bucket_prefix TO maybe_public_bucket_prefix;
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN maybe_private_bucket_extension TO maybe_public_bucket_extension;
|
||||
@@ -113,22 +113,22 @@ CREATE TABLE model_weights (
|
||||
-- The hash for the bucket directory that contains the original upload
|
||||
-- as well as any associated other files.
|
||||
-- The bucket filename for the primary file (not including the directory path) is given by:
|
||||
-- `[{maybe_private_bucket_prefix}]{private_bucket_hash}[{maybe_private_bucket_extension}]`
|
||||
private_bucket_hash VARCHAR(32) NOT NULL,
|
||||
-- `[{maybe_public_bucket_prefix}]{public_bucket_hash}[{maybe_public_bucket_extension}]`
|
||||
public_bucket_hash VARCHAR(32) NOT NULL,
|
||||
|
||||
-- An optional prefix on the bucket filename.
|
||||
-- If present, this will be prepended to the beginning of the bucket filename to access the file.
|
||||
-- The bucket filename for the primary file (not including the directory path) is given by:
|
||||
-- `[{maybe_private_bucket_prefix}]{private_directory_hash}[{maybe_private_bucket_extension}]`
|
||||
maybe_private_bucket_prefix VARCHAR(16) DEFAULT NULL,
|
||||
-- `[{maybe_public_bucket_prefix}]{public_bucket_hash}[{maybe_public_bucket_extension}]`
|
||||
maybe_public_bucket_prefix VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
-- An optional appended extension on the bucket filename.
|
||||
-- If present, this will be appended to the end of the bucket filename to access the file.
|
||||
-- To allow for flexibility, this extension typically will contain a leading period if
|
||||
-- the file needs it (eg ".mp4" rather than "mp4")!
|
||||
-- The bucket filename for the primary file (not including the directory path) is given by:
|
||||
-- `[{maybe_private_bucket_prefix}]{private_directory_hash}[{maybe_private_bucket_extension}]`
|
||||
maybe_private_bucket_extension VARCHAR(16) DEFAULT NULL,
|
||||
-- `[{maybe_public_bucket_prefix}]{public_bucket_hash}[{maybe_public_bucket_extension}]`
|
||||
maybe_public_bucket_extension VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
|
||||
-- ========== MODERATION DETAILS ==========
|
||||
|
||||
@@ -18,6 +18,7 @@ path = "src/lib.rs"
|
||||
crockford = { path = "../../lib/crockford" }
|
||||
errors = { path = "../../lib/errors" }
|
||||
|
||||
|
||||
# Workspace hack (faster compile times)
|
||||
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
// Okay to toggle
|
||||
#![forbid(unreachable_patterns)]
|
||||
#![forbid(unused_imports)]
|
||||
// #![forbid(unused_imports)]
|
||||
#![forbid(unused_mut)]
|
||||
#![forbid(unused_variables)]
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
pub trait descriptor {
|
||||
fn my_method(&self);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
pub mod bucket_directory;
|
||||
pub mod bucket_file_path;
|
||||
pub mod web_file_manager;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
pub struct FileBucketPath {
|
||||
pub bucket_clients: BucketClients
|
||||
}
|
||||
|
||||
impl web_file_manager {
|
||||
pub fn new(my_field: i32) -> Self {
|
||||
web_file_manager { my_field }
|
||||
}
|
||||
|
||||
pub fn increment(&mut self) {
|
||||
self.my_field += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
let my_class = web_file_manager::new(10);
|
||||
assert_eq!(my_class.my_field, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_increment() {
|
||||
let mut my_class = web_file_manager::new(10);
|
||||
my_class.increment();
|
||||
assert_eq!(my_class.my_field, 11);
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,4 @@ pub mod media_uploads;
|
||||
pub mod public_path;
|
||||
pub mod voice_conversion_results;
|
||||
pub mod weight_uploads;
|
||||
pub mod weight_files;
|
||||
pub mod weight_files;
|
||||
|
||||
@@ -25,6 +25,31 @@ impl PublicPath for WeightFileBucketPath {}
|
||||
|
||||
impl WeightFileBucketPath {
|
||||
|
||||
// TODO(bt,2023-12-19): This is temporary standardization. Clean this up.
|
||||
pub fn generate_for_svc_model() -> Self {
|
||||
Self::generate_new(Some("svc_"), Some(".pt"))
|
||||
}
|
||||
|
||||
// TODO(bt,2023-12-19): This is temporary standardization. Clean this up.
|
||||
pub fn generate_for_rvc_model() -> Self {
|
||||
Self::generate_new(Some("rvc_"), Some(".pt"))
|
||||
}
|
||||
|
||||
// TODO(bt,2023-12-19): This is temporary standardization. Clean this up.
|
||||
pub fn svc_model_file_from_object_hash(hash: &str) -> Self {
|
||||
Self::from_object_hash(hash, Some("svc_"), Some(".pt"))
|
||||
}
|
||||
|
||||
// TODO(bt,2023-12-19): This is temporary standardization. Clean this up.
|
||||
pub fn rvc_model_file_from_object_hash(hash: &str) -> Self {
|
||||
Self::from_object_hash(hash, Some("rvc_"), Some(".pt"))
|
||||
}
|
||||
|
||||
// TODO(bt,2023-12-19): This is temporary standardization. Clean this up.
|
||||
pub fn rvc_index_file_from_object_hash(hash: &str) -> Self {
|
||||
Self::from_object_hash(hash, Some("rvc_"), Some(".index"))
|
||||
}
|
||||
|
||||
pub fn generate_new(optional_prefix: Option<&str>, optional_extension: Option<&str>) -> Self {
|
||||
let entropy = crockford_entropy_lower(32);
|
||||
Self::from_object_hash(&entropy, optional_prefix, optional_extension)
|
||||
@@ -71,6 +96,14 @@ impl WeightFileBucketPath {
|
||||
pub fn get_basename(&self) -> &str {
|
||||
&self.filename
|
||||
}
|
||||
|
||||
pub fn get_optional_prefix(&self) -> Option<&str> {
|
||||
self.optional_prefix.as_deref()
|
||||
}
|
||||
|
||||
pub fn get_optional_extension(&self) -> Option<&str> {
|
||||
self.optional_extension.as_deref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -95,6 +128,49 @@ mod tests {
|
||||
assert_eq!(file.get_full_object_path_str(), "/weights/a/b/c/d/e/abcdefghijk/pre_abcdefghijk.mp4");
|
||||
assert_eq!(file.get_basename(), "pre_abcdefghijk.mp4");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn generate_for_rvc_model() {
|
||||
let file = WeightFileBucketPath::generate_for_rvc_model();
|
||||
assert_eq!(file.get_object_hash().len(), 32);
|
||||
assert_eq!(file.get_directory().get_object_hash().len(), 32);
|
||||
assert_eq!(file.get_optional_prefix(), Some("rvc_"));
|
||||
assert_eq!(file.get_optional_extension(), Some(".pt"));
|
||||
assert!(file.get_basename().starts_with("rvc_"));
|
||||
assert!(file.get_basename().ends_with(".pt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn generate_for_svc_model() {
|
||||
let file = WeightFileBucketPath::generate_for_svc_model();
|
||||
assert_eq!(file.get_object_hash().len(), 32);
|
||||
assert_eq!(file.get_directory().get_object_hash().len(), 32);
|
||||
assert_eq!(file.get_optional_prefix(), Some("svc_"));
|
||||
assert_eq!(file.get_optional_extension(), Some(".pt"));
|
||||
assert!(file.get_basename().starts_with("svc_"));
|
||||
assert!(file.get_basename().ends_with(".pt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn svc_model_file_from_object_hash() {
|
||||
let file = WeightFileBucketPath::svc_model_file_from_object_hash("hashed");
|
||||
assert_eq!(file.get_full_object_path_str(), "/weights/h/a/s/h/e/hashed/svc_hashed.pt");
|
||||
assert_eq!(file.get_basename(), "svc_hashed.pt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn rvc_model_file_from_object_hash() {
|
||||
let file = WeightFileBucketPath::rvc_model_file_from_object_hash("hashed");
|
||||
assert_eq!(file.get_full_object_path_str(), "/weights/h/a/s/h/e/hashed/rvc_hashed.pt");
|
||||
assert_eq!(file.get_basename(), "rvc_hashed.pt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn rvc_index_file_from_object_hash() {
|
||||
let file = WeightFileBucketPath::rvc_index_file_from_object_hash("hashed");
|
||||
assert_eq!(file.get_full_object_path_str(), "/weights/h/a/s/h/e/hashed/rvc_hashed.index");
|
||||
assert_eq!(file.get_basename(), "rvc_hashed.index");
|
||||
}
|
||||
}
|
||||
|
||||
mod without_prefix_and_extension {
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use errors::AnyhowResult;
|
||||
use errors::bail;
|
||||
|
||||
#[deprecated(note = "this is a messy function and should be avoided")]
|
||||
pub (crate) fn hash_to_bucket_path(file_hash: &str,
|
||||
optional_root_directory: Option<&str>)
|
||||
-> AnyhowResult<PathBuf>
|
||||
{
|
||||
if file_hash.len() < 4 {
|
||||
bail!("File length is too short");
|
||||
}
|
||||
|
||||
let root_directory = optional_root_directory
|
||||
.map(|root| PathBuf::from(root.to_string()))
|
||||
.unwrap_or(PathBuf::from("/"));
|
||||
|
||||
let file_path = format!(
|
||||
"{}/{}/{}/{}",
|
||||
&file_hash[0..1],
|
||||
&file_hash[1..2],
|
||||
&file_hash[2..3],
|
||||
&file_hash,
|
||||
);
|
||||
|
||||
Ok(root_directory.join(file_path))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::util::hash_to_bucket_path::hash_to_bucket_path;
|
||||
|
||||
#[test]
|
||||
fn test_bucket_without_root() {
|
||||
assert_eq!(
|
||||
hash_to_bucket_path("abcdefg", None).unwrap(),
|
||||
PathBuf::from("/a/b/c/abcdefg"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bucket_with_root() {
|
||||
assert_eq!(
|
||||
hash_to_bucket_path("abcdefg", Some("/root")).unwrap(),
|
||||
PathBuf::from("/root/a/b/c/abcdefg"));
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
use errors::anyhow;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
use crate::util::hash_to_bucket_path::hash_to_bucket_path;
|
||||
|
||||
#[deprecated(note = "this is a messy function and should be avoided")]
|
||||
pub fn hash_to_bucket_path_string(file_hash: &str,
|
||||
optional_root_directory: Option<&str>)
|
||||
-> AnyhowResult<String>
|
||||
{
|
||||
let path = hash_to_bucket_path(file_hash, optional_root_directory)?;
|
||||
|
||||
let maybe_path = path.to_str().map(|s| s.to_string());
|
||||
|
||||
maybe_path.ok_or(anyhow!("Path could not be converted"))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::util::hash_to_bucket_path_string::hash_to_bucket_path_string;
|
||||
|
||||
#[test]
|
||||
fn test_bucket_without_root() {
|
||||
assert_eq!(
|
||||
hash_to_bucket_path_string("abcdefg", None).unwrap(),
|
||||
"/a/b/c/abcdefg".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bucket_with_root() {
|
||||
assert_eq!(
|
||||
hash_to_bucket_path_string("abcdefg", Some("/root")).unwrap(),
|
||||
"/root/a/b/c/abcdefg".to_string());
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
/// With a million items, each directory will have ~244 items.
|
||||
/// With a billion items, each directory will have ~244,140 items (impractical at this scale).
|
||||
///
|
||||
#[deprecated(note = "Use hashed_directory_path_long_string instead! (This function is only used by BucketPathUnifier, which should also die)")]
|
||||
pub fn hashed_directory_path_short_string(file_hash: &str) -> String {
|
||||
match file_hash.len() {
|
||||
0 | 1 => "".to_string(),
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
pub (crate) mod hash_to_bucket_path;
|
||||
pub mod hash_to_bucket_path_string;
|
||||
pub mod hashed_directory_path_long_string;
|
||||
pub mod hashed_directory_path_short_string;
|
||||
|
||||
@@ -26,8 +26,8 @@ pub enum InferenceCategory {
|
||||
#[serde(rename = "voice_conversion")]
|
||||
VoiceConversion,
|
||||
|
||||
#[serde(rename = "rerender_a_video")]
|
||||
RerenderAVideo,
|
||||
#[serde(rename = "video_filter")]
|
||||
VideoFilter,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -41,7 +41,7 @@ impl InferenceCategory {
|
||||
Self::LipsyncAnimation => "lipsync_animation",
|
||||
Self::TextToSpeech => "text_to_speech",
|
||||
Self::VoiceConversion => "voice_conversion",
|
||||
Self::RerenderAVideo => "rerender_a_video",
|
||||
Self::VideoFilter => "video_filter",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ impl InferenceCategory {
|
||||
"lipsync_animation" => Ok(Self::LipsyncAnimation),
|
||||
"text_to_speech" => Ok(Self::TextToSpeech),
|
||||
"voice_conversion" => Ok(Self::VoiceConversion),
|
||||
"rerender_a_video" => Ok(Self::RerenderAVideo),
|
||||
"video_filter" => Ok(Self::VideoFilter),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ impl InferenceCategory {
|
||||
Self::LipsyncAnimation,
|
||||
Self::TextToSpeech,
|
||||
Self::VoiceConversion,
|
||||
Self::RerenderAVideo,
|
||||
Self::VideoFilter,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ mod tests {
|
||||
assert_serialization(InferenceCategory::LipsyncAnimation, "lipsync_animation");
|
||||
assert_serialization(InferenceCategory::TextToSpeech, "text_to_speech");
|
||||
assert_serialization(InferenceCategory::VoiceConversion, "voice_conversion");
|
||||
assert_serialization(InferenceCategory::RerenderAVideo, "rerender_a_video");
|
||||
assert_serialization(InferenceCategory::VideoFilter, "video_filter");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -85,7 +85,7 @@ mod tests {
|
||||
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::RerenderAVideo.to_str(), "rerender_a_video");
|
||||
assert_eq!(InferenceCategory::VideoFilter.to_str(), "video_filter");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -93,7 +93,7 @@ mod tests {
|
||||
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("rerender_a_video").unwrap(), InferenceCategory::RerenderAVideo);
|
||||
assert_eq!(InferenceCategory::from_str("video_filter").unwrap(), InferenceCategory::VideoFilter);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -104,7 +104,7 @@ mod tests {
|
||||
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::RerenderAVideo));
|
||||
assert_eq!(variants.pop_first(), Some(InferenceCategory::VideoFilter));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
|
||||
// Generated check
|
||||
|
||||
@@ -21,9 +21,9 @@ pub enum IdCategory {
|
||||
#[serde(rename = "lipsync_animation")]
|
||||
LipsyncAnimationResult,
|
||||
|
||||
// Results from rerender a video
|
||||
#[serde(rename = "rerender")]
|
||||
RerenderResult,
|
||||
// Results from video filters
|
||||
#[serde(rename = "video_filter")]
|
||||
VideoFilterResult,
|
||||
|
||||
/// Results from tacotron2
|
||||
/// Applies for RVC and SVC
|
||||
@@ -49,6 +49,10 @@ pub enum IdCategory {
|
||||
|
||||
#[serde(rename = "model_weights")]
|
||||
ModelWeights,
|
||||
|
||||
/// Files that are uploaded with no general product area they belong to. (Eg. local dev testing)
|
||||
#[serde(rename = "file_upload")]
|
||||
FileUpload,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -66,8 +70,9 @@ impl IdCategory {
|
||||
Self::ZeroShotVoiceDataset => "zs_dataset",
|
||||
Self::ZeroShotVoiceEmbedding => "zs_voice",
|
||||
Self::ZeroShotTtsResult => "zs_tts_result",
|
||||
Self::RerenderResult => "rerender",
|
||||
Self::VideoFilterResult => "video_filter",
|
||||
Self::ModelWeights => "model_weights",
|
||||
Self::FileUpload => "file_upload",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,8 +85,9 @@ impl IdCategory {
|
||||
"zs_dataset" => Ok(Self::ZeroShotVoiceDataset),
|
||||
"zs_voice" => Ok(Self::ZeroShotVoiceEmbedding),
|
||||
"zs_tts_result" => Ok(Self::ZeroShotTtsResult),
|
||||
"rerender" => Ok(Self::RerenderResult),
|
||||
"video_filter" => Ok(Self::VideoFilterResult),
|
||||
"model_weights" => Ok(Self::ModelWeights),
|
||||
"file_upload" => Ok(Self::FileUpload),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -92,13 +98,14 @@ impl IdCategory {
|
||||
BTreeSet::from([
|
||||
Self::MediaFile,
|
||||
Self::LipsyncAnimationResult,
|
||||
Self::RerenderResult,
|
||||
Self::VideoFilterResult,
|
||||
Self::TtsResult,
|
||||
Self::VoiceConversionResult,
|
||||
Self::ZeroShotTtsResult,
|
||||
Self::ZeroShotVoiceDataset,
|
||||
Self::ZeroShotVoiceEmbedding,
|
||||
Self::ModelWeights,
|
||||
Self::FileUpload,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -115,55 +122,59 @@ mod tests {
|
||||
fn test_serialization() {
|
||||
assert_serialization(IdCategory::MediaFile, "media_file");
|
||||
assert_serialization(IdCategory::LipsyncAnimationResult, "lipsync_animation");
|
||||
assert_serialization(IdCategory::RerenderResult, "rerender");
|
||||
assert_serialization(IdCategory::VideoFilterResult, "video_filter");
|
||||
assert_serialization(IdCategory::TtsResult, "tts_result");
|
||||
assert_serialization(IdCategory::VoiceConversionResult, "voice_conversion");
|
||||
assert_serialization(IdCategory::ZeroShotVoiceDataset, "zs_dataset");
|
||||
assert_serialization(IdCategory::ZeroShotVoiceEmbedding, "zs_voice");
|
||||
assert_serialization(IdCategory::ZeroShotTtsResult, "zs_tts_result");
|
||||
assert_serialization(IdCategory::ModelWeights, "model_weights")
|
||||
assert_serialization(IdCategory::ModelWeights, "model_weights");
|
||||
assert_serialization(IdCategory::FileUpload, "file_upload");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(IdCategory::MediaFile.to_str(), "media_file");
|
||||
assert_eq!(IdCategory::LipsyncAnimationResult.to_str(), "lipsync_animation");
|
||||
assert_eq!(IdCategory::RerenderResult.to_str(), "rerender");
|
||||
assert_eq!(IdCategory::VideoFilterResult.to_str(), "video_filter");
|
||||
assert_eq!(IdCategory::TtsResult.to_str(), "tts_result");
|
||||
assert_eq!(IdCategory::VoiceConversionResult.to_str(), "voice_conversion");
|
||||
assert_eq!(IdCategory::ZeroShotVoiceDataset.to_str(), "zs_dataset");
|
||||
assert_eq!(IdCategory::ZeroShotVoiceEmbedding.to_str(), "zs_voice");
|
||||
assert_eq!(IdCategory::ZeroShotTtsResult.to_str(), "zs_tts_result");
|
||||
assert_eq!(IdCategory::ModelWeights.to_str(), "model_weights");
|
||||
assert_eq!(IdCategory::FileUpload.to_str(), "file_upload");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(IdCategory::from_str("media_file").unwrap(), IdCategory::MediaFile);
|
||||
assert_eq!(IdCategory::from_str("lipsync_animation").unwrap(), IdCategory::LipsyncAnimationResult);
|
||||
assert_eq!(IdCategory::from_str("rerender").unwrap(), IdCategory::RerenderResult);
|
||||
assert_eq!(IdCategory::from_str("video_filter").unwrap(), IdCategory::VideoFilterResult);
|
||||
assert_eq!(IdCategory::from_str("tts_result").unwrap(), IdCategory::TtsResult);
|
||||
assert_eq!(IdCategory::from_str("voice_conversion").unwrap(), IdCategory::VoiceConversionResult);
|
||||
assert_eq!(IdCategory::from_str("zs_dataset").unwrap(), IdCategory::ZeroShotVoiceDataset);
|
||||
assert_eq!(IdCategory::from_str("zs_voice").unwrap(), IdCategory::ZeroShotVoiceEmbedding);
|
||||
assert_eq!(IdCategory::from_str("zs_tts_result").unwrap(), IdCategory::ZeroShotTtsResult);
|
||||
assert_eq!(IdCategory::from_str("model_weights").unwrap(), IdCategory::ModelWeights);
|
||||
assert_eq!(IdCategory::from_str("file_upload").unwrap(), IdCategory::FileUpload);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
// Static check
|
||||
let mut variants = IdCategory::all_variants();
|
||||
assert_eq!(variants.len(), 9);
|
||||
assert_eq!(variants.len(), 10);
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::MediaFile));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::LipsyncAnimationResult));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::RerenderResult));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::VideoFilterResult));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::TtsResult));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::VoiceConversionResult));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::ZeroShotTtsResult));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::ZeroShotVoiceDataset));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::ZeroShotVoiceEmbedding));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::ModelWeights));
|
||||
assert_eq!(variants.pop_first(), Some(IdCategory::FileUpload));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
|
||||
// Generated check
|
||||
|
||||
@@ -6,12 +6,13 @@ use serde::Serialize;
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `media_files` table in a `VARCHAR` field.
|
||||
///
|
||||
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MediaFileOriginCategory {
|
||||
/// ML model inference output - uploaded models or zero shot.
|
||||
|
||||
@@ -6,12 +6,13 @@ use serde::Serialize;
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `media_files` table in a `VARCHAR` field.
|
||||
///
|
||||
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MediaFileOriginModelType {
|
||||
/// RVC (v2) voice conversion models
|
||||
|
||||
+12
-11
@@ -4,6 +4,7 @@ use std::collections::BTreeSet;
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `media_files` table in `VARCHAR(16)` field `origin_product_category`.
|
||||
///
|
||||
@@ -14,7 +15,7 @@ use strum::EnumIter;
|
||||
///
|
||||
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
|
||||
pub enum MediaFileOriginProductCategory {
|
||||
/// Media files created by (or uploaded for) the Face Animator product.
|
||||
/// The underlying model could be SadTalker, Wav2Lip, or some future model
|
||||
@@ -39,9 +40,9 @@ pub enum MediaFileOriginProductCategory {
|
||||
#[serde(rename = "zs_voice")]
|
||||
ZeroShotVoice,
|
||||
|
||||
// Media files for Rerender
|
||||
#[serde(rename = "rerender")]
|
||||
Rerender,
|
||||
// Media files for video filters
|
||||
#[serde(rename = "video_filter")]
|
||||
VideoFilter,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -58,7 +59,7 @@ impl MediaFileOriginProductCategory {
|
||||
Self::Unknown => "unknown",
|
||||
Self::VoiceConversion => "voice_conversion",
|
||||
Self::ZeroShotVoice => "zs_voice",
|
||||
Self::Rerender => "rerender",
|
||||
Self::VideoFilter => "video_filter",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ impl MediaFileOriginProductCategory {
|
||||
"unknown" => Ok(Self::Unknown),
|
||||
"voice_conversion" => Ok(Self::VoiceConversion),
|
||||
"zs_voice" => Ok(Self::ZeroShotVoice),
|
||||
"rerender" => Ok(Self::Rerender),
|
||||
"video_filter" => Ok(Self::VideoFilter),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -80,7 +81,7 @@ impl MediaFileOriginProductCategory {
|
||||
BTreeSet::from([
|
||||
Self::FaceAnimator,
|
||||
Self::TextToSpeech,
|
||||
Self::Rerender,
|
||||
Self::VideoFilter,
|
||||
Self::Unknown,
|
||||
Self::VoiceConversion,
|
||||
Self::ZeroShotVoice,
|
||||
@@ -103,7 +104,7 @@ mod tests {
|
||||
assert_serialization(MediaFileOriginProductCategory::Unknown, "unknown");
|
||||
assert_serialization(MediaFileOriginProductCategory::VoiceConversion, "voice_conversion");
|
||||
assert_serialization(MediaFileOriginProductCategory::ZeroShotVoice, "zs_voice");
|
||||
assert_serialization(MediaFileOriginProductCategory::Rerender, "rerender")
|
||||
assert_serialization(MediaFileOriginProductCategory::VideoFilter, "video_filter")
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -113,7 +114,7 @@ mod tests {
|
||||
assert_eq!(MediaFileOriginProductCategory::Unknown.to_str(), "unknown");
|
||||
assert_eq!(MediaFileOriginProductCategory::VoiceConversion.to_str(), "voice_conversion");
|
||||
assert_eq!(MediaFileOriginProductCategory::ZeroShotVoice.to_str(), "zs_voice");
|
||||
assert_eq!(MediaFileOriginProductCategory::Rerender.to_str(), "rerender");
|
||||
assert_eq!(MediaFileOriginProductCategory::VideoFilter.to_str(), "video_filter");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -123,7 +124,7 @@ mod tests {
|
||||
assert_eq!(MediaFileOriginProductCategory::from_str("unknown").unwrap(), MediaFileOriginProductCategory::Unknown);
|
||||
assert_eq!(MediaFileOriginProductCategory::from_str("voice_conversion").unwrap(), MediaFileOriginProductCategory::VoiceConversion);
|
||||
assert_eq!(MediaFileOriginProductCategory::from_str("zs_voice").unwrap(), MediaFileOriginProductCategory::ZeroShotVoice);
|
||||
assert_eq!(MediaFileOriginProductCategory::from_str("rerender").unwrap(), MediaFileOriginProductCategory::Rerender);
|
||||
assert_eq!(MediaFileOriginProductCategory::from_str("video_filter").unwrap(), MediaFileOriginProductCategory::VideoFilter);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -135,7 +136,7 @@ mod tests {
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::Unknown));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::VoiceConversion));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::ZeroShotVoice));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::Rerender));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::VideoFilter));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ use std::collections::BTreeSet;
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `media_files` table in a `VARCHAR` field.
|
||||
///
|
||||
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum MediaFileType {
|
||||
/// Audio files: wav, mp3, etc.
|
||||
|
||||
@@ -4,10 +4,11 @@ use serde::Serialize;
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `user_bookmarks` table in a `VARCHAR(32)` field named `entity_type`.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize, ToSchema)]
|
||||
pub enum UserBookmarkEntityType {
|
||||
/// User
|
||||
#[serde(rename = "user")]
|
||||
|
||||
@@ -2,11 +2,12 @@ use std::fmt::Debug;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::prefixes::TokenPrefix;
|
||||
|
||||
/// The primary key for Audit Logs.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[sqlx(transparent)]
|
||||
pub struct MediaFileToken(pub String);
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@ use std::fmt::Debug;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use utoipa::ToSchema;
|
||||
use crate::prefixes::TokenPrefix;
|
||||
|
||||
|
||||
/// The primary key for Audit Logs.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[sqlx(transparent)]
|
||||
pub struct UserBookmarkToken(pub String);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use enums::by_table::model_weights::{
|
||||
};
|
||||
use enums::common::visibility::Visibility;
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use mysql_queries::queries::model_weights::create_weight::{create_weight, CreateModelWeightsArgs};
|
||||
use mysql_queries::queries::model_weights::create::create_weight::{create_weight, CreateModelWeightsArgs};
|
||||
use mysql_queries::queries::users::user::get_user_token_by_username::get_user_token_by_username;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
@@ -335,9 +335,9 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
original_filename: Some(original_filename),
|
||||
file_size_bytes: 1024,
|
||||
file_checksum_sha2: "checksum1".to_string(),
|
||||
private_bucket_hash: "bucket_hash1".to_string(),
|
||||
maybe_private_bucket_prefix: Some(private_bucket_prefix),
|
||||
maybe_private_bucket_extension: Some(private_bucket_extension),
|
||||
public_bucket_hash: "bucket_hash1".to_string(),
|
||||
maybe_public_bucket_prefix: Some(private_bucket_prefix),
|
||||
maybe_public_bucket_extension: Some(private_bucket_extension),
|
||||
cached_user_ratings_total_count,
|
||||
cached_user_ratings_positive_count,
|
||||
cached_user_ratings_negative_count,
|
||||
@@ -381,9 +381,9 @@ pub async fn seed_weights_for_user_token(
|
||||
original_filename: Some("filename1.txt".to_string()),
|
||||
file_size_bytes: 1024,
|
||||
file_checksum_sha2: "checksum1".to_string(),
|
||||
private_bucket_hash: "bucket_hash1".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("rvc".to_string()),
|
||||
public_bucket_hash: "bucket_hash1".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("rvc".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
@@ -407,9 +407,9 @@ pub async fn seed_weights_for_user_token(
|
||||
original_filename: Some("filename2.txt".to_string()),
|
||||
file_size_bytes: 2024,
|
||||
file_checksum_sha2: "checksum2".to_string(),
|
||||
private_bucket_hash: "bucket_hash2".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("tt2".to_string()),
|
||||
public_bucket_hash: "bucket_hash2".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("tt2".to_string()),
|
||||
cached_user_ratings_total_count: 20,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 2,
|
||||
@@ -433,9 +433,9 @@ pub async fn seed_weights_for_user_token(
|
||||
original_filename: Some("filename3.txt".to_string()),
|
||||
file_size_bytes: 3024,
|
||||
file_checksum_sha2: "checksum3".to_string(),
|
||||
private_bucket_hash: "bucket_hash3".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("safetensors".to_string()),
|
||||
public_bucket_hash: "bucket_hash3".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("safetensors".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
@@ -459,9 +459,9 @@ pub async fn seed_weights_for_user_token(
|
||||
original_filename: Some("filename1.txt".to_string()),
|
||||
file_size_bytes: 1024,
|
||||
file_checksum_sha2: "checksum4".to_string(),
|
||||
private_bucket_hash: "bucket_hash4".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("LoRA".to_string()),
|
||||
public_bucket_hash: "bucket_hash4".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("LoRA".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
@@ -485,9 +485,9 @@ pub async fn seed_weights_for_user_token(
|
||||
original_filename: Some("filename1.txt".to_string()),
|
||||
file_size_bytes: 1024,
|
||||
file_checksum_sha2: "checksum4".to_string(),
|
||||
private_bucket_hash: "bucket_hash4".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("LoRA".to_string()),
|
||||
public_bucket_hash: "bucket_hash4".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("LoRA".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
@@ -537,9 +537,9 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
original_filename: Some("filename1.txt".to_string()),
|
||||
file_size_bytes: 1024,
|
||||
file_checksum_sha2: "checksum1".to_string(),
|
||||
private_bucket_hash: "bucket_hash1".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("rvc".to_string()),
|
||||
public_bucket_hash: "bucket_hash1".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("rvc".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
@@ -563,9 +563,9 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
original_filename: Some("filename2.txt".to_string()),
|
||||
file_size_bytes: 2024,
|
||||
file_checksum_sha2: "checksum2".to_string(),
|
||||
private_bucket_hash: "bucket_hash2".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("tt2".to_string()),
|
||||
public_bucket_hash: "bucket_hash2".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("tt2".to_string()),
|
||||
cached_user_ratings_total_count: 20,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 2,
|
||||
@@ -589,9 +589,9 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
original_filename: Some("filename3.txt".to_string()),
|
||||
file_size_bytes: 3024,
|
||||
file_checksum_sha2: "checksum3".to_string(),
|
||||
private_bucket_hash: "bucket_hash3".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("safetensors".to_string()),
|
||||
public_bucket_hash: "bucket_hash3".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("safetensors".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
@@ -615,9 +615,9 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
original_filename: Some("filename1.txt".to_string()),
|
||||
file_size_bytes: 1024,
|
||||
file_checksum_sha2: "checksum4".to_string(),
|
||||
private_bucket_hash: "bucket_hash4".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("LoRA".to_string()),
|
||||
public_bucket_hash: "bucket_hash4".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("LoRA".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
@@ -641,9 +641,9 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
original_filename: Some("filename1.txt".to_string()),
|
||||
file_size_bytes: 1025,
|
||||
file_checksum_sha2: "checksum5".to_string(),
|
||||
private_bucket_hash: "bucket_hash5".to_string(),
|
||||
maybe_private_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_private_bucket_extension: Some("LoRA".to_string()),
|
||||
public_bucket_hash: "bucket_hash5".to_string(),
|
||||
maybe_public_bucket_prefix: Some("_fake".to_string()),
|
||||
maybe_public_bucket_extension: Some("LoRA".to_string()),
|
||||
cached_user_ratings_total_count: 10,
|
||||
cached_user_ratings_positive_count: 9,
|
||||
cached_user_ratings_negative_count: 1,
|
||||
|
||||
@@ -5,16 +5,18 @@ use sqlx::{MySql, Pool};
|
||||
|
||||
use buckets::public::media_files::bucket_file_path::MediaFileBucketPath;
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
|
||||
use enums::common::visibility::Visibility;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
use filesys::file_read_bytes::file_read_bytes;
|
||||
use filesys::file_size::file_size;
|
||||
use filesys::path_to_string::path_to_string;
|
||||
use hashing::sha256::sha256_hash_file::sha256_hash_file;
|
||||
use mimetypes::mimetype_for_bytes::get_mimetype_for_bytes;
|
||||
use mimetypes::mimetype_for_file::get_mimetype_for_file;
|
||||
use mysql_queries::queries::media_files::create::insert_media_file_from_cli_tool::{insert_media_file_from_cli_tool, InsertArgs};
|
||||
use mysql_queries::queries::media_files::get_media_file::get_media_file;
|
||||
use mysql_queries::queries::media_files::insert_media_file_from_cli_tool::{insert_media_file_from_cli_tool, InsertArgs};
|
||||
use storyteller_root::get_seed_tool_data_root;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
@@ -106,7 +108,7 @@ async fn seed_model(
|
||||
let mut bucket_hash = "NOT_UPLOADED_BY_SEED_TOOL".to_string();
|
||||
let mut maybe_bucket_prefix = None;
|
||||
let mut maybe_bucket_extension = None;
|
||||
|
||||
|
||||
if media_file_exists(mysql_pool, media_file_token).await? {
|
||||
info!("Media file already seeded: {:?}", media_file_token);
|
||||
return Ok(())
|
||||
@@ -181,16 +183,16 @@ async fn seed_file_to_bucket(
|
||||
.extension()
|
||||
.map(|extension| extension.to_str())
|
||||
.flatten();
|
||||
|
||||
// get the new bucket path ...
|
||||
let bucket_location = MediaFileBucketPath::generate_new(maybe_bucket_prefix, maybe_bucket_extension);
|
||||
|
||||
|
||||
let bucket_path = path_to_string(bucket_location.to_full_object_pathbuf());
|
||||
|
||||
info!("Reading media file: {:?}", media_file_path);
|
||||
|
||||
// get meta data
|
||||
let bytes = file_read_bytes(media_file_path)?;
|
||||
let mimetype = get_mimetype_for_bytes(&bytes).unwrap_or("application/octet-stream");
|
||||
|
||||
|
||||
info!("Uploading media file to bucket path: {:?}", bucket_path);
|
||||
|
||||
let _r = bucket_clients.public.upload_file_with_content_type(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{path::Path, string};
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use log::{info, warn};
|
||||
use std::path::Path;
|
||||
|
||||
use log::info;
|
||||
use rand::Rng;
|
||||
use sqlx::{MySql, Pool};
|
||||
|
||||
@@ -9,12 +9,13 @@ use enums::{
|
||||
by_table::model_weights::{weights_category::WeightsCategory, weights_types::WeightsType},
|
||||
common::visibility::Visibility,
|
||||
};
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use filesys::file_read_bytes::file_read_bytes;
|
||||
use filesys::file_size::file_size;
|
||||
use filesys::path_to_string::path_to_string;
|
||||
use hashing::sha256::sha256_hash_file::sha256_hash_file;
|
||||
use mimetypes::mimetype_for_bytes::get_mimetype_for_bytes;
|
||||
use mysql_queries::queries::model_weights::create_weight::{
|
||||
use mysql_queries::queries::model_weights::create::create_weight::{
|
||||
create_weight,
|
||||
CreateModelWeightsArgs,
|
||||
};
|
||||
@@ -24,7 +25,7 @@ use tokens::tokens::users::UserToken;
|
||||
|
||||
use crate::bucket_clients::BucketClients;
|
||||
use crate::seeding::users::HANASHI_USER_TOKEN;
|
||||
|
||||
use std::result::Result::Ok;
|
||||
pub async fn seed_weights_files(
|
||||
mysql_pool: &Pool<MySql>,
|
||||
maybe_bucket_clients: Option<&BucketClients>
|
||||
@@ -140,9 +141,9 @@ pub async fn seed_weights_files(
|
||||
original_filename: Some(original_filename.to_string()),
|
||||
file_size_bytes: file_size_bytes as i32, // Assuming the file size is 0
|
||||
file_checksum_sha2: sha256_checksum.to_string(), // Assuming the file checksum is an empty string
|
||||
private_bucket_hash: bucket_hash,
|
||||
maybe_private_bucket_prefix: Some(maybe_bucket_prefix.to_string()),
|
||||
maybe_private_bucket_extension: Some(maybe_bucket_extension.to_string()),
|
||||
public_bucket_hash: bucket_hash,
|
||||
maybe_public_bucket_prefix: Some(maybe_bucket_prefix.to_string()),
|
||||
maybe_public_bucket_extension: Some(maybe_bucket_extension.to_string()),
|
||||
cached_user_ratings_total_count,
|
||||
cached_user_ratings_positive_count,
|
||||
cached_user_ratings_negative_count,
|
||||
@@ -201,7 +202,7 @@ async fn seed_file_to_bucket(
|
||||
.map(|extension| extension.to_str())
|
||||
.flatten();
|
||||
// we should just have this be file bucket path and then we can use a file descriptor to turn it into a specific type of path
|
||||
let bucket_location = WeightFileBucketPath::generate_new(
|
||||
let bucket_location: WeightFileBucketPath = WeightFileBucketPath::generate_new(
|
||||
maybe_bucket_prefix,
|
||||
maybe_bucket_extension
|
||||
);
|
||||
|
||||
@@ -44,6 +44,7 @@ async fn create_rvc_model(
|
||||
|
||||
insert_voice_conversion_model_from_download_job(InsertVoiceConversionModelArgs {
|
||||
model_type: VoiceConversionModelType::RvcV2,
|
||||
maybe_new_weights_token: None,
|
||||
title,
|
||||
original_download_url: "https://example.com",
|
||||
original_filename: "unknown.zip",
|
||||
|
||||
@@ -11,7 +11,7 @@ use enums::common::visibility::Visibility;
|
||||
use errors::{AnyhowResult, bail};
|
||||
use filesys::file_read_bytes::file_read_bytes;
|
||||
use mimetypes::mimetype_for_bytes::get_mimetype_for_bytes;
|
||||
use mysql_queries::queries::media_files::insert_media_file_from_cli_tool::{insert_media_file_from_cli_tool, InsertArgs};
|
||||
use mysql_queries::queries::media_files::create::insert_media_file_from_cli_tool::{insert_media_file_from_cli_tool, InsertArgs};
|
||||
|
||||
use crate::cli_args::parse_cli_args;
|
||||
|
||||
|
||||
@@ -15,10 +15,13 @@ path = "src/main.rs"
|
||||
[dependencies]
|
||||
# Internal
|
||||
buckets = { path = "../../_types/buckets" }
|
||||
cloud_storage = { path = "../../lib/api_clients/cloud_storage" }
|
||||
config = { path = "../../lib/deprecated/config" }
|
||||
easyenv = { path = "../../lib/easyenv" }
|
||||
enums = { path = "../../_types/enums" }
|
||||
errors = { path = "../../lib/errors" }
|
||||
filesys = { path = "../../lib/files/filesys" }
|
||||
hashing = { path = "../../lib/files/hashing" }
|
||||
mysql_queries = { path = "../../lib/mysql_queries" }
|
||||
storyteller_root = { path = "../../lib/storyteller_root" }
|
||||
tokens = { path = "../../_types/tokens" }
|
||||
@@ -30,6 +33,7 @@ my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
|
||||
clap = "4.4.8"
|
||||
log = "0.4.14"
|
||||
strum = { version = "0.25", features = ["derive"] }
|
||||
tempdir = "0.3.7"
|
||||
|
||||
# Async + clients
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
use sqlx::{MySql, Pool};
|
||||
use cloud_storage::bucket_client::BucketClient;
|
||||
|
||||
pub struct Deps {
|
||||
pub mysql_development : Pool<MySql>,
|
||||
pub mysql_production : Pool<MySql>,
|
||||
|
||||
pub bucket_development_public: BucketClient,
|
||||
pub bucket_development_private: BucketClient,
|
||||
|
||||
pub bucket_production_public: BucketClient,
|
||||
pub bucket_production_private: BucketClient,
|
||||
}
|
||||
@@ -4,9 +4,21 @@
|
||||
//!
|
||||
|
||||
|
||||
use std::time::Duration;
|
||||
use log::info;
|
||||
use sqlx::{MySql, Pool};
|
||||
use sqlx::mysql::MySqlPoolOptions;
|
||||
use cloud_storage::bucket_client::BucketClient;
|
||||
|
||||
use config::shared_constants::DEFAULT_RUST_LOG;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
use crate::deps::Deps;
|
||||
use crate::migrations::voice_conversion_to_weights::migrate::migrate_voice_conversion_to_weights;
|
||||
|
||||
pub mod deps;
|
||||
pub mod migrations;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() -> AnyhowResult<()> {
|
||||
println!("migration-tool: migrate database records");
|
||||
@@ -18,6 +30,51 @@ pub async fn main() -> AnyhowResult<()> {
|
||||
// from other sources. (Hopefully this isn't getting out of hand at this point.)
|
||||
easyenv::from_filename(".env-migration-tool-secrets")?;
|
||||
|
||||
let deps = Deps {
|
||||
mysql_development: get_mysql("MYSQL_DEVELOPMENT_URL").await?,
|
||||
mysql_production: get_mysql("MYSQL_PRODUCTION_URL").await?,
|
||||
|
||||
bucket_development_public: get_bucket_client("DEVELOPMENT_PUBLIC")?,
|
||||
bucket_development_private: get_bucket_client("DEVELOPMENT_PRIVATE")?,
|
||||
bucket_production_public: get_bucket_client("PRODUCTION_PUBLIC")?,
|
||||
bucket_production_private: get_bucket_client("PRODUCTION_PRIVATE")?,
|
||||
};
|
||||
|
||||
migrate_voice_conversion_to_weights(&deps).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn get_mysql(env_var_name: &str) -> AnyhowResult<Pool<MySql>> {
|
||||
info!("Connecting to MySQL {env_var_name}...");
|
||||
|
||||
let pool = MySqlPoolOptions::new()
|
||||
.max_connections(easyenv::get_env_num("MYSQL_MAX_CONNECTIONS", 3)?)
|
||||
.connect(&easyenv::get_env_string_required(env_var_name)?)
|
||||
.await?;
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
|
||||
pub fn get_bucket_client(env_var_suffix: &str) -> AnyhowResult<BucketClient> {
|
||||
let env_var_suffix = env_var_suffix.to_uppercase();
|
||||
let access_key = easyenv::get_env_string_required(&format!("ACCESS_KEY_{env_var_suffix}"))?;
|
||||
let secret_key = easyenv::get_env_string_required(&format!("SECRET_KEY_{env_var_suffix}"))?;
|
||||
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}"))?;
|
||||
|
||||
// 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(
|
||||
"BUCKET_TIMEOUT_SECONDS", Duration::from_secs(60 * 10));
|
||||
|
||||
info!("Configuring GCS bucket {env_var_suffix} ...");
|
||||
|
||||
Ok(BucketClient::create(
|
||||
&access_key,
|
||||
&secret_key,
|
||||
®ion_name,
|
||||
&bucket_name,
|
||||
None,
|
||||
Some(bucket_timeout),
|
||||
)?)
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub mod voice_conversion_to_weights;
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
use tempdir::TempDir;
|
||||
|
||||
use buckets::public::weight_files::bucket_file_path::WeightFileBucketPath;
|
||||
use cloud_storage::bucket_path_unifier::BucketPathUnifier;
|
||||
use enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType;
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use filesys::safe_delete_temp_directory::safe_delete_temp_directory;
|
||||
use filesys::safe_delete_temp_file::safe_delete_temp_file;
|
||||
use hashing::sha256::sha256_hash_file::sha256_hash_file;
|
||||
use mysql_queries::queries::model_weights::migration::upsert_model_weight_from_voice_conversion_model::CopiedFileData;
|
||||
use mysql_queries::queries::voice_conversion::migration::list_whole_voice_conversion_models_using_cursor::WholeVoiceConversionModelRecord;
|
||||
|
||||
use crate::deps::Deps;
|
||||
|
||||
pub async fn copy_cloud_files(model: &WholeVoiceConversionModelRecord, deps: &Deps) -> AnyhowResult<CopiedFileData> {
|
||||
let copied_file_data = copy_model(model, deps).await?;
|
||||
|
||||
if model.has_index_file {
|
||||
copy_index_file(model, deps, &copied_file_data.bucket_path).await?;
|
||||
}
|
||||
|
||||
Ok(copied_file_data)
|
||||
}
|
||||
|
||||
async fn copy_model(model: &WholeVoiceConversionModelRecord, deps: &Deps) -> AnyhowResult<CopiedFileData> {
|
||||
let bucket_path_unifier = BucketPathUnifier::default_paths();
|
||||
|
||||
let old_model_bucket_path = match model.model_type {
|
||||
VoiceConversionModelType::RvcV2 => bucket_path_unifier.rvc_v2_model_path(&model.private_bucket_hash),
|
||||
VoiceConversionModelType::SoVitsSvc => bucket_path_unifier.so_vits_svc_model_path(&model.private_bucket_hash),
|
||||
VoiceConversionModelType::SoftVc => return Err(anyhow!("we never built softvc models")),
|
||||
};
|
||||
|
||||
// TODO(bt,2023-12-19): Probably faster to stream between buckets, but whatever.
|
||||
let temp_dir = TempDir::new("model_transfer")?;
|
||||
let model_temp_fs_path = temp_dir.path().join("model.bin");
|
||||
|
||||
deps.bucket_production_private.download_file_to_disk(&old_model_bucket_path, &model_temp_fs_path).await?;
|
||||
|
||||
let file_checksum = sha256_hash_file(&model_temp_fs_path)?;
|
||||
|
||||
let new_model_bucket_path = match model.model_type {
|
||||
VoiceConversionModelType::RvcV2 => WeightFileBucketPath::generate_for_rvc_model(),
|
||||
VoiceConversionModelType::SoVitsSvc => WeightFileBucketPath::generate_for_svc_model(),
|
||||
VoiceConversionModelType::SoftVc => return Err(anyhow!("we never built softvc models")),
|
||||
};
|
||||
|
||||
deps.bucket_production_public.upload_filename_with_content_type(
|
||||
&new_model_bucket_path.get_full_object_path_str(),
|
||||
&model_temp_fs_path,
|
||||
"application/octet-stream").await?;
|
||||
|
||||
safe_delete_temp_file(&model_temp_fs_path);
|
||||
safe_delete_temp_directory(&temp_dir);
|
||||
|
||||
Ok(CopiedFileData {
|
||||
bucket_path: new_model_bucket_path,
|
||||
file_sha_hash: file_checksum,
|
||||
})
|
||||
}
|
||||
|
||||
async fn copy_index_file(model: &WholeVoiceConversionModelRecord, deps: &Deps, bucket_path: &WeightFileBucketPath) -> AnyhowResult<()> {
|
||||
let bucket_path_unifier = BucketPathUnifier::default_paths();
|
||||
|
||||
let old_model_index_bucket_path = bucket_path_unifier.rvc_v2_model_index_path(&model.private_bucket_hash);
|
||||
|
||||
// TODO(bt,2023-12-19): Probably faster to stream between buckets, but whatever.
|
||||
let temp_dir = TempDir::new("model_transfer")?;
|
||||
let model_temp_fs_path = temp_dir.path().join("model.bin");
|
||||
|
||||
deps.bucket_production_private.download_file_to_disk(&old_model_index_bucket_path, &model_temp_fs_path).await?;
|
||||
|
||||
let new_model_bucket_path =
|
||||
WeightFileBucketPath::rvc_index_file_from_object_hash(bucket_path.get_object_hash());
|
||||
|
||||
deps.bucket_production_public.upload_filename_with_content_type(
|
||||
&new_model_bucket_path.get_full_object_path_str(),
|
||||
&model_temp_fs_path,
|
||||
"application/octet-stream").await?;
|
||||
|
||||
safe_delete_temp_file(&model_temp_fs_path);
|
||||
safe_delete_temp_directory(&temp_dir);
|
||||
|
||||
Ok(()) // NB: We don't care about the path of the index file.
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use log::{info, warn};
|
||||
|
||||
use buckets::public::weight_files::bucket_file_path::WeightFileBucketPath;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use errors::AnyhowResult;
|
||||
use mysql_queries::queries::model_weights::get_weight::get_weight_by_token;
|
||||
use mysql_queries::queries::model_weights::migration::upsert_model_weight_from_voice_conversion_model::{CopiedFileData, upsert_model_weight_from_voice_conversion_model};
|
||||
use mysql_queries::queries::voice_conversion::migration::list_whole_voice_conversion_models_using_cursor::{list_whole_voice_conversion_models_using_cursor, WholeVoiceConversionModelRecord};
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
use crate::deps::Deps;
|
||||
use crate::migrations::voice_conversion_to_weights::copy_cloud_files::copy_cloud_files;
|
||||
|
||||
const PAGE_SIZE: u64 = 10;
|
||||
|
||||
pub async fn migrate_voice_conversion_to_weights(deps: &Deps) -> AnyhowResult<()> {
|
||||
|
||||
let mut cursor = 0;
|
||||
|
||||
loop {
|
||||
info!("Querying {PAGE_SIZE} models at cursor = {cursor}");
|
||||
|
||||
let results
|
||||
= list_whole_voice_conversion_models_using_cursor(&deps.mysql_production, PAGE_SIZE, cursor).await?;
|
||||
|
||||
if results.is_empty() {
|
||||
warn!("No more results found; exiting.");
|
||||
break;
|
||||
}
|
||||
|
||||
for result in results.iter() {
|
||||
println!("\n\nmigrating over result {:?} : {:?} ...", result.token, result);
|
||||
copy_model_record_and_bucket_files(result, &deps).await?;
|
||||
}
|
||||
|
||||
if let Some(last_id) = results.last().map(|result| result.id) {
|
||||
cursor = last_id as u64;
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_secs(2));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn copy_model_record_and_bucket_files(record: &WholeVoiceConversionModelRecord, deps: &Deps) -> AnyhowResult<()> {
|
||||
let mut maybe_copied_data = None;
|
||||
|
||||
match &record.maybe_migration_new_model_weights_token {
|
||||
None => {
|
||||
info!("Copying bucket files for record {:?} ...", record.token);
|
||||
let result = copy_cloud_files(record, &deps).await?;
|
||||
maybe_copied_data = Some(result);
|
||||
}
|
||||
Some(token) => {
|
||||
info!("Existing migrated record; skipping cloud bucket copy...");
|
||||
maybe_copied_data = lookup_bucket_details_from_record(token, &deps).await?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(copied_data) = &maybe_copied_data {
|
||||
info!("Upserting records...");
|
||||
upsert_model_weight_from_voice_conversion_model(record, &deps.mysql_production, copied_data).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Look up the bucket storage details from a previously-migrated record
|
||||
async fn lookup_bucket_details_from_record(model_weight_token: &ModelWeightToken, deps: &Deps) -> AnyhowResult<Option<CopiedFileData>> {
|
||||
let maybe_model_weight_record =
|
||||
get_weight_by_token(model_weight_token, true, &deps.mysql_production).await?;
|
||||
|
||||
let model_weight_record = match maybe_model_weight_record {
|
||||
None => return Ok(None),
|
||||
Some(record) => record,
|
||||
};
|
||||
|
||||
let bucket_path = match model_weight_record.weights_type {
|
||||
WeightsType::RvcV2 => WeightFileBucketPath::rvc_model_file_from_object_hash(&model_weight_record.public_bucket_hash),
|
||||
WeightsType::SoVitsSvc => WeightFileBucketPath::svc_model_file_from_object_hash(&model_weight_record.public_bucket_hash),
|
||||
_ => return Ok(None), // NB: Stable Diffusion, etc. aren't valid for migration
|
||||
};
|
||||
|
||||
Ok(Some(CopiedFileData {
|
||||
bucket_path,
|
||||
file_sha_hash: model_weight_record.file_checksum_sha2,
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod copy_cloud_files;
|
||||
pub mod migrate;
|
||||
@@ -16,14 +16,21 @@ path = "src/lib.rs"
|
||||
|
||||
# Internal
|
||||
buckets = { path = "../../../_types/buckets" }
|
||||
|
||||
crockford = { path = "../../../lib/crockford" }
|
||||
errors = { path = "../../../lib/errors" }
|
||||
easyenv = { path = "../../../lib/easyenv" }
|
||||
filesys = { path = "../../../lib/files/filesys" }
|
||||
hashing = { path = "../../../lib/files/hashing" }
|
||||
mimetypes = { path = "../../../lib/files/mimetypes" }
|
||||
storyteller_root = { path = "../../../lib/storyteller_root" }
|
||||
# Workspace hack (faster compile times)
|
||||
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
|
||||
# External
|
||||
anyhow = "1.0.75"
|
||||
log = "0.4.14"
|
||||
|
||||
env_logger = "0.10.1"
|
||||
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" }
|
||||
@@ -31,3 +38,4 @@ rust-s3 = { version = "0.33.0" }
|
||||
# Runtime
|
||||
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
|
||||
tokio = { version = "1.34.0", features = ["macros"] }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
use errors::AnyhowResult;
|
||||
use anyhow::anyhow;
|
||||
use anyhow::bail;
|
||||
use log::info;
|
||||
@@ -10,15 +10,31 @@ use s3::creds::Credentials;
|
||||
use s3::region::Region;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BucketClient {
|
||||
bucket: Bucket,
|
||||
|
||||
/// If set, put all files under this root path.
|
||||
optional_bucket_root: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BucketClientError {
|
||||
ErrorWithCodeAndMessage { code: u16, message: String },
|
||||
}
|
||||
|
||||
impl std::fmt::Display for BucketClientError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
BucketClientError::ErrorWithCodeAndMessage { code, message } => write!(f, "Error {}: {}", code, message),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Error for BucketClientError {}
|
||||
|
||||
|
||||
impl BucketClient {
|
||||
|
||||
pub fn create(
|
||||
@@ -87,6 +103,25 @@ impl BucketClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn upload_file_with_content_type_process(&self, object_name: &str, bytes: &[u8], content_type: &str) -> AnyhowResult<()> {
|
||||
info!("Filename for bucket: {}", object_name);
|
||||
let object_name = self.get_rooted_object_name(object_name);
|
||||
info!("Rooted filename for bucket: {}", object_name);
|
||||
let response = self.bucket.put_object_with_content_type(&object_name, bytes, content_type).await?;
|
||||
let body_bytes = response.bytes();
|
||||
let code = response.status_code();
|
||||
info!("upload code: {}", code);
|
||||
if code != 200 {
|
||||
let body = String::from_utf8_lossy(body_bytes);
|
||||
warn!("upload body: {}", body);
|
||||
return Err(anyhow!("upload failed: {}", code));
|
||||
} else {
|
||||
info!("upload success: {}", code);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated = "Use upload_file instead above it returns an error we can surface and act on. upload_file_with_content_type_process"]
|
||||
pub async fn upload_file_with_content_type(&self, object_name: &str, bytes: &[u8], content_type: &str) -> anyhow::Result<()> {
|
||||
info!("Filename for bucket: {}", object_name);
|
||||
|
||||
@@ -191,8 +226,7 @@ impl BucketClient {
|
||||
&self,
|
||||
object_path: P,
|
||||
filesystem_path: Q,
|
||||
) -> anyhow::Result<()> {
|
||||
// TODO I think we might want to return an error here? but there has to a reason why we are just returning ok?
|
||||
) -> AnyhowResult<()> {
|
||||
let object_path_str = object_path.as_ref()
|
||||
.to_str()
|
||||
.map(|s| s.to_string())
|
||||
@@ -208,9 +242,7 @@ impl BucketClient {
|
||||
404 => bail!("File not found in bucket: {}", &object_path_str),
|
||||
_ => {},
|
||||
}
|
||||
|
||||
info!("download code: {}", status_code);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
pub mod bucket_client;
|
||||
pub mod bucket_path_unifier;
|
||||
pub mod remote_file_manager;
|
||||
pub mod remote_file_manager_mock;
|
||||
@@ -0,0 +1,131 @@
|
||||
use log::info;
|
||||
use tokio::time::Duration;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
use crate::bucket_client::BucketClient;
|
||||
use crate::remote_file_manager::file_meta_data::FileMetaData;
|
||||
|
||||
#[async_trait]
|
||||
pub trait BucketOrchestrationCore {
|
||||
async fn download_file_to_disk(
|
||||
&self,
|
||||
object_path: String,
|
||||
filesystem_path: String,
|
||||
is_public: bool,
|
||||
) -> AnyhowResult<()>;
|
||||
|
||||
async fn upload_file_with_content_type_process(&self, object_name: &str,
|
||||
bytes: &[u8],
|
||||
content_type: &str,
|
||||
is_public: bool) -> AnyhowResult<()>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub struct BucketOrchestration {
|
||||
access_key: String,
|
||||
secret_key: String,
|
||||
region_name: String,
|
||||
public_bucket_name: String,
|
||||
private_bucket_name: String,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl BucketOrchestrationCore for BucketOrchestration {
|
||||
async fn download_file_to_disk(
|
||||
&self,
|
||||
object_path: String,
|
||||
filesystem_path: String,
|
||||
is_public: bool,
|
||||
) -> AnyhowResult<()> {
|
||||
let bucket_client = self.get_bucket_with_visbility(is_public).await?;
|
||||
bucket_client.download_file_to_disk(object_path, filesystem_path).await
|
||||
}
|
||||
|
||||
async fn upload_file_with_content_type_process(&self, object_name: &str,
|
||||
bytes: &[u8],
|
||||
content_type: &str,
|
||||
is_public: bool) -> AnyhowResult<()> {
|
||||
let bucket_client = self.get_bucket_with_visbility(is_public).await?;
|
||||
bucket_client.upload_file_with_content_type_process(
|
||||
object_name,
|
||||
bytes,
|
||||
content_type,
|
||||
).await
|
||||
}
|
||||
}
|
||||
|
||||
impl BucketOrchestration {
|
||||
pub fn new_bucket_client_from_existing_env() -> AnyhowResult<Self> {
|
||||
let access_key = easyenv::get_env_string_required("ACCESS_KEY")?;
|
||||
let secret_key = easyenv::get_env_string_required("SECRET_KEY")?;
|
||||
|
||||
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 bucket_orchestration = BucketOrchestration::new(
|
||||
access_key,
|
||||
secret_key,
|
||||
region_name,
|
||||
public_bucket_name,
|
||||
private_bucket_name,
|
||||
);
|
||||
|
||||
Ok(bucket_orchestration)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
access_key: String,
|
||||
secret_key: String,
|
||||
region_name: String,
|
||||
public_bucket_name: String,
|
||||
private_bucket_name: String) -> Self {
|
||||
Self {
|
||||
access_key: access_key,
|
||||
secret_key: secret_key,
|
||||
region_name: region_name,
|
||||
public_bucket_name: public_bucket_name,
|
||||
private_bucket_name: private_bucket_name,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async fn get_bucket_with_visbility(&self, public: bool) -> AnyhowResult<BucketClient> {
|
||||
let bucket_timeout = easyenv::get_env_duration_seconds_or_default(
|
||||
"BUCKET_TIMEOUT_SECONDS", Duration::from_secs(60 * 10));
|
||||
let bucket_client: BucketClient;
|
||||
if public {
|
||||
// use public bucket client
|
||||
info!("Configuring public GCS bucket...");
|
||||
bucket_client = BucketClient::create(
|
||||
&self.access_key,
|
||||
&self.secret_key,
|
||||
&self.region_name,
|
||||
&self.public_bucket_name,
|
||||
None,
|
||||
Some(bucket_timeout),
|
||||
)?;
|
||||
} else {
|
||||
info!("Configuring private GCS bucket...");
|
||||
bucket_client = BucketClient::create(
|
||||
&self.access_key,
|
||||
&self.secret_key,
|
||||
&self.region_name,
|
||||
&self.private_bucket_name,
|
||||
None,
|
||||
Some(bucket_timeout),
|
||||
)?;
|
||||
}
|
||||
Ok(bucket_client)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
pub fn test() {}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Describes the file and how it will be saved to GCBucket
|
||||
// where the file should be stored based off the descriptor
|
||||
|
||||
// DEFAULT IMPLEMENTATION
|
||||
const REMOTE_FILE_DIRECTORY: &str = "/implement_google_cloud_storage_bucket_name";
|
||||
// File Descriptor Steers the Bucket Directory
|
||||
pub trait FileDescriptor {
|
||||
// By default a file belongs in the public bucket will help us figureout which bucket to use.
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file
|
||||
// e.g requires! a period .safetensors .bin .jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "implement".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, loRA, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "implement".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
#[test]
|
||||
pub fn test() {}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
use crockford::crockford_entropy_lower;
|
||||
use buckets::util::hashed_directory_path_long_string;
|
||||
use crate::remote_file_manager::file_descriptor::FileDescriptor;
|
||||
use crate::remote_file_manager::remote_cloud_bucket_details::RemoteCloudBucketDetails;
|
||||
|
||||
pub struct FileBucketDirectory {
|
||||
file_object_hash: String,
|
||||
remote_cloud_base_directory: String,
|
||||
full_remote_cloud_file_path: String,
|
||||
file_name: String,
|
||||
file_descriptor: Box<dyn FileDescriptor>
|
||||
}
|
||||
|
||||
impl FileBucketDirectory {
|
||||
pub fn generate_new(file_descriptor: Box<dyn FileDescriptor>) -> Self {
|
||||
Self::new_from_file_descriptor(file_descriptor)
|
||||
}
|
||||
|
||||
// TODO refactor this out of here
|
||||
pub fn from_existing_bucket_details(bucket_details:RemoteCloudBucketDetails) -> Self {
|
||||
let file_descriptor = bucket_details.file_descriptor_from_bucket_details();
|
||||
let entropy = bucket_details.get_object_hash();
|
||||
let middle = hashed_directory_path_long_string::hashed_directory_path_long_string(entropy.as_ref());
|
||||
// gets you cloud bucket path e.g weights/a/b/c/d/clould_path_entropy
|
||||
let remote_cloud_base_directory = format!("{}/{}{}", file_descriptor.remote_directory_path(), middle, entropy);
|
||||
// gets you name of the file with suffix and prefix and entropy in the centre
|
||||
let file_name = format!("{}_{}.{}", bucket_details.get_prefix(), entropy, bucket_details.get_suffix());
|
||||
// note: no longer optional because it's easy to know what it would be in the db explicit is better than implcit.
|
||||
// This is the full path you download from
|
||||
let full_remote_cloud_file_path = format!("{}/{}", remote_cloud_base_directory , file_name);
|
||||
Self {
|
||||
file_object_hash: entropy.to_string(),
|
||||
remote_cloud_base_directory: remote_cloud_base_directory,
|
||||
full_remote_cloud_file_path: full_remote_cloud_file_path,
|
||||
file_name:file_name,
|
||||
file_descriptor:file_descriptor
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_file_descriptor(file_descriptor: Box<dyn FileDescriptor>) -> Self {
|
||||
let entropy = crockford_entropy_lower(32);
|
||||
// gets you wiki /a/b/c/d folder structure
|
||||
let middle = hashed_directory_path_long_string::hashed_directory_path_long_string(entropy.as_ref());
|
||||
// gets you cloud bucket path e.g weights/a/b/c/d/clould_path_entropy
|
||||
let remote_cloud_base_directory = format!("{}/{}{}", file_descriptor.remote_directory_path(), middle, entropy);
|
||||
// gets you name of the file with suffix and prefix and entropy in the centre
|
||||
let file_name = format!("{}_{}.{}", file_descriptor.get_prefix(), entropy, file_descriptor.get_suffix());
|
||||
// note: no longer optional because it's easy to know what it would be in the db explicit is better than implcit.
|
||||
|
||||
// This is the full path you upload to.
|
||||
let full_remote_cloud_file_path = format!("{}/{}", remote_cloud_base_directory , file_name);
|
||||
Self {
|
||||
file_object_hash: entropy,
|
||||
remote_cloud_base_directory: remote_cloud_base_directory,
|
||||
full_remote_cloud_file_path: full_remote_cloud_file_path,
|
||||
file_name:file_name,
|
||||
file_descriptor:file_descriptor
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_file_object_hash(&self) -> &str {
|
||||
&self.file_object_hash
|
||||
}
|
||||
|
||||
pub fn get_remote_cloud_base_directory(&self) -> &str {
|
||||
&self.remote_cloud_base_directory
|
||||
}
|
||||
|
||||
pub fn get_full_remote_cloud_file_path(&self) -> &str {
|
||||
&self.full_remote_cloud_file_path
|
||||
}
|
||||
|
||||
pub fn to_full_remote_cloud_file_path_pathbuf(&self) -> PathBuf {
|
||||
PathBuf::from(&self.full_remote_cloud_file_path)
|
||||
}
|
||||
pub fn get_file_name(&self) -> &str {
|
||||
&self.file_name
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FileMetaData {
|
||||
pub file_size_bytes: u64,
|
||||
pub sha256_checksum: String,
|
||||
pub mimetype: String
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
pub mod remote_cloud_file_manager;
|
||||
pub mod remote_cloud_bucket_details;
|
||||
|
||||
pub mod bucket_orchestration;
|
||||
|
||||
|
||||
pub mod file_directory;
|
||||
pub mod file_meta_data;
|
||||
pub mod file_descriptor;
|
||||
|
||||
pub mod media_descriptor;
|
||||
pub mod weights_descriptor;
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
|
||||
|
||||
use super::file_descriptor::FileDescriptor;
|
||||
use crate::remote_file_manager::weights_descriptor::{WeightsLoRADescriptor, WeightsSD15Descriptor, WeightsSDXLDescriptor, self};
|
||||
|
||||
pub struct RemoteCloudBucketDetails {
|
||||
pub object_hash: String,
|
||||
pub prefix: String,
|
||||
pub suffix: String,
|
||||
}
|
||||
|
||||
impl RemoteCloudBucketDetails {
|
||||
pub fn new(object_hash: String, prefix: String, suffix: String) -> Self {
|
||||
Self {
|
||||
object_hash: object_hash,
|
||||
prefix: prefix,
|
||||
suffix: suffix
|
||||
}
|
||||
}
|
||||
pub fn get_object_hash(&self) -> &str {
|
||||
&self.object_hash
|
||||
}
|
||||
pub fn get_prefix(&self) -> &str {
|
||||
&self.prefix
|
||||
}
|
||||
pub fn get_suffix(&self) -> &str {
|
||||
&self.suffix
|
||||
}
|
||||
|
||||
pub fn file_descriptor_from_bucket_details(&self) -> Box<dyn FileDescriptor> {
|
||||
match self.prefix.as_str() {
|
||||
"loRA" => Box::new(weights_descriptor::WeightsLoRADescriptor {}),
|
||||
"sd15" => Box::new(weights_descriptor::WeightsSD15Descriptor {}),
|
||||
"sdxl" => Box::new(weights_descriptor::WeightsSDXLDescriptor {}),
|
||||
"valle_prompt" => Box::new(weights_descriptor::WeightsVallePromptDescriptor {}),
|
||||
"rvc" => {
|
||||
match self.suffix.as_str() {
|
||||
"safetensors" => Box::new(weights_descriptor::WeightsRVCDescriptor {}),
|
||||
"index" => Box::new(weights_descriptor::WeightsRVCIndexDescriptor {}),
|
||||
_ => panic!("Unknown suffix: {}",self.suffix)
|
||||
}
|
||||
},
|
||||
"svc" => Box::new(weights_descriptor::WeightsSVCDescriptor {}),
|
||||
_ => panic!("Unknown prefix: {}", self.prefix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
pub fn test() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
|
||||
|
||||
use crate::remote_file_manager::file_directory::FileBucketDirectory;
|
||||
use crate::remote_file_manager::remote_cloud_bucket_details::RemoteCloudBucketDetails;
|
||||
|
||||
use super::bucket_orchestration;
|
||||
use super::file_descriptor::{FileDescriptor};
|
||||
use super::file_meta_data::FileMetaData;
|
||||
|
||||
use errors:: AnyhowResult;
|
||||
|
||||
use filesys::file_read_bytes::file_read_bytes;
|
||||
use filesys::file_size::file_size;
|
||||
|
||||
use hashing::sha256::sha256_hash_file::sha256_hash_file;
|
||||
use mimetypes::mimetype_for_bytes::get_mimetype_for_bytes;
|
||||
|
||||
use crate::remote_file_manager::bucket_orchestration::{BucketOrchestrationCore};
|
||||
|
||||
struct RemoteCloudFileClient {
|
||||
bucket_orchestration_client: Box<dyn BucketOrchestrationCore>
|
||||
}
|
||||
|
||||
impl RemoteCloudFileClient {
|
||||
pub fn new(bucket_orchestration_client: Box<dyn BucketOrchestrationCore>) -> Self {
|
||||
Self {
|
||||
bucket_orchestration_client: bucket_orchestration_client
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn download_file(&self, remote_cloud_bucket_details:RemoteCloudBucketDetails, to_system_file_path:String) -> AnyhowResult<()> {
|
||||
let file_descriptor = remote_cloud_bucket_details.file_descriptor_from_bucket_details();
|
||||
let file_bucket_directory = FileBucketDirectory::from_existing_bucket_details(remote_cloud_bucket_details);
|
||||
let full_remote_cloud_file_path = file_bucket_directory.get_full_remote_cloud_file_path().to_string();
|
||||
let is_public = file_descriptor.is_public().clone();
|
||||
|
||||
self.bucket_orchestration_client.download_file_to_disk(full_remote_cloud_file_path, to_system_file_path, is_public).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// return error or success with meta data.
|
||||
pub async fn upload_file(&self, file_descriptor:Box<dyn FileDescriptor>, from_system_file_path:&str) -> AnyhowResult<FileMetaData> {
|
||||
|
||||
// get file meta data
|
||||
println!("Reading media file: {:?}", from_system_file_path);
|
||||
// get meta data
|
||||
let bytes = file_read_bytes(from_system_file_path)?;
|
||||
let result = Self::get_file_meta_data(from_system_file_path)?;
|
||||
let is_public = file_descriptor.is_public();
|
||||
|
||||
let directory = FileBucketDirectory::generate_new(
|
||||
file_descriptor
|
||||
);
|
||||
|
||||
println!("Uploading media file to bucket path: {:?}",directory.get_full_remote_cloud_file_path());
|
||||
|
||||
self.bucket_orchestration_client.upload_file_with_content_type_process(
|
||||
&directory.get_remote_cloud_base_directory(),
|
||||
bytes.as_ref(),
|
||||
result.mimetype.as_ref(),
|
||||
is_public
|
||||
).await?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// Retrieve the metadata from the file
|
||||
fn get_file_meta_data(system_file_path:&str) -> AnyhowResult<FileMetaData> {
|
||||
let file_size_bytes = file_size(system_file_path.clone())?;
|
||||
let sha256_checksum = sha256_hash_file(system_file_path.clone())?;
|
||||
|
||||
let bytes = file_read_bytes(system_file_path)?;
|
||||
let mimetype: &str = get_mimetype_for_bytes(&bytes).unwrap_or("application/octet-stream");
|
||||
|
||||
Ok(FileMetaData {
|
||||
file_size_bytes: file_size_bytes,
|
||||
sha256_checksum: sha256_checksum,
|
||||
mimetype: mimetype.to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use async_trait::async_trait;
|
||||
use env_logger;
|
||||
use errors::AnyhowResult;
|
||||
use crate::remote_file_manager::bucket_orchestration::BucketOrchestrationCore;
|
||||
use crate::remote_file_manager::weights_descriptor::{WeightsLoRADescriptor, WeightsSD15Descriptor, WeightsSDXLDescriptor};
|
||||
|
||||
struct BucketOrchestrationMock {}
|
||||
|
||||
#[async_trait]
|
||||
impl BucketOrchestrationCore for BucketOrchestrationMock {
|
||||
async fn download_file_to_disk(
|
||||
&self,
|
||||
object_path: String,
|
||||
filesystem_path: String,
|
||||
is_public: bool,
|
||||
) -> AnyhowResult<()>{
|
||||
println!("Download File to Disk");
|
||||
println!("{}",object_path);
|
||||
println!("{}",filesystem_path);
|
||||
println!("{}",is_public);
|
||||
println!("Download Done Downloading");
|
||||
|
||||
assert_eq!(String::from("/weights/1/2/123/loRA_123.safetensors"),object_path);
|
||||
assert_eq!(String::from("./file_path_here"),filesystem_path);
|
||||
assert_eq!(is_public,true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn upload_file_with_content_type_process(&self, object_name: &str,
|
||||
bytes: &[u8],
|
||||
content_type: &str,
|
||||
is_public: bool) -> AnyhowResult<()> {
|
||||
println!("Upload File to Disk");
|
||||
println!("{}",object_name);
|
||||
assert_eq!(object_name,String::from("/weights/2/y/q/m/2/2yqm2f1bamh88seyd690h9v24apgezhr/loRA_2yqm2f1bamh88seyd690h9v24apgezhr.safetensors"));
|
||||
println!("ContentType:{}",content_type);
|
||||
println!("{}",is_public);
|
||||
assert_eq!(is_public,true);
|
||||
|
||||
println!("Is Done Uploading");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
async fn remote_file_manager_descriptor_test() {
|
||||
use super::*;
|
||||
let remote_cloud_bucket_details = RemoteCloudBucketDetails::new("object_hash".to_string(), "loRA".to_string(), "safetensors".to_string());
|
||||
let file_descriptor = remote_cloud_bucket_details.file_descriptor_from_bucket_details();
|
||||
|
||||
assert_eq!(file_descriptor.get_prefix(), "loRA");
|
||||
assert_eq!(file_descriptor.get_suffix(), "safetensors");
|
||||
assert_eq!(file_descriptor.is_public(), true);
|
||||
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn remote_file_manager_download_existing_file() {
|
||||
use super::*;
|
||||
|
||||
env_logger::init();
|
||||
|
||||
let file_path:&str= "./file_path_here";
|
||||
|
||||
let remote_cloud_file_manager = RemoteCloudFileClient {
|
||||
bucket_orchestration_client: Box::new(BucketOrchestrationMock {})
|
||||
};
|
||||
|
||||
println!("begin upload from file_path: {:?}", file_path);
|
||||
let details = RemoteCloudBucketDetails {
|
||||
object_hash: String::from("123"),
|
||||
prefix: String::from("loRA"),
|
||||
suffix: String::from("safetensors")
|
||||
};
|
||||
let result = remote_cloud_file_manager.download_file(details,file_path.to_string()).await;
|
||||
|
||||
match result {
|
||||
Ok(file_meta_data) => {
|
||||
println!("file_meta_data: {:?}", file_meta_data);
|
||||
},
|
||||
Err(e) => {
|
||||
println!("error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn remote_file_manager_upload_existing_file() {
|
||||
use super::*;
|
||||
|
||||
env_logger::init();
|
||||
// Replace with a test file.
|
||||
let weight_path:&str= "/home/tensor/code/storyteller/storyteller-rust/crates/lib/api_clients/cloud_storage/src/remote_file_manager/remote_cloud_file_manager.rs";
|
||||
|
||||
let remote_cloud_file_manager = RemoteCloudFileClient {
|
||||
bucket_orchestration_client: Box::new(BucketOrchestrationMock {})
|
||||
};
|
||||
|
||||
println!("begin upload from weight_path: {:?}", weight_path);
|
||||
|
||||
let result = remote_cloud_file_manager.upload_file(Box::new(WeightsLoRADescriptor {}),weight_path).await;
|
||||
|
||||
match result {
|
||||
Ok(file_meta_data) => {
|
||||
println!("file_meta_data: {:?}", file_meta_data);
|
||||
},
|
||||
Err(e) => {
|
||||
println!("error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
use super::file_descriptor::FileDescriptor;
|
||||
|
||||
pub struct WeightsLoRADescriptor {}
|
||||
|
||||
const REMOTE_FILE_DIRECTORY: &str = "/weights";
|
||||
|
||||
impl FileDescriptor for WeightsLoRADescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file peroid is handled by the file formatter
|
||||
// e.g safetensors bin jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "safetensors".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, loRA, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "loRA".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsSD15Descriptor {}
|
||||
|
||||
impl FileDescriptor for WeightsSD15Descriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file peroid is handled by the file formatter
|
||||
// e.g safetensors bin jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "safetensors".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, SD15, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "sd15".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct WeightsSDXLDescriptor {}
|
||||
|
||||
impl FileDescriptor for WeightsSDXLDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file peroid is handled by the file formatter
|
||||
// e.g safetensors bin jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "safetensors".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, SD15, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "sdxl".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsSVCDescriptor {}
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsSVCDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file peroid is handled by the file formatter
|
||||
// e.g safetensors bin jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "safetensors".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, SD15, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "svc".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsRVCDescriptor {}
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsRVCDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file peroid is handled by the file formatter
|
||||
// e.g safetensors bin jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "pth".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, SD15, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "rvc".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsRVCIndexDescriptor {}
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsRVCIndexDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file peroid is handled by the file formatter
|
||||
// e.g safetensors bin jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "index".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, SD15, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "rvc".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsVallePromptDescriptor {}
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsVallePromptDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
}
|
||||
// this will be the type of file peroid is handled by the file formatter
|
||||
// e.g safetensors bin jpg
|
||||
fn get_suffix(&self)->String {
|
||||
return "safetensors".to_string();
|
||||
}
|
||||
// This will be the prefix of the media type or the weights type.
|
||||
// name of the weights or the name of the media type
|
||||
// vall-e_prompt, SD15, sd15, sdxl when implmenting add to the end
|
||||
fn get_prefix(&self)->String {
|
||||
return "valle_prompt".to_string();
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
fn is_public(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod bucket_orchestration_mock;
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Nearly a third of `ErrorKind` is nightly rust, so we're going to have to match on
|
||||
// unix error codes until the rest of the ErrorKind enum variants are stable.
|
||||
// The error codes are maintained in sys/unix/mod.rs - decode_error_kind(i32)
|
||||
// The error codes are maintained in sys/unix/voice_conversion_to_weights - decode_error_kind(i32)
|
||||
|
||||
const E_FILESYSTEM_QUOTA_EXCEEDED : i32 = 122; // pub const EDQUOT: ::c_int = 122;
|
||||
const E_STORAGE_FULL : i32 = 28; // pub const ENOSPC: ::c_int = 28;
|
||||
|
||||
@@ -43,7 +43,7 @@ pub fn rename_across_devices<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) ->
|
||||
|
||||
// Nearly a third of `ErrorKind` is nightly rust, so we're going to have to match on
|
||||
// unix error codes until the rest of the ErrorKind enum variants are stable.
|
||||
// The error codes are maintained in sys/unix/mod.rs - decode_error_kind(i32)
|
||||
// The error codes are maintained in sys/unix/voice_conversion_to_weights - decode_error_kind(i32)
|
||||
const E_CROSSES_DEVICES : i32 = 18; // pub const EXDEV: ::c_int = 18;
|
||||
|
||||
if is_filesystem_full_error(&err) {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
[package]
|
||||
name = "migration"
|
||||
edition = "2018"
|
||||
version = "0.0.1"
|
||||
authors = [
|
||||
"Brandon Thomas <bt@brand.io>",
|
||||
"Brandon Thomas <echelon@gmail.com>",
|
||||
]
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
# NB: Public "migration" crate does not exist, so we're fine to use this internally for a bit.
|
||||
name = "migration"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
# Internal
|
||||
buckets = { path = "../../_types/buckets" }
|
||||
cloud_storage = { path = "../../lib/api_clients/cloud_storage" }
|
||||
enums = { path = "../../_types/enums" }
|
||||
errors = { path = "../../lib/errors" }
|
||||
jobs_common = { path = "../../lib/jobs_common" }
|
||||
mysql_queries = { path = "../../lib/mysql_queries" }
|
||||
tokens = { path = "../../_types/tokens" }
|
||||
|
||||
# External
|
||||
anyhow = "1.0.75"
|
||||
chrono = { version = "0.4.22", features = ["serde"] }
|
||||
once_cell = "1.18.0"
|
||||
|
||||
# Serialization
|
||||
serde = "1.0.125"
|
||||
serde_derive = "1.0.125"
|
||||
serde_json = "1.0.108"
|
||||
toml = "0.5.8"
|
||||
serial_test = "2.0.0"
|
||||
|
||||
# Runtime + Clients
|
||||
tokio = { version = "1.34.0", features = ["full"] }
|
||||
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
|
||||
|
||||
# Workspace hack (faster compile times)
|
||||
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
|
||||
|
||||
[dev-dependencies]
|
||||
# None yet
|
||||
@@ -0,0 +1,20 @@
|
||||
//! migration
|
||||
//!
|
||||
//! This crate should contain short-lived migration utilities for our services.
|
||||
//!
|
||||
|
||||
// Never allow these
|
||||
#![forbid(private_in_public)]
|
||||
#![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)]
|
||||
|
||||
pub mod voice_conversion;
|
||||
@@ -0,0 +1,147 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use sqlx::MySql;
|
||||
use sqlx::pool::PoolConnection;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType;
|
||||
|
||||
use enums::common::visibility::Visibility;
|
||||
use errors::AnyhowResult;
|
||||
use mysql_queries::queries::model_weights::list::list_model_weights_for_voice_conversion::{list_model_weights_for_voice_conversion, ModelWeightForVoiceConversion};
|
||||
use mysql_queries::queries::voice_conversion::models::list_voice_conversion_models::{list_voice_conversion_models_with_connection, VoiceConversionModelRecordForList};
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
/// List VC models
|
||||
/// This is for the voice conversion model list page.
|
||||
/// Since we're listing, we have to use a flag to determine which query to perform.
|
||||
pub async fn list_vc_models_for_migration(
|
||||
mysql_connection: &mut PoolConnection<MySql>,
|
||||
use_weights_table: bool,
|
||||
) -> AnyhowResult<Vec<VcModelForList>> {
|
||||
// NB: This is temporary migration code as we switch from the `voice_conversion_models` table to the `model_weights` table.
|
||||
if use_weights_table {
|
||||
let models = list_model_weights_for_voice_conversion(
|
||||
mysql_connection).await?;
|
||||
|
||||
Ok(models.into_iter()
|
||||
.map(|model| VcModelForList::ModelWeight(model))
|
||||
.collect())
|
||||
|
||||
} else {
|
||||
let models = list_voice_conversion_models_with_connection(
|
||||
mysql_connection, None).await?;
|
||||
|
||||
Ok(models.into_iter()
|
||||
.map(|model| VcModelForList::LegacyVoiceConversion(model))
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
/// Union over the legacy table and the new table to support an easier migration.
|
||||
/// This enum can hold a record of either type and present a unified accessor interface.
|
||||
#[derive(Clone)]
|
||||
pub enum VcModelForList {
|
||||
/// Old type from the `voice_conversion_models` table, on the way out
|
||||
LegacyVoiceConversion(VoiceConversionModelRecordForList),
|
||||
/// New type, replacing the `voice_conversion_models` table.
|
||||
ModelWeight(ModelWeightForVoiceConversion),
|
||||
}
|
||||
|
||||
impl VcModelForList {
|
||||
pub fn token(&self) -> &str {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => model.token.as_str(),
|
||||
VcModelForList::ModelWeight(ref model) => model.token.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn legacy_voice_conversion_model_type(&self) -> Option<VoiceConversionModelType> {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => Some(model.model_type),
|
||||
VcModelForList::ModelWeight(ref model) => match model.weight_type {
|
||||
WeightsType::SoVitsSvc => Some(VoiceConversionModelType::SoVitsSvc),
|
||||
WeightsType::RvcV2 => Some(VoiceConversionModelType::RvcV2),
|
||||
// NB: The following weights are not voice conversion models.
|
||||
WeightsType::HifiganTacotron2 => None,
|
||||
WeightsType::StableDiffusion15 => None,
|
||||
WeightsType::StableDiffusionXL => None,
|
||||
WeightsType::Tacotron2 => None,
|
||||
WeightsType::LoRA => None,
|
||||
WeightsType::VallE => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_voice_conversion_model(&self) -> bool {
|
||||
self.legacy_voice_conversion_model_type().is_some()
|
||||
}
|
||||
|
||||
pub fn title(&self) -> &str {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.title,
|
||||
VcModelForList::ModelWeight(ref model) => &model.title,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ietf_language_tag(&self) -> &str {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.ietf_language_tag,
|
||||
VcModelForList::ModelWeight(ref model) => &model.ietf_language_tag,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ietf_primary_language_subtag(&self) -> &str {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.ietf_primary_language_subtag,
|
||||
VcModelForList::ModelWeight(ref model) => &model.ietf_primary_language_subtag,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn creator_user_token(&self) -> &UserToken {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.creator_user_token,
|
||||
VcModelForList::ModelWeight(ref model) => &model.creator_user_token,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn creator_username(&self) -> &str {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.creator_username,
|
||||
VcModelForList::ModelWeight(ref model) => &model.creator_username,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn creator_display_name(&self) -> &str {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.creator_display_name,
|
||||
VcModelForList::ModelWeight(ref model) => &model.creator_display_name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn creator_gravatar_hash(&self) -> &str {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.creator_gravatar_hash,
|
||||
VcModelForList::ModelWeight(ref model) => &model.creator_gravatar_hash,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn creator_set_visibility(&self) -> Visibility{
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => model.creator_set_visibility,
|
||||
VcModelForList::ModelWeight(ref model) => model.creator_set_visibility,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn created_at(&self) -> &DateTime<Utc> {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.created_at,
|
||||
VcModelForList::ModelWeight(ref model) => &model.created_at,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updated_at(&self) -> &DateTime<Utc> {
|
||||
match self {
|
||||
VcModelForList::LegacyVoiceConversion(ref model) => &model.updated_at,
|
||||
VcModelForList::ModelWeight(ref model) => &model.updated_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod list_vc_models_for_migration;
|
||||
pub mod query_vc_model_for_migration;
|
||||
pub mod query_vc_model_info_lite_for_migration;
|
||||
@@ -0,0 +1,393 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use sqlx::MySqlPool;
|
||||
|
||||
use buckets::public::weight_files::bucket_file_path::WeightFileBucketPath;
|
||||
use cloud_storage::bucket_path_unifier::BucketPathUnifier;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType;
|
||||
use jobs_common::semi_persistent_cache_dir::SemiPersistentCacheDir;
|
||||
use mysql_queries::queries::model_weights::inference::get_model_weight_for_voice_conversion_inference::{get_model_weight_for_voice_conversion_inference, ModelWeightError, ModelWeightForVoiceConversionInference};
|
||||
use mysql_queries::queries::voice_conversion::inference::get_voice_conversion_model_for_inference::{get_voice_conversion_model_for_inference, VoiceConversionModelForInference, VoiceConversionModelForInferenceError};
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum VcModelError {
|
||||
ModelDeleted,
|
||||
DatabaseError { reason: String },
|
||||
}
|
||||
|
||||
impl std::fmt::Display for VcModelError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
VcModelError::ModelDeleted => write!(f, "ModelDeleted"),
|
||||
VcModelError::DatabaseError { reason} =>
|
||||
write!(f, "Database error: {:?}", reason),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for VcModelError {}
|
||||
|
||||
/// Query model info
|
||||
/// Depending on the token prefix, this does either a modern or legacy lookup.
|
||||
pub async fn query_vc_model_for_migration(model_token: &str, mysql_pool: &MySqlPool) -> Result<Option<VcModel>, VcModelError> {
|
||||
// NB: This is temporary migration code as we switch from the `voice_conversion_models` table to the `model_weights` table.
|
||||
if model_token.starts_with(ModelWeightToken::token_prefix()) {
|
||||
let model_weights_token = ModelWeightToken::new_from_str(model_token);
|
||||
|
||||
let maybe_model = get_model_weight_for_voice_conversion_inference(
|
||||
&mysql_pool, &model_weights_token).await.map_err(|err|
|
||||
match err {
|
||||
ModelWeightError::ModelDeleted => VcModelError::ModelDeleted,
|
||||
ModelWeightError::DatabaseError { reason } => VcModelError::DatabaseError { reason },
|
||||
}
|
||||
)?;
|
||||
|
||||
Ok(maybe_model
|
||||
.map(|model| VcModel::ModelWeight(model)))
|
||||
|
||||
} else {
|
||||
let maybe_vc_model = get_voice_conversion_model_for_inference(
|
||||
&mysql_pool, model_token).await.map_err(|err|
|
||||
match err {
|
||||
VoiceConversionModelForInferenceError::ModelDeleted => VcModelError::ModelDeleted,
|
||||
VoiceConversionModelForInferenceError::DatabaseError { reason } => VcModelError::DatabaseError { reason },
|
||||
})?;
|
||||
|
||||
Ok(maybe_vc_model
|
||||
.map(|model| VcModel::LegacyVoiceConversion(model)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Union over the legacy table and the new table to support an easier migration.
|
||||
/// This enum can hold a record of either type and present a unified accessor interface.
|
||||
#[derive(Clone)]
|
||||
pub enum VcModel {
|
||||
/// Old type from the `voice_conversion_models` table, on the way out
|
||||
LegacyVoiceConversion(VoiceConversionModelForInference),
|
||||
/// New type, replacing the `voice_conversion_models` table.
|
||||
ModelWeight(ModelWeightForVoiceConversionInference),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum VcModelType {
|
||||
RvcV2,
|
||||
SoVitsSvc,
|
||||
/// We never finished support for SoftVC
|
||||
SoftVc,
|
||||
/// Another type of model we don't support as voice conversion (eg. Stable Diffusion)
|
||||
Invalid,
|
||||
}
|
||||
|
||||
impl VcModel {
|
||||
pub fn get_model_token(&self) -> &str {
|
||||
match self {
|
||||
VcModel::LegacyVoiceConversion(ref model) => model.token.as_str(),
|
||||
VcModel::ModelWeight(ref model) => model.token.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_model_type(&self) -> VcModelType {
|
||||
match self {
|
||||
VcModel::LegacyVoiceConversion(ref model) => match model.model_type {
|
||||
VoiceConversionModelType::RvcV2 => VcModelType::RvcV2,
|
||||
VoiceConversionModelType::SoftVc => VcModelType::SoftVc,
|
||||
VoiceConversionModelType::SoVitsSvc => VcModelType::SoVitsSvc,
|
||||
}
|
||||
VcModel::ModelWeight(ref model) => match model.weights_type {
|
||||
// Valid types
|
||||
WeightsType::SoVitsSvc => VcModelType::SoVitsSvc,
|
||||
WeightsType::RvcV2 => VcModelType::RvcV2,
|
||||
// Invalid types
|
||||
WeightsType::StableDiffusion15 => VcModelType::Invalid,
|
||||
WeightsType::HifiganTacotron2 => VcModelType::Invalid,
|
||||
WeightsType::StableDiffusionXL => VcModelType::Invalid,
|
||||
WeightsType::Tacotron2 => VcModelType::Invalid,
|
||||
WeightsType::LoRA => VcModelType::Invalid,
|
||||
WeightsType::VallE => VcModelType::Invalid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the model has an associated speaker index file. Only applies to certain RVC models.
|
||||
pub fn has_index_file(&self) -> bool {
|
||||
match self {
|
||||
VcModel::LegacyVoiceConversion(ref model) => {
|
||||
match model.model_type {
|
||||
VoiceConversionModelType::RvcV2 => model.has_index_file,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
VcModel::ModelWeight(ref model) => {
|
||||
match model.weights_type {
|
||||
WeightsType::RvcV2 => model.has_index_file,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Location where the SVC or RVC model weights are stored in the cloud bucket.
|
||||
pub fn get_model_cloud_bucket_path(&self, bucket_path_unifier: &BucketPathUnifier) -> PathBuf {
|
||||
match self {
|
||||
VcModel::LegacyVoiceConversion(ref model) => {
|
||||
match model.model_type {
|
||||
VoiceConversionModelType::RvcV2 => {
|
||||
bucket_path_unifier.rvc_v2_model_path(&model.private_bucket_hash)
|
||||
}
|
||||
VoiceConversionModelType::SoVitsSvc => {
|
||||
bucket_path_unifier.so_vits_svc_model_path(&model.private_bucket_hash)
|
||||
}
|
||||
VoiceConversionModelType::SoftVc => {
|
||||
// NB: Technically wrong, but there are none of these models and I want the
|
||||
// method to be infallible since it is in all other cases.
|
||||
PathBuf::from("SOFT_VC_UNUSED_AND_UNIMPLEMENTED")
|
||||
}
|
||||
}
|
||||
}
|
||||
VcModel::ModelWeight(ref model) => {
|
||||
let path = WeightFileBucketPath::from_object_hash(
|
||||
&model.public_bucket_hash,
|
||||
model.maybe_public_bucket_prefix.as_deref(),
|
||||
model.maybe_public_bucket_extension.as_deref());
|
||||
|
||||
PathBuf::from(path.get_full_object_path_str())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Location where the optional index file is stored in the cloud bucket.
|
||||
/// Only RVC models have index files.
|
||||
pub fn get_index_file_cloud_bucket_path(&self, bucket_path_unifier: &BucketPathUnifier) -> Option<PathBuf> {
|
||||
match self {
|
||||
VcModel::LegacyVoiceConversion(ref model) => {
|
||||
if !model.has_index_file {
|
||||
return None;
|
||||
}
|
||||
match model.model_type {
|
||||
VoiceConversionModelType::SoVitsSvc => None,
|
||||
VoiceConversionModelType::SoftVc => None,
|
||||
VoiceConversionModelType::RvcV2 => {
|
||||
Some(bucket_path_unifier.rvc_v2_model_index_path(&model.private_bucket_hash))
|
||||
}
|
||||
}
|
||||
}
|
||||
VcModel::ModelWeight(ref model) => {
|
||||
if !model.has_index_file {
|
||||
return None;
|
||||
}
|
||||
// NB: Technically, we should read prefix/extension from DB. We keep index file extensions by convention, however.
|
||||
let path = WeightFileBucketPath::rvc_index_file_from_object_hash(&model.public_bucket_hash);
|
||||
Some(PathBuf::from(path.get_full_object_path_str()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// We store models on the filesystem long term to speed up future instances of the job
|
||||
/// that use the same model. This way we don't incur the same (time and monetary) costs
|
||||
/// of downloading the model again and again.
|
||||
pub fn get_model_persistent_filesystem_path(&self, cache_dir: &SemiPersistentCacheDir) -> PathBuf {
|
||||
let token = match self {
|
||||
VcModel::LegacyVoiceConversion(ref model) => model.token.as_str(),
|
||||
VcModel::ModelWeight(ref model) => model.token.as_str(),
|
||||
};
|
||||
let filename = format!("{token}.pt");
|
||||
cache_dir.voice_conversion_model_path(&filename)
|
||||
}
|
||||
|
||||
/// Same as `get_model_persistent_filesystem_path`, but for RVC index files.
|
||||
/// This will return a valid path even if the model doesn't have an index file, so be sure
|
||||
/// to check if the model has an index model first.
|
||||
pub fn get_index_file_persistent_filesystem_path(&self, cache_dir: &SemiPersistentCacheDir) -> PathBuf {
|
||||
let token = match self {
|
||||
VcModel::LegacyVoiceConversion(ref model) => model.token.as_str(),
|
||||
VcModel::ModelWeight(ref model) => model.token.as_str(),
|
||||
};
|
||||
let filename = format!("{token}.index");
|
||||
cache_dir.voice_conversion_model_path(&filename)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
mod legacy_voice_conversion_models {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use cloud_storage::bucket_path_unifier::BucketPathUnifier;
|
||||
use enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType;
|
||||
use jobs_common::semi_persistent_cache_dir::SemiPersistentCacheDir;
|
||||
use mysql_queries::queries::voice_conversion::inference::get_voice_conversion_model_for_inference::VoiceConversionModelForInference;
|
||||
use tokens::tokens::voice_conversion_models::VoiceConversionModelToken;
|
||||
|
||||
use crate::voice_conversion::query_vc_model_for_migration::{VcModel, VcModelType};
|
||||
|
||||
fn default_model() -> VoiceConversionModelForInference {
|
||||
// NB: We could implement/derive the default trait, but this works just as well for now.
|
||||
VoiceConversionModelForInference {
|
||||
token: VoiceConversionModelToken::new_from_str("vcm_entropy"),
|
||||
model_type: VoiceConversionModelType::RvcV2,
|
||||
private_bucket_hash: "hash".to_string(),
|
||||
has_index_file: false,
|
||||
title: "title".to_string(),
|
||||
created_at: Default::default(),
|
||||
updated_at: Default::default(),
|
||||
user_deleted_at: None,
|
||||
mod_deleted_at: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_token() {
|
||||
let model = default_model();
|
||||
assert_eq!(VcModel::LegacyVoiceConversion(model).get_model_token(), "vcm_entropy");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_type() {
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::RvcV2;
|
||||
assert_eq!(VcModel::LegacyVoiceConversion(model).get_model_type(), VcModelType::RvcV2);
|
||||
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::SoftVc;
|
||||
assert_eq!(VcModel::LegacyVoiceConversion(model).get_model_type(), VcModelType::SoftVc);
|
||||
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::SoVitsSvc;
|
||||
assert_eq!(VcModel::LegacyVoiceConversion(model).get_model_type(), VcModelType::SoVitsSvc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_index_file() {
|
||||
let mut model = default_model();
|
||||
model.has_index_file = false;
|
||||
model.model_type = VoiceConversionModelType::RvcV2;
|
||||
assert_eq!(VcModel::LegacyVoiceConversion(model).has_index_file(), false);
|
||||
|
||||
let mut model = default_model();
|
||||
model.has_index_file = true;
|
||||
model.model_type = VoiceConversionModelType::RvcV2;
|
||||
assert_eq!(VcModel::LegacyVoiceConversion(model).has_index_file(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_persistent_file_path() {
|
||||
let model = default_model();
|
||||
let path = VcModel::LegacyVoiceConversion(model).get_model_persistent_filesystem_path(&SemiPersistentCacheDir::default_paths());
|
||||
assert_eq!(path, PathBuf::from("/file_cache/voice_conversion/models/vcm_entropy.pt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_cloud_bucket_path() {
|
||||
let model = default_model();
|
||||
let path = VcModel::LegacyVoiceConversion(model).get_model_cloud_bucket_path(&BucketPathUnifier::default_paths());
|
||||
assert_eq!(path, PathBuf::from("/user_uploaded_rvc_v2_models/h/a/s/hash.pt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_index_file_cloud_bucket_path() {
|
||||
let model = default_model();
|
||||
let path = VcModel::LegacyVoiceConversion(model).get_index_file_cloud_bucket_path(&BucketPathUnifier::default_paths());
|
||||
assert_eq!(path, None);
|
||||
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::RvcV2;
|
||||
model.has_index_file = true;
|
||||
let path = VcModel::LegacyVoiceConversion(model).get_index_file_cloud_bucket_path(&BucketPathUnifier::default_paths());
|
||||
assert_eq!(path, Some(PathBuf::from("/user_uploaded_rvc_v2_models/h/a/s/hash.index")));
|
||||
}
|
||||
}
|
||||
|
||||
mod new_model_weights {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use cloud_storage::bucket_path_unifier::BucketPathUnifier;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use jobs_common::semi_persistent_cache_dir::SemiPersistentCacheDir;
|
||||
use mysql_queries::queries::model_weights::inference::get_model_weight_for_voice_conversion_inference::ModelWeightForVoiceConversionInference;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
use crate::voice_conversion::query_vc_model_for_migration::{VcModel, VcModelType};
|
||||
|
||||
fn default_model() -> ModelWeightForVoiceConversionInference {
|
||||
// NB: We could implement/derive the default trait, but this works just as well for now.
|
||||
ModelWeightForVoiceConversionInference {
|
||||
token: ModelWeightToken::new_from_str("weight_entropy"),
|
||||
weights_type: WeightsType::RvcV2,
|
||||
has_index_file: false,
|
||||
public_bucket_hash: "hash".to_string(),
|
||||
maybe_public_bucket_prefix: None,
|
||||
maybe_public_bucket_extension: None,
|
||||
title: "title".to_string(),
|
||||
created_at: Default::default(),
|
||||
updated_at: Default::default(),
|
||||
user_deleted_at: None,
|
||||
mod_deleted_at: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_token() {
|
||||
let model = default_model();
|
||||
assert_eq!(VcModel::ModelWeight(model).get_model_token(), "weight_entropy");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_type() {
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::RvcV2;
|
||||
assert_eq!(VcModel::ModelWeight(model).get_model_type(), VcModelType::RvcV2);
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::StableDiffusion15;
|
||||
assert_eq!(VcModel::ModelWeight(model).get_model_type(), VcModelType::Invalid);
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::SoVitsSvc;
|
||||
assert_eq!(VcModel::ModelWeight(model).get_model_type(), VcModelType::SoVitsSvc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_index_file() {
|
||||
let mut model = default_model();
|
||||
model.has_index_file = false;
|
||||
model.weights_type = WeightsType::RvcV2;
|
||||
assert_eq!(VcModel::ModelWeight(model).has_index_file(), false);
|
||||
|
||||
let mut model = default_model();
|
||||
model.has_index_file = true;
|
||||
model.weights_type = WeightsType::RvcV2;
|
||||
assert_eq!(VcModel::ModelWeight(model).has_index_file(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_persistent_file_path() {
|
||||
let model = default_model();
|
||||
let path = VcModel::ModelWeight(model).get_model_persistent_filesystem_path(&SemiPersistentCacheDir::default_paths());
|
||||
assert_eq!(path, PathBuf::from("/file_cache/voice_conversion/models/weight_entropy.pt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_cloud_bucket_path() {
|
||||
let model = default_model();
|
||||
let path = VcModel::ModelWeight(model).get_model_cloud_bucket_path(&BucketPathUnifier::default_paths());
|
||||
assert_eq!(path, PathBuf::from("/weights/h/a/s/hash/file.bin"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_index_file_cloud_bucket_path() {
|
||||
let model = default_model();
|
||||
let path = VcModel::ModelWeight(model).get_index_file_cloud_bucket_path(&BucketPathUnifier::default_paths());
|
||||
assert_eq!(path, None);
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::RvcV2;
|
||||
model.has_index_file = true;
|
||||
let path = VcModel::ModelWeight(model).get_index_file_cloud_bucket_path(&BucketPathUnifier::default_paths());
|
||||
assert_eq!(path, Some(PathBuf::from("/weights/h/a/s/hash/rvc_hash.index")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
use sqlx::{MySql, MySqlPool};
|
||||
use sqlx::pool::PoolConnection;
|
||||
|
||||
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
|
||||
use enums::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType;
|
||||
use errors::AnyhowResult;
|
||||
use mysql_queries::queries::model_weights::model_weight_info_lite::get_model_weight_info_lite::get_model_weight_info_lite_with_connection;
|
||||
use mysql_queries::queries::model_weights::model_weight_info_lite::model_weight_info_lite::ModelWeightInfoLite;
|
||||
use mysql_queries::queries::voice_conversion::model_info_lite::get_voice_conversion_model_info_lite::get_voice_conversion_model_info_lite_with_connection;
|
||||
use mysql_queries::queries::voice_conversion::model_info_lite::model_info_lite::VoiceConversionModelInfoLite;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
/// Query "light info" for models.
|
||||
/// This is typically used for in-memory token-to-type caches.
|
||||
pub async fn query_vc_model_info_lite_for_migration(model_token: &str, mysql_pool: &MySqlPool) -> AnyhowResult<Option<VcModelLite>> {
|
||||
let mut connection = mysql_pool.acquire().await?;
|
||||
query_vc_model_info_lite_for_migration_with_connection(model_token, &mut connection).await
|
||||
}
|
||||
|
||||
/// Query "light info" for models.
|
||||
/// This is typically used for in-memory token-to-type caches.
|
||||
pub async fn query_vc_model_info_lite_for_migration_with_connection(
|
||||
model_token: &str,
|
||||
mysql_connection: &mut PoolConnection<MySql>
|
||||
) -> AnyhowResult<Option<VcModelLite>> {
|
||||
// NB: This is temporary migration code as we switch from the `voice_conversion_models` table to the `model_weights` table.
|
||||
if model_token.starts_with(ModelWeightToken::token_prefix()) {
|
||||
let model_weights_token = ModelWeightToken::new_from_str(model_token);
|
||||
|
||||
let maybe_model = get_model_weight_info_lite_with_connection(
|
||||
&model_weights_token, mysql_connection).await?;
|
||||
|
||||
Ok(maybe_model.map(|model| VcModelLite::ModelWeight(model)))
|
||||
|
||||
} else {
|
||||
let maybe_vc_model = get_voice_conversion_model_info_lite_with_connection(
|
||||
model_token, mysql_connection).await?;
|
||||
|
||||
Ok(maybe_vc_model.map(|model| VcModelLite::LegacyVoiceConversion(model)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Union over the legacy table and the new table to support an easier migration.
|
||||
/// This enum can hold a record of either type and present a unified accessor interface.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum VcModelLite {
|
||||
/// Old type from the `voice_conversion_models` table, on the way out
|
||||
LegacyVoiceConversion(VoiceConversionModelInfoLite),
|
||||
/// New type, replacing the `voice_conversion_models` table.
|
||||
ModelWeight(ModelWeightInfoLite),
|
||||
}
|
||||
|
||||
impl VcModelLite {
|
||||
pub fn get_model_token(&self) -> &str {
|
||||
match self {
|
||||
VcModelLite::LegacyVoiceConversion(ref model) => model.token.as_str(),
|
||||
VcModelLite::ModelWeight(ref model) => model.token.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_inference_category(&self) -> Option<InferenceCategory> {
|
||||
match self {
|
||||
VcModelLite::LegacyVoiceConversion(ref model) => match model.model_type {
|
||||
VoiceConversionModelType::RvcV2 => Some(InferenceCategory::VoiceConversion),
|
||||
VoiceConversionModelType::SoftVc => Some(InferenceCategory::VoiceConversion),
|
||||
VoiceConversionModelType::SoVitsSvc => Some(InferenceCategory::VoiceConversion),
|
||||
}
|
||||
VcModelLite::ModelWeight(ref model) => match model.weights_type {
|
||||
WeightsType::SoVitsSvc => Some(InferenceCategory::VoiceConversion),
|
||||
WeightsType::RvcV2 => Some(InferenceCategory::VoiceConversion),
|
||||
WeightsType::Tacotron2 => Some(InferenceCategory::TextToSpeech),
|
||||
WeightsType::StableDiffusion15 => None, // TODO(bt,2023-12-18): New category for image generation
|
||||
WeightsType::StableDiffusionXL => None, // TODO(bt,2023-12-18): New category for image generation
|
||||
WeightsType::HifiganTacotron2 => None, // NB: Not used directly in inference. Included by other models.
|
||||
WeightsType::LoRA => None, // NB: not used directly in inference. Included in other models.
|
||||
WeightsType::VallE => None, // TODO(bt,2023-12-18): Does this mean speaker weights?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_inference_model_type(&self) -> Option<InferenceModelType> {
|
||||
match self {
|
||||
VcModelLite::LegacyVoiceConversion(ref model) => match model.model_type {
|
||||
VoiceConversionModelType::RvcV2 => Some(InferenceModelType::RvcV2),
|
||||
VoiceConversionModelType::SoftVc => None, // NB: Not supported.
|
||||
VoiceConversionModelType::SoVitsSvc => Some(InferenceModelType::SoVitsSvc),
|
||||
}
|
||||
VcModelLite::ModelWeight(ref model) => match model.weights_type {
|
||||
WeightsType::SoVitsSvc => Some(InferenceModelType::SoVitsSvc),
|
||||
WeightsType::RvcV2 => Some(InferenceModelType::RvcV2),
|
||||
WeightsType::Tacotron2 => Some(InferenceModelType::Tacotron2),
|
||||
WeightsType::StableDiffusion15 => None, // TODO(bt, 2023-12-18): New model type for image generation
|
||||
WeightsType::StableDiffusionXL => None, // TODO(bt, 2023-12-18): New model type for image generation
|
||||
WeightsType::HifiganTacotron2 => None, // NB: Not used directly in inference. Included by other models.
|
||||
WeightsType::LoRA => None, // NB: not used directly in inference. Included in other models.
|
||||
WeightsType::VallE => None, // TODO(bt,2023-12-18): Does this mean speaker weights?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
mod legacy_voice_conversion_models {
|
||||
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
|
||||
use enums::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
|
||||
use enums::by_table::voice_conversion_models::voice_conversion_model_type::VoiceConversionModelType;
|
||||
use mysql_queries::queries::voice_conversion::model_info_lite::model_info_lite::VoiceConversionModelInfoLite;
|
||||
use tokens::tokens::voice_conversion_models::VoiceConversionModelToken;
|
||||
|
||||
use crate::voice_conversion::query_vc_model_info_lite_for_migration::VcModelLite;
|
||||
|
||||
fn default_model() -> VoiceConversionModelInfoLite {
|
||||
// NB: We could implement/derive the default trait, but this works just as well for now.
|
||||
VoiceConversionModelInfoLite {
|
||||
token: VoiceConversionModelToken::new_from_str("vcm_entropy"),
|
||||
model_type: VoiceConversionModelType::RvcV2,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_token() {
|
||||
let model = default_model();
|
||||
assert_eq!(VcModelLite::LegacyVoiceConversion(model).get_model_token(), "vcm_entropy");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_inference_category() {
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::RvcV2;
|
||||
assert_eq!(VcModelLite::LegacyVoiceConversion(model).get_inference_category(), Some(InferenceCategory::VoiceConversion));
|
||||
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::SoVitsSvc;
|
||||
assert_eq!(VcModelLite::LegacyVoiceConversion(model).get_inference_category(), Some(InferenceCategory::VoiceConversion));
|
||||
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::SoftVc;
|
||||
assert_eq!(VcModelLite::LegacyVoiceConversion(model).get_inference_category(), Some(InferenceCategory::VoiceConversion));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_inference_model_type() {
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::RvcV2;
|
||||
assert_eq!(VcModelLite::LegacyVoiceConversion(model).get_inference_model_type(), Some(InferenceModelType::RvcV2));
|
||||
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::SoVitsSvc;
|
||||
assert_eq!(VcModelLite::LegacyVoiceConversion(model).get_inference_model_type(), Some(InferenceModelType::SoVitsSvc));
|
||||
|
||||
let mut model = default_model();
|
||||
model.model_type = VoiceConversionModelType::SoftVc;
|
||||
assert_eq!(VcModelLite::LegacyVoiceConversion(model).get_inference_model_type(), None);
|
||||
}
|
||||
}
|
||||
|
||||
mod new_model_weights {
|
||||
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
|
||||
use enums::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use mysql_queries::queries::model_weights::model_weight_info_lite::model_weight_info_lite::ModelWeightInfoLite;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
use crate::voice_conversion::query_vc_model_info_lite_for_migration::VcModelLite;
|
||||
|
||||
fn default_model() -> ModelWeightInfoLite {
|
||||
// NB: We could implement/derive the default trait, but this works just as well for now.
|
||||
ModelWeightInfoLite {
|
||||
token: ModelWeightToken::new_from_str("weight_entropy"),
|
||||
weights_type: WeightsType::RvcV2,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_model_token() {
|
||||
let model = default_model();
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_model_token(), "weight_entropy");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_inference_category() {
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::RvcV2;
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_inference_category(), Some(InferenceCategory::VoiceConversion));
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::SoVitsSvc;
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_inference_category(), Some(InferenceCategory::VoiceConversion));
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::Tacotron2;
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_inference_category(), Some(InferenceCategory::TextToSpeech));
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::StableDiffusion15;
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_inference_category(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_inference_model_type() {
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::RvcV2;
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_inference_model_type(), Some(InferenceModelType::RvcV2));
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::SoVitsSvc;
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_inference_model_type(), Some(InferenceModelType::SoVitsSvc));
|
||||
|
||||
let mut model = default_model();
|
||||
model.weights_type = WeightsType::StableDiffusion15;
|
||||
assert_eq!(VcModelLite::ModelWeight(model).get_inference_model_type(), None);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -37,9 +37,9 @@ pub enum InferenceCategoryAbbreviated {
|
||||
#[serde(alias = "voice_conversion")]
|
||||
VoiceConversion,
|
||||
|
||||
#[serde(rename = "rr")] // NB: DO NOT CHANGE. It could break live jobs. Renamed to be fewer bytes.
|
||||
#[serde(alias = "rerender_a_video")]
|
||||
RerenderAVideo,
|
||||
#[serde(rename = "vf")] // NB: DO NOT CHANGE. It could break live jobs. Renamed to be fewer bytes.
|
||||
#[serde(alias = "video_filter")]
|
||||
VideoFilter,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
|
||||
@@ -112,7 +112,7 @@ impl InferenceCategoryAbbreviated {
|
||||
InferenceCategory::LipsyncAnimation => Self::LipsyncAnimation,
|
||||
InferenceCategory::TextToSpeech => Self::TextToSpeech,
|
||||
InferenceCategory::VoiceConversion => Self::VoiceConversion,
|
||||
InferenceCategory::RerenderAVideo => Self::RerenderAVideo,
|
||||
InferenceCategory::VideoFilter => Self::VideoFilter,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ impl InferenceCategoryAbbreviated {
|
||||
Self::LipsyncAnimation => InferenceCategory::LipsyncAnimation,
|
||||
Self::TextToSpeech => InferenceCategory::TextToSpeech,
|
||||
Self::VoiceConversion => InferenceCategory::VoiceConversion,
|
||||
Self::RerenderAVideo => InferenceCategory::RerenderAVideo,
|
||||
Self::VideoFilter => InferenceCategory::VideoFilter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-1
@@ -1,3 +1,5 @@
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
/// Video sources can be one of several:
|
||||
/// - F: media_files (todo)
|
||||
/// - U: media_uploads (legacy)
|
||||
@@ -32,5 +34,25 @@ pub struct RerenderArgs {
|
||||
|
||||
#[serde(rename = "sd")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_sd_model: Option<String>,
|
||||
pub maybe_sd_model_token: Option<ModelWeightToken>,
|
||||
|
||||
#[serde(rename = "lora")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_lora_model_token: Option<ModelWeightToken>,
|
||||
|
||||
#[serde(rename = "p")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_prompt: Option<String>,
|
||||
|
||||
#[serde(rename = "ap")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_a_prompt: Option<String>,
|
||||
|
||||
#[serde(rename = "np")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_n_prompt: Option<String>,
|
||||
|
||||
#[serde(rename = "se")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_seed: Option<i32>,
|
||||
}
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ SELECT
|
||||
id,
|
||||
token,
|
||||
|
||||
creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
|
||||
creator_user_token,
|
||||
creator_ip_address,
|
||||
creator_set_visibility,
|
||||
|
||||
@@ -101,7 +101,7 @@ WHERE
|
||||
id: GenericDownloadJobId(record.id),
|
||||
download_job_token: DownloadJobToken::new(record.token),
|
||||
creator_ip_address: record.creator_ip_address,
|
||||
creator_user_token: record.creator_user_token,
|
||||
creator_user_token: UserToken::new_from_str(&record.creator_user_token),
|
||||
// NB: Failure case for parsing visibility - default to private
|
||||
creator_set_visibility: Visibility::from_str(&record.creator_set_visibility)
|
||||
.unwrap_or(Visibility::Private),
|
||||
@@ -144,7 +144,7 @@ struct AvailableDownloadJobRawInternal {
|
||||
pub id: i64,
|
||||
pub token: String,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_user_token: String,
|
||||
pub creator_ip_address: String,
|
||||
pub creator_set_visibility: String,
|
||||
|
||||
|
||||
+2
-2
@@ -178,7 +178,7 @@ fn raw_record_to_public_result(record: RawGenericInferenceJobStatus) -> GenericI
|
||||
InferenceCategory::LipsyncAnimation => Some("lipsync animation"),
|
||||
InferenceCategory::TextToSpeech => record.maybe_tts_model_title.as_deref(),
|
||||
InferenceCategory::VoiceConversion => record.maybe_voice_conversion_model_title.as_deref(),
|
||||
InferenceCategory::RerenderAVideo => Some("rerender animation"),
|
||||
InferenceCategory::VideoFilter => Some("Video Filter"),
|
||||
};
|
||||
|
||||
// NB: A bit of a hack. We store TTS results with a full path.
|
||||
@@ -187,7 +187,7 @@ fn raw_record_to_public_result(record: RawGenericInferenceJobStatus) -> GenericI
|
||||
InferenceCategory::LipsyncAnimation => (true, record.maybe_media_file_public_bucket_directory_hash.as_deref()),
|
||||
InferenceCategory::TextToSpeech => (false, record.maybe_tts_public_bucket_path.as_deref()),
|
||||
InferenceCategory::VoiceConversion => (true, record.maybe_voice_conversion_public_bucket_hash.as_deref()),
|
||||
InferenceCategory::RerenderAVideo => (true, record.maybe_media_file_public_bucket_directory_hash.as_deref()),
|
||||
InferenceCategory::VideoFilter => (true, record.maybe_media_file_public_bucket_directory_hash.as_deref()),
|
||||
};
|
||||
|
||||
// NB: We've moved voice conversion out of their own table and into media_files
|
||||
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
use anyhow::anyhow;
|
||||
use sqlx;
|
||||
use sqlx::MySqlPool;
|
||||
|
||||
use enums::by_table::generic_synthetic_ids::id_category::IdCategory;
|
||||
use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory;
|
||||
use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory;
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::common::visibility::Visibility;
|
||||
use errors::AnyhowResult;
|
||||
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
use crate::queries::generic_synthetic_ids::transactional_increment_generic_synthetic_id::transactional_increment_generic_synthetic_id;
|
||||
|
||||
pub enum UploadType {
|
||||
Filesystem,
|
||||
DeviceCaptureApi,
|
||||
}
|
||||
|
||||
pub struct InsertMediaFileFromUploadArgs<'a> {
|
||||
pub pool: &'a MySqlPool,
|
||||
|
||||
pub maybe_creator_user_token: Option<&'a UserToken>,
|
||||
pub maybe_creator_anonymous_visitor_token: Option<&'a AnonymousVisitorTrackingToken>,
|
||||
pub creator_ip_address: &'a str,
|
||||
pub creator_set_visibility: Visibility,
|
||||
|
||||
pub upload_type: UploadType,
|
||||
|
||||
pub media_file_type: MediaFileType,
|
||||
pub maybe_mime_type: Option<&'a str>,
|
||||
pub file_size_bytes: u64,
|
||||
pub duration_millis: u64,
|
||||
pub sha256_checksum: &'a str,
|
||||
|
||||
// TODO: Media duration.
|
||||
//pub duration_millis: u64,
|
||||
|
||||
pub public_bucket_directory_hash: &'a str,
|
||||
pub maybe_public_bucket_prefix: Option<&'a str>,
|
||||
pub maybe_public_bucket_extension: Option<&'a str>,
|
||||
}
|
||||
|
||||
pub async fn insert_media_file_from_file_upload(
|
||||
args: InsertMediaFileFromUploadArgs<'_>
|
||||
) -> AnyhowResult<(MediaFileToken, u64)>
|
||||
{
|
||||
let token = MediaFileToken::generate();
|
||||
|
||||
let origin_category = match args.upload_type {
|
||||
UploadType::Filesystem => MediaFileOriginCategory::Upload,
|
||||
UploadType::DeviceCaptureApi => MediaFileOriginCategory::DeviceApi,
|
||||
};
|
||||
|
||||
let mut maybe_creator_file_synthetic_id : Option<u64> = None;
|
||||
let mut maybe_creator_category_synthetic_id : Option<u64> = None;
|
||||
|
||||
let mut transaction = args.pool.begin().await?;
|
||||
|
||||
if let Some(user_token) = args.maybe_creator_user_token.as_deref() {
|
||||
|
||||
let next_media_file_id = transactional_increment_generic_synthetic_id(
|
||||
&user_token,
|
||||
IdCategory::MediaFile,
|
||||
&mut transaction
|
||||
).await?;
|
||||
|
||||
let next_voice_conversion_id = transactional_increment_generic_synthetic_id(
|
||||
&user_token,
|
||||
IdCategory::FileUpload,
|
||||
&mut transaction
|
||||
).await?;
|
||||
|
||||
maybe_creator_file_synthetic_id = Some(next_media_file_id);
|
||||
maybe_creator_category_synthetic_id = Some(next_voice_conversion_id);
|
||||
}
|
||||
|
||||
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::Unknown;
|
||||
|
||||
let record_id = {
|
||||
let query_result = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO media_files
|
||||
SET
|
||||
token = ?,
|
||||
|
||||
origin_category = ?,
|
||||
origin_product_category = ?,
|
||||
|
||||
maybe_origin_model_type = NULL,
|
||||
maybe_origin_model_token = NULL,
|
||||
|
||||
media_type = ?,
|
||||
maybe_mime_type = ?,
|
||||
file_size_bytes = ?,
|
||||
|
||||
checksum_sha2 = ?,
|
||||
|
||||
public_bucket_directory_hash = ?,
|
||||
maybe_public_bucket_prefix = ?,
|
||||
maybe_public_bucket_extension = ?,
|
||||
|
||||
maybe_creator_user_token = ?,
|
||||
maybe_creator_anonymous_visitor_token = ?,
|
||||
creator_ip_address = ?,
|
||||
|
||||
creator_set_visibility = ?,
|
||||
|
||||
maybe_creator_file_synthetic_id = ?,
|
||||
maybe_creator_category_synthetic_id = ?
|
||||
"#,
|
||||
token.as_str(),
|
||||
|
||||
origin_category.to_str(),
|
||||
ORIGIN_PRODUCT_CATEGORY.to_str(),
|
||||
|
||||
args.media_file_type.to_str(),
|
||||
args.maybe_mime_type,
|
||||
args.file_size_bytes,
|
||||
|
||||
args.sha256_checksum,
|
||||
|
||||
args.public_bucket_directory_hash,
|
||||
args.maybe_public_bucket_prefix,
|
||||
args.maybe_public_bucket_extension,
|
||||
|
||||
args.maybe_creator_user_token,
|
||||
args.maybe_creator_anonymous_visitor_token,
|
||||
args.creator_ip_address,
|
||||
|
||||
args.creator_set_visibility.to_str(),
|
||||
|
||||
maybe_creator_file_synthetic_id,
|
||||
maybe_creator_category_synthetic_id,
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await;
|
||||
|
||||
let record_id = match query_result {
|
||||
Ok(res) => {
|
||||
res.last_insert_id()
|
||||
},
|
||||
Err(err) => {
|
||||
// TODO: handle better
|
||||
//transaction.rollback().await?;
|
||||
return Err(anyhow!("Mysql error: {:?}", err));
|
||||
}
|
||||
};
|
||||
|
||||
record_id
|
||||
};
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok((token, record_id))
|
||||
}
|
||||
+2
-2
@@ -55,7 +55,7 @@ pub async fn insert_media_file_from_rerender(
|
||||
|
||||
let next_rerender_id = transactional_increment_generic_synthetic_id(
|
||||
&user_token,
|
||||
IdCategory::RerenderResult,
|
||||
IdCategory::VideoFilterResult,
|
||||
&mut transaction
|
||||
).await?;
|
||||
|
||||
@@ -67,7 +67,7 @@ pub async fn insert_media_file_from_rerender(
|
||||
let creator_set_visibility = args.job.creator_set_visibility.clone();
|
||||
|
||||
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
|
||||
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::Rerender;
|
||||
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::VideoFilter;
|
||||
const ORIGIN_MODEL_TYPE : MediaFileOriginModelType = MediaFileOriginModelType::Rerender;
|
||||
const MEDIA_TYPE : MediaFileType = MediaFileType::Video;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
pub mod insert_media_file_from_cli_tool;
|
||||
pub mod insert_media_file_from_face_animation;
|
||||
pub mod insert_media_file_from_file_upload;
|
||||
pub mod insert_media_file_from_rerender;
|
||||
pub mod insert_media_file_from_tacotron2;
|
||||
pub mod insert_media_file_from_voice_conversion;
|
||||
pub mod insert_media_file_from_zero_shot_tts;
|
||||
+25
-4
@@ -44,6 +44,9 @@ pub struct MediaFileListItem {
|
||||
|
||||
pub creator_set_visibility: Visibility,
|
||||
|
||||
pub comment_count: u64,
|
||||
pub favorite_count: u64,
|
||||
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
@@ -100,6 +103,8 @@ pub async fn list_media_files(args: ListMediaFilesArgs<'_>) -> AnyhowResult<Medi
|
||||
maybe_creator_display_name: record.maybe_creator_display_name,
|
||||
maybe_creator_gravatar_hash: record.maybe_creator_gravatar_hash,
|
||||
creator_set_visibility: record.creator_set_visibility,
|
||||
comment_count: record.comment_count as u64,
|
||||
favorite_count: record.favorite_count as u64,
|
||||
created_at: record.created_at,
|
||||
updated_at: record.updated_at,
|
||||
}
|
||||
@@ -148,14 +153,22 @@ SELECT
|
||||
|
||||
m.creator_set_visibility,
|
||||
m.created_at,
|
||||
m.updated_at
|
||||
m.updated_at,
|
||||
|
||||
COUNT(f.id) as favorite_count,
|
||||
COUNT(c.id) as comment_count
|
||||
|
||||
FROM media_files AS m
|
||||
|
||||
LEFT OUTER JOIN users AS u
|
||||
ON m.maybe_creator_user_token = u.token
|
||||
|
||||
WHERE m.user_deleted_at IS NULL
|
||||
AND m.mod_deleted_at IS NULL
|
||||
LEFT OUTER JOIN favorites as f
|
||||
ON f.entity_type = 'media_file' AND f.entity_token = m.token
|
||||
LEFT OUTER JOIN comments as c
|
||||
ON c.entity_type = 'media_file' AND c.entity_token = c.token
|
||||
WHERE
|
||||
m.user_deleted_at IS NULL
|
||||
AND m.mod_deleted_at IS NULL
|
||||
"#
|
||||
);
|
||||
|
||||
@@ -186,6 +199,9 @@ AND m.mod_deleted_at IS NULL
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
query_builder.push(" GROUP BY m.id");
|
||||
|
||||
if cursor_is_reversed {
|
||||
query_builder.push(" ORDER BY m.id ASC ");
|
||||
} else {
|
||||
@@ -218,6 +234,9 @@ struct MediaFileListItemInternal {
|
||||
|
||||
creator_set_visibility: Visibility,
|
||||
|
||||
comment_count: i64,
|
||||
favorite_count: i64,
|
||||
|
||||
created_at: DateTime<Utc>,
|
||||
updated_at: DateTime<Utc>,
|
||||
}
|
||||
@@ -257,6 +276,8 @@ impl FromRow<'_, MySqlRow> for MediaFileListItemInternal {
|
||||
creator_set_visibility: Visibility::try_from_mysql_row(row, "creator_set_visibility")?,
|
||||
created_at: row.try_get("created_at")?,
|
||||
updated_at: row.try_get("updated_at")?,
|
||||
comment_count: row.try_get("comment_count")?,
|
||||
favorite_count: row.try_get("favorite_count")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
+14
-21
@@ -51,13 +51,12 @@ pub struct ListMediaFileForUserArgs<'a> {
|
||||
pub maybe_filter_media_type: Option<MediaFileType>,
|
||||
pub page_size: usize,
|
||||
pub page_index: usize,
|
||||
pub cursor_is_reversed: bool,
|
||||
pub sort_ascending: bool,
|
||||
pub view_as: ViewAs,
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
|
||||
pub async fn list_media_files_for_user(args: ListMediaFileForUserArgs<'_>) -> AnyhowResult<MediaFileListPage> {
|
||||
|
||||
/// Let's figure out how many results we could have returned total
|
||||
let count_fields = select_total_count_field();
|
||||
let mut count_query_builder = query_builder(
|
||||
@@ -66,16 +65,13 @@ pub async fn list_media_files_for_user(args: ListMediaFileForUserArgs<'_>) -> An
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
args.cursor_is_reversed,
|
||||
args.sort_ascending,
|
||||
args.view_as,
|
||||
count_fields.as_str(),
|
||||
);
|
||||
|
||||
let row_count_query = count_query_builder.build_query_scalar::<i64>();
|
||||
let row_count_result = row_count_query.fetch_one(args.mysql_pool).await?;
|
||||
/// Figure out limit start and end based on page size and indexes as requested
|
||||
let limit_start = args.page_size * args.page_index;
|
||||
let limit_end = limit_start + args.page_size;
|
||||
|
||||
/// Now fetch the actual results with all the fields
|
||||
let result_fields = select_result_fields();
|
||||
@@ -83,9 +79,9 @@ pub async fn list_media_files_for_user(args: ListMediaFileForUserArgs<'_>) -> An
|
||||
args.maybe_filter_media_type,
|
||||
args.username,
|
||||
true,
|
||||
limit_start,
|
||||
limit_end,
|
||||
args.cursor_is_reversed,
|
||||
args.page_index,
|
||||
args.page_size,
|
||||
args.sort_ascending,
|
||||
args.view_as,
|
||||
result_fields.as_str(),
|
||||
);
|
||||
@@ -115,7 +111,7 @@ pub async fn list_media_files_for_user(args: ListMediaFileForUserArgs<'_>) -> An
|
||||
|
||||
Ok(MediaFileListPage {
|
||||
records: results,
|
||||
sort_ascending: !args.cursor_is_reversed,
|
||||
sort_ascending: args.sort_ascending,
|
||||
current_page: args.page_index,
|
||||
total_page_count: number_of_pages,
|
||||
})
|
||||
@@ -157,9 +153,9 @@ fn query_builder<'a>(
|
||||
maybe_filter_media_type: Option<MediaFileType>,
|
||||
username: &'a str,
|
||||
enforce_limits: bool,
|
||||
limit_start: usize,
|
||||
limit_end: usize,
|
||||
cursor_is_reversed: bool,
|
||||
page_index: usize,
|
||||
page_size: usize,
|
||||
sort_ascending: bool,
|
||||
view_as: ViewAs,
|
||||
select_fields: &'a str,
|
||||
) -> QueryBuilder<'a, MySql> {
|
||||
@@ -201,18 +197,15 @@ WHERE m.user_deleted_at IS NULL
|
||||
}
|
||||
}
|
||||
|
||||
if cursor_is_reversed {
|
||||
query_builder.push(" ORDER BY m.id ASC ");
|
||||
if sort_ascending {
|
||||
query_builder.push(" ORDER BY m.created_at ASC ");
|
||||
} else {
|
||||
query_builder.push(" ORDER BY m.id DESC ");
|
||||
query_builder.push(" ORDER BY m.created_at DESC ");
|
||||
}
|
||||
|
||||
if enforce_limits {
|
||||
if cursor_is_reversed {
|
||||
query_builder.push(format!(" LIMIT {limit_start}, {limit_end} "));
|
||||
} else {
|
||||
query_builder.push(format!(" LIMIT {limit_end}, {limit_start} "));
|
||||
}
|
||||
let offset = page_index * page_size;
|
||||
query_builder.push(format!(" LIMIT {page_size} OFFSET {offset} "));
|
||||
}
|
||||
|
||||
query_builder
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod list_media_files;
|
||||
pub mod list_media_files_by_tokens;
|
||||
pub mod list_media_files_for_user;
|
||||
@@ -1,12 +1,5 @@
|
||||
pub mod create;
|
||||
pub mod delete_media_file;
|
||||
pub mod get_media_file;
|
||||
pub mod insert_media_file_from_cli_tool;
|
||||
pub mod insert_media_file_from_face_animation;
|
||||
pub mod insert_media_file_from_rerender;
|
||||
pub mod insert_media_file_from_tacotron2;
|
||||
pub mod insert_media_file_from_voice_conversion;
|
||||
pub mod insert_media_file_from_zero_shot_tts;
|
||||
pub mod list_media_files;
|
||||
pub mod list_media_files_by_tokens;
|
||||
pub mod list_media_files_for_user;
|
||||
pub mod list;
|
||||
pub mod update_media_file;
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
use anyhow::anyhow;
|
||||
use sqlx::MySqlPool;
|
||||
|
||||
use enums::by_table::model_weights::weights_category::WeightsCategory;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use enums::common::visibility::Visibility;
|
||||
use errors::AnyhowResult;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
use tokens::tokens::voice_conversion_models::VoiceConversionModelToken;
|
||||
|
||||
pub struct CreateModelWeightArgs<'a> {
|
||||
pub maybe_use_model_weights_token: Option<ModelWeightToken>,
|
||||
pub maybe_old_voice_conversion_model_token: Option<VoiceConversionModelToken>,
|
||||
|
||||
pub weights_type: WeightsType,
|
||||
pub weights_category: WeightsCategory,
|
||||
|
||||
pub title: &'a str,
|
||||
|
||||
pub original_download_url: &'a str,
|
||||
pub original_filename: &'a str,
|
||||
pub file_size_bytes: u64,
|
||||
pub file_checksum_sha2: &'a str,
|
||||
|
||||
pub creator_user_token: &'a UserToken,
|
||||
pub creator_ip_address: &'a str,
|
||||
pub creator_set_visibility: Visibility,
|
||||
|
||||
/// (For rvc_v2 models) - whether the model has an associated `.index` file.
|
||||
pub has_index_file: bool,
|
||||
|
||||
pub public_bucket_hash: String,
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
|
||||
pub async fn create_model_weight_from_voice_conversion_download_job(
|
||||
args: CreateModelWeightArgs<'_>,
|
||||
) -> AnyhowResult<(u64, ModelWeightToken)> {
|
||||
|
||||
let weights_token = args.maybe_use_model_weights_token
|
||||
.map(|token| token.clone())
|
||||
.unwrap_or_else(|| ModelWeightToken::generate());
|
||||
|
||||
let mut transaction = args.mysql_pool.begin().await?;
|
||||
|
||||
// NB: Not setting the following:
|
||||
// - created_at
|
||||
// - updated_at
|
||||
// - user_deleted_at
|
||||
// - mod_deleted_at
|
||||
// - version = 0
|
||||
|
||||
let query_result = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO model_weights
|
||||
SET
|
||||
token = ?,
|
||||
weights_type = ?,
|
||||
weights_category = ?,
|
||||
title = ?,
|
||||
|
||||
maybe_thumbnail_token = NULL,
|
||||
maybe_avatar_media_file_token = NULL,
|
||||
maybe_cover_media_file_token = NULL,
|
||||
description_markdown = NULL,
|
||||
description_rendered_html = NULL,
|
||||
|
||||
maybe_last_update_user_token = NULL,
|
||||
original_download_url = ?,
|
||||
original_filename = ?,
|
||||
file_size_bytes = ?,
|
||||
file_checksum_sha2 = ?,
|
||||
|
||||
creator_user_token = ?,
|
||||
creator_ip_address = ?,
|
||||
creator_set_visibility = ?,
|
||||
|
||||
public_bucket_hash = ?,
|
||||
maybe_public_bucket_prefix = ?,
|
||||
maybe_public_bucket_extension = ?,
|
||||
|
||||
cached_user_ratings_total_count = 0,
|
||||
cached_user_ratings_positive_count = 0,
|
||||
cached_user_ratings_negative_count = 0,
|
||||
maybe_cached_user_ratings_ratio = 0.0,
|
||||
cached_user_ratings_last_updated_at = NOW(),
|
||||
|
||||
maybe_migration_old_model_token = ?
|
||||
"#,
|
||||
&weights_token,
|
||||
args.weights_type,
|
||||
args.weights_category,
|
||||
args.title,
|
||||
|
||||
args.original_download_url,
|
||||
args.original_filename,
|
||||
args.file_size_bytes,
|
||||
args.file_checksum_sha2,
|
||||
|
||||
args.creator_user_token,
|
||||
args.creator_ip_address,
|
||||
args.creator_set_visibility.to_str(),
|
||||
|
||||
args.public_bucket_hash,
|
||||
args.maybe_public_bucket_prefix,
|
||||
args.maybe_public_bucket_extension,
|
||||
|
||||
args.maybe_old_voice_conversion_model_token,
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await;
|
||||
|
||||
let model_weights_record_id = match query_result {
|
||||
Ok(res) => res.last_insert_id(),
|
||||
Err(err) => return Err(anyhow!("Mysql error: {:?}", err)),
|
||||
};
|
||||
|
||||
let query_result = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO model_weights_extension_voice_conversion_details
|
||||
SET
|
||||
model_weights_token = ?,
|
||||
has_index_file = ?
|
||||
"#,
|
||||
&weights_token,
|
||||
args.has_index_file
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await;
|
||||
|
||||
match query_result {
|
||||
Ok(_res) => {},
|
||||
Err(err) => return Err(anyhow!("Mysql error: {:?}", err)),
|
||||
};
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok((model_weights_record_id, weights_token))
|
||||
}
|
||||
+9
-9
@@ -24,9 +24,9 @@ pub struct CreateModelWeightsArgs<'a> {
|
||||
pub original_filename: Option<String>,
|
||||
pub file_size_bytes: i32,
|
||||
pub file_checksum_sha2: String,
|
||||
pub private_bucket_hash: String,
|
||||
pub maybe_private_bucket_prefix: Option<String>,
|
||||
pub maybe_private_bucket_extension: Option<String>,
|
||||
pub public_bucket_hash: String,
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
@@ -58,9 +58,9 @@ pub async fn create_weight(args: CreateModelWeightsArgs<'_>) -> AnyhowResult<Mod
|
||||
original_filename = ?,
|
||||
file_size_bytes = ?,
|
||||
file_checksum_sha2 = ?,
|
||||
private_bucket_hash = ?,
|
||||
maybe_private_bucket_prefix = ?,
|
||||
maybe_private_bucket_extension = ?,
|
||||
public_bucket_hash = ?,
|
||||
maybe_public_bucket_prefix = ?,
|
||||
maybe_public_bucket_extension = ?,
|
||||
cached_user_ratings_total_count = ?,
|
||||
cached_user_ratings_positive_count = ?,
|
||||
cached_user_ratings_negative_count = ?,
|
||||
@@ -82,9 +82,9 @@ pub async fn create_weight(args: CreateModelWeightsArgs<'_>) -> AnyhowResult<Mod
|
||||
args.original_filename,
|
||||
args.file_size_bytes,
|
||||
args.file_checksum_sha2,
|
||||
args.private_bucket_hash,
|
||||
args.maybe_private_bucket_prefix,
|
||||
args.maybe_private_bucket_extension,
|
||||
args.public_bucket_hash,
|
||||
args.maybe_public_bucket_prefix,
|
||||
args.maybe_public_bucket_extension,
|
||||
args.cached_user_ratings_total_count,
|
||||
args.cached_user_ratings_positive_count,
|
||||
args.cached_user_ratings_negative_count,
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod create_model_weight_from_voice_conversion_download_job;
|
||||
pub mod create_weight;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user