mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-30 23:35:54 -04:00
Compare commits
32
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afa91c032e | ||
|
|
a76807ab7d | ||
|
|
15c1cb8e5e | ||
|
|
4a69589f1d | ||
|
|
ed72cf7f7f | ||
|
|
ad093d3fa8 | ||
|
|
b505896864 | ||
|
|
b680002c6b | ||
|
|
40bb91f024 | ||
|
|
fa002d3fe3 | ||
|
|
02bec3655c | ||
|
|
12b7f4d25e | ||
|
|
02d6f6c940 | ||
|
|
f5d7c93c22 | ||
|
|
0125eba7cc | ||
|
|
033e42d1b1 | ||
|
|
aa0632bd41 | ||
|
|
87cc49982e | ||
|
|
853943f21a | ||
|
|
6f9dd4d6e3 | ||
|
|
5de56cd11b | ||
|
|
df16a4aa89 | ||
|
|
613289f1ab | ||
|
|
ae49b9da7d | ||
|
|
3f531ae9f0 | ||
|
|
370bcf3f2d | ||
|
|
685264e20c | ||
|
|
2c7400bf76 | ||
|
|
fae36d485b | ||
|
|
fe3107b1b0 | ||
|
|
bdde5da223 | ||
|
|
7539237ee4 |
+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_cover_image_media_file_token = NULL,\n maybe_description_markdown = ?,\n maybe_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_cover_image_media_file_token = NULL,\n maybe_description_markdown = ?,\n maybe_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": "0a392b6adb884a4bb4c08fbc2123d40c27e9fbb5c2b688b182f849b0c1cc5735"
|
||||
}
|
||||
-212
@@ -1,212 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n f.token as `token: tokens::tokens::user_bookmarks::UserBookmarkToken`,\n f.entity_type as `entity_type: enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType`,\n f.entity_token,\n f.user_token as `user_token: tokens::tokens::users::UserToken`,\n u.username,\n u.display_name as user_display_name,\n u.email_gravatar_hash as user_gravatar_hash,\n f.created_at,\n f.updated_at,\n f.deleted_at,\n\n media_files.media_type as `maybe_media_file_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n media_files.origin_product_category as `maybe_media_file_origin_category: enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory`,\n\n model_weights.title as maybe_descriptive_text_model_weight_title,\n tts_models.title as maybe_descriptive_text_tts_model_title,\n tts_results.raw_inference_text as maybe_descriptive_text_tts_result_inference_text,\n users.display_name as maybe_descriptive_text_user_display_name,\n voice_conversion_models.title as maybe_descriptive_text_voice_conversion_model_title,\n zs_voices.title as maybe_descriptive_text_zs_voice_title\n\nFROM\n user_bookmarks AS f\nJOIN users AS u\n ON f.user_token = u.token\n\nLEFT OUTER JOIN model_weights ON model_weights.token = f.entity_token\nLEFT OUTER JOIN media_files ON media_files.token = f.entity_token\nLEFT OUTER JOIN tts_models ON tts_models.token = f.entity_token\nLEFT OUTER JOIN tts_results ON tts_results.token = f.entity_token\nLEFT OUTER JOIN users ON users.token = f.entity_token\nLEFT OUTER JOIN voice_conversion_models ON voice_conversion_models.token = f.entity_token\nLEFT OUTER JOIN zs_voices ON zs_voices.token = f.entity_token\n\nWHERE\n u.username = ?\n AND f.entity_type = ?\n AND f.deleted_at IS NULL\nORDER BY f.id DESC\nLIMIT 50\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::user_bookmarks::UserBookmarkToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "entity_type: enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "entity_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "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": 4,
|
||||
"name": "username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "user_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "user_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | 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": "deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_media_file_type: enums::by_table::media_files::media_file_type::MediaFileType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_media_file_origin_category: enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_descriptive_text_model_weight_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_descriptive_text_tts_model_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "maybe_descriptive_text_tts_result_inference_text",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "maybe_descriptive_text_user_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_descriptive_text_voice_conversion_model_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "maybe_descriptive_text_zs_voice_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "3a7ac7f979ac270dad1070031d0d663d0eb3d969365f6b2fd048ca41c5c455b2"
|
||||
}
|
||||
+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_cover_image_media_file_token = NULL,\n maybe_description_markdown = NULL,\n maybe_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": "6512f05410514927b52b8cc42f4eda0ad7a256254fd7fcf3b8a1cc429b06ad38"
|
||||
}
|
||||
-212
@@ -1,212 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n f.token as `token: tokens::tokens::user_bookmarks::UserBookmarkToken`,\n f.entity_type as `entity_type: enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType`,\n f.entity_token,\n f.user_token as `user_token: tokens::tokens::users::UserToken`,\n u.username,\n u.display_name as user_display_name,\n u.email_gravatar_hash as user_gravatar_hash,\n f.created_at,\n f.updated_at,\n f.deleted_at,\n\n media_files.media_type as `maybe_media_file_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n media_files.origin_product_category as `maybe_media_file_origin_category: enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory`,\n\n model_weights.title as maybe_descriptive_text_model_weight_title,\n tts_models.title as maybe_descriptive_text_tts_model_title,\n tts_results.raw_inference_text as maybe_descriptive_text_tts_result_inference_text,\n users.display_name as maybe_descriptive_text_user_display_name,\n voice_conversion_models.title as maybe_descriptive_text_voice_conversion_model_title,\n zs_voices.title as maybe_descriptive_text_zs_voice_title\n\nFROM\n user_bookmarks AS f\nJOIN users AS u\n ON f.user_token = u.token\n\nLEFT OUTER JOIN model_weights ON model_weights.token = f.entity_token\nLEFT OUTER JOIN media_files ON media_files.token = f.entity_token\nLEFT OUTER JOIN tts_models ON tts_models.token = f.entity_token\nLEFT OUTER JOIN tts_results ON tts_results.token = f.entity_token\nLEFT OUTER JOIN users ON users.token = f.entity_token\nLEFT OUTER JOIN voice_conversion_models ON voice_conversion_models.token = f.entity_token\nLEFT OUTER JOIN zs_voices ON zs_voices.token = f.entity_token\n\nWHERE\n u.username = ?\n AND f.deleted_at IS NULL\nORDER BY f.id DESC\nLIMIT 50\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::user_bookmarks::UserBookmarkToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "entity_type: enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "entity_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "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": 4,
|
||||
"name": "username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "user_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "user_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | 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": "deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_media_file_type: enums::by_table::media_files::media_file_type::MediaFileType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_media_file_origin_category: enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_descriptive_text_model_weight_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_descriptive_text_tts_model_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "maybe_descriptive_text_tts_result_inference_text",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "maybe_descriptive_text_user_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_descriptive_text_voice_conversion_model_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "maybe_descriptive_text_zs_voice_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "707af35ee4ab4519f28e6d69982944666e6c7c0f24b5da79dde828ffdb2c8302"
|
||||
}
|
||||
+44
-55
@@ -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\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 ",
|
||||
"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_description_markdown,\n wt.maybe_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\n wt.public_bucket_hash,\n wt.maybe_public_bucket_prefix,\n wt.maybe_public_bucket_extension,\n\n cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_cover_image_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 cover_image\n ON cover_image.token = wt.maybe_cover_image_media_file_token\n WHERE\n wt.token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -45,36 +45,26 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "maybe_thumbnail_token",
|
||||
"name": "maybe_description_markdown",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"type": "Blob",
|
||||
"flags": "BLOB | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "description_markdown",
|
||||
"name": "maybe_description_rendered_html",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "BLOB | BINARY",
|
||||
"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": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -84,7 +74,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 7,
|
||||
"name": "creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -94,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 8,
|
||||
"name": "creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -104,7 +94,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 9,
|
||||
"name": "creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -114,7 +104,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 10,
|
||||
"name": "creator_ip_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +114,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 11,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -134,7 +124,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 12,
|
||||
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -144,7 +134,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 13,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -154,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 14,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -164,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 15,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -174,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"ordinal": 16,
|
||||
"name": "file_checksum_sha2",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -184,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 17,
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -194,7 +184,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 18,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -204,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 19,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -214,8 +204,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "maybe_avatar_public_bucket_hash",
|
||||
"ordinal": 20,
|
||||
"name": "maybe_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
@@ -223,9 +213,19 @@
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "maybe_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "maybe_avatar_public_bucket_prefix",
|
||||
"name": "maybe_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -235,16 +235,6 @@
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -254,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 24,
|
||||
"name": "cached_user_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -264,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 25,
|
||||
"name": "cached_user_ratings_total_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -274,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 26,
|
||||
"name": "maybe_cached_user_ratings_ratio",
|
||||
"type_info": {
|
||||
"type": "Float",
|
||||
@@ -284,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"ordinal": 27,
|
||||
"name": "cached_user_ratings_last_updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -294,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"ordinal": 28,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -304,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"ordinal": 29,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -314,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"ordinal": 30,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -324,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"ordinal": 31,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -334,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 33,
|
||||
"ordinal": 32,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -353,8 +343,7 @@
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -384,5 +373,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "4e30e34cdf7a5834a3981d5e634506966bac9f9c420e800d15ce313778272cee"
|
||||
"hash": "7d3806f46b5cc96c0e3df22454190834c0294ad34db2d8271f2e2863a3cca3a1"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n UPDATE model_weights\n SET\n title = COALESCE(?, title),\n description_markdown = COALESCE(?, description_markdown),\n maybe_thumbnail_token = COALESCE(?, maybe_thumbnail_token),\n description_rendered_html = COALESCE(?, description_rendered_html),\n creator_set_visibility = COALESCE(?, creator_set_visibility),\n version = version + 1\n WHERE token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "81df77a84fee48398e8a07e053b0393a0e341caf652c18c7160dd0a59247a19a"
|
||||
}
|
||||
-355
@@ -1,355 +0,0 @@
|
||||
{
|
||||
"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.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": [
|
||||
{
|
||||
"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": "title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"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": 3,
|
||||
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "maybe_thumbnail_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_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_email_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",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"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": 13,
|
||||
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 2048
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "file_checksum_sha2",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "cached_user_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "cached_user_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"name": "cached_user_ratings_total_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"name": "maybe_cached_user_ratings_ratio",
|
||||
"type_info": {
|
||||
"type": "Float",
|
||||
"flags": "",
|
||||
"char_set": 63,
|
||||
"max_size": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"name": "cached_user_ratings_last_updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "854da1bad28fbcf5a8f82c26c52c25a7727957b52b727831ce62518b3c5fc9bd"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n INSERT INTO model_weights\n SET\n token = ?,\n weights_type = ?,\n weights_category = ?,\n title = ?,\n maybe_description_markdown = ?,\n maybe_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": {
|
||||
"Right": 22
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a18c5b1418d71fa9aefd3ae5c440be2afc1f9467808aa66d3b850a4d54c81e4d"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
+44
-55
@@ -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_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 ",
|
||||
"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_description_markdown,\n wt.maybe_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 cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_cover_image_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 cover_image\n ON cover_image.token = wt.maybe_cover_image_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": [
|
||||
{
|
||||
@@ -45,36 +45,26 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "maybe_thumbnail_token",
|
||||
"name": "maybe_description_markdown",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"type": "Blob",
|
||||
"flags": "BLOB | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
"max_size": 262140
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "description_markdown",
|
||||
"name": "maybe_description_rendered_html",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
|
||||
"flags": "BLOB | BINARY",
|
||||
"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": "creator_ip_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -84,7 +74,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 7,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -94,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 8,
|
||||
"name": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -104,7 +94,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 9,
|
||||
"name": "creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -114,7 +104,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 10,
|
||||
"name": "creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +114,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 11,
|
||||
"name": "creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -134,7 +124,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 12,
|
||||
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -144,7 +134,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 13,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -154,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 14,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -164,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 15,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -174,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"ordinal": 16,
|
||||
"name": "file_checksum_sha2",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -184,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 17,
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -194,7 +184,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 18,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -204,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 19,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -214,8 +204,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "maybe_avatar_public_bucket_hash",
|
||||
"ordinal": 20,
|
||||
"name": "maybe_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
@@ -223,9 +213,19 @@
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "maybe_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "maybe_avatar_public_bucket_prefix",
|
||||
"name": "maybe_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -235,16 +235,6 @@
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -254,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 24,
|
||||
"name": "cached_user_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -264,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 25,
|
||||
"name": "cached_user_ratings_total_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -274,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 26,
|
||||
"name": "maybe_cached_user_ratings_ratio",
|
||||
"type_info": {
|
||||
"type": "Float",
|
||||
@@ -284,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"ordinal": 27,
|
||||
"name": "cached_user_ratings_last_updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -294,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"ordinal": 28,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -304,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"ordinal": 29,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -314,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"ordinal": 30,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -324,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"ordinal": 31,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -334,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 33,
|
||||
"ordinal": 32,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -353,8 +343,7 @@
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -384,5 +373,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "93084dc42ae4ada186dc90bdd470122342586f4f19a3ac961286c1c54a5c32b2"
|
||||
"hash": "bb2c5a81ab6f38ecef7ee177a4ea36e75c5d2180a897094f940f097bbbd66060"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"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 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": {
|
||||
"Right": 23
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "cb07f1522d0d619e2f364af78250080c99e7930ec095c5600abb80a9d8c5154d"
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n UPDATE model_weights\n SET\n maybe_avatar_media_file_token = ?\n WHERE token = ?\n LIMIT 1\n ",
|
||||
"query": "\n UPDATE model_weights\n SET\n maybe_cover_image_media_file_token = ?\n WHERE token = ?\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -8,5 +8,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "bda002b24b98328f0fb0440cfc82a47faf01e5d16d1030e15a7e2da161dd0d80"
|
||||
"hash": "d7b28a5b4f0220b02eacb01df030c4d971fd191cf3cb5f0211ce29604d36bca3"
|
||||
}
|
||||
-355
@@ -1,355 +0,0 @@
|
||||
{
|
||||
"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.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": [
|
||||
{
|
||||
"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": "title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"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": 3,
|
||||
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "maybe_thumbnail_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_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_email_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",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"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": 13,
|
||||
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "original_download_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 2048
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "original_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "file_size_bytes",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "file_checksum_sha2",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"name": "cached_user_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"name": "cached_user_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"name": "cached_user_ratings_total_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"name": "maybe_cached_user_ratings_ratio",
|
||||
"type_info": {
|
||||
"type": "Float",
|
||||
"flags": "",
|
||||
"char_set": 63,
|
||||
"max_size": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"name": "cached_user_ratings_last_updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"name": "user_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"name": "mod_deleted_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "ec733ae6705dc03fb785e2299c35fcfef23422142735319c8cd091ca8179f97d"
|
||||
}
|
||||
Generated
+4
-3
@@ -1914,6 +1914,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"storyteller_root",
|
||||
"subprocess",
|
||||
"subprocess_common",
|
||||
"tempdir",
|
||||
@@ -2949,9 +2950,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.11.0"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6c16b11a665b26aeeb9b1d7f954cdeb034be38dd00adab4f2ae921a8fee804"
|
||||
checksum = "cb33622da908807a06f9513c19b3c1ad50fab3e4137d82a78107d502075aa199"
|
||||
dependencies = [
|
||||
"cfb 0.7.3",
|
||||
]
|
||||
@@ -3564,7 +3565,7 @@ dependencies = [
|
||||
name = "mimetypes"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"infer 0.11.0",
|
||||
"infer 0.15.0",
|
||||
"my-workspace-hack",
|
||||
]
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@ select
|
||||
id,
|
||||
token,
|
||||
download_type,
|
||||
title,
|
||||
download_url,
|
||||
SUBSTRING(title, 1, 35) as title,
|
||||
SUBSTRING(download_url, 1, 100) as title,
|
||||
status,
|
||||
attempt_count
|
||||
from generic_download_jobs
|
||||
where status IN ('started', 'attempt_failed', 'complete_failure', 'dead')
|
||||
and download_type NOT IN ('vits', 'hifigan')
|
||||
and created_at > NOW() - INTERVAL 15 DAY;
|
||||
and created_at > NOW() - INTERVAL 30 DAY;
|
||||
|
||||
|
||||
-- 2) Then restart them
|
||||
@@ -32,7 +32,7 @@ where token IN (
|
||||
from generic_download_jobs
|
||||
where status IN ('started', 'attempt_failed', 'complete_failure', 'dead')
|
||||
and download_type NOT IN ('vits', 'hifigan')
|
||||
and created_at > NOW() - INTERVAL 15 DAY
|
||||
and created_at > NOW() - INTERVAL 30 DAY
|
||||
) as x
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN maybe_cover_image_media_file_token TO maybe_cover_media_file_token;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE model_weights
|
||||
RENAME COLUMN maybe_cover_media_file_token TO maybe_cover_image_media_file_token;
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE model_weights
|
||||
ADD COLUMN maybe_thumbnail_token VARCHAR(32) DEFAULT NULL
|
||||
AFTER title;
|
||||
|
||||
ALTER TABLE model_weights
|
||||
ADD COLUMN maybe_avatar_media_file_token VARCHAR(32) DEFAULT NULL
|
||||
AFTER maybe_thumbnail_token;
|
||||
|
||||
CREATE INDEX fk_maybe_avatar_media_file_token ON model_weights (maybe_avatar_media_file_token);
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Drop column
|
||||
ALTER TABLE model_weights DROP COLUMN maybe_thumbnail_token;
|
||||
ALTER TABLE model_weights DROP COLUMN maybe_avatar_media_file_token;
|
||||
@@ -0,0 +1,9 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE model_weights
|
||||
CHANGE maybe_description_markdown description_markdown TEXT NOT NULL;
|
||||
|
||||
ALTER TABLE model_weights
|
||||
CHANGE maybe_description_rendered_html description_rendered_html TEXT NOT NULL;
|
||||
@@ -0,0 +1,9 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE model_weights
|
||||
CHANGE description_markdown maybe_description_markdown TEXT DEFAULT NULL;
|
||||
|
||||
ALTER TABLE model_weights
|
||||
CHANGE description_rendered_html maybe_description_rendered_html TEXT DEFAULT NULL;
|
||||
@@ -39,23 +39,19 @@ CREATE TABLE model_weights (
|
||||
-- The "name" of the model, which might be complicated.
|
||||
title VARCHAR(255) NOT NULL,
|
||||
|
||||
-- TODO(bt, 2023-12-14): Delete the `maybe_thumbnail_token` column later.
|
||||
-- We're using other columns instead.
|
||||
maybe_thumbnail_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- The "avatar" image is a media file of type image that serves as a
|
||||
-- small avatar or profile picture icon.
|
||||
maybe_avatar_media_file_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- The "cover" image is a media file of type image that covers the
|
||||
-- top of the page.
|
||||
maybe_cover_media_file_token VARCHAR(32) DEFAULT NULL,
|
||||
-- The "cover" image is a media file of type image that severs as a small
|
||||
-- example of the model. Like album art or a user profile picture / avatar.
|
||||
maybe_cover_image_media_file_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- The description of the model in markdown.
|
||||
description_markdown TEXT NOT NULL,
|
||||
-- This is optional, since not all weights are of the same caliber (eg. zero shot models
|
||||
-- don't deserve a description).
|
||||
maybe_description_markdown TEXT DEFAULT NULL,
|
||||
|
||||
-- Generated HTML (not user-editable).
|
||||
description_rendered_html TEXT NOT NULL,
|
||||
-- This is optional, since not all weights are of the same caliber (eg. zero shot
|
||||
-- models don't deserve a description).
|
||||
maybe_description_rendered_html TEXT DEFAULT NULL,
|
||||
|
||||
|
||||
-- ========== CREATOR DETAILS ==========
|
||||
@@ -194,7 +190,6 @@ CREATE TABLE model_weights (
|
||||
KEY index_weights_category (weights_category),
|
||||
KEY fk_creator_user_token (creator_user_token),
|
||||
KEY index_creator_set_visibility (creator_set_visibility),
|
||||
KEY fk_maybe_avatar_media_file_token (maybe_avatar_media_file_token),
|
||||
KEY fk_maybe_cover_media_file_token (maybe_cover_media_file_token)
|
||||
KEY fk_maybe_cover_media_file_token (maybe_cover_image_media_file_token)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
@@ -50,6 +50,7 @@ pub enum UserBookmarkEntityType {
|
||||
// TODO(bt, 2023-01-17): This desperately needs MySQL integration tests!
|
||||
impl_enum_display_and_debug_using_to_str!(UserBookmarkEntityType);
|
||||
impl_mysql_enum_coders!(UserBookmarkEntityType);
|
||||
impl_mysql_from_row!(UserBookmarkEntityType);
|
||||
|
||||
/// NB: Legacy API for older code.
|
||||
impl UserBookmarkEntityType {
|
||||
|
||||
@@ -4,10 +4,11 @@ use serde::Serialize;
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `user_ratings` 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 UserRatingEntityType {
|
||||
/// Media files (inference results, uploads, etc.)
|
||||
#[serde(rename = "media_file")]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// UserRatingValue
|
||||
///
|
||||
@@ -17,7 +18,7 @@ use strum::EnumIter;
|
||||
/// *DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY!*
|
||||
///
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize, sqlx::Type)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize, sqlx::Type, ToSchema)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[sqlx(rename_all = "lowercase")]
|
||||
pub enum UserRatingValue {
|
||||
|
||||
@@ -3,3 +3,4 @@ pub mod job_status_plus;
|
||||
pub mod sqlite;
|
||||
pub mod visibility;
|
||||
pub mod vocoder_type;
|
||||
pub mod view_as;
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
|
||||
|
||||
use utoipa::ToSchema;
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize, sqlx::Type,ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[sqlx(rename_all = "snake_case")]
|
||||
pub enum ViewAs {
|
||||
/// Public entities are able to be listed in public lists.
|
||||
/// It does not mean that they necessarily will be (eg. they could be "mod unapproved" or deleted).
|
||||
Author,
|
||||
/// Hidden entities are not shown in public lists, but the URL to them may be given out freely.
|
||||
/// They are available to non-logged-in users as long as they have the URL.
|
||||
Moderator,
|
||||
/// Private entities should only be available to the creator, a list of approved users, and
|
||||
/// website moderation staff.
|
||||
AnotherUser,
|
||||
}
|
||||
|
||||
|
||||
impl_enum_display_and_debug_using_to_str!(ViewAs);
|
||||
impl_mysql_from_row!(ViewAs);
|
||||
|
||||
impl Default for ViewAs {
|
||||
fn default() -> Self { Self::AnotherUser }
|
||||
}
|
||||
|
||||
/// NB: Legacy API for older code.
|
||||
impl ViewAs {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Author => "author",
|
||||
Self::Moderator => "moderator",
|
||||
Self::AnotherUser => "another_user",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"author" => Ok(Self::Author),
|
||||
"moderator" => Ok(Self::Moderator),
|
||||
"another_user" => Ok(Self::AnotherUser),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::common::view_as::ViewAs;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
#[test]
|
||||
fn test_default() {
|
||||
assert_eq!(ViewAs::default(), ViewAs::AnotherUser);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(ViewAs::Author, "author");
|
||||
assert_serialization(ViewAs::Moderator, "moderator");
|
||||
assert_serialization(ViewAs::AnotherUser, "another_user");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_str() {
|
||||
assert_eq!(ViewAs::Author.to_str(), "author");
|
||||
assert_eq!(ViewAs::Moderator.to_str(), "moderator");
|
||||
assert_eq!(ViewAs::AnotherUser.to_str(), "another_user");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(ViewAs::from_str("author").unwrap(), ViewAs::Author);
|
||||
assert_eq!(ViewAs::from_str("moderator").unwrap(), ViewAs::Moderator);
|
||||
assert_eq!(ViewAs::from_str("another_user").unwrap(), ViewAs::AnotherUser);
|
||||
assert!(ViewAs::from_str("foo").is_err());
|
||||
}
|
||||
|
||||
mod traits {
|
||||
use crate::common::view_as::ViewAs;
|
||||
|
||||
#[test]
|
||||
fn display() {
|
||||
let view_as = ViewAs::Moderator;
|
||||
assert_eq!(format!("{}", view_as), "moderator".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn debug() {
|
||||
let view_as = ViewAs::Moderator;
|
||||
assert_eq!(format!("{:?}", view_as), "moderator".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
struct CompositeType {
|
||||
view_as: ViewAs,
|
||||
string: String,
|
||||
}
|
||||
|
||||
mod serde_serialization {
|
||||
use crate::common::view_as::ViewAs;
|
||||
|
||||
use super::CompositeType;
|
||||
|
||||
#[test]
|
||||
fn serialize() {
|
||||
let expected = "\"author\"".to_string(); // NB: Quoted
|
||||
|
||||
assert_eq!(expected, toml::to_string(&ViewAs::Author).unwrap());
|
||||
|
||||
// Just to show this serializes the same as a string
|
||||
assert_eq!(expected, toml::to_string("author").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_serialize() {
|
||||
let value = CompositeType { view_as: ViewAs::Moderator, string: "bar".to_string() };
|
||||
let expected = r#"{"view_as":"moderator","string":"bar"}"#.to_string();
|
||||
assert_eq!(expected, serde_json::to_string(&value).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
mod serde_deserialization {
|
||||
use crate::common::view_as::ViewAs;
|
||||
|
||||
use super::CompositeType;
|
||||
|
||||
#[test]
|
||||
fn deserialize() {
|
||||
let payload = "\"another_user\""; // NB: Quoted
|
||||
let value: ViewAs = serde_json::from_str(payload).unwrap();
|
||||
assert_eq!(value, ViewAs::AnotherUser);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_deserialize() {
|
||||
let payload = r#"{"view_as":"another_user","string":"bar"}"#.to_string();
|
||||
let expected = CompositeType {
|
||||
view_as: ViewAs::AnotherUser,
|
||||
string: "bar".to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(expected, serde_json::from_str::<CompositeType>(&payload).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,8 +111,7 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
let mut description_rendered_html;
|
||||
let mut original_filename;
|
||||
let mut original_download_url;
|
||||
let mut thumbnail_token;
|
||||
|
||||
|
||||
let mut private_bucket_hash:String = "".to_string();
|
||||
let mut private_bucket_prefix;
|
||||
let mut private_bucket_extension;
|
||||
@@ -140,9 +139,6 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
original_filename = format!("gura_gwar{}.safetensors", i);
|
||||
original_download_url = format!("www.google.ca");
|
||||
|
||||
// NOTE TO SELF this will be a join for later on for now they can use this.
|
||||
thumbnail_token = "";
|
||||
|
||||
// private_bucket_hash = format!("bucket_hash{}", i);
|
||||
private_bucket_prefix = format!("_fake");
|
||||
private_bucket_extension = format!("rvcV2");
|
||||
@@ -171,9 +167,6 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
original_filename = format!("filename{}.txt", i);
|
||||
original_download_url = format!("https://civitai.com/api/download/models/149193?type=Model&format=SafeTensor&size=pruned&fp=fp16");
|
||||
|
||||
// NOTE TO SELF this will be a join for later on for now they can use this.
|
||||
thumbnail_token = "";
|
||||
|
||||
// private_bucket_hash = format!("bucket_hash{}", i);
|
||||
private_bucket_prefix = format!("_fake");
|
||||
private_bucket_extension = format!("tt2");
|
||||
@@ -197,9 +190,6 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
original_filename = format!("filename{}.txt", i);
|
||||
original_download_url = format!("https://civitai.com/api/download/models/149193?type=Model&format=SafeTensor&size=pruned&fp=fp16");
|
||||
|
||||
// NOTE TO SELF this will be a join for later on for now they can use this.
|
||||
thumbnail_token = ""; //sd1_5_image_token;
|
||||
|
||||
// private_bucket_hash = format!("bucket_hash{}", i);
|
||||
private_bucket_prefix = format!("_fake");
|
||||
private_bucket_extension = format!("sd15");
|
||||
@@ -245,9 +235,6 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
original_filename = format!("filename{}.txt", i);
|
||||
original_download_url = format!("https://civitai.com/api/download/models/149193?type=Model&format=SafeTensor&size=pruned&fp=fp16");
|
||||
|
||||
// NOTE TO SELF this will be a join for later on for now they can use this.
|
||||
thumbnail_token = "";
|
||||
|
||||
cached_user_ratings_total_count = i;
|
||||
cached_user_ratings_positive_count = i;
|
||||
cached_user_ratings_negative_count = i;
|
||||
@@ -273,9 +260,6 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
original_filename = format!("filename{}.txt", i);
|
||||
original_download_url = format!("https://civitai.com/api/download/models/149193?type=Model&format=SafeTensor&size=pruned&fp=fp16");
|
||||
|
||||
// NOTE TO SELF this will be a join for later on for now they can use this.
|
||||
thumbnail_token = ""; // lora_image_token;
|
||||
|
||||
// private_bucket_hash = format!("bucket_hash{}", i);
|
||||
private_bucket_prefix = format!("_fake");
|
||||
private_bucket_extension = format!("loRA");
|
||||
@@ -303,9 +287,6 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
original_filename = format!("gura_gwar{}.safetensors", i);
|
||||
original_download_url = format!("www.google.ca");
|
||||
|
||||
// NOTE TO SELF this will be a join for later on for now they can use this.
|
||||
thumbnail_token = "";
|
||||
|
||||
// private_bucket_hash = format!("bucket_hash{}", i);
|
||||
private_bucket_prefix = format!("_fake");
|
||||
private_bucket_extension = format!("rvcV2");
|
||||
@@ -324,9 +305,8 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
|
||||
weights_type: weights_types, // replace with actual WeightsType
|
||||
weights_category, // replace with actual WeightsCategory
|
||||
title,
|
||||
maybe_thumbnail_token: Some(thumbnail_token.to_string()),
|
||||
description_markdown: description,
|
||||
description_rendered_html: description_rendered_html.to_string(),
|
||||
maybe_description_markdown: Some(description),
|
||||
maybe_description_rendered_html: Some(description_rendered_html.to_string()),
|
||||
creator_user_token: Some(&user_token), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -370,9 +350,8 @@ pub async fn seed_weights_for_user_token(
|
||||
weights_type: WeightsType::RvcV2, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::VoiceConversion, // replace with actual WeightsCategory
|
||||
title: "Title 1".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 1".to_string()),
|
||||
description_markdown: "Description 1".to_string(),
|
||||
description_rendered_html: "<p>Description 1</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 1".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 1</p>".to_string()),
|
||||
creator_user_token: Some(&user_token), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -396,9 +375,8 @@ pub async fn seed_weights_for_user_token(
|
||||
weights_type: WeightsType::HifiganTacotron2, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::TextToSpeech, // replace with actual WeightsCategory
|
||||
title: "Title 2".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 2".to_string()),
|
||||
description_markdown: "Description 2".to_string(),
|
||||
description_rendered_html: "<p>Description 2</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 2".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 2</p>".to_string()),
|
||||
creator_user_token: Some(&user_token), // replace with actual UserToken
|
||||
creator_ip_address: "292.268.2.2",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -422,9 +400,8 @@ pub async fn seed_weights_for_user_token(
|
||||
weights_type: WeightsType::StableDiffusion15, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
|
||||
title: "Title 3".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 3".to_string()),
|
||||
description_markdown: "Description 3".to_string(),
|
||||
description_rendered_html: "<p>Description 3</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 3".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 3</p>".to_string()),
|
||||
creator_user_token: Some(&user_token), // replace with actual UserToken
|
||||
creator_ip_address: "392.368.3.3",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -448,9 +425,8 @@ pub async fn seed_weights_for_user_token(
|
||||
weights_type: WeightsType::LoRA, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
|
||||
title: "Title 4".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 4".to_string()),
|
||||
description_markdown: "Description 4".to_string(),
|
||||
description_rendered_html: "<p>Description 4</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 4".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 4</p>".to_string()),
|
||||
creator_user_token: Some(&user_token), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -474,9 +450,8 @@ pub async fn seed_weights_for_user_token(
|
||||
weights_type: WeightsType::LoRA, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
|
||||
title: "Title 5".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 4".to_string()),
|
||||
description_markdown: "Description 4".to_string(),
|
||||
description_rendered_html: "<p>Description 4</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 4".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 4</p>".to_string()),
|
||||
creator_user_token: Some(&user_token), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -526,9 +501,8 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
weights_type: WeightsType::RvcV2, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::VoiceConversion, // replace with actual WeightsCategory
|
||||
title: "Title 1".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 1".to_string()),
|
||||
description_markdown: "Description 1".to_string(),
|
||||
description_rendered_html: "<p>Description 1</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 1".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 1</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token1), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -552,9 +526,8 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
weights_type: WeightsType::HifiganTacotron2, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::TextToSpeech, // replace with actual WeightsCategory
|
||||
title: "Title 2".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 2".to_string()),
|
||||
description_markdown: "Description 2".to_string(),
|
||||
description_rendered_html: "<p>Description 2</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 2".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 2</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token2), // replace with actual UserToken
|
||||
creator_ip_address: "292.268.2.2",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -578,9 +551,8 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
weights_type: WeightsType::StableDiffusion15, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
|
||||
title: "Title 3".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 3".to_string()),
|
||||
description_markdown: "Description 3".to_string(),
|
||||
description_rendered_html: "<p>Description 3</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 3".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 3</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token3), // replace with actual UserToken
|
||||
creator_ip_address: "392.368.3.3",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -604,9 +576,8 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
weights_type: WeightsType::LoRA, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
|
||||
title: "Title 4".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 4".to_string()),
|
||||
description_markdown: "Description 4".to_string(),
|
||||
description_rendered_html: "<p>Description 4</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 4".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 4</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token4), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -630,9 +601,8 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>,user_token: UserToke
|
||||
weights_type: WeightsType::LoRA, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
|
||||
title: "Title 5".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 5".to_string()),
|
||||
description_markdown: "Description 5".to_string(),
|
||||
description_rendered_html: "<p>Description 5</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 5".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 5</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token5), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
|
||||
@@ -92,7 +92,6 @@ pub async fn seed_weights_files(
|
||||
let description_rendered_html = "This is a description rendered html";
|
||||
let original_filename = "model.safetensors";
|
||||
let original_download_url = "https://example.com/model.safetensors";
|
||||
let thumbnail_token = format!("{}", n);
|
||||
|
||||
// let public_bucket_hash: String = weights_file_token.to_string();
|
||||
// let public_bucket_prefix = weights_type.to_string();
|
||||
@@ -130,9 +129,8 @@ pub async fn seed_weights_files(
|
||||
weights_type, // Assuming weights_type is defined elsewhere
|
||||
weights_category, // Assuming weights_category is defined elsewhere
|
||||
title: title.to_string(),
|
||||
maybe_thumbnail_token: Some(thumbnail_token),
|
||||
description_markdown: description.to_string(),
|
||||
description_rendered_html: description_rendered_html.to_string(),
|
||||
maybe_description_markdown: Some(description.to_string()),
|
||||
maybe_description_rendered_html: Some(description_rendered_html.to_string()),
|
||||
creator_user_token: Some(&user_token),
|
||||
creator_ip_address: "127.0.0.1", // Assuming the IP address is localhost
|
||||
creator_set_visibility: Visibility::Public, // Assuming the visibility is public
|
||||
|
||||
@@ -114,7 +114,7 @@ impl BucketClient {
|
||||
if code != 200 {
|
||||
let body = String::from_utf8_lossy(body_bytes);
|
||||
warn!("upload body: {}", body);
|
||||
return Err(anyhow!("upload failed: {}", code));
|
||||
Err(anyhow!("upload failed: {}", code))
|
||||
} else {
|
||||
info!("upload success: {}", code);
|
||||
Ok(())
|
||||
|
||||
+5
-6
@@ -5,7 +5,6 @@ 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 {
|
||||
@@ -85,11 +84,11 @@ impl BucketOrchestration {
|
||||
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,
|
||||
access_key,
|
||||
secret_key,
|
||||
region_name,
|
||||
public_bucket_name,
|
||||
private_bucket_name,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,18 +7,18 @@ const REMOTE_FILE_DIRECTORY: &str = "/implement_google_cloud_storage_bucket_name
|
||||
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;
|
||||
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();
|
||||
"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();
|
||||
"implement".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
|
||||
@@ -32,10 +32,10 @@ pub struct FileBucketDirectory {
|
||||
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
|
||||
remote_cloud_base_directory,
|
||||
full_remote_cloud_file_path,
|
||||
file_name,
|
||||
file_descriptor
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,10 +53,10 @@ pub struct FileBucketDirectory {
|
||||
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
|
||||
remote_cloud_base_directory,
|
||||
full_remote_cloud_file_path,
|
||||
file_name,
|
||||
file_descriptor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -1,7 +1,6 @@
|
||||
|
||||
use crate::remote_file_manager::weights_descriptor::{self};
|
||||
|
||||
use super::file_descriptor::FileDescriptor;
|
||||
use crate::remote_file_manager::weights_descriptor::{WeightsLoRADescriptor, WeightsSD15Descriptor, WeightsSDXLDescriptor, self};
|
||||
|
||||
pub struct RemoteCloudBucketDetails {
|
||||
pub object_hash: String,
|
||||
@@ -12,9 +11,9 @@ pub struct RemoteCloudBucketDetails {
|
||||
impl RemoteCloudBucketDetails {
|
||||
pub fn new(object_hash: String, prefix: String, suffix: String) -> Self {
|
||||
Self {
|
||||
object_hash: object_hash,
|
||||
prefix: prefix,
|
||||
suffix: suffix
|
||||
object_hash,
|
||||
prefix,
|
||||
suffix
|
||||
}
|
||||
}
|
||||
pub fn get_object_hash(&self) -> &str {
|
||||
@@ -49,7 +48,6 @@ impl RemoteCloudBucketDetails {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
pub fn test() {
|
||||
|
||||
|
||||
+14
-18
@@ -1,21 +1,15 @@
|
||||
|
||||
|
||||
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 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};
|
||||
use crate::remote_file_manager::bucket_orchestration::BucketOrchestrationCore;
|
||||
use crate::remote_file_manager::file_directory::FileBucketDirectory;
|
||||
use crate::remote_file_manager::remote_cloud_bucket_details::RemoteCloudBucketDetails;
|
||||
|
||||
use super::file_descriptor::FileDescriptor;
|
||||
use super::file_meta_data::FileMetaData;
|
||||
|
||||
struct RemoteCloudFileClient {
|
||||
bucket_orchestration_client: Box<dyn BucketOrchestrationCore>
|
||||
@@ -24,7 +18,7 @@ struct RemoteCloudFileClient {
|
||||
impl RemoteCloudFileClient {
|
||||
pub fn new(bucket_orchestration_client: Box<dyn BucketOrchestrationCore>) -> Self {
|
||||
Self {
|
||||
bucket_orchestration_client: bucket_orchestration_client
|
||||
bucket_orchestration_client
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +67,8 @@ impl RemoteCloudFileClient {
|
||||
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,
|
||||
file_size_bytes,
|
||||
sha256_checksum,
|
||||
mimetype: mimetype.to_string()
|
||||
})
|
||||
}
|
||||
@@ -85,8 +79,9 @@ 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};
|
||||
use crate::remote_file_manager::weights_descriptor::WeightsLoRADescriptor;
|
||||
|
||||
struct BucketOrchestrationMock {}
|
||||
|
||||
@@ -127,7 +122,6 @@ mod tests {
|
||||
}
|
||||
|
||||
#[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());
|
||||
@@ -138,6 +132,8 @@ mod tests {
|
||||
assert_eq!(file_descriptor.is_public(), true);
|
||||
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[tokio::test]
|
||||
async fn remote_file_manager_download_existing_file() {
|
||||
use super::*;
|
||||
|
||||
+28
-28
@@ -1,23 +1,23 @@
|
||||
use super::file_descriptor::FileDescriptor;
|
||||
|
||||
pub struct WeightsLoRADescriptor {}
|
||||
pub struct WeightsLoRADescriptor;
|
||||
|
||||
const REMOTE_FILE_DIRECTORY: &str = "/weights";
|
||||
|
||||
impl FileDescriptor for WeightsLoRADescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
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();
|
||||
"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();
|
||||
"loRA".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
@@ -26,22 +26,22 @@ impl FileDescriptor for WeightsLoRADescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsSD15Descriptor {}
|
||||
pub struct WeightsSD15Descriptor;
|
||||
|
||||
impl FileDescriptor for WeightsSD15Descriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
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();
|
||||
"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();
|
||||
"sd15".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
@@ -51,22 +51,22 @@ impl FileDescriptor for WeightsSD15Descriptor {
|
||||
}
|
||||
|
||||
|
||||
pub struct WeightsSDXLDescriptor {}
|
||||
pub struct WeightsSDXLDescriptor;
|
||||
|
||||
impl FileDescriptor for WeightsSDXLDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
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();
|
||||
"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();
|
||||
"sdxl".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
@@ -75,22 +75,22 @@ impl FileDescriptor for WeightsSDXLDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsSVCDescriptor {}
|
||||
pub struct WeightsSVCDescriptor;
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsSVCDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
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();
|
||||
"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();
|
||||
"svc".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
@@ -99,22 +99,22 @@ impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsS
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsRVCDescriptor {}
|
||||
pub struct WeightsRVCDescriptor;
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsRVCDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
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();
|
||||
"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();
|
||||
"rvc".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
@@ -123,22 +123,22 @@ impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsR
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsRVCIndexDescriptor {}
|
||||
pub struct WeightsRVCIndexDescriptor;
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsRVCIndexDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
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();
|
||||
"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();
|
||||
"rvc".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
@@ -147,22 +147,22 @@ impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsR
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeightsVallePromptDescriptor {}
|
||||
pub struct WeightsVallePromptDescriptor;
|
||||
|
||||
impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsVallePromptDescriptor {
|
||||
fn remote_directory_path(&self) -> &str {
|
||||
return REMOTE_FILE_DIRECTORY;
|
||||
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();
|
||||
"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();
|
||||
"valle_prompt".to_string()
|
||||
}
|
||||
|
||||
// This will be ensure that the right bucket is picked
|
||||
|
||||
@@ -73,7 +73,7 @@ impl GoogleDriveDownloadCommand {
|
||||
|
||||
info!("Downloading {} to: {}", download_url, temp_filename);
|
||||
|
||||
let mut command = format!("{} --url {} --output_filename {}",
|
||||
let mut command = format!("{} --url \"{}\" --output_filename {}",
|
||||
&self.download_script,
|
||||
download_url,
|
||||
&temp_filename);
|
||||
|
||||
@@ -10,6 +10,14 @@ pub fn is_bad_download_url(url: &str) -> anyhow::Result<bool> {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let looks_malicious = url.contains("\"")
|
||||
|| url.contains("\'")
|
||||
|| url.contains("\\");
|
||||
|
||||
if looks_malicious {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let url = Url::parse(url)?;
|
||||
|
||||
match url.host() {
|
||||
@@ -23,6 +31,8 @@ pub fn is_bad_download_url(url: &str) -> anyhow::Result<bool> {
|
||||
|| domain.contains("youtu.be")
|
||||
|| domain.contains("youtube.com");
|
||||
|
||||
println!("domain: {:?}", domain);
|
||||
|
||||
if bad_host {
|
||||
return Ok(true)
|
||||
}
|
||||
@@ -39,15 +49,31 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn bad_download_url() {
|
||||
assert_eq!(is_bad_download_url("").unwrap(), true);
|
||||
assert_eq!(is_bad_download_url(" ").unwrap(), true);
|
||||
assert_eq!(is_bad_download_url("https://vm.tiktok.com/ZMNYjT7Xy/?k=1 ").unwrap(), true); // NB: We get lots of these
|
||||
assert_eq!(is_bad_download_url("https://m.youtube.com/watch?v=HY-vzGBiAZo").unwrap(), true); // NB: We get lots of these
|
||||
assert_eq!(true, is_bad_download_url("").unwrap());
|
||||
assert_eq!(true, is_bad_download_url(" ").unwrap());
|
||||
assert_eq!(true, is_bad_download_url("https://vm.tiktok.com/ZMNYjT7Xy/?k=1 ").unwrap()); // NB: We get lots of these
|
||||
assert_eq!(true, is_bad_download_url("https://m.youtube.com/watch?v=HY-vzGBiAZo").unwrap()); // NB: We get lots of these
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attacker_urls() {
|
||||
// NB: These URLs may break escaping
|
||||
assert_eq!(true, is_bad_download_url("https://huggingface.co/\"").unwrap());
|
||||
assert_eq!(true, is_bad_download_url("https://huggingface.co/\"/bin/bash").unwrap());
|
||||
assert_eq!(true, is_bad_download_url("https://huggingface.co/\\\'").unwrap());
|
||||
assert_eq!(true, is_bad_download_url("https://huggingface.co/\\\"").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn good_tts_model_url() {
|
||||
assert_eq!(is_bad_download_url("https://drive.google.com/file/d/1-1kEoX4HGCwJm4R9cZhSVByWmUoQVGVm/view").unwrap(), false);
|
||||
assert_eq!(is_bad_download_url("https://drive.google.com/file/d/1SofQhvSkDY-vi_zuBfHivBbJo4CqhJeH/view?usp=sharing").unwrap(), false);
|
||||
assert_eq!(false, is_bad_download_url("https://drive.google.com/file/d/1-1kEoX4HGCwJm4R9cZhSVByWmUoQVGVm/view").unwrap());
|
||||
assert_eq!(false, is_bad_download_url("https://drive.google.com/file/d/1SofQhvSkDY-vi_zuBfHivBbJo4CqhJeH/view?usp=sharing").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tricky_download_urls() {
|
||||
// NB: These are URLs that have caused problems
|
||||
assert_eq!(false, is_bad_download_url("https://huggingface.co/aaalby/nmixx/resolve/main/kyujin(1).zip").unwrap());
|
||||
assert_eq!(false, is_bad_download_url("https://huggingface.co/datasets/Roscall/Elvis70s/resolve/main/Elvis%2070s%20RVC.zip?download=true").unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
pub mod tts_model_document;
|
||||
pub mod tts_model_document;
|
||||
mod model_weight_document;
|
||||
@@ -0,0 +1,65 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use enums::by_table::model_weights::weights_category::WeightsCategory;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
|
||||
use enums::common::visibility::Visibility;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
use crate::traits::document::Document;
|
||||
|
||||
/// The current name for the index.
|
||||
/// We may need to perform migrations in the future
|
||||
pub const MODEL_WEIGHT_INDEX: &str = "model_weights_v1";
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ModelWeightDocument {
|
||||
pub token: ModelWeightToken,
|
||||
|
||||
pub creator_set_visibility: Visibility,
|
||||
|
||||
pub weights_type: WeightsType,
|
||||
pub weights_category: WeightsCategory,
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_cover_image_media_file_token: Option<MediaFileToken>,
|
||||
pub maybe_cover_image_media_bucket_path: Option<String>,
|
||||
|
||||
//pub description_markdown: String,
|
||||
//pub description_markdown_html: String,
|
||||
|
||||
// TODO(bt,2023-12-22): Populate these fields
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
pub cached_user_ratings_ratio: f32,
|
||||
pub cached_user_ratings_last_updated_at: DateTime<Utc>,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_username: String,
|
||||
pub creator_display_name: String,
|
||||
pub creator_gravatar_hash: String,
|
||||
|
||||
// Fields only used for TTS models and voice conversion models.
|
||||
pub maybe_ietf_language_tag: Option<String>,
|
||||
pub maybe_ietf_primary_language_subtag: Option<String>,
|
||||
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl Document for ModelWeightDocument {
|
||||
fn get_document_id(&self) -> String {
|
||||
self.token.to_string()
|
||||
}
|
||||
|
||||
fn get_document_path(&self) -> PathBuf {
|
||||
let document_id = self.get_document_id();
|
||||
PathBuf::from(format!("/{MODEL_WEIGHT_INDEX}/_doc/{document_id}"))
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ path = "src/lib.rs"
|
||||
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
|
||||
|
||||
# External
|
||||
infer = "0.11" # Mimetype detection
|
||||
infer = "0.15.0" # Mimetype detection
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -4,16 +4,23 @@
|
||||
pub fn mimetype_to_extension(mimetype: &str) -> Option<&'static str> {
|
||||
// TODO(bt,2023-11-17): maybe make a bidirectional map
|
||||
match mimetype {
|
||||
// Image
|
||||
"image/gif" => Some("gif"),
|
||||
"image/jpeg" => Some("jpg"),
|
||||
"image/png" => Some("png"),
|
||||
"image/webp" => Some("webp"),
|
||||
// Audio
|
||||
"audio/aac" => Some("aac"),
|
||||
"audio/m4a" => Some("m4a"),
|
||||
"audio/mpeg" => Some("mp3"),
|
||||
"audio/ogg" => Some("ogg"),
|
||||
"audio/opus" => Some("opus"),
|
||||
"audio/x-flac" => Some("flac"),
|
||||
"audio/wav" => Some("wav"),
|
||||
"audio/x-flac" => Some("flac"),
|
||||
"audio/x-wav" => Some("wav"),
|
||||
// Video
|
||||
"video/mp4" /* .mp4 */ => Some("mp4"),
|
||||
"video/quicktime" /* .mov */ => Some("mov"),
|
||||
"video/webm" => Some("webm"), // TODO: Browsers send this for audio?
|
||||
_ => None
|
||||
}
|
||||
@@ -35,5 +42,8 @@ mod test {
|
||||
assert_eq!(mimetype_to_extension("audio/mpeg"), Some("mp3"));
|
||||
assert_eq!(mimetype_to_extension("audio/wav"), Some("wav"));
|
||||
assert_eq!(mimetype_to_extension("audio/x-wav"), Some("wav"));
|
||||
assert_eq!(mimetype_to_extension("image/png"), Some("png"));
|
||||
assert_eq!(mimetype_to_extension("image/jpeg"), Some("jpg"));
|
||||
assert_eq!(mimetype_to_extension("video/mp4"), Some("mp4"));
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCat
|
||||
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
|
||||
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::view_as::ViewAs;
|
||||
use enums::common::visibility::Visibility;
|
||||
use enums::traits::mysql_from_row::MySqlFromRow;
|
||||
use errors::AnyhowResult;
|
||||
@@ -51,17 +52,12 @@ pub struct MediaFileListItem {
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ViewAs {
|
||||
Moderator,
|
||||
NonModerator,
|
||||
}
|
||||
|
||||
pub struct ListMediaFilesArgs<'a> {
|
||||
pub limit: usize,
|
||||
pub maybe_filter_media_type: Option<MediaFileType>,
|
||||
pub maybe_offset: Option<usize>,
|
||||
pub cursor_is_reversed: bool,
|
||||
pub sort_ascending: bool,
|
||||
pub view_as: ViewAs,
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
@@ -73,6 +69,7 @@ pub async fn list_media_files(args: ListMediaFilesArgs<'_>) -> AnyhowResult<Medi
|
||||
args.limit,
|
||||
args.maybe_offset,
|
||||
args.cursor_is_reversed,
|
||||
args.sort_ascending,
|
||||
args.view_as,
|
||||
);
|
||||
|
||||
@@ -124,9 +121,11 @@ fn query_builder<'a>(
|
||||
limit: usize,
|
||||
maybe_offset: Option<usize>,
|
||||
cursor_is_reversed: bool,
|
||||
sort_ascending: bool,
|
||||
view_as: ViewAs,
|
||||
) -> QueryBuilder<'a, MySql> {
|
||||
|
||||
let mut sort_ascending = sort_ascending;
|
||||
// NB: Query cannot be statically checked by sqlx
|
||||
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new(
|
||||
r#"
|
||||
@@ -166,23 +165,35 @@ 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
|
||||
"#
|
||||
);
|
||||
|
||||
let mut first_predicate_added = false;
|
||||
|
||||
if let Some(media_type) = maybe_filter_media_type {
|
||||
if !first_predicate_added {
|
||||
query_builder.push(" WHERE ");
|
||||
first_predicate_added = true;
|
||||
} else {
|
||||
query_builder.push(" AND ");
|
||||
}
|
||||
// FIXME: Binding shouldn't require to_str().
|
||||
// Otherwise, it's calling the Display trait on the raw type which is resulting in an
|
||||
// incorrect binding and runtime error.
|
||||
query_builder.push(" AND m.media_file_type = ");
|
||||
query_builder.push(" m.media_type = ");
|
||||
query_builder.push_bind(media_type.to_str());
|
||||
}
|
||||
|
||||
match view_as {
|
||||
ViewAs::Moderator => {}
|
||||
ViewAs::NonModerator=> {
|
||||
ViewAs::Author | ViewAs::AnotherUser => {
|
||||
if !first_predicate_added {
|
||||
query_builder.push(" WHERE ");
|
||||
first_predicate_added = true;
|
||||
} else {
|
||||
query_builder.push(" AND ");
|
||||
}
|
||||
query_builder.push(" m.user_deleted_at IS NULL AND m.mod_deleted_at IS NULL ");
|
||||
// FIXME: Binding shouldn't require to_str().
|
||||
// Otherwise, it's calling the Display trait on the raw type which is resulting in an
|
||||
// incorrect binding and runtime error.
|
||||
@@ -192,17 +203,36 @@ WHERE
|
||||
}
|
||||
|
||||
if let Some(offset) = maybe_offset {
|
||||
if cursor_is_reversed {
|
||||
query_builder.push(format!(" AND m.id < {offset} "));
|
||||
if !first_predicate_added {
|
||||
query_builder.push(" WHERE ");
|
||||
first_predicate_added = true;
|
||||
} else {
|
||||
query_builder.push(format!(" AND m.id > {offset} "));
|
||||
query_builder.push(" AND ");
|
||||
}
|
||||
}
|
||||
|
||||
if sort_ascending {
|
||||
if cursor_is_reversed {
|
||||
// NB: We're searching backwards.
|
||||
query_builder.push(" AND m.id < ");
|
||||
sort_ascending = !sort_ascending;
|
||||
} else {
|
||||
query_builder.push(" AND m.id > ");
|
||||
}
|
||||
} else {
|
||||
if cursor_is_reversed {
|
||||
// NB: We're searching backwards.
|
||||
query_builder.push(" AND m.id > ");
|
||||
sort_ascending = !sort_ascending;
|
||||
} else {
|
||||
query_builder.push(" AND m.id < ");
|
||||
}
|
||||
}
|
||||
query_builder.push_bind(offset as i64);
|
||||
}
|
||||
|
||||
query_builder.push(" GROUP BY m.id");
|
||||
|
||||
if cursor_is_reversed {
|
||||
if sort_ascending {
|
||||
query_builder.push(" ORDER BY m.id ASC ");
|
||||
} else {
|
||||
query_builder.push(" ORDER BY m.id DESC ");
|
||||
|
||||
@@ -6,6 +6,7 @@ use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCat
|
||||
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
|
||||
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::view_as::ViewAs;
|
||||
use enums::common::visibility::Visibility;
|
||||
use enums::traits::mysql_from_row::MySqlFromRow;
|
||||
use errors::AnyhowResult;
|
||||
@@ -39,12 +40,6 @@ pub struct MediaFileListItem {
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ViewAs {
|
||||
Author,
|
||||
Moderator,
|
||||
AnotherUser,
|
||||
}
|
||||
|
||||
pub struct ListMediaFileForUserArgs<'a> {
|
||||
pub username: &'a str,
|
||||
@@ -168,27 +163,27 @@ SELECT
|
||||
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
|
||||
"#
|
||||
));
|
||||
|
||||
query_builder.push(" AND u.username = ");
|
||||
query_builder.push(" WHERE u.username = ");
|
||||
query_builder.push_bind(username);
|
||||
|
||||
if let Some(media_type) = maybe_filter_media_type {
|
||||
// FIXME: Binding shouldn't require to_str().
|
||||
// Otherwise, it's calling the Display trait on the raw type which is resulting in an
|
||||
// incorrect binding and runtime error.
|
||||
query_builder.push(" AND m.media_file_type = ");
|
||||
query_builder.push(" AND m.media_type = ");
|
||||
query_builder.push_bind(media_type.to_str());
|
||||
}
|
||||
|
||||
match view_as {
|
||||
ViewAs::Author => {}
|
||||
ViewAs::Author => {
|
||||
query_builder.push(" AND m.user_deleted_at IS NULL AND m.mod_deleted_at IS NULL ");
|
||||
}
|
||||
ViewAs::Moderator => {}
|
||||
ViewAs::AnotherUser => {
|
||||
query_builder.push(" AND m.user_deleted_at IS NULL AND m.mod_deleted_at IS NULL ");
|
||||
// FIXME: Binding shouldn't require to_str().
|
||||
// Otherwise, it's calling the Display trait on the raw type which is resulting in an
|
||||
// incorrect binding and runtime error.
|
||||
|
||||
+3
-5
@@ -63,11 +63,9 @@ SET
|
||||
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_cover_image_media_file_token = NULL,
|
||||
maybe_description_markdown = NULL,
|
||||
maybe_description_rendered_html = NULL,
|
||||
|
||||
maybe_last_update_user_token = NULL,
|
||||
original_download_url = ?,
|
||||
|
||||
@@ -13,9 +13,8 @@ pub struct CreateModelWeightsArgs<'a> {
|
||||
pub weights_type: WeightsType,
|
||||
pub weights_category: WeightsCategory,
|
||||
pub title: String,
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
pub maybe_description_markdown: Option<String>,
|
||||
pub maybe_description_rendered_html: Option<String>,
|
||||
pub creator_user_token: Option<&'a UserToken>,
|
||||
pub creator_ip_address: &'a str,
|
||||
pub creator_set_visibility: Visibility,
|
||||
@@ -47,9 +46,8 @@ pub async fn create_weight(args: CreateModelWeightsArgs<'_>) -> AnyhowResult<Mod
|
||||
weights_type = ?,
|
||||
weights_category = ?,
|
||||
title = ?,
|
||||
maybe_thumbnail_token = ?,
|
||||
description_markdown = ?,
|
||||
description_rendered_html = ?,
|
||||
maybe_description_markdown = ?,
|
||||
maybe_description_rendered_html = ?,
|
||||
creator_user_token = ?,
|
||||
creator_ip_address = ?,
|
||||
creator_set_visibility = ?,
|
||||
@@ -71,9 +69,8 @@ pub async fn create_weight(args: CreateModelWeightsArgs<'_>) -> AnyhowResult<Mod
|
||||
args.weights_type.to_str(),
|
||||
args.weights_category.to_str(),
|
||||
args.title,
|
||||
args.maybe_thumbnail_token,
|
||||
args.description_markdown,
|
||||
args.description_rendered_html,
|
||||
args.maybe_description_markdown,
|
||||
args.maybe_description_rendered_html,
|
||||
args.creator_user_token.as_deref(),
|
||||
args.creator_ip_address,
|
||||
args.creator_set_visibility.to_str(),
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
pub mod set_model_weight_avatar;
|
||||
pub mod set_model_weight_cover_image;
|
||||
pub mod update_weight;
|
||||
|
||||
+4
-4
@@ -6,23 +6,23 @@ use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
pub struct UpdateArgs<'a> {
|
||||
pub model_weight_token: &'a ModelWeightToken,
|
||||
pub maybe_avatar_media_file_token: Option<&'a MediaFileToken>,
|
||||
pub maybe_cover_image_media_file_token: Option<&'a MediaFileToken>,
|
||||
//pub update_ip_address: &'a str,
|
||||
pub mysql_pool: &'a MySqlPool
|
||||
}
|
||||
|
||||
pub async fn set_model_weight_avatar(args: UpdateArgs<'_>) -> AnyhowResult<()>{
|
||||
pub async fn set_model_weight_cover_image(args: UpdateArgs<'_>) -> AnyhowResult<()>{
|
||||
let transaction = args.mysql_pool.begin().await?;
|
||||
|
||||
let query_result = sqlx::query!(
|
||||
r#"
|
||||
UPDATE model_weights
|
||||
SET
|
||||
maybe_avatar_media_file_token = ?
|
||||
maybe_cover_image_media_file_token = ?
|
||||
WHERE token = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
args.maybe_avatar_media_file_token,
|
||||
args.maybe_cover_image_media_file_token,
|
||||
args.model_weight_token,
|
||||
).execute(args.mysql_pool).await;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::anyhow;
|
||||
use sqlx::MySqlPool;
|
||||
use sqlx::{MySql, MySqlPool, QueryBuilder};
|
||||
|
||||
use enums::common::visibility::Visibility;
|
||||
use errors::AnyhowResult;
|
||||
@@ -8,9 +8,8 @@ use tokens::tokens::model_weights::ModelWeightToken;
|
||||
pub struct UpdateWeightArgs<'a> {
|
||||
pub weight_token: &'a ModelWeightToken,
|
||||
pub title: Option<&'a str>,
|
||||
pub maybe_thumbnail_token: Option<&'a str>,
|
||||
pub description_markdown: Option<&'a str>,
|
||||
pub description_rendered_html: Option<&'a str>,
|
||||
pub maybe_description_markdown: Option<&'a str>,
|
||||
pub maybe_description_rendered_html: Option<&'a str>,
|
||||
pub creator_set_visibility: Option<&'a Visibility>,
|
||||
pub weights_type: Option<String>,
|
||||
pub weights_category: Option<String>,
|
||||
@@ -18,36 +17,63 @@ pub struct UpdateWeightArgs<'a> {
|
||||
}
|
||||
|
||||
pub async fn update_weights(args: UpdateWeightArgs<'_>) -> AnyhowResult<()> {
|
||||
let transaction = args.mysql_pool.begin().await?;
|
||||
if args.title.is_none()
|
||||
&& args.maybe_description_markdown.is_none()
|
||||
&& args.maybe_description_rendered_html.is_none()
|
||||
&& args.creator_set_visibility.is_none()
|
||||
&& args.weights_type.is_none()
|
||||
&& args.weights_category.is_none(){
|
||||
return Err(anyhow!("No fields to update"));
|
||||
}
|
||||
|
||||
|
||||
let query_result = sqlx::query!(
|
||||
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new(
|
||||
r#"
|
||||
UPDATE model_weights
|
||||
SET
|
||||
title = COALESCE(?, title),
|
||||
description_markdown = COALESCE(?, description_markdown),
|
||||
maybe_thumbnail_token = COALESCE(?, maybe_thumbnail_token),
|
||||
description_rendered_html = COALESCE(?, description_rendered_html),
|
||||
creator_set_visibility = COALESCE(?, creator_set_visibility),
|
||||
version = version + 1
|
||||
WHERE token = ?
|
||||
"#,
|
||||
args.title.as_deref(),
|
||||
args.description_markdown.as_deref(),
|
||||
args.maybe_thumbnail_token.as_deref(),
|
||||
args.description_rendered_html.as_deref(),
|
||||
args.creator_set_visibility.as_deref(),
|
||||
args.weight_token.as_str()
|
||||
)
|
||||
.execute(args.mysql_pool).await;
|
||||
UPDATE model_weights
|
||||
SET
|
||||
"#
|
||||
);
|
||||
|
||||
let mut separated = query_builder.separated(", ");
|
||||
|
||||
if let Some(title) = args.title {
|
||||
separated.push("title = ");
|
||||
separated.push_bind_unseparated(title);
|
||||
}
|
||||
if let Some(maybe_description_markdown) = args.maybe_description_markdown {
|
||||
separated.push("maybe_description_markdown = ");
|
||||
separated.push_bind_unseparated(maybe_description_markdown);
|
||||
}
|
||||
if let Some(maybe_description_rendered_html) = args.maybe_description_rendered_html {
|
||||
separated.push("maybe_description_rendered_html = ");
|
||||
separated.push_bind_unseparated(maybe_description_rendered_html);
|
||||
}
|
||||
if let Some(creator_set_visibility) = args.creator_set_visibility {
|
||||
separated.push("creator_set_visibility = ");
|
||||
separated.push_bind_unseparated(creator_set_visibility.to_str());
|
||||
}
|
||||
if let Some(weights_type) = args.weights_type {
|
||||
separated.push("weights_type = ");
|
||||
separated.push_bind_unseparated(weights_type);
|
||||
}
|
||||
if let Some(weights_category) = args.weights_category {
|
||||
separated.push("weights_category = ");
|
||||
separated.push_bind_unseparated(weights_category);
|
||||
}
|
||||
|
||||
separated.push("version = version + 1");
|
||||
|
||||
separated.push_unseparated(" WHERE token = ");
|
||||
separated.push_bind_unseparated(args.weight_token.as_str());
|
||||
separated.push_unseparated(" LIMIT 1");
|
||||
|
||||
let transaction = args.mysql_pool.begin().await?;
|
||||
let query_result = query_builder.build().execute(args.mysql_pool).await;
|
||||
transaction.commit().await?;
|
||||
|
||||
match query_result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
Err(anyhow!("weights update error: {:?}", err))
|
||||
Err(anyhow!("weights update error: {:?}", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +88,7 @@ mod tests {
|
||||
use config::shared_constants::DEFAULT_MYSQL_CONNECTION_STRING;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
#[ignore]
|
||||
#[tokio::test]
|
||||
async fn test_update_weights() -> AnyhowResult<()> {
|
||||
let db_connection_string = DEFAULT_MYSQL_CONNECTION_STRING;
|
||||
|
||||
@@ -19,9 +19,8 @@ pub struct RetrievedModelWeight {
|
||||
pub title: String,
|
||||
pub weights_type: WeightsType,
|
||||
pub weights_category: WeightsCategory,
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
pub maybe_description_markdown: Option<String>,
|
||||
pub maybe_description_rendered_html: Option<String>,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_username: String,
|
||||
@@ -40,9 +39,9 @@ pub struct RetrievedModelWeight {
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
pub maybe_avatar_public_bucket_hash: Option<String>,
|
||||
pub maybe_avatar_public_bucket_prefix: Option<String>,
|
||||
pub maybe_avatar_public_bucket_extension: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
@@ -95,9 +94,8 @@ pub async fn get_weights_by_token_with_connection(
|
||||
title: record.title,
|
||||
weights_type: record.weights_type,
|
||||
weights_category: record.weights_category,
|
||||
maybe_thumbnail_token: record.maybe_thumbnail_token,
|
||||
description_markdown: record.description_markdown,
|
||||
description_rendered_html: record.description_rendered_html,
|
||||
maybe_description_markdown: record.maybe_description_markdown,
|
||||
maybe_description_rendered_html: record.maybe_description_rendered_html,
|
||||
creator_user_token: record.creator_user_token,
|
||||
creator_username: record.creator_username,
|
||||
creator_display_name: record.creator_display_name,
|
||||
@@ -112,9 +110,9 @@ pub async fn get_weights_by_token_with_connection(
|
||||
public_bucket_hash: record.public_bucket_hash,
|
||||
maybe_public_bucket_prefix: record.maybe_public_bucket_prefix,
|
||||
maybe_public_bucket_extension: record.maybe_public_bucket_extension,
|
||||
maybe_avatar_public_bucket_hash: record.maybe_avatar_public_bucket_hash,
|
||||
maybe_avatar_public_bucket_prefix: record.maybe_avatar_public_bucket_prefix,
|
||||
maybe_avatar_public_bucket_extension: record.maybe_avatar_public_bucket_extension,
|
||||
maybe_cover_image_public_bucket_hash: record.maybe_cover_image_public_bucket_hash,
|
||||
maybe_cover_image_public_bucket_prefix: record.maybe_cover_image_public_bucket_prefix,
|
||||
maybe_cover_image_public_bucket_extension: record.maybe_cover_image_public_bucket_extension,
|
||||
cached_user_ratings_negative_count: record.cached_user_ratings_negative_count,
|
||||
cached_user_ratings_positive_count: record.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_total_count: record.cached_user_ratings_total_count,
|
||||
@@ -142,9 +140,8 @@ async fn select_include_deleted(
|
||||
wt.title,
|
||||
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
|
||||
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
|
||||
wt.maybe_thumbnail_token,
|
||||
wt.description_markdown,
|
||||
wt.description_rendered_html,
|
||||
wt.maybe_description_markdown,
|
||||
wt.maybe_description_rendered_html,
|
||||
|
||||
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
|
||||
users.username as creator_username,
|
||||
@@ -158,13 +155,14 @@ async fn select_include_deleted(
|
||||
wt.original_filename,
|
||||
wt.file_size_bytes,
|
||||
wt.file_checksum_sha2,
|
||||
|
||||
wt.public_bucket_hash,
|
||||
wt.maybe_public_bucket_prefix,
|
||||
wt.maybe_public_bucket_extension,
|
||||
|
||||
avatar.public_bucket_directory_hash as maybe_avatar_public_bucket_hash,
|
||||
avatar.maybe_public_bucket_prefix as maybe_avatar_public_bucket_prefix,
|
||||
avatar.maybe_public_bucket_extension as maybe_avatar_public_bucket_extension,
|
||||
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
|
||||
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
|
||||
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
|
||||
|
||||
wt.cached_user_ratings_negative_count,
|
||||
wt.cached_user_ratings_positive_count,
|
||||
@@ -179,8 +177,8 @@ async fn select_include_deleted(
|
||||
FROM model_weights as wt
|
||||
JOIN users
|
||||
ON users.token = wt.creator_user_token
|
||||
LEFT OUTER JOIN media_files as avatar
|
||||
ON avatar.token = wt.maybe_avatar_media_file_token
|
||||
LEFT OUTER JOIN media_files as cover_image
|
||||
ON cover_image.token = wt.maybe_cover_image_media_file_token
|
||||
WHERE
|
||||
wt.token = ?
|
||||
"#,
|
||||
@@ -204,9 +202,8 @@ async fn select_without_deleted(
|
||||
wt.title,
|
||||
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
|
||||
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
|
||||
wt.maybe_thumbnail_token,
|
||||
wt.description_markdown,
|
||||
wt.description_rendered_html,
|
||||
wt.maybe_description_markdown,
|
||||
wt.maybe_description_rendered_html,
|
||||
wt.creator_ip_address,
|
||||
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
|
||||
|
||||
@@ -224,9 +221,9 @@ async fn select_without_deleted(
|
||||
wt.maybe_public_bucket_prefix,
|
||||
wt.maybe_public_bucket_extension,
|
||||
|
||||
avatar.public_bucket_directory_hash as maybe_avatar_public_bucket_hash,
|
||||
avatar.maybe_public_bucket_prefix as maybe_avatar_public_bucket_prefix,
|
||||
avatar.maybe_public_bucket_extension as maybe_avatar_public_bucket_extension,
|
||||
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
|
||||
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
|
||||
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
|
||||
|
||||
wt.cached_user_ratings_negative_count,
|
||||
wt.cached_user_ratings_positive_count,
|
||||
@@ -241,8 +238,8 @@ async fn select_without_deleted(
|
||||
FROM model_weights as wt
|
||||
JOIN users
|
||||
ON users.token = wt.creator_user_token
|
||||
LEFT OUTER JOIN media_files as avatar
|
||||
ON avatar.token = wt.maybe_avatar_media_file_token
|
||||
LEFT OUTER JOIN media_files as cover_image
|
||||
ON cover_image.token = wt.maybe_cover_image_media_file_token
|
||||
WHERE
|
||||
wt.token = ?
|
||||
AND wt.user_deleted_at IS NULL
|
||||
@@ -260,9 +257,8 @@ pub struct RawWeight {
|
||||
pub title: String,
|
||||
pub weights_type: WeightsType,
|
||||
pub weights_category: WeightsCategory,
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
pub maybe_description_markdown: Option<String>,
|
||||
pub maybe_description_rendered_html: Option<String>,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_username: String,
|
||||
@@ -280,9 +276,9 @@ pub struct RawWeight {
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
pub maybe_avatar_public_bucket_hash: Option<String>,
|
||||
pub maybe_avatar_public_bucket_prefix: Option<String>,
|
||||
pub maybe_avatar_public_bucket_extension: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
|
||||
@@ -20,8 +20,6 @@ pub struct WeightsByTokensRecord {
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_username: String,
|
||||
pub creator_display_name: String,
|
||||
@@ -31,6 +29,10 @@ pub struct WeightsByTokensRecord {
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
@@ -71,7 +73,6 @@ async fn get_raw_weights_by_tokens(
|
||||
mw.title,
|
||||
mw.weights_type,
|
||||
mw.weights_category,
|
||||
mw.maybe_thumbnail_token,
|
||||
users.token as creator_user_token,
|
||||
users.username as creator_username,
|
||||
users.display_name as creator_display_name,
|
||||
@@ -79,6 +80,9 @@ async fn get_raw_weights_by_tokens(
|
||||
mw.public_bucket_hash,
|
||||
mw.maybe_public_bucket_prefix,
|
||||
mw.maybe_public_bucket_extension,
|
||||
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
|
||||
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
|
||||
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
|
||||
mw.cached_user_ratings_negative_count,
|
||||
mw.cached_user_ratings_positive_count,
|
||||
mw.cached_user_ratings_total_count,
|
||||
@@ -91,6 +95,8 @@ async fn get_raw_weights_by_tokens(
|
||||
FROM model_weights as mw
|
||||
JOIN users
|
||||
ON users.token = mw.creator_user_token
|
||||
LEFT OUTER JOIN media_files as cover_image
|
||||
ON cover_image.token = mw.maybe_cover_image_media_file_token
|
||||
WHERE
|
||||
mw.creator_set_visibility = "public"
|
||||
AND mw.token IN (
|
||||
@@ -104,7 +110,6 @@ async fn get_raw_weights_by_tokens(
|
||||
mw.title,
|
||||
mw.weights_type,
|
||||
mw.weights_category,
|
||||
mw.maybe_thumbnail_token,
|
||||
users.token as creator_user_token,
|
||||
users.username as creator_username,
|
||||
users.display_name as creator_display_name,
|
||||
@@ -112,6 +117,9 @@ async fn get_raw_weights_by_tokens(
|
||||
mw.public_bucket_hash,
|
||||
mw.maybe_public_bucket_prefix,
|
||||
mw.maybe_public_bucket_extension,
|
||||
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
|
||||
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
|
||||
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
|
||||
mw.cached_user_ratings_negative_count,
|
||||
mw.cached_user_ratings_positive_count,
|
||||
mw.cached_user_ratings_total_count,
|
||||
@@ -124,6 +132,8 @@ async fn get_raw_weights_by_tokens(
|
||||
FROM model_weights as mw
|
||||
JOIN users
|
||||
ON users.token = mw.creator_user_token
|
||||
LEFT OUTER JOIN media_files as cover_image
|
||||
ON cover_image.token = mw.maybe_cover_image_media_file_token
|
||||
WHERE
|
||||
mw.creator_set_visibility = "public"
|
||||
AND mw.user_deleted_at IS NULL
|
||||
@@ -157,34 +167,37 @@ fn token_predicate(tokens: &[ModelWeightToken]) -> String {
|
||||
fn map_to_weights(dataset:Vec<RawWeightJoinUser>) -> Vec<WeightsByTokensRecord> {
|
||||
let weights: Vec<WeightsByTokensRecord> = dataset
|
||||
.into_iter()
|
||||
.map(|dataset: RawWeightJoinUser| {
|
||||
.map(|weight| {
|
||||
WeightsByTokensRecord {
|
||||
token: dataset.token,
|
||||
title: dataset.title,
|
||||
weights_type: dataset.weights_type,
|
||||
weights_category: dataset.weights_category,
|
||||
maybe_thumbnail_token: dataset.maybe_thumbnail_token,
|
||||
token: weight.token,
|
||||
title: weight.title,
|
||||
weights_type: weight.weights_type,
|
||||
weights_category: weight.weights_category,
|
||||
|
||||
creator_user_token: dataset.creator_user_token,
|
||||
creator_username:dataset.creator_username,
|
||||
creator_display_name:dataset.creator_display_name,
|
||||
creator_email_gravatar_hash:dataset.creator_email_gravatar_hash,
|
||||
creator_user_token: weight.creator_user_token,
|
||||
creator_username: weight.creator_username,
|
||||
creator_display_name: weight.creator_display_name,
|
||||
creator_email_gravatar_hash: weight.creator_email_gravatar_hash,
|
||||
|
||||
public_bucket_hash: dataset.public_bucket_hash,
|
||||
maybe_public_bucket_prefix: dataset.maybe_public_bucket_prefix,
|
||||
maybe_public_bucket_extension: dataset.maybe_public_bucket_extension,
|
||||
public_bucket_hash: weight.public_bucket_hash,
|
||||
maybe_public_bucket_prefix: weight.maybe_public_bucket_prefix,
|
||||
maybe_public_bucket_extension: weight.maybe_public_bucket_extension,
|
||||
|
||||
cached_user_ratings_negative_count: dataset.cached_user_ratings_negative_count,
|
||||
cached_user_ratings_positive_count: dataset.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_total_count: dataset.cached_user_ratings_total_count,
|
||||
maybe_cover_image_public_bucket_hash: weight.maybe_cover_image_public_bucket_hash,
|
||||
maybe_cover_image_public_bucket_prefix: weight.maybe_cover_image_public_bucket_prefix,
|
||||
maybe_cover_image_public_bucket_extension: weight.maybe_cover_image_public_bucket_extension,
|
||||
|
||||
maybe_cached_user_ratings_ratio: dataset.maybe_cached_user_ratings_ratio,
|
||||
cached_user_ratings_last_updated_at: dataset.cached_user_ratings_last_updated_at,
|
||||
cached_user_ratings_negative_count: weight.cached_user_ratings_negative_count,
|
||||
cached_user_ratings_positive_count: weight.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_total_count: weight.cached_user_ratings_total_count,
|
||||
|
||||
created_at: dataset.created_at,
|
||||
updated_at: dataset.updated_at,
|
||||
user_deleted_at: dataset.user_deleted_at,
|
||||
mod_deleted_at: dataset.mod_deleted_at,
|
||||
maybe_cached_user_ratings_ratio: weight.maybe_cached_user_ratings_ratio,
|
||||
cached_user_ratings_last_updated_at: weight.cached_user_ratings_last_updated_at,
|
||||
|
||||
created_at: weight.created_at,
|
||||
updated_at: weight.updated_at,
|
||||
user_deleted_at: weight.user_deleted_at,
|
||||
mod_deleted_at: weight.mod_deleted_at,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
@@ -200,8 +213,6 @@ fn map_to_weights(dataset:Vec<RawWeightJoinUser>) -> Vec<WeightsByTokensRecord>
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_username: String,
|
||||
pub creator_display_name: String,
|
||||
@@ -210,7 +221,11 @@ fn map_to_weights(dataset:Vec<RawWeightJoinUser>) -> Vec<WeightsByTokensRecord>
|
||||
pub public_bucket_hash: String,
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
@@ -242,7 +257,6 @@ impl FromRow<'_, MySqlRow> for RawWeightJoinUser {
|
||||
weights_type: WeightsType::try_from_mysql_row(row, "weights_type")?,
|
||||
weights_category: WeightsCategory::try_from_mysql_row(row, "weights_category")?,
|
||||
title: row.try_get("title")?,
|
||||
maybe_thumbnail_token: row.try_get("maybe_thumbnail_token")?,
|
||||
creator_user_token: UserToken::new_from_str(row.try_get("creator_user_token")?),
|
||||
creator_username: row.try_get("creator_username")?,
|
||||
creator_display_name: row.try_get("creator_display_name")?,
|
||||
@@ -250,6 +264,9 @@ impl FromRow<'_, MySqlRow> for RawWeightJoinUser {
|
||||
public_bucket_hash: row.try_get("public_bucket_hash")?,
|
||||
maybe_public_bucket_prefix: row.try_get("maybe_public_bucket_prefix")?,
|
||||
maybe_public_bucket_extension: row.try_get("maybe_public_bucket_extension")?,
|
||||
maybe_cover_image_public_bucket_hash: row.try_get("maybe_cover_image_public_bucket_hash")?,
|
||||
maybe_cover_image_public_bucket_prefix: row.try_get("maybe_cover_image_public_bucket_prefix")?,
|
||||
maybe_cover_image_public_bucket_extension: row.try_get("maybe_cover_image_public_bucket_extension")?,
|
||||
cached_user_ratings_total_count: row.try_get("cached_user_ratings_total_count")?,
|
||||
cached_user_ratings_positive_count: row.try_get("cached_user_ratings_positive_count")?,
|
||||
cached_user_ratings_negative_count: row.try_get("cached_user_ratings_negative_count")?,
|
||||
|
||||
@@ -6,6 +6,7 @@ use enums::by_table::model_weights::{
|
||||
weights_category::WeightsCategory,
|
||||
weights_types::WeightsType,
|
||||
};
|
||||
use enums::common::view_as::ViewAs;
|
||||
use enums::common::visibility::Visibility;
|
||||
use enums::traits::mysql_from_row::MySqlFromRow;
|
||||
use errors::AnyhowResult;
|
||||
@@ -21,7 +22,6 @@ pub struct WeightsForUserListPage {
|
||||
pub total_page_count: usize,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct WeightsJoinUserRecord {
|
||||
pub token: ModelWeightToken,
|
||||
@@ -30,11 +30,11 @@ pub struct WeightsJoinUserRecord {
|
||||
pub weights_category: WeightsCategory,
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
|
||||
// TODO(bt,2023-12-24): These aren't really appropriate for a list endpoint.
|
||||
// Hopefully we don't break the frontend by omitting these.
|
||||
//pub maybe_description_markdown: String,
|
||||
//pub maybe_description_rendered_html: String,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_ip_address: String,
|
||||
@@ -51,6 +51,10 @@ pub struct WeightsJoinUserRecord {
|
||||
pub public_bucket_hash: String,
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
@@ -76,7 +80,7 @@ pub struct ListWeightsForUserArgs<'a> {
|
||||
pub page_size: usize,
|
||||
pub page_index: usize,
|
||||
pub sort_ascending: bool,
|
||||
pub can_see_deleted: bool,
|
||||
pub view_as: ViewAs,
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
|
||||
@@ -89,7 +93,7 @@ pub async fn list_weights_by_creator_username(args: ListWeightsForUserArgs<'_>)
|
||||
0,
|
||||
args.sort_ascending,
|
||||
count_fields.as_str(),
|
||||
args.can_see_deleted,
|
||||
args.view_as,
|
||||
);
|
||||
|
||||
let row_count_query = count_query_builder.build_query_scalar::<i64>();
|
||||
@@ -104,7 +108,7 @@ pub async fn list_weights_by_creator_username(args: ListWeightsForUserArgs<'_>)
|
||||
args.page_size,
|
||||
args.sort_ascending,
|
||||
result_fields.as_str(),
|
||||
args.can_see_deleted,
|
||||
args.view_as,
|
||||
);
|
||||
|
||||
let query = query.build_query_as::<RawWeightJoinUser>();
|
||||
@@ -112,11 +116,8 @@ pub async fn list_weights_by_creator_username(args: ListWeightsForUserArgs<'_>)
|
||||
|
||||
let number_of_pages = (row_count_result / args.page_size as i64) as usize;
|
||||
|
||||
|
||||
|
||||
let weights_records: Vec<WeightsJoinUserRecord> = map_to_weights(results).await;
|
||||
|
||||
|
||||
Ok(WeightsForUserListPage {
|
||||
records: weights_records,
|
||||
sort_ascending: args.sort_ascending,
|
||||
@@ -134,38 +135,41 @@ fn select_total_count_field() -> String {
|
||||
|
||||
fn select_result_fields() -> String {
|
||||
r#"
|
||||
mw.token,
|
||||
mw.title,
|
||||
mw.weights_type,
|
||||
mw.weights_category,
|
||||
mw.maybe_thumbnail_token,
|
||||
mw.description_markdown,
|
||||
mw.description_rendered_html,
|
||||
u.token as creator_user_token,
|
||||
u.username as creator_username,
|
||||
u.display_name as creator_display_name,
|
||||
u.email_gravatar_hash as creator_email_gravatar_hash,
|
||||
mw.creator_ip_address,
|
||||
mw.creator_set_visibility,
|
||||
mw.maybe_last_update_user_token,
|
||||
mw.original_download_url,
|
||||
mw.original_filename,
|
||||
mw.file_size_bytes,
|
||||
mw.file_checksum_sha2,
|
||||
mw.public_bucket_hash,
|
||||
mw.maybe_public_bucket_prefix,
|
||||
mw.maybe_public_bucket_extension,
|
||||
mw.cached_user_ratings_negative_count,
|
||||
mw.cached_user_ratings_positive_count,
|
||||
mw.cached_user_ratings_total_count,
|
||||
mw.maybe_cached_user_ratings_ratio,
|
||||
mw.cached_user_ratings_last_updated_at,
|
||||
mw.version,
|
||||
mw.created_at,
|
||||
mw.updated_at,
|
||||
mw.user_deleted_at,
|
||||
mw.mod_deleted_at
|
||||
"#.to_string()
|
||||
mw.token,
|
||||
mw.title,
|
||||
mw.weights_type,
|
||||
mw.weights_category,
|
||||
u.token as creator_user_token,
|
||||
u.username as creator_username,
|
||||
u.display_name as creator_display_name,
|
||||
u.email_gravatar_hash as creator_email_gravatar_hash,
|
||||
mw.creator_ip_address,
|
||||
mw.creator_set_visibility,
|
||||
mw.maybe_last_update_user_token,
|
||||
mw.original_download_url,
|
||||
mw.original_filename,
|
||||
mw.file_size_bytes,
|
||||
mw.file_checksum_sha2,
|
||||
|
||||
mw.public_bucket_hash,
|
||||
mw.maybe_public_bucket_prefix,
|
||||
mw.maybe_public_bucket_extension,
|
||||
|
||||
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
|
||||
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
|
||||
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
|
||||
|
||||
mw.cached_user_ratings_negative_count,
|
||||
mw.cached_user_ratings_positive_count,
|
||||
mw.cached_user_ratings_total_count,
|
||||
mw.maybe_cached_user_ratings_ratio,
|
||||
mw.cached_user_ratings_last_updated_at,
|
||||
mw.version,
|
||||
mw.created_at,
|
||||
mw.updated_at,
|
||||
mw.user_deleted_at,
|
||||
mw.mod_deleted_at
|
||||
"#.to_string()
|
||||
}
|
||||
|
||||
fn query_builder<'a>(
|
||||
@@ -175,7 +179,7 @@ fn query_builder<'a>(
|
||||
page_size: usize,
|
||||
sort_ascending: bool,
|
||||
select_fields: &'a str,
|
||||
can_see_deleted: bool,
|
||||
view_as: ViewAs,
|
||||
) -> QueryBuilder<'a, MySql> {
|
||||
|
||||
// NB: Query cannot be statically checked by sqlx
|
||||
@@ -186,16 +190,25 @@ SELECT
|
||||
FROM model_weights as mw
|
||||
JOIN users as u
|
||||
ON u.token = mw.creator_user_token
|
||||
LEFT OUTER JOIN media_files as cover_image
|
||||
ON cover_image.token = mw.maybe_cover_image_media_file_token
|
||||
"#
|
||||
));
|
||||
|
||||
if !can_see_deleted {
|
||||
query_builder.push(" WHERE mw.user_deleted_at IS NULL AND mw.mod_deleted_at IS NULL ");
|
||||
}
|
||||
|
||||
query_builder.push(" AND u.username = ");
|
||||
query_builder.push(" WHERE u.username = ");
|
||||
query_builder.push_bind(username);
|
||||
|
||||
match view_as {
|
||||
ViewAs::Author => {
|
||||
query_builder.push(" AND mw.user_deleted_at IS NULL AND mw.mod_deleted_at IS NULL ");
|
||||
}
|
||||
ViewAs::Moderator => {}
|
||||
ViewAs::AnotherUser => {
|
||||
query_builder.push(" AND mw.user_deleted_at IS NULL AND mw.mod_deleted_at IS NULL ");
|
||||
query_builder.push(" AND mw.creator_set_visibility = ");
|
||||
query_builder.push_bind(Visibility::Public.to_str());
|
||||
}
|
||||
}
|
||||
|
||||
if sort_ascending {
|
||||
query_builder.push(" ORDER BY mw.created_at ASC ");
|
||||
@@ -215,44 +228,47 @@ JOIN users as u
|
||||
async fn map_to_weights(dataset:Vec<RawWeightJoinUser>) -> Vec<WeightsJoinUserRecord> {
|
||||
let weights: Vec<WeightsJoinUserRecord> = dataset
|
||||
.into_iter()
|
||||
.map(|dataset: RawWeightJoinUser| {
|
||||
.map(|weight: RawWeightJoinUser| {
|
||||
WeightsJoinUserRecord {
|
||||
token: dataset.token,
|
||||
title: dataset.title,
|
||||
weights_type: dataset.weights_type,
|
||||
weights_category: dataset.weights_category,
|
||||
maybe_thumbnail_token: dataset.maybe_thumbnail_token,
|
||||
description_markdown: dataset.description_markdown,
|
||||
description_rendered_html: dataset.description_rendered_html,
|
||||
token: weight.token,
|
||||
title: weight.title,
|
||||
weights_type: weight.weights_type,
|
||||
weights_category: weight.weights_category,
|
||||
//maybe_description_markdown: weight.maybe_description_markdown,
|
||||
//maybe_description_rendered_html: weight.maybe_description_rendered_html,
|
||||
|
||||
creator_user_token: dataset.creator_user_token,
|
||||
creator_ip_address: dataset.creator_ip_address,
|
||||
creator_set_visibility: dataset.creator_set_visibility,
|
||||
creator_user_token: weight.creator_user_token,
|
||||
creator_ip_address: weight.creator_ip_address,
|
||||
creator_set_visibility: weight.creator_set_visibility,
|
||||
|
||||
maybe_last_update_user_token: dataset.maybe_last_update_user_token,
|
||||
original_download_url: dataset.original_download_url,
|
||||
original_filename: dataset.original_filename,
|
||||
file_size_bytes: dataset.file_size_bytes,
|
||||
file_checksum_sha2: dataset.file_checksum_sha2,
|
||||
public_bucket_hash: dataset.public_bucket_hash,
|
||||
maybe_public_bucket_prefix: dataset.maybe_public_bucket_prefix,
|
||||
maybe_public_bucket_extension: dataset.maybe_public_bucket_extension,
|
||||
maybe_last_update_user_token: weight.maybe_last_update_user_token,
|
||||
original_download_url: weight.original_download_url,
|
||||
original_filename: weight.original_filename,
|
||||
file_size_bytes: weight.file_size_bytes,
|
||||
file_checksum_sha2: weight.file_checksum_sha2,
|
||||
public_bucket_hash: weight.public_bucket_hash,
|
||||
maybe_public_bucket_prefix: weight.maybe_public_bucket_prefix,
|
||||
maybe_public_bucket_extension: weight.maybe_public_bucket_extension,
|
||||
|
||||
cached_user_ratings_negative_count: dataset.cached_user_ratings_negative_count,
|
||||
cached_user_ratings_positive_count: dataset.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_total_count: dataset.cached_user_ratings_total_count,
|
||||
maybe_cover_image_public_bucket_hash: weight.maybe_cover_image_public_bucket_hash,
|
||||
maybe_cover_image_public_bucket_prefix: weight.maybe_cover_image_public_bucket_prefix,
|
||||
maybe_cover_image_public_bucket_extension: weight.maybe_cover_image_public_bucket_extension,
|
||||
|
||||
maybe_cached_user_ratings_ratio: dataset.maybe_cached_user_ratings_ratio,
|
||||
cached_user_ratings_last_updated_at: dataset.cached_user_ratings_last_updated_at,
|
||||
version: dataset.version,
|
||||
created_at: dataset.created_at,
|
||||
updated_at: dataset.updated_at,
|
||||
user_deleted_at: dataset.user_deleted_at,
|
||||
mod_deleted_at: dataset.mod_deleted_at,
|
||||
cached_user_ratings_negative_count: weight.cached_user_ratings_negative_count,
|
||||
cached_user_ratings_positive_count: weight.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_total_count: weight.cached_user_ratings_total_count,
|
||||
|
||||
creator_username:dataset.creator_username,
|
||||
creator_display_name:dataset.creator_display_name,
|
||||
creator_email_gravatar_hash:dataset.creator_email_gravatar_hash
|
||||
maybe_cached_user_ratings_ratio: weight.maybe_cached_user_ratings_ratio,
|
||||
cached_user_ratings_last_updated_at: weight.cached_user_ratings_last_updated_at,
|
||||
version: weight.version,
|
||||
created_at: weight.created_at,
|
||||
updated_at: weight.updated_at,
|
||||
user_deleted_at: weight.user_deleted_at,
|
||||
mod_deleted_at: weight.mod_deleted_at,
|
||||
|
||||
creator_username: weight.creator_username,
|
||||
creator_display_name: weight.creator_display_name,
|
||||
creator_email_gravatar_hash: weight.creator_email_gravatar_hash,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
@@ -267,11 +283,11 @@ async fn map_to_weights(dataset:Vec<RawWeightJoinUser>) -> Vec<WeightsJoinUserRe
|
||||
pub weights_category: WeightsCategory,
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
|
||||
// TODO(bt,2023-12-24): These aren't really appropriate for a list endpoint.
|
||||
// Hopefully we don't break the frontend by omitting these.
|
||||
//pub description_markdown: String,
|
||||
//pub description_rendered_html: String,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_ip_address: String,
|
||||
@@ -288,7 +304,11 @@ async fn map_to_weights(dataset:Vec<RawWeightJoinUser>) -> Vec<WeightsJoinUserRe
|
||||
pub public_bucket_hash: String,
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
@@ -309,15 +329,16 @@ async fn map_to_weights(dataset:Vec<RawWeightJoinUser>) -> Vec<WeightsJoinUserRe
|
||||
}
|
||||
|
||||
impl FromRow<'_, MySqlRow> for RawWeightJoinUser {
|
||||
fn from_row(row: &MySqlRow) -> std::result::Result<Self, sqlx::Error> {
|
||||
fn from_row(row: &MySqlRow) -> Result<Self, sqlx::Error> {
|
||||
Ok(Self {
|
||||
token: row.try_get("token")?,
|
||||
weights_type: row.try_get("weights_type")?,
|
||||
weights_category: row.try_get("weights_category")?,
|
||||
title: row.try_get("title")?,
|
||||
maybe_thumbnail_token: row.try_get("maybe_thumbnail_token")?,
|
||||
description_markdown: row.try_get("description_markdown")?,
|
||||
description_rendered_html: row.try_get("description_rendered_html")?,
|
||||
// TODO(bt,2023-12-24): These aren't really appropriate for a list endpoint.
|
||||
// Hopefully we don't break the frontend by omitting these.
|
||||
//maybe_description_markdown: row.try_get("maybe_description_markdown")?,
|
||||
//maybe_description_rendered_html: row.try_get("maybe_description_rendered_html")?,
|
||||
creator_user_token: row.try_get("creator_user_token")?,
|
||||
creator_ip_address: row.try_get("creator_ip_address")?,
|
||||
creator_set_visibility: Visibility::try_from_mysql_row(row, "creator_set_visibility")?,
|
||||
@@ -329,6 +350,9 @@ impl FromRow<'_, MySqlRow> for RawWeightJoinUser {
|
||||
public_bucket_hash: row.try_get("public_bucket_hash")?,
|
||||
maybe_public_bucket_prefix: row.try_get("maybe_public_bucket_prefix")?,
|
||||
maybe_public_bucket_extension: row.try_get("maybe_public_bucket_extension")?,
|
||||
maybe_cover_image_public_bucket_hash: row.try_get("maybe_cover_image_public_bucket_hash")?,
|
||||
maybe_cover_image_public_bucket_prefix: row.try_get("maybe_cover_image_public_bucket_prefix")?,
|
||||
maybe_cover_image_public_bucket_extension: row.try_get("maybe_cover_image_public_bucket_extension")?,
|
||||
cached_user_ratings_total_count: row.try_get("cached_user_ratings_total_count")?,
|
||||
cached_user_ratings_positive_count: row.try_get("cached_user_ratings_positive_count")?,
|
||||
cached_user_ratings_negative_count: row.try_get("cached_user_ratings_negative_count")?,
|
||||
|
||||
+32
-27
@@ -36,10 +36,8 @@ pub struct WeightJoinUser {
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
pub maybe_description_markdown: Option<String>,
|
||||
pub maybe_description_rendered_html: Option<String>,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator_ip_address: String,
|
||||
@@ -57,6 +55,10 @@ pub struct WeightJoinUser {
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
@@ -160,13 +162,15 @@ impl ListWeightsQueryBuilder {
|
||||
mysql_pool: &MySqlPool
|
||||
) -> AnyhowResult<Vec<RawWeightJoinUser>> {
|
||||
let query = self.build_query_string();
|
||||
//println!("HERE! query: {}", query);
|
||||
//panic!("query: {:?}", query);
|
||||
|
||||
let mut query = sqlx::query_as::<_, RawWeightJoinUser>(&query);
|
||||
|
||||
// NB: The following bindings must match the order of the query builder !!
|
||||
|
||||
if let Some(offset) = self.offset {
|
||||
query = query.bind(offset);
|
||||
}
|
||||
|
||||
if let Some(username) = self.scope_creator_username.as_deref() {
|
||||
query = query.bind(username);
|
||||
}
|
||||
@@ -181,9 +185,6 @@ impl ListWeightsQueryBuilder {
|
||||
|
||||
query = query.bind(self.limit);
|
||||
|
||||
if let Some(offset) = self.offset {
|
||||
query = query.bind(offset);
|
||||
}
|
||||
|
||||
let mut results = query.fetch_all(mysql_pool).await?;
|
||||
|
||||
@@ -216,9 +217,8 @@ impl ListWeightsQueryBuilder {
|
||||
record.weights_category.as_str()
|
||||
).unwrap(),
|
||||
title: record.title,
|
||||
maybe_thumbnail_token: record.maybe_thumbnail_token,
|
||||
description_markdown: record.description_markdown,
|
||||
description_rendered_html: record.description_rendered_html,
|
||||
maybe_description_markdown: record.maybe_description_markdown,
|
||||
maybe_description_rendered_html: record.maybe_description_rendered_html,
|
||||
creator_user_token: UserToken::new_from_str(&record.creator_user_token),
|
||||
creator_ip_address: record.creator_ip_address,
|
||||
creator_set_visibility: Visibility::from_str(
|
||||
@@ -234,6 +234,9 @@ impl ListWeightsQueryBuilder {
|
||||
public_bucket_hash: record.public_bucket_hash,
|
||||
maybe_public_bucket_prefix: record.maybe_public_bucket_prefix,
|
||||
maybe_public_bucket_extension: record.maybe_public_bucket_extension,
|
||||
maybe_cover_image_public_bucket_hash: record.maybe_cover_image_public_bucket_hash,
|
||||
maybe_cover_image_public_bucket_prefix: record.maybe_cover_image_public_bucket_prefix,
|
||||
maybe_cover_image_public_bucket_extension: record.maybe_cover_image_public_bucket_extension,
|
||||
cached_user_ratings_total_count: record.cached_user_ratings_total_count,
|
||||
cached_user_ratings_positive_count: record.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_negative_count: record.cached_user_ratings_negative_count,
|
||||
@@ -268,9 +271,8 @@ impl ListWeightsQueryBuilder {
|
||||
model_weights.weights_type,
|
||||
model_weights.weights_category,
|
||||
model_weights.title,
|
||||
model_weights.maybe_thumbnail_token,
|
||||
model_weights.description_markdown,
|
||||
model_weights.description_rendered_html,
|
||||
model_weights.maybe_description_markdown,
|
||||
model_weights.maybe_description_rendered_html,
|
||||
model_weights.creator_user_token,
|
||||
model_weights.creator_ip_address,
|
||||
model_weights.creator_set_visibility,
|
||||
@@ -282,6 +284,9 @@ impl ListWeightsQueryBuilder {
|
||||
model_weights.public_bucket_hash,
|
||||
model_weights.maybe_public_bucket_prefix,
|
||||
model_weights.maybe_public_bucket_extension,
|
||||
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
|
||||
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
|
||||
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
|
||||
model_weights.cached_user_ratings_total_count,
|
||||
model_weights.cached_user_ratings_positive_count,
|
||||
model_weights.cached_user_ratings_negative_count,
|
||||
@@ -298,6 +303,8 @@ impl ListWeightsQueryBuilder {
|
||||
FROM model_weights
|
||||
JOIN users
|
||||
ON users.token = model_weights.creator_user_token
|
||||
LEFT OUTER JOIN media_files as cover_image
|
||||
ON cover_image.token = model_weights.maybe_cover_image_media_file_token
|
||||
"#.to_string();
|
||||
|
||||
query.push_str(&self.build_predicates());
|
||||
@@ -323,18 +330,18 @@ impl ListWeightsQueryBuilder {
|
||||
if sort_ascending {
|
||||
if self.cursor_is_reversed {
|
||||
// NB: We're searching backwards.
|
||||
query.push_str(" model_weights.id");
|
||||
query.push_str(" model_weights.id < ? ");
|
||||
sort_ascending = !sort_ascending;
|
||||
} else {
|
||||
query.push_str(" model_weights.id");
|
||||
query.push_str(" model_weights.id > ? ");
|
||||
}
|
||||
} else {
|
||||
if self.cursor_is_reversed {
|
||||
// NB: We're searching backwards.
|
||||
query.push_str(" model_weights.id");
|
||||
query.push_str(" model_weights.id > ? ");
|
||||
sort_ascending = !sort_ascending;
|
||||
} else {
|
||||
query.push_str(" model_weights.id");
|
||||
query.push_str(" model_weights.id < ? ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -403,10 +410,6 @@ impl ListWeightsQueryBuilder {
|
||||
query.push_str(" LIMIT ?");
|
||||
}
|
||||
|
||||
if let Some(_) = self.offset {
|
||||
query.push_str(" OFFSET ?");
|
||||
}
|
||||
|
||||
query
|
||||
}
|
||||
}
|
||||
@@ -422,10 +425,8 @@ struct RawWeightJoinUser {
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
pub maybe_description_markdown: Option<String>,
|
||||
pub maybe_description_rendered_html: Option<String>,
|
||||
|
||||
pub creator_user_token: String,
|
||||
pub creator_ip_address: String,
|
||||
@@ -443,6 +444,10 @@ struct RawWeightJoinUser {
|
||||
pub maybe_public_bucket_prefix: Option<String>,
|
||||
pub maybe_public_bucket_extension: Option<String>,
|
||||
|
||||
pub maybe_cover_image_public_bucket_hash: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_prefix: Option<String>,
|
||||
pub maybe_cover_image_public_bucket_extension: Option<String>,
|
||||
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
|
||||
+6
-10
@@ -76,11 +76,9 @@ SET
|
||||
weights_type = ?,
|
||||
weights_category = ?,
|
||||
title = ?,
|
||||
maybe_thumbnail_token = NULL,
|
||||
maybe_avatar_media_file_token = NULL,
|
||||
maybe_cover_media_file_token = NULL,
|
||||
description_markdown = ?,
|
||||
description_rendered_html = ?,
|
||||
maybe_cover_image_media_file_token = NULL,
|
||||
maybe_description_markdown = ?,
|
||||
maybe_description_rendered_html = ?,
|
||||
creator_user_token = ?,
|
||||
creator_ip_address = ?,
|
||||
|
||||
@@ -111,11 +109,9 @@ ON DUPLICATE KEY UPDATE
|
||||
weights_type = ?,
|
||||
weights_category = ?,
|
||||
title = ?,
|
||||
maybe_thumbnail_token = NULL,
|
||||
maybe_avatar_media_file_token = NULL,
|
||||
maybe_cover_media_file_token = NULL,
|
||||
description_markdown = ?,
|
||||
description_rendered_html = ?,
|
||||
maybe_cover_image_media_file_token = NULL,
|
||||
maybe_description_markdown = ?,
|
||||
maybe_description_rendered_html = ?,
|
||||
creator_user_token = ?,
|
||||
creator_ip_address = ?,
|
||||
creator_set_visibility = ?,
|
||||
|
||||
@@ -4,9 +4,8 @@ CREATE TABLE model_weights (
|
||||
weights_type VARCHAR(32) NOT NULL,
|
||||
weights_category VARCHAR(32) NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
maybe_thumbnail_token VARCHAR(32) DEFAULT NULL,
|
||||
description_markdown TEXT NOT NULL,
|
||||
description_rendered_html TEXT NOT NULL,
|
||||
maybe_description_markdown TEXT DEFAULT NULL,
|
||||
maybe_description_rendered_html TEXT DEFAULT NULL,
|
||||
creator_user_token VARCHAR(32) NOT NULL,
|
||||
creator_ip_address VARCHAR(40) NOT NULL,
|
||||
creator_set_visibility ENUM(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#[ignore]
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Ok;
|
||||
@@ -65,9 +66,8 @@ mod tests {
|
||||
weights_type: WeightsType::RvcV2, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::VoiceConversion, // replace with actual WeightsCategory
|
||||
title: "Title 1".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 1".to_string()),
|
||||
description_markdown: "Description 1".to_string(),
|
||||
description_rendered_html: "<p>Description 1</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 1".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 1</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token1), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -98,9 +98,8 @@ mod tests {
|
||||
assert_eq!(result.title, "Title 1".to_string());
|
||||
assert_eq!(result.weights_type, WeightsType::RvcV2);
|
||||
assert_eq!(result.weights_category, WeightsCategory::VoiceConversion);
|
||||
assert_eq!(result.maybe_thumbnail_token, Some("Thumbnail 1".to_string()));
|
||||
assert_eq!(result.description_markdown, "Description 1".to_string());
|
||||
assert_eq!(result.description_rendered_html, "<p>Description 1</p>".to_string());
|
||||
assert_eq!(result.maybe_description_markdown, Some("Description 1".to_string()));
|
||||
assert_eq!(result.maybe_description_rendered_html, Some("<p>Description 1</p>".to_string()));
|
||||
assert_eq!(result.creator_user_token, creator_token1);
|
||||
assert_eq!(result.creator_ip_address, "192.168.1.1".to_string());
|
||||
assert_eq!(result.creator_set_visibility, Visibility::Public);
|
||||
@@ -140,9 +139,8 @@ mod tests {
|
||||
weights_type: WeightsType::RvcV2, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::VoiceConversion, // replace with actual WeightsCategory
|
||||
title: "Title 1".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 1".to_string()),
|
||||
description_markdown: "Description 1".to_string(),
|
||||
description_rendered_html: "<p>Description 1</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 1".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 1</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token1), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -217,9 +215,8 @@ mod tests {
|
||||
weights_type: WeightsType::RvcV2, // replace with actual WeightsType
|
||||
weights_category: WeightsCategory::VoiceConversion, // replace with actual WeightsCategory
|
||||
title: "Title 1".to_string(),
|
||||
maybe_thumbnail_token: Some("Thumbnail 1".to_string()),
|
||||
description_markdown: "Description 1".to_string(),
|
||||
description_rendered_html: "<p>Description 1</p>".to_string(),
|
||||
maybe_description_markdown: Some("Description 1".to_string()),
|
||||
maybe_description_rendered_html: Some("<p>Description 1</p>".to_string()),
|
||||
creator_user_token: Some(&creator_token1), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -329,12 +326,11 @@ mod tests {
|
||||
|
||||
let args = CreateModelWeightsArgs {
|
||||
token: &model_weight_token, // replace with actual ModelWeightToken
|
||||
weights_type: weights_type, // replace with actual WeightsType
|
||||
weights_category: weights_category, // replace with actual WeightsCategory
|
||||
weights_type, // replace with actual WeightsType
|
||||
weights_category, // replace with actual WeightsCategory
|
||||
title: format!("Title {}", i),
|
||||
maybe_thumbnail_token: Some(format!("Thumbnail {}", i)),
|
||||
description_markdown: format!("Description {}", i),
|
||||
description_rendered_html: format!("<p>Description {}</p>", i),
|
||||
maybe_description_markdown: Some(format!("Description {}", i)),
|
||||
maybe_description_rendered_html: Some(format!("<p>Description {}</p>", i)),
|
||||
creator_user_token: Some(&creator_token), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
@@ -572,12 +568,11 @@ mod tests {
|
||||
|
||||
let args = CreateModelWeightsArgs {
|
||||
token: &model_weight_token, // replace with actual ModelWeightToken
|
||||
weights_type: weights_type, // replace with actual WeightsType
|
||||
weights_category: weights_category, // replace with actual WeightsCategory
|
||||
weights_type, // replace with actual WeightsType
|
||||
weights_category, // replace with actual WeightsCategory
|
||||
title: format!("Title {}", i),
|
||||
maybe_thumbnail_token: Some(format!("Thumbnail {}", i)),
|
||||
description_markdown: format!("Description {}", i),
|
||||
description_rendered_html: format!("<p>Description {}</p>", i),
|
||||
maybe_description_markdown: Some(format!("Description {}", i)),
|
||||
maybe_description_rendered_html: Some(format!("<p>Description {}</p>", i)),
|
||||
creator_user_token: Some(&creator_token), // replace with actual UserToken
|
||||
creator_ip_address: "192.168.1.1",
|
||||
creator_set_visibility: Visibility::Public,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use anyhow::anyhow;
|
||||
use log::warn;
|
||||
use sqlx::MySqlPool;
|
||||
use sqlx::{MySql, MySqlPool, QueryBuilder};
|
||||
|
||||
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
|
||||
use errors::AnyhowResult;
|
||||
@@ -8,21 +6,37 @@ use errors::AnyhowResult;
|
||||
use crate::queries::user_bookmarks::list_user_bookmarks_result::RawUserBookmarkRecord;
|
||||
use crate::queries::user_bookmarks::list_user_bookmarks_result::UserBookmark;
|
||||
|
||||
pub async fn list_user_bookmarks(
|
||||
username: &str,
|
||||
mysql_pool: &MySqlPool
|
||||
) -> AnyhowResult<Vec<UserBookmark>> {
|
||||
pub struct UserBookmarkListPage {
|
||||
pub results: Vec<UserBookmark>,
|
||||
|
||||
/// TODO(bt,2023-11-21): Maybe this query can use a switch
|
||||
/// See: https://stackoverflow.com/questions/2761574/mysql-use-case-else-value-as-join-parameter
|
||||
let maybe_results= sqlx::query_as!(
|
||||
RawUserBookmarkRecord,
|
||||
r#"
|
||||
SELECT
|
||||
f.token as `token: tokens::tokens::user_bookmarks::UserBookmarkToken`,
|
||||
f.entity_type as `entity_type: enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType`,
|
||||
pub sort_ascending: bool,
|
||||
|
||||
pub current_page: usize,
|
||||
pub total_page_count: usize,
|
||||
}
|
||||
|
||||
pub struct ListUserBookmarksForUserArgs<'a> {
|
||||
pub username: &'a str,
|
||||
pub maybe_filter_entity_type: Option<UserBookmarkEntityType>,
|
||||
pub page_size: usize,
|
||||
pub page_index: usize,
|
||||
pub sort_ascending: bool,
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
|
||||
fn select_total_count_field() -> String {
|
||||
r#"
|
||||
COUNT(f.id) AS total_count
|
||||
"#
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn select_result_fields() -> String {
|
||||
r#"
|
||||
f.token,
|
||||
f.entity_type,
|
||||
f.entity_token,
|
||||
f.user_token as `user_token: tokens::tokens::users::UserToken`,
|
||||
f.user_token,
|
||||
u.username,
|
||||
u.display_name as user_display_name,
|
||||
u.email_gravatar_hash as user_gravatar_hash,
|
||||
@@ -30,8 +44,8 @@ SELECT
|
||||
f.updated_at,
|
||||
f.deleted_at,
|
||||
|
||||
media_files.media_type as `maybe_media_file_type: enums::by_table::media_files::media_file_type::MediaFileType`,
|
||||
media_files.origin_product_category as `maybe_media_file_origin_category: enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory`,
|
||||
media_files.media_type as maybe_media_file_type,
|
||||
media_files.origin_product_category as maybe_media_file_origin_category,
|
||||
|
||||
model_weights.title as maybe_descriptive_text_model_weight_title,
|
||||
tts_models.title as maybe_descriptive_text_tts_model_title,
|
||||
@@ -39,7 +53,25 @@ SELECT
|
||||
users.display_name as maybe_descriptive_text_user_display_name,
|
||||
voice_conversion_models.title as maybe_descriptive_text_voice_conversion_model_title,
|
||||
zs_voices.title as maybe_descriptive_text_zs_voice_title
|
||||
"#.to_string()
|
||||
}
|
||||
|
||||
fn query_builder<'a>(
|
||||
maybe_filter_entity_type: Option<UserBookmarkEntityType>,
|
||||
maybe_username: Option<&'a str>,
|
||||
enforce_limits: bool,
|
||||
page_index: usize,
|
||||
page_size: usize,
|
||||
sort_ascending: bool,
|
||||
select_fields: &'a str,
|
||||
) -> QueryBuilder<'a, MySql> {
|
||||
|
||||
let mut first_predicate_added = false;
|
||||
// NB: Query cannot be statically checked by sqlx
|
||||
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new(
|
||||
format!(r#"
|
||||
SELECT
|
||||
{select_fields}
|
||||
FROM
|
||||
user_bookmarks AS f
|
||||
JOIN users AS u
|
||||
@@ -52,99 +84,91 @@ LEFT OUTER JOIN tts_results ON tts_results.token = f.entity_token
|
||||
LEFT OUTER JOIN users ON users.token = f.entity_token
|
||||
LEFT OUTER JOIN voice_conversion_models ON voice_conversion_models.token = f.entity_token
|
||||
LEFT OUTER JOIN zs_voices ON zs_voices.token = f.entity_token
|
||||
"#
|
||||
));
|
||||
|
||||
WHERE
|
||||
u.username = ?
|
||||
AND f.deleted_at IS NULL
|
||||
ORDER BY f.id DESC
|
||||
LIMIT 50
|
||||
"#,
|
||||
username
|
||||
)
|
||||
.fetch_all(mysql_pool)
|
||||
.await;
|
||||
if let Some(username) = maybe_username {
|
||||
if !first_predicate_added {
|
||||
query_builder.push(" WHERE ");
|
||||
first_predicate_added = true;
|
||||
} else {
|
||||
query_builder.push(" AND ");
|
||||
}
|
||||
query_builder.push(" u.username = ");
|
||||
query_builder.push_bind(username);
|
||||
}
|
||||
|
||||
match maybe_results {
|
||||
Err(err) => match err {
|
||||
sqlx::Error::RowNotFound => Ok(Vec::new()),
|
||||
_ => {
|
||||
warn!("list user_bookmarks db error: {:?}", err);
|
||||
Err(anyhow!("error with query: {:?}", err))
|
||||
}
|
||||
},
|
||||
Ok(results) => Ok(results.into_iter()
|
||||
.map(|user_bookmark| user_bookmark.into_public_type())
|
||||
.collect()),
|
||||
}
|
||||
if let Some(entity_type) = maybe_filter_entity_type {
|
||||
if !first_predicate_added {
|
||||
query_builder.push(" WHERE ");
|
||||
first_predicate_added = true;
|
||||
} else {
|
||||
query_builder.push(" AND ");
|
||||
}
|
||||
query_builder.push(" f.entity_type = ");
|
||||
query_builder.push_bind(entity_type.to_str());
|
||||
}
|
||||
|
||||
query_builder.push(" AND f.deleted_at IS NULL ");
|
||||
|
||||
if sort_ascending {
|
||||
query_builder.push(" ORDER BY f.created_at ASC ");
|
||||
} else {
|
||||
query_builder.push(" ORDER BY f.created_at DESC ");
|
||||
}
|
||||
|
||||
if enforce_limits {
|
||||
let offset = page_index * page_size;
|
||||
query_builder.push(format!(" LIMIT {page_size} OFFSET {offset} "));
|
||||
}
|
||||
|
||||
query_builder
|
||||
}
|
||||
|
||||
pub async fn list_user_user_bookmarks_by_entity_type(
|
||||
username: &str,
|
||||
entity_type: UserBookmarkEntityType,
|
||||
mysql_pool: &MySqlPool
|
||||
) -> AnyhowResult<Vec<UserBookmark>> {
|
||||
pub async fn list_user_bookmarks_by_maybe_entity_type(
|
||||
args: ListUserBookmarksForUserArgs<'_>
|
||||
) -> AnyhowResult<UserBookmarkListPage> {
|
||||
|
||||
let maybe_results= sqlx::query_as!(
|
||||
RawUserBookmarkRecord,
|
||||
r#"
|
||||
SELECT
|
||||
f.token as `token: tokens::tokens::user_bookmarks::UserBookmarkToken`,
|
||||
f.entity_type as `entity_type: enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType`,
|
||||
f.entity_token,
|
||||
f.user_token as `user_token: tokens::tokens::users::UserToken`,
|
||||
u.username,
|
||||
u.display_name as user_display_name,
|
||||
u.email_gravatar_hash as user_gravatar_hash,
|
||||
f.created_at,
|
||||
f.updated_at,
|
||||
f.deleted_at,
|
||||
let count_fields = select_total_count_field();
|
||||
let mut count_query_builder = query_builder(
|
||||
args.maybe_filter_entity_type,
|
||||
Some(args.username),
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
args.sort_ascending,
|
||||
count_fields.as_str(),
|
||||
);
|
||||
|
||||
media_files.media_type as `maybe_media_file_type: enums::by_table::media_files::media_file_type::MediaFileType`,
|
||||
media_files.origin_product_category as `maybe_media_file_origin_category: enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory`,
|
||||
let row_count_query = count_query_builder.build_query_scalar::<i64>();
|
||||
let row_count_result = row_count_query.fetch_one(args.mysql_pool).await?;
|
||||
|
||||
model_weights.title as maybe_descriptive_text_model_weight_title,
|
||||
tts_models.title as maybe_descriptive_text_tts_model_title,
|
||||
tts_results.raw_inference_text as maybe_descriptive_text_tts_result_inference_text,
|
||||
users.display_name as maybe_descriptive_text_user_display_name,
|
||||
voice_conversion_models.title as maybe_descriptive_text_voice_conversion_model_title,
|
||||
zs_voices.title as maybe_descriptive_text_zs_voice_title
|
||||
/// Now fetch the actual results with all the fields
|
||||
let result_fields = select_result_fields();
|
||||
let mut query = query_builder(
|
||||
args.maybe_filter_entity_type,
|
||||
Some(args.username),
|
||||
true,
|
||||
args.page_index,
|
||||
args.page_size,
|
||||
args.sort_ascending,
|
||||
result_fields.as_str(),
|
||||
);
|
||||
|
||||
FROM
|
||||
user_bookmarks AS f
|
||||
JOIN users AS u
|
||||
ON f.user_token = u.token
|
||||
let query = query.build_query_as::<RawUserBookmarkRecord>();
|
||||
let results = query.fetch_all(args.mysql_pool).await?;
|
||||
|
||||
LEFT OUTER JOIN model_weights ON model_weights.token = f.entity_token
|
||||
LEFT OUTER JOIN media_files ON media_files.token = f.entity_token
|
||||
LEFT OUTER JOIN tts_models ON tts_models.token = f.entity_token
|
||||
LEFT OUTER JOIN tts_results ON tts_results.token = f.entity_token
|
||||
LEFT OUTER JOIN users ON users.token = f.entity_token
|
||||
LEFT OUTER JOIN voice_conversion_models ON voice_conversion_models.token = f.entity_token
|
||||
LEFT OUTER JOIN zs_voices ON zs_voices.token = f.entity_token
|
||||
let number_of_pages = (row_count_result / args.page_size as i64) as usize;
|
||||
let results = results.into_iter()
|
||||
.map(|record| {
|
||||
record.into_public_type()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
WHERE
|
||||
u.username = ?
|
||||
AND f.entity_type = ?
|
||||
AND f.deleted_at IS NULL
|
||||
ORDER BY f.id DESC
|
||||
LIMIT 50
|
||||
"#,
|
||||
username,
|
||||
entity_type
|
||||
)
|
||||
.fetch_all(mysql_pool)
|
||||
.await;
|
||||
|
||||
match maybe_results {
|
||||
Err(err) => match err {
|
||||
sqlx::Error::RowNotFound => Ok(Vec::new()),
|
||||
_ => {
|
||||
warn!("list user_bookmarks db error: {:?}", err);
|
||||
Err(anyhow!("error with query: {:?}", err))
|
||||
}
|
||||
},
|
||||
Ok(results) => Ok(results.into_iter()
|
||||
.map(|user_bookmark| user_bookmark.into_public_type())
|
||||
.collect()),
|
||||
}
|
||||
Ok(UserBookmarkListPage {
|
||||
results,
|
||||
sort_ascending: args.sort_ascending,
|
||||
current_page: args.page_index,
|
||||
total_page_count: number_of_pages,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use sqlx::{FromRow, Row};
|
||||
use sqlx::mysql::MySqlRow;
|
||||
|
||||
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
|
||||
use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory;
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
|
||||
use enums::traits::mysql_from_row::MySqlFromRow;
|
||||
use tokens::tokens::user_bookmarks::UserBookmarkToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
@@ -85,3 +88,28 @@ impl RawUserBookmarkRecord {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRow<'_, MySqlRow> for RawUserBookmarkRecord {
|
||||
fn from_row(row: &MySqlRow) -> Result<Self, sqlx::Error> {
|
||||
Ok(Self {
|
||||
token: UserBookmarkToken::new(row.try_get("token")?),
|
||||
entity_type: UserBookmarkEntityType::try_from_mysql_row(row, "entity_type")?,
|
||||
entity_token: row.try_get("entity_token")?,
|
||||
user_token: row.try_get("user_token")?,
|
||||
username: row.try_get("username")?,
|
||||
user_display_name: row.try_get("user_display_name")?,
|
||||
user_gravatar_hash: row.try_get("user_gravatar_hash")?,
|
||||
created_at: row.try_get("created_at")?,
|
||||
updated_at: row.try_get("updated_at")?,
|
||||
deleted_at: row.try_get("deleted_at")?,
|
||||
maybe_media_file_type: MediaFileType::try_from_mysql_row_nullable(row,"maybe_media_file_type")?,
|
||||
maybe_media_file_origin_category: MediaFileOriginCategory::try_from_mysql_row_nullable(row,"maybe_media_file_origin_category")?,
|
||||
maybe_descriptive_text_model_weight_title: row.try_get("maybe_descriptive_text_model_weight_title")?,
|
||||
maybe_descriptive_text_tts_model_title: row.try_get("maybe_descriptive_text_tts_model_title")?,
|
||||
maybe_descriptive_text_tts_result_inference_text: row.try_get("maybe_descriptive_text_tts_result_inference_text")?,
|
||||
maybe_descriptive_text_user_display_name: row.try_get("maybe_descriptive_text_user_display_name")?,
|
||||
maybe_descriptive_text_voice_conversion_model_title: row.try_get("maybe_descriptive_text_voice_conversion_model_title")?,
|
||||
maybe_descriptive_text_zs_voice_title: row.try_get("maybe_descriptive_text_zs_voice_title")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ migration = { path = "../../../lib/migration" }
|
||||
mimetypes = { path = "../../../lib/files/mimetypes" }
|
||||
mysql_queries = { path = "../../../lib/mysql_queries" }
|
||||
reusable_types = { path = "../../../_types/reusable_types" }
|
||||
storyteller_root = { path = "../../../lib/storyteller_root" }
|
||||
subprocess_common = { path = "../../../lib/subprocess_common" }
|
||||
tokens = { path = "../../../_types/tokens" }
|
||||
|
||||
|
||||
+42
-2
@@ -46,9 +46,10 @@ pub fn extract_rvc_files(download_file: &Path, temp_dir: &TempDir) -> AnyhowResu
|
||||
return Ok(DownloadedRvcFile::ModelFileOnly { model_file: download_file.to_path_buf() });
|
||||
}
|
||||
|
||||
if archive.len() > 3 {
|
||||
// There's something suspicious if the model files has more than 3 entries.
|
||||
if archive.len() > 7 {
|
||||
// There's something suspicious if the model files has more than 7 entries.
|
||||
// It should have the .pth file, a .index file, and _maybe_ a .txt file for credits.
|
||||
// Mac users sometimes have a bogus __MACOSX directory, which may double the file count.
|
||||
warn!("File has wrong number of entries to be a valid model: {}", archive.len());
|
||||
return Ok(DownloadedRvcFile::InvalidModel);
|
||||
}
|
||||
@@ -62,6 +63,11 @@ pub fn extract_rvc_files(download_file: &Path, temp_dir: &TempDir) -> AnyhowResu
|
||||
let mut file = archive.by_index(i)?;
|
||||
let filename = file.name().to_lowercase();
|
||||
|
||||
if filename.starts_with("__macosx/") {
|
||||
// Mac users sometimes have a bogus __MACOSX directory, which may double the file count.
|
||||
continue;
|
||||
}
|
||||
|
||||
let temp_file_path;
|
||||
|
||||
if filename.ends_with(".pth") {
|
||||
@@ -103,3 +109,37 @@ pub fn extract_rvc_files(download_file: &Path, temp_dir: &TempDir) -> AnyhowResu
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::bail;
|
||||
use tempdir::TempDir;
|
||||
|
||||
use errors::AnyhowResult;
|
||||
use storyteller_root::get_seed_tool_data_root;
|
||||
|
||||
use crate::job_types::voice_conversion::rvc_v2::extract_rvc_files::{DownloadedRvcFile, extract_rvc_files};
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rvc_with_macos_directory() -> AnyhowResult<()> {
|
||||
let root = get_seed_tool_data_root();
|
||||
let broken_model = root.join("models/rvc/sakura-hkt48.zip");
|
||||
let tempdir = TempDir::new("test").expect("tempdir creation failed");
|
||||
|
||||
let extracted = extract_rvc_files(&broken_model, &tempdir).unwrap();
|
||||
|
||||
match extracted {
|
||||
DownloadedRvcFile::InvalidModel => bail!("should not be broken"),
|
||||
DownloadedRvcFile::ModelFileOnly { .. } => bail!("should not be model file only"),
|
||||
DownloadedRvcFile::ModelAndIndexFile { model_file, index_file } => {
|
||||
assert!(model_file.ends_with("model.pth"));
|
||||
assert!(index_file.ends_with("model.index"));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,57 +1,66 @@
|
||||
use crate::http_server::endpoints::voice_designer::inference::enqueue_tts_request::*;
|
||||
use utoipa::OpenApi;
|
||||
|
||||
use crate::http_server::endpoints::weights::list_available_weights::*;
|
||||
use crate::http_server::web_utils::response_success_helpers::*;
|
||||
use crate::http_server::endpoints::weights::delete_weight::*;
|
||||
use crate::http_server::endpoints::weights::get_weight::*;
|
||||
use crate::http_server::endpoints::weights::update_weight::*;
|
||||
use crate::http_server::endpoints::weights::list_weights_by_user::*;
|
||||
use crate::http_server::common_responses::user_details_lite::{DefaultAvatarInfo, UserDetailsLight};
|
||||
use crate::http_server::common_responses::media_file_social_meta_lite::MediaFileSocialMetaLight;
|
||||
use crate::http_server::common_responses::pagination_cursors::PaginationCursors;
|
||||
use crate::http_server::common_responses::pagination_page::PaginationPage;
|
||||
use crate::http_server::endpoints::media_files::list_featured_media_files::*;
|
||||
use crate::http_server::endpoints::media_files::list_media_files::*;
|
||||
use crate::http_server::endpoints::media_files::list_media_files_for_user::*;
|
||||
use enums::by_table::model_weights::{weights_types::WeightsType, weights_category::WeightsCategory};
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory;
|
||||
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
|
||||
use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory;
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::by_table::model_weights::{weights_category::WeightsCategory, weights_types::WeightsType};
|
||||
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
|
||||
use enums::by_table::user_ratings::entity_type::UserRatingEntityType;
|
||||
use enums::by_table::user_ratings::rating_value::UserRatingValue;
|
||||
use enums::common::visibility::Visibility;
|
||||
use tokens::tokens::generic_inference_jobs::*;
|
||||
use tokens::tokens::media_files::*;
|
||||
use tokens::tokens::model_weights::*;
|
||||
use tokens::tokens::user_bookmarks::*;
|
||||
use tokens::tokens::users::*;
|
||||
|
||||
use crate::http_server::common_responses::media_file_social_meta_lite::MediaFileSocialMetaLight;
|
||||
use crate::http_server::common_responses::pagination_cursors::PaginationCursors;
|
||||
use crate::http_server::common_responses::pagination_page::PaginationPage;
|
||||
use crate::http_server::common_responses::user_details_lite::{DefaultAvatarInfo, UserDetailsLight};
|
||||
use crate::http_server::endpoints::media_files::list_featured_media_files::*;
|
||||
use crate::http_server::endpoints::media_files::list_media_files::*;
|
||||
use crate::http_server::endpoints::media_files::list_media_files_for_user::*;
|
||||
use crate::http_server::endpoints::media_files::upload::upload_error::MediaFileUploadError;
|
||||
use crate::http_server::endpoints::media_files::upload_media_file::*;
|
||||
use crate::http_server::endpoints::user_bookmarks::create_user_bookmark_handler::*;
|
||||
use crate::http_server::endpoints::user_bookmarks::delete_user_bookmark_handler::*;
|
||||
use crate::http_server::endpoints::user_bookmarks::list_user_bookmarks_for_entity_handler::*;
|
||||
use crate::http_server::endpoints::user_bookmarks::list_user_bookmarks_for_session_handler::*;
|
||||
use crate::http_server::endpoints::user_bookmarks::list_user_bookmarks_for_user_handler::*;
|
||||
use crate::http_server::endpoints::voice_designer::inference::enqueue_tts_request::*;
|
||||
use crate::http_server::endpoints::weights::delete_weight::*;
|
||||
use crate::http_server::endpoints::weights::get_weight::*;
|
||||
use crate::http_server::endpoints::weights::list_available_weights::*;
|
||||
use crate::http_server::endpoints::weights::list_weights_by_user::*;
|
||||
use crate::http_server::endpoints::weights::set_model_weight_cover_image::*;
|
||||
use crate::http_server::endpoints::weights::update_weight::*;
|
||||
use crate::http_server::web_utils::response_success_helpers::*;
|
||||
use crate::http_server::endpoints::user_ratings::get_user_rating_handler::*;
|
||||
use crate::http_server::endpoints::user_ratings::set_user_rating_handler::*;
|
||||
|
||||
use tokens::tokens::generic_inference_jobs::*;
|
||||
use tokens::tokens::model_weights::*;
|
||||
use tokens::tokens::users::*;
|
||||
use tokens::tokens::media_files::*;
|
||||
use tokens::tokens::user_bookmarks::*;
|
||||
use enums::common::visibility::Visibility;
|
||||
use chrono::{DateTime, Utc};
|
||||
use utoipa::OpenApi;
|
||||
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(paths(crate::http_server::endpoints::voice_designer::inference::enqueue_tts_request::enqueue_tts_request,
|
||||
crate::http_server::endpoints::weights::list_available_weights::list_available_weights_handler,
|
||||
crate::http_server::endpoints::weights::delete_weight::delete_weight_handler,
|
||||
crate::http_server::endpoints::weights::update_weight::update_weight_handler,
|
||||
crate::http_server::endpoints::weights::get_weight::get_weight_handler,
|
||||
crate::http_server::endpoints::weights::list_weights_by_user::list_weights_by_user_handler,
|
||||
#[openapi(
|
||||
paths(
|
||||
crate::http_server::endpoints::media_files::list_featured_media_files::list_featured_media_files_handler,
|
||||
crate::http_server::endpoints::media_files::list_media_files::list_media_files_handler,
|
||||
crate::http_server::endpoints::media_files::list_media_files_for_user::list_media_files_for_user_handler,
|
||||
crate::http_server::endpoints::media_files::upload_media_file::upload_media_file_handler,
|
||||
crate::http_server::endpoints::user_bookmarks::create_user_bookmark_handler::create_user_bookmark_handler,
|
||||
crate::http_server::endpoints::user_bookmarks::delete_user_bookmark_handler::delete_user_bookmark_handler,
|
||||
crate::http_server::endpoints::user_bookmarks::list_user_bookmarks_for_user_handler::list_user_bookmarks_for_user_handler,
|
||||
crate::http_server::endpoints::user_bookmarks::list_user_bookmarks_for_entity_handler::list_user_bookmarks_for_entity_handler,
|
||||
),components(schemas(
|
||||
crate::http_server::endpoints::user_bookmarks::list_user_bookmarks_for_user_handler::list_user_bookmarks_for_user_handler,
|
||||
crate::http_server::endpoints::voice_designer::inference::enqueue_tts_request::enqueue_tts_request,
|
||||
crate::http_server::endpoints::weights::delete_weight::delete_weight_handler,
|
||||
crate::http_server::endpoints::weights::get_weight::get_weight_handler,
|
||||
crate::http_server::endpoints::weights::list_available_weights::list_available_weights_handler,
|
||||
crate::http_server::endpoints::weights::list_weights_by_user::list_weights_by_user_handler,
|
||||
crate::http_server::endpoints::weights::set_model_weight_cover_image::set_model_weight_cover_image_handler,
|
||||
crate::http_server::endpoints::weights::update_weight::update_weight_handler,
|
||||
crate::http_server::endpoints::user_ratings::get_user_rating_handler::get_user_rating_handler,
|
||||
crate::http_server::endpoints::user_ratings::set_user_rating_handler::set_user_rating_handler,
|
||||
),
|
||||
components(schemas(
|
||||
// Tokens
|
||||
UserToken,Visibility,
|
||||
//
|
||||
@@ -62,7 +71,9 @@ use utoipa::OpenApi;
|
||||
ModelWeightToken,WeightsCategory,WeightsType,
|
||||
GetWeightPathInfo,GetWeightResponse,GetWeightError,
|
||||
UpdateWeightRequest,UpdateWeightRequest,UpdateWeightPathInfo,UpdateWeightRequest,UpdateWeightError,
|
||||
SetModelWeightCoverImageRequest,SetModelWeightCoverImageResponse,SetModelWeightCoverImagePathInfo,SetModelWeightCoverImageError,
|
||||
DeleteWeightPathInfo,DeleteWeightRequest,DeleteWeightError,DeleteWeightRequest,DeleteWeightError,
|
||||
UploadMediaSuccessResponse,MediaFileUploadError,
|
||||
ListWeightError,ModelWeightForList,ListWeightError,
|
||||
ListAvailableWeightsQuery,ListAvailableWeightsSuccessResponse,ModelWeightForList,
|
||||
ListWeightsByUserError,ListWeightsByUserSuccessResponse,ListWeightsByUserPathInfo,Weight,
|
||||
@@ -80,5 +91,8 @@ use utoipa::OpenApi;
|
||||
DeleteUserBookmarkPathInfo,DeleteUserBookmarkError,DeleteUserBookmarkRequest,
|
||||
ListUserBookmarksPathInfo,ListUserBookmarksForUserError,ListUserBookmarksForUserSuccessResponse,UserBookmarkListItem,
|
||||
ListUserBookmarksForEntityPathInfo,ListUserBookmarksForEntityError,ListUserBookmarksForEntitySuccessResponse,UserBookmarkForEntityListItem,
|
||||
)))]
|
||||
GetUserRatingError,GetUserRatingResponse,UserRatingValue,UserRatingEntityType,
|
||||
SetUserRatingError,SetUserRatingRequest,SetUserRatingResponse,
|
||||
))
|
||||
)]
|
||||
pub struct ApiDoc;
|
||||
|
||||
+6
-4
@@ -13,8 +13,9 @@ use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCat
|
||||
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
|
||||
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::view_as::ViewAs;
|
||||
use enums::common::visibility::Visibility;
|
||||
use mysql_queries::queries::media_files::list::list_media_files::{list_media_files, ListMediaFilesArgs, ViewAs};
|
||||
use mysql_queries::queries::media_files::list::list_media_files::{list_media_files, ListMediaFilesArgs};
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
use crate::http_server::common_responses::media_file_social_meta_lite::MediaFileSocialMetaLight;
|
||||
@@ -26,7 +27,7 @@ use crate::server_state::ServerState;
|
||||
#[derive(Deserialize, ToSchema, IntoParams)]
|
||||
pub struct ListMediaFilesQueryParams {
|
||||
pub sort_ascending: Option<bool>,
|
||||
pub per_page: Option<usize>,
|
||||
pub page_size: Option<usize>,
|
||||
pub cursor: Option<String>,
|
||||
pub cursor_is_reversed: Option<bool>,
|
||||
pub filter_media_type: Option<MediaFileType>,
|
||||
@@ -125,7 +126,7 @@ pub async fn list_media_files_handler(
|
||||
};
|
||||
|
||||
// TODO(bt,2023-12-04): Enforce real maximums and defaults
|
||||
let limit = query.per_page.unwrap_or(25);
|
||||
let limit = query.page_size.unwrap_or(25);
|
||||
|
||||
let sort_ascending = query.sort_ascending.unwrap_or(false);
|
||||
let cursor_is_reversed = query.cursor_is_reversed.unwrap_or(false);
|
||||
@@ -144,7 +145,7 @@ pub async fn list_media_files_handler(
|
||||
let view_as = if is_mod {
|
||||
ViewAs::Moderator
|
||||
} else {
|
||||
ViewAs::NonModerator
|
||||
ViewAs::AnotherUser
|
||||
};
|
||||
|
||||
let query_results = list_media_files(ListMediaFilesArgs {
|
||||
@@ -152,6 +153,7 @@ pub async fn list_media_files_handler(
|
||||
maybe_filter_media_type: query.filter_media_type,
|
||||
maybe_offset: cursor,
|
||||
cursor_is_reversed,
|
||||
sort_ascending,
|
||||
view_as,
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
}).await;
|
||||
|
||||
+2
-2
@@ -13,8 +13,9 @@ use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCat
|
||||
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
|
||||
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::view_as::ViewAs;
|
||||
use enums::common::visibility::Visibility;
|
||||
use mysql_queries::queries::media_files::list::list_media_files_for_user::{list_media_files_for_user, ListMediaFileForUserArgs, ViewAs};
|
||||
use mysql_queries::queries::media_files::list::list_media_files_for_user::{list_media_files_for_user, ListMediaFileForUserArgs};
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
use crate::http_server::common_responses::pagination_page::PaginationPage;
|
||||
@@ -127,7 +128,6 @@ pub async fn list_media_files_for_user_handler(
|
||||
};
|
||||
|
||||
// TODO(bt,2023-12-04): Enforce real maximums and defaults
|
||||
let limit = query.page_size.unwrap_or(25);
|
||||
let sort_ascending = query.sort_ascending.unwrap_or(false);
|
||||
let page_size = query.page_size.unwrap_or_else(|| 25);
|
||||
let page_index = query.page_index.unwrap_or_else(|| 0);
|
||||
|
||||
+6
-22
@@ -12,6 +12,7 @@ use hashing::sha256::sha256_hash_bytes::sha256_hash_bytes;
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use media::decode_basic_audio_info::decode_basic_audio_bytes_info;
|
||||
use mimetypes::mimetype_for_bytes::get_mimetype_for_bytes;
|
||||
use mimetypes::mimetype_to_extension::mimetype_to_extension;
|
||||
use mysql_queries::queries::media_files::create::insert_media_file_from_file_upload::{insert_media_file_from_file_upload, InsertMediaFileFromUploadArgs, UploadType};
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
@@ -194,6 +195,7 @@ pub async fn process_upload_media_file(
|
||||
"audio/x-flac" /* .flac */ => Some(MediaFileType::Audio),
|
||||
"audio/x-wav" /* .wav */ => Some(MediaFileType::Audio),
|
||||
// Image
|
||||
"image/gif" /* .gif */ => Some(MediaFileType::Image),
|
||||
"image/jpeg" /* .jpg */ => Some(MediaFileType::Image),
|
||||
"image/png" /* .png */ => Some(MediaFileType::Image),
|
||||
"image/webp" /* .webp */ => Some(MediaFileType::Image),
|
||||
@@ -277,30 +279,12 @@ pub async fn process_upload_media_file(
|
||||
},
|
||||
};
|
||||
|
||||
// TODO(bt,2023-12-20): Reasonable extensions.
|
||||
let extension = match mime_type {
|
||||
// Audio
|
||||
"audio/aac" /* .aac */ => Some(".aac"),
|
||||
"audio/m4a" /* .m4a */ => Some(".m4a"),
|
||||
"audio/mpeg" /* .mp3 */ => Some(".mp3"),
|
||||
"audio/ogg" /* .ogg */ => Some(".ogg"),
|
||||
"audio/opus" /* .opus */ => Some(".opus"),
|
||||
"audio/x-flac" /* .flac */ => Some(".flac"),
|
||||
"audio/x-wav" /* .wav */ => Some(".wav"),
|
||||
// Image
|
||||
"image/jpeg" /* .jpg */ => Some(".jpg"),
|
||||
"image/png" /* .png */ => Some(".png"),
|
||||
"image/webp" /* .webp */ => Some(".webp"),
|
||||
// Video
|
||||
"video/mp4" /* .mp4 */ => Some(".mp4"),
|
||||
"video/quicktime" /* .mov */ => Some(".mov"),
|
||||
"video/webm" /* .webm */ => Some(".webm"),
|
||||
_ => None,
|
||||
};
|
||||
let extension = mimetype_to_extension(mime_type)
|
||||
.map(|extension| format!(".{extension}"));
|
||||
|
||||
const PREFIX : Option<&str> = Some("upload_");
|
||||
|
||||
let public_upload_path = MediaFileBucketPath::generate_new(PREFIX, extension);
|
||||
let public_upload_path = MediaFileBucketPath::generate_new(PREFIX, extension.as_deref());
|
||||
|
||||
info!("Uploading media to bucket path: {}", public_upload_path.get_full_object_path_str());
|
||||
|
||||
@@ -327,7 +311,7 @@ pub async fn process_upload_media_file(
|
||||
sha256_checksum: &hash,
|
||||
public_bucket_directory_hash: public_upload_path.get_object_hash(),
|
||||
maybe_public_bucket_prefix: PREFIX,
|
||||
maybe_public_bucket_extension: extension,
|
||||
maybe_public_bucket_extension: extension.as_deref(),
|
||||
pool: &server_state.mysql_pool,
|
||||
})
|
||||
.await
|
||||
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
use actix_web::error::ResponseError;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::HttpResponse;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use http_server_common::response::serialize_as_json_error::serialize_as_json_error;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub enum MediaFileUploadError {
|
||||
BadInput(String),
|
||||
NotAuthorized,
|
||||
|
||||
+23
-3
@@ -4,14 +4,15 @@ use std::sync::Arc;
|
||||
use actix_multipart::Multipart;
|
||||
use actix_web::{HttpRequest, HttpResponse, web};
|
||||
use once_cell::sync::Lazy;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
use crate::http_server::endpoints::media_files::upload::process_upload_media_file::process_upload_media_file;
|
||||
|
||||
|
||||
use crate::http_server::endpoints::media_files::upload::upload_error::MediaFileUploadError;
|
||||
use crate::server_state::ServerState;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct UploadMediaSuccessResponse {
|
||||
pub success: bool,
|
||||
pub media_file_token: MediaFileToken,
|
||||
@@ -33,9 +34,28 @@ static ALLOWED_MIME_TYPES : Lazy<HashSet<&'static str>> = Lazy::new(|| {
|
||||
"video/mp4",
|
||||
"video/webm",
|
||||
//"video/quicktime",
|
||||
// Image
|
||||
"image/gif",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
])
|
||||
});
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/v1/media_files/upload",
|
||||
responses(
|
||||
(status = 200, description = "Success Update", body = UploadMediaSuccessResponse),
|
||||
(status = 400, description = "Bad input", body = MediaFileUploadError),
|
||||
(status = 401, description = "Not authorized", body = MediaFileUploadError),
|
||||
(status = 429, description = "Too many requests", body = MediaFileUploadError),
|
||||
(status = 500, description = "Server error", body = MediaFileUploadError),
|
||||
),
|
||||
params(
|
||||
("request" = (), description = "Ask Brandon. This is form-multipart."),
|
||||
)
|
||||
)]
|
||||
pub async fn upload_media_file_handler(
|
||||
http_request: HttpRequest,
|
||||
server_state: web::Data<Arc<ServerState>>,
|
||||
|
||||
+8
-31
@@ -1,7 +1,3 @@
|
||||
// NB: Incrementally getting rid of build warnings...
|
||||
#![forbid(unused_imports)]
|
||||
#![forbid(unused_mut)]
|
||||
#![forbid(unused_variables)]
|
||||
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
@@ -14,7 +10,7 @@ use chrono::{DateTime, Utc};
|
||||
use log::warn;
|
||||
|
||||
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
|
||||
use mysql_queries::queries::user_bookmarks::list_user_bookmarks::{list_user_bookmarks, list_user_user_bookmarks_by_entity_type};
|
||||
use mysql_queries::queries::user_bookmarks::list_user_bookmarks::{ list_user_bookmarks_by_maybe_entity_type};
|
||||
use tokens::tokens::user_bookmarks::UserBookmarkToken;
|
||||
|
||||
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
|
||||
@@ -100,36 +96,17 @@ pub async fn list_user_bookmarks_for_session_handler(
|
||||
})?
|
||||
.ok_or(ListUserBookmarksError::NotAuthorizedError)?;
|
||||
|
||||
let query_results = match query.maybe_scoped_entity_type {
|
||||
None => list_user_bookmarks(&user_session.username, &server_state.mysql_pool).await,
|
||||
Some(entity_type) =>
|
||||
list_user_user_bookmarks_by_entity_type(&user_session.username, entity_type, &server_state.mysql_pool)
|
||||
.await,
|
||||
};
|
||||
// let query_results = match query.maybe_scoped_entity_type {
|
||||
// None => list_user_bookmarks(&user_session.username, &server_state.mysql_pool).await,
|
||||
// Some(entity_type) =>
|
||||
// list_user_user_bookmarks_by_entity_type(&user_session.username, entity_type, &server_state.mysql_pool)
|
||||
// .await,
|
||||
// };
|
||||
|
||||
let user_bookmarks = match query_results {
|
||||
Ok(results) => results,
|
||||
Err(e) => {
|
||||
warn!("Query error: {:?}", e);
|
||||
return Err(ListUserBookmarksError::ServerError);
|
||||
}
|
||||
};
|
||||
|
||||
let response = ListUserBookmarksSuccessResponse {
|
||||
success: true,
|
||||
user_bookmarks: user_bookmarks.into_iter()
|
||||
.map(|user_bookmark| UserBookmark {
|
||||
token: user_bookmark.token,
|
||||
details: UserBookmarkDetails {
|
||||
entity_type: user_bookmark.entity_type,
|
||||
entity_token: user_bookmark.entity_token,
|
||||
maybe_summary_text: None,
|
||||
maybe_thumbnail_url: None,
|
||||
},
|
||||
created_at: user_bookmark.created_at,
|
||||
updated_at: user_bookmark.updated_at,
|
||||
})
|
||||
.collect(),
|
||||
user_bookmarks: Vec::new()
|
||||
};
|
||||
|
||||
let body = serde_json::to_string(&response)
|
||||
|
||||
+37
-13
@@ -15,9 +15,9 @@ use log::warn;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
use enums::by_table::user_bookmarks::user_bookmark_entity_type::UserBookmarkEntityType;
|
||||
use mysql_queries::queries::user_bookmarks::list_user_bookmarks::{list_user_bookmarks, list_user_user_bookmarks_by_entity_type};
|
||||
use mysql_queries::queries::user_bookmarks::list_user_bookmarks::{list_user_bookmarks_by_maybe_entity_type, ListUserBookmarksForUserArgs};
|
||||
use tokens::tokens::user_bookmarks::UserBookmarkToken;
|
||||
|
||||
use crate::http_server::common_responses::pagination_page::PaginationPage;
|
||||
use crate::http_server::web_utils::response_error_helpers::to_simple_json_error;
|
||||
use crate::server_state::ServerState;
|
||||
|
||||
@@ -28,13 +28,17 @@ pub struct ListUserBookmarksPathInfo {
|
||||
|
||||
#[derive(Deserialize, ToSchema, IntoParams)]
|
||||
pub struct ListUserBookmarksQueryData {
|
||||
sort_ascending: Option<bool>,
|
||||
page_size: Option<usize>,
|
||||
page_index: Option<usize>,
|
||||
maybe_scoped_entity_type: Option<UserBookmarkEntityType>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListUserBookmarksForUserSuccessResponse {
|
||||
pub success: bool,
|
||||
pub user_bookmarks: Vec<UserBookmarkListItem>,
|
||||
pub results: Vec<UserBookmarkListItem>,
|
||||
pub pagination: PaginationPage,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
@@ -101,21 +105,37 @@ responses(
|
||||
),
|
||||
)]
|
||||
pub async fn list_user_bookmarks_for_user_handler(
|
||||
_http_request: HttpRequest,
|
||||
http_request: HttpRequest,
|
||||
path: Path<ListUserBookmarksPathInfo>,
|
||||
query: Query<ListUserBookmarksQueryData>,
|
||||
server_state: web::Data<Arc<ServerState>>
|
||||
) -> Result<HttpResponse, ListUserBookmarksForUserError>
|
||||
{
|
||||
let _maybe_user_session = server_state
|
||||
.session_checker
|
||||
.maybe_get_user_session(&http_request, &server_state.mysql_pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Session checker error: {:?}", e);
|
||||
ListUserBookmarksForUserError::ServerError
|
||||
})?;
|
||||
|
||||
let query_results = match query.maybe_scoped_entity_type {
|
||||
None => list_user_bookmarks(&path.username, &server_state.mysql_pool).await,
|
||||
Some(entity_type) =>
|
||||
list_user_user_bookmarks_by_entity_type(&path.username, entity_type, &server_state.mysql_pool)
|
||||
.await,
|
||||
};
|
||||
|
||||
let user_bookmarks = match query_results {
|
||||
let sort_ascending = query.sort_ascending.unwrap_or(false);
|
||||
let page_size = query.page_size.unwrap_or_else(|| 25);
|
||||
let page_index = query.page_index.unwrap_or_else(|| 0);
|
||||
|
||||
let query_results =
|
||||
list_user_bookmarks_by_maybe_entity_type(ListUserBookmarksForUserArgs{
|
||||
username: path.username.as_ref(),
|
||||
maybe_filter_entity_type: query.maybe_scoped_entity_type.clone(),
|
||||
sort_ascending,
|
||||
page_size,
|
||||
page_index,
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
}).await;
|
||||
|
||||
let results_page = match query_results {
|
||||
Ok(results) => results,
|
||||
Err(e) => {
|
||||
warn!("Query error: {:?}", e);
|
||||
@@ -125,7 +145,7 @@ pub async fn list_user_bookmarks_for_user_handler(
|
||||
|
||||
let response = ListUserBookmarksForUserSuccessResponse {
|
||||
success: true,
|
||||
user_bookmarks: user_bookmarks.into_iter()
|
||||
results: results_page.results.into_iter()
|
||||
.map(|user_bookmark| UserBookmarkListItem {
|
||||
token: user_bookmark.token,
|
||||
details: UserBookmarkDetailsForUserList {
|
||||
@@ -140,6 +160,10 @@ pub async fn list_user_bookmarks_for_user_handler(
|
||||
updated_at: user_bookmark.updated_at,
|
||||
})
|
||||
.collect(),
|
||||
pagination: PaginationPage{
|
||||
current: results_page.current_page,
|
||||
total_page_count: results_page.total_page_count,
|
||||
}
|
||||
};
|
||||
|
||||
let body = serde_json::to_string(&response)
|
||||
@@ -148,4 +172,4 @@ pub async fn list_user_bookmarks_for_user_handler(
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("application/json")
|
||||
.body(body))
|
||||
}
|
||||
}
|
||||
+19
-3
@@ -3,6 +3,7 @@ use std::sync::Arc;
|
||||
use actix_web::{HttpRequest, HttpResponse, ResponseError, web};
|
||||
use actix_web::http::StatusCode;
|
||||
use log::{error, info};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::by_table::user_ratings::entity_type::UserRatingEntityType;
|
||||
use enums::by_table::user_ratings::rating_value::UserRatingValue;
|
||||
@@ -19,7 +20,7 @@ use crate::server_state::ServerState;
|
||||
// =============== Request ===============
|
||||
|
||||
/// For the URL PathInfo
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct GetUserRatingPath {
|
||||
/// The type of the entity being rated.
|
||||
pub entity_type: UserRatingEntityType,
|
||||
@@ -30,7 +31,7 @@ pub struct GetUserRatingPath {
|
||||
|
||||
// =============== Success Response ===============
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct GetUserRatingResponse {
|
||||
pub success: bool,
|
||||
|
||||
@@ -41,7 +42,7 @@ pub struct GetUserRatingResponse {
|
||||
|
||||
// =============== Error Response ===============
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub enum GetUserRatingError {
|
||||
BadInput(String),
|
||||
NotAuthorized,
|
||||
@@ -71,6 +72,21 @@ impl std::fmt::Display for GetUserRatingError {
|
||||
|
||||
// =============== Handler ===============
|
||||
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/v1/user_rating/view/{entity_type}/{entity_token}",
|
||||
params(
|
||||
("entity_type", description = "The type of the entity being rated."),
|
||||
("entity_token", description = "Entity token"),
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "List User Bookmarks", body = GetUserRatingResponse),
|
||||
(status = 400, description = "Bad input", body = GetUserRatingError),
|
||||
(status = 401, description = "Not authorized", body = GetUserRatingError),
|
||||
(status = 500, description = "Server error", body = GetUserRatingError),
|
||||
),
|
||||
)]
|
||||
pub async fn get_user_rating_handler(
|
||||
http_request: HttpRequest,
|
||||
path: web::Path<GetUserRatingPath>,
|
||||
|
||||
+15
-3
@@ -3,6 +3,7 @@ use std::sync::Arc;
|
||||
use actix_web::{HttpRequest, HttpResponse, ResponseError, web};
|
||||
use actix_web::http::StatusCode;
|
||||
use log::{error, info, warn};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::by_table::user_ratings::entity_type::UserRatingEntityType;
|
||||
use enums::by_table::user_ratings::rating_value::UserRatingValue;
|
||||
@@ -22,7 +23,7 @@ use crate::server_state::ServerState;
|
||||
|
||||
// =============== Request ===============
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct SetUserRatingRequest {
|
||||
/// The type of the entity being rated.
|
||||
pub entity_type: UserRatingEntityType,
|
||||
@@ -35,14 +36,14 @@ pub struct SetUserRatingRequest {
|
||||
|
||||
// =============== Success Response ===============
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct SetUserRatingResponse {
|
||||
pub success: bool,
|
||||
}
|
||||
|
||||
// =============== Error Response ===============
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub enum SetUserRatingError {
|
||||
BadInput(String),
|
||||
NotAuthorized,
|
||||
@@ -72,6 +73,17 @@ impl std::fmt::Display for SetUserRatingError {
|
||||
|
||||
// =============== Handler ===============
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/v1/user_rating/rate",
|
||||
request_body = SetUserRatingRequest,
|
||||
responses(
|
||||
(status = 200, description = "Set user rating", body = SetUserRatingResponse),
|
||||
(status = 400, description = "Bad input", body = SetUserRatingError),
|
||||
(status = 401, description = "Not authorized", body = SetUserRatingError),
|
||||
(status = 500, description = "Server error", body = SetUserRatingError),
|
||||
),
|
||||
)]
|
||||
pub async fn set_user_rating_handler(
|
||||
http_request: HttpRequest,
|
||||
request: web::Json<SetUserRatingRequest>,
|
||||
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_multipart::Multipart;
|
||||
use actix_web::{HttpRequest, HttpResponse, web};
|
||||
use enums::by_table::model_weights::weights_category::WeightsCategory;
|
||||
use enums::by_table::model_weights::weights_types::WeightsType;
|
||||
use mysql_queries::queries::model_weights::create_weight::{self, create_weight};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
use crate::http_server::endpoints::media_uploads::common::upload_error::UploadError;
|
||||
use crate::server_state::ServerState;
|
||||
|
||||
use log::{error, info, warn};
|
||||
|
||||
use buckets::public::weight_uploads::original_file::WeightUploadOriginalFilePath;
|
||||
use enums::by_table::media_uploads::media_upload_source::MediaUploadSource;
|
||||
use enums::by_table::media_uploads::media_upload_type::MediaUploadType;
|
||||
use enums::common::visibility::Visibility;
|
||||
use hashing::sha256::sha256_hash_bytes::sha256_hash_bytes;
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use media::decode_basic_audio_info::decode_basic_audio_bytes_info;
|
||||
use mimetypes::mimetype_for_bytes::get_mimetype_for_bytes;
|
||||
use mysql_queries::queries::media_uploads::get_media_upload_by_uuid::get_media_upload_by_uuid_with_connection;
|
||||
use mysql_queries::queries::media_uploads::insert_media_upload::{Args, insert_media_upload};
|
||||
|
||||
use crate::http_server::endpoints::media_uploads::common::drain_multipart_request::{drain_multipart_request, MediaSource};
|
||||
use crate::validations::validate_idempotency_token_format::validate_idempotency_token_format;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
#[derive(Serialize,ToSchema)]
|
||||
pub struct UploadWeightsSuccessResponse {
|
||||
pub success: bool,
|
||||
pub upload_token: ModelWeightToken,
|
||||
}
|
||||
|
||||
static ALLOWED_MIME_TYPES : Lazy<HashSet<&'static str>> = Lazy::new(|| {
|
||||
HashSet::from([
|
||||
"binary/octet-stream",
|
||||
])
|
||||
});
|
||||
|
||||
// pub async fn create_weight_handler(
|
||||
// http_request: HttpRequest,
|
||||
// server_state: web::Data<Arc<ServerState>>,
|
||||
// mut multipart_payload: Multipart,
|
||||
// ) -> Result<HttpResponse, UploadError> {
|
||||
|
||||
|
||||
// let weight_upload_token = response.to_model_token();
|
||||
|
||||
// let response: UploadWeightsSuccessResponse = UploadWeightsSuccessResponse {
|
||||
// success: true,
|
||||
// upload_token: weight_upload_token,
|
||||
// };
|
||||
|
||||
// let body = serde_json::to_string(&response)
|
||||
// .map_err(|e| UploadError::ServerError)?;
|
||||
|
||||
// return Ok(HttpResponse::Ok()
|
||||
// .content_type("application/json")
|
||||
// .body(body));
|
||||
// }
|
||||
|
||||
// pub enum SuccessCase {
|
||||
// WeightAlreadyUploaded {
|
||||
// existing_upload_token: ModelWeightToken,
|
||||
// },
|
||||
// WeightSuccessfullyUploaded {
|
||||
// upload_token: ModelWeightToken,
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl SuccessCase {
|
||||
// pub fn to_model_token(self) -> ModelWeightToken {
|
||||
// match self {
|
||||
// SuccessCase::WeightAlreadyUploaded { existing_upload_token } => existing_upload_token,
|
||||
// SuccessCase::WeightSuccessfullyUploaded { upload_token } => upload_token,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// let token = create_weight(CreateModelWeightsArgs {
|
||||
// token: &ModelWeightToken::generate(),
|
||||
// weights_type: WeightsType::LoRA, // to do parse multi part for this
|
||||
// weights_category: WeightsCategory::ImageGeneration,
|
||||
// title: upload_weights_request.file_name.as_deref(),
|
||||
// maybe_thumbnail_token: &ThumbnailToken::generate(),
|
||||
// description_markdown: "",
|
||||
// description_rendered_html: "",
|
||||
// creator_user_token: maybe_user_token.as_str(),
|
||||
// creator_ip_address: &ip_address,
|
||||
// creator_set_visibility,
|
||||
// maybe_last_update_user_token: "",
|
||||
// original_download_url: "",
|
||||
// original_filename: upload_weights_request.file_name.as_deref(),
|
||||
// file_size_bytes: file_size_bytes as i32,
|
||||
// file_checksum_sha2: hash,
|
||||
// private_bucket_hash: private_bucket_hash,
|
||||
// maybe_private_bucket_prefix: None,
|
||||
// maybe_private_bucket_extension: None,
|
||||
// cached_user_ratings_total_count: 0,
|
||||
// cached_user_ratings_positive_count: 0,
|
||||
// cached_user_ratings_negative_count: 0,
|
||||
// maybe_cached_user_ratings_ratio: None,
|
||||
// version: 0,
|
||||
// mysql_pool: &server_state.mysql_pool,
|
||||
// }).await
|
||||
// .map_err(|e| {
|
||||
// error!("Error creating weights upload: {:?}", e);
|
||||
// UploadError::ServerError
|
||||
// })?;
|
||||
|
||||
// info!("new weights upload id: {} token: {:?}", record_id, &token);
|
||||
|
||||
// Ok()
|
||||
// }
|
||||
+14
-10
@@ -26,8 +26,11 @@ pub struct GetWeightResponse {
|
||||
title: String,
|
||||
weights_type: WeightsType,
|
||||
weights_category: WeightsCategory,
|
||||
maybe_thumbnail_token: Option<String>,
|
||||
|
||||
// TODO(bt,2023-12-24): Migrated the column. We should return nullables, but I don't want to break the frontend
|
||||
description_markdown: String,
|
||||
|
||||
// TODO(bt,2023-12-24): Migrated the column. We should return nullables, but I don't want to break the frontend
|
||||
description_rendered_html: String,
|
||||
|
||||
creator: UserDetailsLight,
|
||||
@@ -36,8 +39,9 @@ pub struct GetWeightResponse {
|
||||
file_size_bytes: i32,
|
||||
file_checksum_sha2: String,
|
||||
|
||||
/// If an avatar is set, this is the path to the asset.
|
||||
maybe_avatar_public_bucket_path: Option<String>,
|
||||
/// Cover images are small descriptive images that can be set for any model.
|
||||
/// If a cover image is set, this is the path to the asset.
|
||||
maybe_cover_image_public_bucket_path: Option<String>,
|
||||
|
||||
cached_user_ratings_negative_count: u32,
|
||||
cached_user_ratings_positive_count: u32,
|
||||
@@ -144,13 +148,13 @@ pub async fn get_weight_handler(
|
||||
return Err(GetWeightError::NotAuthorized);
|
||||
}
|
||||
|
||||
let maybe_avatar = weight.maybe_avatar_public_bucket_hash
|
||||
let maybe_cover_image = weight.maybe_cover_image_public_bucket_hash
|
||||
.as_deref()
|
||||
.map(|hash| {
|
||||
MediaFileBucketPath::from_object_hash(
|
||||
hash,
|
||||
weight.maybe_public_bucket_prefix.as_deref(),
|
||||
weight.maybe_public_bucket_extension.as_deref())
|
||||
weight.maybe_cover_image_public_bucket_prefix.as_deref(),
|
||||
weight.maybe_cover_image_public_bucket_extension.as_deref())
|
||||
.get_full_object_path_str()
|
||||
.to_string()
|
||||
});
|
||||
@@ -168,10 +172,10 @@ pub async fn get_weight_handler(
|
||||
title: weight.title,
|
||||
weights_type: weight.weights_type,
|
||||
weights_category: weight.weights_category,
|
||||
maybe_thumbnail_token: weight.maybe_thumbnail_token,
|
||||
description_markdown: weight.description_markdown,
|
||||
description_rendered_html: weight.description_rendered_html,
|
||||
maybe_avatar_public_bucket_path: maybe_avatar,
|
||||
// TODO(bt,2023-12-24): Migrated the column. We should return nullable fields, but I don't want to break the frontend
|
||||
description_markdown: weight.maybe_description_markdown.unwrap_or_else(|| "".to_string()),
|
||||
description_rendered_html: weight.maybe_description_rendered_html.unwrap_or_else(|| "".to_string()),
|
||||
maybe_cover_image_public_bucket_path: maybe_cover_image,
|
||||
creator,
|
||||
creator_set_visibility: weight.creator_set_visibility,
|
||||
file_size_bytes: weight.file_size_bytes,
|
||||
|
||||
+84
-52
@@ -6,7 +6,7 @@ use actix_web::http::StatusCode;
|
||||
use chrono::{DateTime, Utc};
|
||||
use log::{info, warn};
|
||||
use rand::Rng;
|
||||
use utoipa::ToSchema;
|
||||
use buckets::public::media_files::bucket_file_path::MediaFileBucketPath;
|
||||
|
||||
use enums::by_table::model_weights::{
|
||||
weights_category::WeightsCategory,
|
||||
@@ -16,27 +16,32 @@ use enums::common::visibility::Visibility;
|
||||
use mysql_queries::queries::model_weights::list::list_weights_query_builder::ListWeightsQueryBuilder;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
use crate::http_server::common_responses::user_details_lite::UserDetailsLight;
|
||||
|
||||
use crate::server_state::ServerState;
|
||||
|
||||
|
||||
|
||||
use utoipa::ToSchema;
|
||||
use crate::http_server::common_responses::pagination_cursors::PaginationCursors;
|
||||
|
||||
|
||||
#[derive(Deserialize,ToSchema)]
|
||||
pub struct ListAvailableWeightsQuery {
|
||||
pub sort_ascending: Option<bool>,
|
||||
pub page_size: u16,
|
||||
pub page_index : u16,
|
||||
pub page_size: Option<u16>,
|
||||
pub username: Option<String>,
|
||||
pub weights_type: Option<String>,
|
||||
pub weights_category: Option<String>,
|
||||
pub cursor_is_reversed: Option<bool>,
|
||||
pub cursor: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize,ToSchema)]
|
||||
pub struct ListAvailableWeightsSuccessResponse {
|
||||
pub success: bool,
|
||||
pub weights: Vec<ModelWeightForList>,
|
||||
pub page_size: u16,
|
||||
pub page_index : u16,
|
||||
pub cursor_next: Option<String>,
|
||||
pub cursor_previous: Option<String>,
|
||||
pub results: Vec<ModelWeightForList>,
|
||||
pub pagination: PaginationCursors,
|
||||
}
|
||||
|
||||
#[derive(Serialize,ToSchema)]
|
||||
@@ -48,12 +53,16 @@ pub struct ModelWeightForList {
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
// TODO(bt,2023-12-24): These aren't really appropriate for a list endpoint.
|
||||
// Hopefully we don't break the frontend by omitting these.
|
||||
//pub description_markdown: String,
|
||||
//pub description_rendered_html: String,
|
||||
|
||||
pub description_markdown: String,
|
||||
pub description_rendered_html: String,
|
||||
/// Cover images are small descriptive images that can be set for any model.
|
||||
/// If a cover image is set, this is the path to the asset.
|
||||
pub maybe_cover_image_public_bucket_path: Option<String>,
|
||||
|
||||
pub creator_user_token: UserToken,
|
||||
pub creator: UserDetailsLight,
|
||||
pub creator_set_visibility: Visibility,
|
||||
|
||||
pub file_size_bytes: i32,
|
||||
@@ -64,8 +73,6 @@ pub struct ModelWeightForList {
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
pub maybe_cached_user_ratings_ratio: Option<f32>,
|
||||
|
||||
pub version: i32,
|
||||
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
|
||||
@@ -125,20 +132,28 @@ pub async fn list_available_weights_handler(
|
||||
})?;
|
||||
|
||||
let mut is_mod = false;
|
||||
let user_session = match maybe_user_session {
|
||||
match maybe_user_session {
|
||||
None => {},
|
||||
Some(session) => {
|
||||
is_mod = session.can_ban_users;
|
||||
session
|
||||
}
|
||||
None => {
|
||||
info!("not logged in");
|
||||
return Err(ListWeightError::NotAuthorized);
|
||||
}
|
||||
};
|
||||
|
||||
let limit = query.page_size;
|
||||
let limit = query.page_size.unwrap_or(25);
|
||||
|
||||
let sort_ascending = query.sort_ascending.unwrap_or(false);
|
||||
let cursor_is_reversed = query.cursor_is_reversed.unwrap_or(false);
|
||||
|
||||
let cursor = if let Some(cursor) = query.cursor.as_deref() {
|
||||
let cursor = server_state.sort_key_crypto.decrypt_id(cursor)
|
||||
.map_err(|e| {
|
||||
warn!("crypto error: {:?}", e);
|
||||
ListWeightError::ServerError
|
||||
})?;
|
||||
Some(cursor)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let include_user_hidden = is_mod;
|
||||
|
||||
@@ -173,6 +188,7 @@ pub async fn list_available_weights_handler(
|
||||
|
||||
let mut query_builder = ListWeightsQueryBuilder::new()
|
||||
.sort_ascending(sort_ascending)
|
||||
.cursor_is_reversed(cursor_is_reversed)
|
||||
.weights_category(weights_category)
|
||||
.weights_type(weights_type)
|
||||
.scope_creator_username(None)
|
||||
@@ -180,7 +196,7 @@ pub async fn list_available_weights_handler(
|
||||
.include_user_deleted_results(is_mod)
|
||||
.include_mod_deleted_results(is_mod)
|
||||
.limit(limit)
|
||||
.offset(Some((query.page_index as u64) * (query.page_size as u64)));
|
||||
.offset(cursor);
|
||||
|
||||
let query_results = query_builder.perform_query_for_page(&server_state.mysql_pool).await;
|
||||
|
||||
@@ -221,45 +237,61 @@ pub async fn list_available_weights_handler(
|
||||
// generate parse a response
|
||||
let response = ListAvailableWeightsSuccessResponse {
|
||||
success: true,
|
||||
weights: weights_page.weights.into_iter()
|
||||
.map(|weights| ModelWeightForList {
|
||||
weight_token: weights.token,
|
||||
title: weights.title,
|
||||
weights_type: weights.weights_type,
|
||||
weights_category: weights.weights_category,
|
||||
results: weights_page.weights.into_iter()
|
||||
.map(|weight| {
|
||||
|
||||
maybe_thumbnail_token:weights.maybe_thumbnail_token,
|
||||
description_markdown: weights.description_markdown,
|
||||
description_rendered_html: weights.description_rendered_html,
|
||||
let maybe_cover_image = weight.maybe_cover_image_public_bucket_hash
|
||||
.as_deref()
|
||||
.map(|hash| {
|
||||
MediaFileBucketPath::from_object_hash(
|
||||
hash,
|
||||
weight.maybe_cover_image_public_bucket_prefix.as_deref(),
|
||||
weight.maybe_cover_image_public_bucket_extension.as_deref())
|
||||
.get_full_object_path_str()
|
||||
.to_string()
|
||||
});
|
||||
|
||||
creator_user_token: weights.creator_user_token,
|
||||
creator_set_visibility: weights.creator_set_visibility,
|
||||
ModelWeightForList {
|
||||
weight_token: weight.token,
|
||||
title: weight.title,
|
||||
weights_type: weight.weights_type,
|
||||
weights_category: weight.weights_category,
|
||||
|
||||
file_size_bytes:weights.file_size_bytes,
|
||||
file_checksum_sha2: weights.file_checksum_sha2,
|
||||
maybe_cover_image_public_bucket_path: maybe_cover_image,
|
||||
|
||||
cached_user_ratings_total_count: weights.cached_user_ratings_total_count,
|
||||
cached_user_ratings_positive_count: weights.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_negative_count: weights.cached_user_ratings_negative_count,
|
||||
maybe_cached_user_ratings_ratio: weights.maybe_cached_user_ratings_ratio,
|
||||
creator: UserDetailsLight::from_db_fields(
|
||||
&weight.creator_user_token,
|
||||
&weight.creator_username,
|
||||
&weight.creator_display_name,
|
||||
&weight.creator_email_gravatar_hash
|
||||
),
|
||||
creator_set_visibility: weight.creator_set_visibility,
|
||||
|
||||
version: weights.version,
|
||||
file_size_bytes: weight.file_size_bytes,
|
||||
file_checksum_sha2: weight.file_checksum_sha2,
|
||||
|
||||
created_at: weights.created_at,
|
||||
updated_at: weights.updated_at,
|
||||
cached_user_ratings_total_count: weight.cached_user_ratings_total_count,
|
||||
cached_user_ratings_positive_count: weight.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_negative_count: weight.cached_user_ratings_negative_count,
|
||||
maybe_cached_user_ratings_ratio: weight.maybe_cached_user_ratings_ratio,
|
||||
|
||||
creator_username: weights.creator_username,
|
||||
creator_display_name: weights.creator_display_name,
|
||||
creator_email_gravatar_hash: weights.creator_email_gravatar_hash,
|
||||
created_at: weight.created_at,
|
||||
updated_at: weight.updated_at,
|
||||
|
||||
// TODO: FIX THIS when we align again.
|
||||
bookmarks: random_bool,
|
||||
likes: rng.gen_range(0..1000),
|
||||
creator_username: weight.creator_username,
|
||||
creator_display_name: weight.creator_display_name,
|
||||
creator_email_gravatar_hash: weight.creator_email_gravatar_hash,
|
||||
|
||||
// TODO: FIX THIS when we align again.
|
||||
bookmarks: random_bool,
|
||||
likes: rng.gen_range(0..1000),
|
||||
}
|
||||
}).collect::<Vec<_>>(),
|
||||
cursor_next,
|
||||
cursor_previous,
|
||||
page_index: query.page_index,
|
||||
page_size: query.page_size
|
||||
pagination: PaginationCursors {
|
||||
maybe_next: cursor_next,
|
||||
maybe_previous: cursor_previous,
|
||||
cursor_is_reversed,
|
||||
},
|
||||
};
|
||||
|
||||
let body = serde_json::to_string(&response)
|
||||
|
||||
+37
-20
@@ -7,6 +7,7 @@ use chrono::{DateTime, Utc};
|
||||
use log::{debug, error, warn};
|
||||
use r2d2_redis::redis::Commands;
|
||||
use utoipa::ToSchema;
|
||||
use buckets::public::media_files::bucket_file_path::MediaFileBucketPath;
|
||||
|
||||
use enums::by_table::model_weights::{
|
||||
weights_category::WeightsCategory,
|
||||
@@ -33,10 +34,12 @@ pub struct ModelWeightForList {
|
||||
|
||||
pub title: String,
|
||||
|
||||
pub maybe_thumbnail_token: Option<String>,
|
||||
|
||||
pub creator: UserDetailsLight,
|
||||
|
||||
/// Cover images are small descriptive images that can be set for any model.
|
||||
/// If a cover image is set, this is the path to the asset.
|
||||
pub maybe_cover_image_public_bucket_path: Option<String>,
|
||||
|
||||
pub cached_user_ratings_total_count: u32,
|
||||
pub cached_user_ratings_positive_count: u32,
|
||||
pub cached_user_ratings_negative_count: u32,
|
||||
@@ -125,24 +128,38 @@ pub async fn list_featured_weights_handler(
|
||||
let response = ListFeaturedWeightsSuccessResponse {
|
||||
success: true,
|
||||
weights: weights.into_iter()
|
||||
.map(|w| ModelWeightForList {
|
||||
weight_token: w.token,
|
||||
title: w.title,
|
||||
weights_type: w.weights_type,
|
||||
weights_category: w.weights_category,
|
||||
maybe_thumbnail_token: w.maybe_thumbnail_token,
|
||||
creator: UserDetailsLight::from_db_fields(
|
||||
&w.creator_user_token,
|
||||
&w.creator_username,
|
||||
&w.creator_display_name,
|
||||
&w.creator_email_gravatar_hash
|
||||
),
|
||||
cached_user_ratings_total_count: w.cached_user_ratings_total_count,
|
||||
cached_user_ratings_positive_count: w.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_negative_count: w.cached_user_ratings_negative_count,
|
||||
maybe_cached_user_ratings_ratio: w.maybe_cached_user_ratings_ratio,
|
||||
created_at: w.created_at,
|
||||
updated_at: w.updated_at,
|
||||
.map(|w| {
|
||||
|
||||
let maybe_cover_image = w.maybe_cover_image_public_bucket_hash
|
||||
.as_deref()
|
||||
.map(|hash| {
|
||||
MediaFileBucketPath::from_object_hash(
|
||||
hash,
|
||||
w.maybe_cover_image_public_bucket_prefix.as_deref(),
|
||||
w.maybe_cover_image_public_bucket_extension.as_deref())
|
||||
.get_full_object_path_str()
|
||||
.to_string()
|
||||
});
|
||||
|
||||
ModelWeightForList {
|
||||
weight_token: w.token,
|
||||
title: w.title,
|
||||
weights_type: w.weights_type,
|
||||
weights_category: w.weights_category,
|
||||
maybe_cover_image_public_bucket_path: maybe_cover_image,
|
||||
creator: UserDetailsLight::from_db_fields(
|
||||
&w.creator_user_token,
|
||||
&w.creator_username,
|
||||
&w.creator_display_name,
|
||||
&w.creator_email_gravatar_hash
|
||||
),
|
||||
cached_user_ratings_total_count: w.cached_user_ratings_total_count,
|
||||
cached_user_ratings_positive_count: w.cached_user_ratings_positive_count,
|
||||
cached_user_ratings_negative_count: w.cached_user_ratings_negative_count,
|
||||
maybe_cached_user_ratings_ratio: w.maybe_cached_user_ratings_ratio,
|
||||
created_at: w.created_at,
|
||||
updated_at: w.updated_at,
|
||||
}
|
||||
}).collect::<Vec<_>>(),
|
||||
};
|
||||
|
||||
|
||||
+47
-30
@@ -8,6 +8,8 @@ use actix_web::web::{Path, Query};
|
||||
use chrono::{DateTime, Utc};
|
||||
use log::warn;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
use buckets::public::media_files::bucket_file_path::MediaFileBucketPath;
|
||||
use enums::common::view_as::ViewAs;
|
||||
|
||||
use enums::common::visibility::Visibility;
|
||||
use mysql_queries::queries::model_weights::list::list_weights_by_user::{list_weights_by_creator_username, ListWeightsForUserArgs};
|
||||
@@ -26,16 +28,22 @@ pub struct Weight {
|
||||
creator: UserDetailsLight,
|
||||
creator_set_visibility: Visibility,
|
||||
|
||||
maybe_thumbnail_token: Option<String>,
|
||||
|
||||
description_markdown: String,
|
||||
description_rendered_html: String,
|
||||
// TODO(bt,2023-12-24): These aren't really appropriate for a list endpoint.
|
||||
// Hopefully we don't break the frontend by omitting these.
|
||||
//description_markdown: String,
|
||||
//description_rendered_html: String,
|
||||
|
||||
file_size_bytes: i32,
|
||||
file_checksum_sha2: String,
|
||||
|
||||
/// Cover images are small descriptive images that can be set for any model.
|
||||
/// If a cover image is set, this is the path to the asset.
|
||||
maybe_cover_image_public_bucket_path: Option<String>,
|
||||
|
||||
cached_user_ratings_total_count: u32,
|
||||
cached_user_ratings_positive_count: u32,
|
||||
cached_user_ratings_negative_count: u32,
|
||||
|
||||
maybe_cached_user_ratings_ratio: Option<f32>,
|
||||
cached_user_ratings_last_updated_at: DateTime<Utc>,
|
||||
|
||||
@@ -112,17 +120,27 @@ pub async fn list_weights_by_user_handler(
|
||||
ListWeightsByUserError::ServerError
|
||||
})?;
|
||||
|
||||
let user_session = match maybe_user_session {
|
||||
Some(session) => session,
|
||||
None => {
|
||||
warn!("not logged in");
|
||||
return Err(ListWeightsByUserError::NotAuthorized);
|
||||
}
|
||||
let mut is_author = false;
|
||||
let mut is_mod = false;
|
||||
|
||||
match maybe_user_session {
|
||||
None => {},
|
||||
Some(session) => {
|
||||
is_author = session.username == path.username;
|
||||
is_mod = session.can_ban_users;
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
let view_as = if is_author {
|
||||
ViewAs::Author
|
||||
} else if is_mod {
|
||||
ViewAs::Moderator
|
||||
} else {
|
||||
ViewAs::AnotherUser
|
||||
};
|
||||
|
||||
let username = path.username.as_ref();
|
||||
let creator_user_token = user_session.user_token.clone();
|
||||
let is_mod = user_session.can_ban_users;
|
||||
let limit = query.page_size.unwrap_or(25);
|
||||
let sort_ascending = query.sort_ascending.unwrap_or(false);
|
||||
let page_size = query.page_size.unwrap_or_else(|| 25);
|
||||
@@ -133,8 +151,8 @@ pub async fn list_weights_by_user_handler(
|
||||
creator_username: username,
|
||||
page_size,
|
||||
page_index,
|
||||
can_see_deleted: is_mod,
|
||||
sort_ascending,
|
||||
view_as,
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
}
|
||||
).await.map_err(|e| {
|
||||
@@ -151,6 +169,18 @@ pub async fn list_weights_by_user_handler(
|
||||
};
|
||||
|
||||
let weights:Vec<Weight> = results_page.records.into_iter().map(|weight| {
|
||||
|
||||
let maybe_cover_image = weight.maybe_cover_image_public_bucket_hash
|
||||
.as_deref()
|
||||
.map(|hash| {
|
||||
MediaFileBucketPath::from_object_hash(
|
||||
hash,
|
||||
weight.maybe_cover_image_public_bucket_prefix.as_deref(),
|
||||
weight.maybe_cover_image_public_bucket_extension.as_deref())
|
||||
.get_full_object_path_str()
|
||||
.to_string()
|
||||
});
|
||||
|
||||
Weight {
|
||||
weight_token: weight.token,
|
||||
title: weight.title,
|
||||
@@ -162,9 +192,9 @@ pub async fn list_weights_by_user_handler(
|
||||
&weight.creator_display_name,
|
||||
&weight.creator_email_gravatar_hash,
|
||||
),
|
||||
maybe_thumbnail_token: weight.maybe_thumbnail_token,
|
||||
description_markdown: weight.description_markdown,
|
||||
description_rendered_html: weight.description_rendered_html,
|
||||
maybe_cover_image_public_bucket_path: maybe_cover_image,
|
||||
//description_markdown: weight.maybe_description_markdown,
|
||||
//description_rendered_html: weight.maybe_description_rendered_html,
|
||||
file_size_bytes: weight.file_size_bytes,
|
||||
file_checksum_sha2: weight.file_checksum_sha2,
|
||||
cached_user_ratings_total_count: weight.cached_user_ratings_total_count,
|
||||
@@ -178,23 +208,10 @@ pub async fn list_weights_by_user_handler(
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let final_weights:Vec<Weight>;
|
||||
|
||||
// if it's not the user ... then only show public weights else show private and public
|
||||
if creator_user_token != user_session.user_token {
|
||||
final_weights = weights.into_iter().filter(|weight| {
|
||||
weight.creator_set_visibility == Visibility::Public
|
||||
}).collect();
|
||||
|
||||
}
|
||||
else {
|
||||
final_weights = weights;
|
||||
}
|
||||
|
||||
|
||||
let response: ListWeightsByUserSuccessResponse = ListWeightsByUserSuccessResponse {
|
||||
success: true,
|
||||
results: final_weights,
|
||||
results: weights,
|
||||
pagination: PaginationPage {
|
||||
current: results_page.current_page,
|
||||
total_page_count: results_page.total_page_count,
|
||||
|
||||
@@ -3,7 +3,5 @@ pub mod get_weight;
|
||||
pub mod list_available_weights;
|
||||
pub mod list_featured_weights;
|
||||
pub mod list_weights_by_user;
|
||||
pub mod set_model_weight_avatar;
|
||||
pub mod update_weight;
|
||||
// pub mod create_weight; this is a private api call internally
|
||||
// pub mod drain_multipart_weights_request;
|
||||
pub mod set_model_weight_cover_image;
|
||||
pub mod update_weight;
|
||||
+49
-34
@@ -6,6 +6,7 @@ use actix_web::error::ResponseError;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::web::Path;
|
||||
use log::warn;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::common::visibility::Visibility;
|
||||
@@ -13,46 +14,46 @@ use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use http_server_common::response::response_success_helpers::simple_json_success;
|
||||
use http_server_common::response::serialize_as_json_error::serialize_as_json_error;
|
||||
use mysql_queries::queries::media_files::get_media_file::get_media_file;
|
||||
use mysql_queries::queries::model_weights::edit::set_model_weight_avatar::{set_model_weight_avatar, UpdateArgs};
|
||||
use mysql_queries::queries::model_weights::edit::set_model_weight_cover_image::{set_model_weight_cover_image, UpdateArgs};
|
||||
use mysql_queries::queries::model_weights::get_weight::get_weight_by_token;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
|
||||
use crate::server_state::ServerState;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct SetModelWeightAvatarRequest {
|
||||
pub avatar_media_file_token: Option<MediaFileToken>,
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct SetModelWeightCoverImageRequest {
|
||||
pub cover_image_media_file_token: Option<MediaFileToken>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SetModelWeightAvatarResponse {
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct SetModelWeightCoverImageResponse {
|
||||
pub success: bool,
|
||||
}
|
||||
|
||||
/// For the URL PathInfo
|
||||
#[derive(Deserialize)]
|
||||
pub struct SetModelWeightAvatarPathInfo {
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct SetModelWeightCoverImagePathInfo {
|
||||
token: ModelWeightToken,
|
||||
}
|
||||
|
||||
// =============== Error Response ===============
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum SetModelWeightAvatarError {
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub enum SetModelWeightCoverImageError {
|
||||
BadInput(String),
|
||||
NotFound,
|
||||
NotAuthorized,
|
||||
ServerError,
|
||||
}
|
||||
|
||||
impl ResponseError for SetModelWeightAvatarError {
|
||||
impl ResponseError for SetModelWeightCoverImageError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match *self {
|
||||
SetModelWeightAvatarError::BadInput(_) => StatusCode::BAD_REQUEST,
|
||||
SetModelWeightAvatarError::NotFound => StatusCode::NOT_FOUND,
|
||||
SetModelWeightAvatarError::NotAuthorized => StatusCode::UNAUTHORIZED,
|
||||
SetModelWeightAvatarError::ServerError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
SetModelWeightCoverImageError::BadInput(_) => StatusCode::BAD_REQUEST,
|
||||
SetModelWeightCoverImageError::NotFound => StatusCode::NOT_FOUND,
|
||||
SetModelWeightCoverImageError::NotAuthorized => StatusCode::UNAUTHORIZED,
|
||||
SetModelWeightCoverImageError::ServerError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ impl ResponseError for SetModelWeightAvatarError {
|
||||
}
|
||||
|
||||
// NB: Not using derive_more::Display since Clion doesn't understand it.
|
||||
impl fmt::Display for SetModelWeightAvatarError {
|
||||
impl fmt::Display for SetModelWeightCoverImageError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
@@ -70,11 +71,25 @@ impl fmt::Display for SetModelWeightAvatarError {
|
||||
|
||||
// =============== Handler ===============
|
||||
|
||||
pub async fn set_model_weight_avatar_handler(
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/v1/weights/weight/{weight_token}/cover_image",
|
||||
responses(
|
||||
(status = 200, description = "Success Update", body = SetModelWeightCoverImageResponse),
|
||||
(status = 400, description = "Bad input", body = SetModelWeightCoverImageError),
|
||||
(status = 401, description = "Not authorized", body = SetModelWeightCoverImageError),
|
||||
(status = 500, description = "Server error", body = SetModelWeightCoverImageError),
|
||||
),
|
||||
params(
|
||||
("request" = SetModelWeightCoverImageRequest, description = "Payload for Request"),
|
||||
("path" = SetModelWeightCoverImagePathInfo, description = "Path for Request")
|
||||
)
|
||||
)]
|
||||
pub async fn set_model_weight_cover_image_handler(
|
||||
http_request: HttpRequest,
|
||||
path: Path<SetModelWeightAvatarPathInfo>,
|
||||
request: web::Json<SetModelWeightAvatarRequest>,
|
||||
server_state: web::Data<Arc<ServerState>>) -> Result<HttpResponse, SetModelWeightAvatarError>
|
||||
path: Path<SetModelWeightCoverImagePathInfo>,
|
||||
request: web::Json<SetModelWeightCoverImageRequest>,
|
||||
server_state: web::Data<Arc<ServerState>>) -> Result<HttpResponse, SetModelWeightCoverImageError>
|
||||
{
|
||||
let maybe_user_session = server_state
|
||||
.session_checker
|
||||
@@ -82,14 +97,14 @@ pub async fn set_model_weight_avatar_handler(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Session checker error: {:?}", e);
|
||||
SetModelWeightAvatarError::ServerError
|
||||
SetModelWeightCoverImageError::ServerError
|
||||
})?;
|
||||
|
||||
let user_session = match maybe_user_session {
|
||||
Some(session) => session,
|
||||
None => {
|
||||
warn!("not logged in");
|
||||
return Err(SetModelWeightAvatarError::NotAuthorized);
|
||||
return Err(SetModelWeightCoverImageError::NotAuthorized);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,11 +122,11 @@ pub async fn set_model_weight_avatar_handler(
|
||||
Ok(Some(model_weight)) => model_weight,
|
||||
Ok(None) => {
|
||||
warn!("Model weight not found: {:?}", &path.token);
|
||||
return Err(SetModelWeightAvatarError::NotFound);
|
||||
return Err(SetModelWeightCoverImageError::NotFound);
|
||||
},
|
||||
Err(err) => {
|
||||
warn!("Error looking up model_weights : {:?}", err);
|
||||
return Err(SetModelWeightAvatarError::ServerError);
|
||||
return Err(SetModelWeightCoverImageError::ServerError);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -119,18 +134,18 @@ pub async fn set_model_weight_avatar_handler(
|
||||
|
||||
if !is_creator && !is_mod {
|
||||
warn!("user is not allowed to edit this media_file: {}", user_session.user_token);
|
||||
return Err(SetModelWeightAvatarError::NotAuthorized);
|
||||
return Err(SetModelWeightCoverImageError::NotAuthorized);
|
||||
}
|
||||
|
||||
let mut maybe_set_media_file_token = None;
|
||||
|
||||
let delete_avatar = request.avatar_media_file_token
|
||||
let delete_cover_image = request.cover_image_media_file_token
|
||||
.as_ref()
|
||||
.map(|token| token.as_str().trim().is_empty())
|
||||
.unwrap_or(true);
|
||||
|
||||
if !delete_avatar {
|
||||
if let Some(media_file_token) = &request.avatar_media_file_token {
|
||||
if !delete_cover_image {
|
||||
if let Some(media_file_token) = &request.cover_image_media_file_token {
|
||||
let media_file_lookup_result = get_media_file(
|
||||
&media_file_token,
|
||||
false,
|
||||
@@ -141,17 +156,17 @@ pub async fn set_model_weight_avatar_handler(
|
||||
Ok(Some(model_weight)) => model_weight,
|
||||
Ok(None) => {
|
||||
warn!("Media file not found: {:?}", media_file_token);
|
||||
return Err(SetModelWeightAvatarError::NotFound);
|
||||
return Err(SetModelWeightCoverImageError::NotFound);
|
||||
},
|
||||
Err(err) => {
|
||||
warn!("Error looking up model_weights : {:?}", err);
|
||||
return Err(SetModelWeightAvatarError::ServerError);
|
||||
return Err(SetModelWeightCoverImageError::ServerError);
|
||||
}
|
||||
};
|
||||
|
||||
if media_file.creator_set_visibility != Visibility::Public
|
||||
|| media_file.media_type != MediaFileType::Image {
|
||||
return Err(SetModelWeightAvatarError::BadInput("Invalid media file token.".to_string()));
|
||||
return Err(SetModelWeightCoverImageError::BadInput("Invalid media file token.".to_string()));
|
||||
}
|
||||
|
||||
maybe_set_media_file_token = Some(media_file.token);
|
||||
@@ -161,9 +176,9 @@ pub async fn set_model_weight_avatar_handler(
|
||||
// TODO(bt,2023-12-21): DB needs a column, or we need an ip audit log
|
||||
let _ip_address = get_request_ip(&http_request);
|
||||
|
||||
let query_result = set_model_weight_avatar(UpdateArgs {
|
||||
let query_result = set_model_weight_cover_image(UpdateArgs {
|
||||
model_weight_token: &path.token,
|
||||
maybe_avatar_media_file_token: maybe_set_media_file_token.as_ref(),
|
||||
maybe_cover_image_media_file_token: maybe_set_media_file_token.as_ref(),
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
}).await;
|
||||
|
||||
@@ -171,7 +186,7 @@ pub async fn set_model_weight_avatar_handler(
|
||||
Ok(_) => {},
|
||||
Err(err) => {
|
||||
warn!("Update MediaFile DB error: {:?}", err);
|
||||
return Err(SetModelWeightAvatarError::ServerError);
|
||||
return Err(SetModelWeightCoverImageError::ServerError);
|
||||
}
|
||||
};
|
||||
|
||||
+34
-9
@@ -1,27 +1,31 @@
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::{ HttpRequest, HttpResponse, web };
|
||||
use actix_web::{HttpRequest, HttpResponse, web};
|
||||
use actix_web::error::ResponseError;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::web::Path;
|
||||
use log::{ error, warn };
|
||||
use log::warn;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::common::visibility::Visibility;
|
||||
use http_server_common::response::response_success_helpers::simple_json_success;
|
||||
use http_server_common::response::serialize_as_json_error::serialize_as_json_error;
|
||||
use mysql_queries::queries::model_weights::edit::update_weight::{update_weights, UpdateWeightArgs};
|
||||
use mysql_queries::queries::model_weights::get_weight::get_weight_by_token;
|
||||
use mysql_queries::queries::model_weights::edit::update_weight::{ update_weights, UpdateWeightArgs };
|
||||
use tokens::tokens::model_weights::ModelWeightToken;
|
||||
use user_input_common::check_for_slurs::contains_slurs;
|
||||
use user_input_common::markdown_to_html::markdown_to_html;
|
||||
|
||||
use crate::server_state::ServerState;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// TODO will eventually be polymorphic
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct UpdateWeightRequest {
|
||||
pub title: Option<String>,
|
||||
pub thumbnail_token: Option<String>,
|
||||
pub description_markdown: Option<String>,
|
||||
// KS: We should probably remove this
|
||||
// Users have to update markdown, not html directly
|
||||
pub description_rendered_html: Option<String>,
|
||||
pub weight_type: Option<String>,
|
||||
pub weight_category: Option<String>,
|
||||
@@ -139,13 +143,34 @@ pub async fn update_weight_handler(
|
||||
return Err(UpdateWeightError::NotAuthorized);
|
||||
}
|
||||
|
||||
let mut weight_title = None;
|
||||
let mut description_markdown = None;
|
||||
let mut description_rendered_html = None;
|
||||
|
||||
|
||||
if let Some(title) = &request.title {
|
||||
if (contains_slurs(title)) {
|
||||
return Err(UpdateWeightError::BadInput("Title contains slurs".to_string()));
|
||||
}
|
||||
weight_title = Some(title.trim().to_string());
|
||||
}
|
||||
|
||||
if let Some(markdown) = &request.description_markdown {
|
||||
if (contains_slurs(markdown)) {
|
||||
return Err(UpdateWeightError::BadInput("Description contains slurs".to_string()));
|
||||
}
|
||||
let markdown = markdown.trim().to_string();
|
||||
let html = markdown_to_html(&markdown);
|
||||
description_markdown = Some(markdown);
|
||||
description_rendered_html = Some(html);
|
||||
}
|
||||
|
||||
let query_result = update_weights(UpdateWeightArgs {
|
||||
weight_token: &ModelWeightToken::new(path.weight_token.clone()),
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
title: request.title.as_deref(),
|
||||
maybe_thumbnail_token: request.thumbnail_token.as_deref(),
|
||||
description_markdown: request.description_markdown.as_deref(),
|
||||
description_rendered_html: request.description_rendered_html.as_deref(),
|
||||
title: weight_title.as_deref(),
|
||||
maybe_description_markdown: description_markdown.as_deref(),
|
||||
maybe_description_rendered_html: description_rendered_html.as_deref(),
|
||||
creator_set_visibility: request.visibility.as_ref(),
|
||||
weights_type: request.weight_type.as_deref().map(|s| s.to_string()),
|
||||
weights_category: request.weight_category.as_deref().map(|s| s.to_string()),
|
||||
|
||||
@@ -160,7 +160,7 @@ use crate::http_server::endpoints::weights::get_weight::get_weight_handler;
|
||||
use crate::http_server::endpoints::weights::list_available_weights::list_available_weights_handler;
|
||||
use crate::http_server::endpoints::weights::list_featured_weights::list_featured_weights_handler;
|
||||
use crate::http_server::endpoints::weights::list_weights_by_user::list_weights_by_user_handler;
|
||||
use crate::http_server::endpoints::weights::set_model_weight_avatar::set_model_weight_avatar_handler;
|
||||
use crate::http_server::endpoints::weights::set_model_weight_cover_image::set_model_weight_cover_image_handler;
|
||||
use crate::http_server::endpoints::weights::update_weight::update_weight_handler;
|
||||
|
||||
pub fn add_routes<T, B> (app: App<T>, server_environment: ServerEnvironment) -> App<T>
|
||||
@@ -1278,8 +1278,8 @@ fn add_weights_routes<T, B>(app: App<T>) -> App<T>
|
||||
.route(web::post().to(update_weight_handler))
|
||||
.route(web::delete().to(delete_weight_handler))
|
||||
)
|
||||
.service(web::resource("/weight/{token}/avatar")
|
||||
.route(web::post().to(set_model_weight_avatar_handler))
|
||||
.service(web::resource("/weight/{token}/cover_image")
|
||||
.route(web::post().to(set_model_weight_cover_image_handler))
|
||||
)
|
||||
.route("/by_user/{username}", web::get().to(list_weights_by_user_handler))
|
||||
.route("/list", web::get().to(list_available_weights_handler))
|
||||
|
||||
Reference in New Issue
Block a user