mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-22 01:29:31 -04:00
Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37c446185e | ||
|
|
1dfb62454a | ||
|
|
87f35f3e6f | ||
|
|
df0a82cbdb | ||
|
|
c5071d4f2e | ||
|
|
57c77cbbc2 | ||
|
|
98c4fad729 | ||
|
|
f50bfa9ee7 | ||
|
|
d90d446643 | ||
|
|
c4d188a600 | ||
|
|
1d5d63fda1 | ||
|
|
6af5cc7d0b | ||
|
|
a7cd9f3b2f |
+223
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.id as `id: u64`,\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.maybe_project_type as `project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.maybe_title,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m FORCE INDEX (fk_maybe_creator_user_token)\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nWHERE\n m.maybe_creator_user_token = ?\n AND m.media_class = 'project'\n AND m.maybe_project_type IS NOT NULL\n AND m.maybe_project_type = ?\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n AND NOT m.is_intermediate_system_file\n AND m.id > ?\nORDER BY m.id ASC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "media_class: enums::by_table::media_files::media_file_class::MediaFileClass",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "media_type: enums::by_table::media_files::media_file_type::MediaFileType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "11cc7b91730784e9e8c8f073aeaf51a1f1660584e379b9a5be3aea370d84f692"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n INSERT INTO media_files\n SET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n is_user_upload = ?,\n is_intermediate_system_file = ?,\n\n origin_category = ?, \n origin_product_category = ?, \n maybe_origin_model_type = ?, \n maybe_origin_model_token = ?, \n maybe_origin_filename = ?,\n\n maybe_batch_token = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n maybe_duration_millis = ?,\n maybe_audio_encoding = ?, \n maybe_video_encoding = ?, \n maybe_frame_width = ?, \n maybe_frame_height = ?,\n maybe_prompt_token = ?,\n checksum_sha2 = ?,\n \n maybe_engine_category = ?,\n\n maybe_title = ?,\n maybe_text_transcript = ?,\n\n maybe_scene_source_media_file_token = ?,\n\n public_bucket_directory_hash = ?, \n maybe_public_bucket_prefix = ?, \n maybe_public_bucket_extension = ?, \n\n maybe_creator_user_token = ?, \n maybe_creator_anonymous_visitor_token = ?, \n\n creator_ip_address = ?, \n creator_set_visibility = ?, \n\n maybe_creator_file_synthetic_id = ?, \n maybe_creator_category_synthetic_id = ?,\n\n extra_file_modification_info = ?,\n\n maybe_generation_provider = ?,\n\n platform_type = ?,\n\n maybe_cover_image_media_file_token = ?,\n\n maybe_mod_user_token = ?,\n is_generated_on_prem = ?,\n generated_by_worker = ?,\n generated_by_cluster = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 41
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "1c74e9c2dcc9205e2c9fe60a6de0828208e497e68560246e588092bafd03eb59"
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n t.token as `token: tokens::tokens::tags::TagToken`,\n t.tag_value\n\nFROM\n tags AS t\nJOIN tag_uses AS u\n ON t.token = u.tag_token\nWHERE\n u.entity_type = ?\n AND u.entity_token = ?\n AND u.maybe_deleted_at IS NULL\nORDER BY t.id DESC\nLIMIT 500\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::tags::TagToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "tag_value",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3929e9fe74e75fad7252681880c6c3bd7e76e96b0bf603f77f6a9b2d4fcda18d"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nDELETE FROM tag_uses\nWHERE entity_type = ?\nAND entity_token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "41b16ccf04ef1ffb8b48bc59edf9389f61f54b871f6361f35529706b98d419ec"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO media_files\nSET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n\n maybe_engine_category = ?,\n maybe_animation_type = ?,\n\n maybe_media_subtype = ?,\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?,\n\n is_user_upload = TRUE,\n\n maybe_origin_model_type = NULL,\n maybe_origin_model_token = NULL\n\nON DUPLICATE KEY UPDATE\n\n media_class = ?,\n media_type = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n\n maybe_engine_category = ?,\n maybe_animation_type = ?,\n\n maybe_media_subtype = ?,\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?,\n\n is_user_upload = TRUE,\n\n maybe_origin_model_type = NULL,\n maybe_origin_model_token = NULL\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 39
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "55706e6ac35be221b9d9c6e8b247812944c61941964bb53815d31dc30d506be8"
|
||||
}
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.id as `id: u64`,\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.maybe_project_type as `project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.maybe_title,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m FORCE INDEX (fk_maybe_creator_user_token)\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nWHERE\n m.maybe_creator_user_token = ?\n AND m.media_class = 'project'\n AND m.maybe_project_type IS NOT NULL\n AND m.maybe_project_type = ?\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n AND NOT m.is_intermediate_system_file\n AND m.id < ?\nORDER BY m.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "media_class: enums::by_table::media_files::media_file_class::MediaFileClass",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "media_type: enums::by_table::media_files::media_file_type::MediaFileType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "6c7adbc8171bc3fdfb6109193ffb0a55413fa0942746d65037c2b1d39b361bd0"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO media_files\nSET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n\n maybe_engine_category = ?,\n maybe_animation_type = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n maybe_prompt_token = ?,\n maybe_batch_token = ?,\n\n maybe_title = ?,\n maybe_duration_millis = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n maybe_scene_source_media_file_token = ?,\n\n is_intermediate_system_file = ?,\n is_user_upload = ?,\n\n maybe_generation_provider = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?,\n\n maybe_origin_model_type = NULL,\n maybe_origin_model_token = NULL\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 27
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "7369b2f3fd9e7c1e968dc5501ef9bea7e1610fd7a044a0f9ad8b908dfada2b6a"
|
||||
}
|
||||
+43
-54
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_media_subtype as `maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype`,\n\n m.maybe_mime_type,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.is_user_upload,\n m.is_intermediate_system_file,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.extra_file_modification_info,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n ",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_mime_type,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.is_user_upload,\n m.is_intermediate_system_file,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.extra_file_modification_info,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -55,16 +55,6 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_mime_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -74,7 +64,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"ordinal": 6,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -84,7 +74,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 7,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -94,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -104,7 +94,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -114,7 +104,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +114,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 11,
|
||||
"name": "maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -134,7 +124,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 12,
|
||||
"name": "maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -144,7 +134,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 13,
|
||||
"name": "maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -154,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 14,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -164,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 15,
|
||||
"name": "maybe_text_transcript",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -174,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"ordinal": 16,
|
||||
"name": "maybe_origin_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -184,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 17,
|
||||
"name": "maybe_duration_millis",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -194,7 +184,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 18,
|
||||
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -204,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 19,
|
||||
"name": "maybe_other_prompt_args",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -214,7 +204,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"ordinal": 20,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -224,7 +214,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"ordinal": 21,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -234,7 +224,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"ordinal": 22,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -244,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"ordinal": 23,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -254,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 24,
|
||||
"name": "is_user_upload",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
@@ -264,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 25,
|
||||
"name": "is_intermediate_system_file",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
@@ -274,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 26,
|
||||
"name": "maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -284,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"ordinal": 27,
|
||||
"name": "maybe_model_weights_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -294,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"ordinal": 28,
|
||||
"name": "maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -304,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"ordinal": 29,
|
||||
"name": "maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -314,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"ordinal": 30,
|
||||
"name": "maybe_model_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -324,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"ordinal": 31,
|
||||
"name": "maybe_model_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -334,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 33,
|
||||
"ordinal": 32,
|
||||
"name": "maybe_model_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -344,7 +334,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 34,
|
||||
"ordinal": 33,
|
||||
"name": "maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -354,7 +344,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 35,
|
||||
"ordinal": 34,
|
||||
"name": "maybe_model_weight_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -364,7 +354,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 36,
|
||||
"ordinal": 35,
|
||||
"name": "maybe_model_weight_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -374,7 +364,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 37,
|
||||
"ordinal": 36,
|
||||
"name": "maybe_model_weight_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -384,7 +374,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 38,
|
||||
"ordinal": 37,
|
||||
"name": "extra_file_modification_info",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -394,7 +384,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 39,
|
||||
"ordinal": 38,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -404,7 +394,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 40,
|
||||
"ordinal": 39,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -414,7 +404,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 41,
|
||||
"ordinal": 40,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -424,7 +414,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 42,
|
||||
"ordinal": 41,
|
||||
"name": "maybe_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -434,7 +424,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 43,
|
||||
"ordinal": 42,
|
||||
"name": "maybe_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -444,7 +434,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 44,
|
||||
"ordinal": 43,
|
||||
"name": "maybe_bookmark_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -454,7 +444,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 45,
|
||||
"ordinal": 44,
|
||||
"name": "is_featured",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
@@ -464,7 +454,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 46,
|
||||
"ordinal": 45,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -474,7 +464,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 47,
|
||||
"ordinal": 46,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -511,7 +501,6 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -538,5 +527,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "f6c37066ab3e508050e81cf3bea38cc708b05c5c59ba1c322dcfb775e4b9e7a6"
|
||||
"hash": "784ca68c6cb61d481b605bfe6ee3248a5b44499038c71b57fc9ea6c4722d170f"
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n maybe_creator_user_token as `maybe_creator_user_token: UserToken`,\n maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: AnonymousVisitorTrackingToken`,\n media_type as `media_type: MediaFileType`,\n maybe_project_type as `maybe_project_type: MediaFileProjectType`\nFROM media_files\nWHERE token = ?\n AND user_deleted_at IS NULL\n AND mod_deleted_at IS NULL\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "maybe_creator_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "maybe_creator_anonymous_visitor_token: AnonymousVisitorTrackingToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "media_type: MediaFileType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "maybe_project_type: MediaFileProjectType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "8dcd4bb064881f245beb39dd246e74ec1a2c47b69d7ce92a0d175f58dc4b9e63"
|
||||
}
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.id as `id: u64`,\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.maybe_project_type as `project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.maybe_title,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m FORCE INDEX (fk_maybe_creator_user_token)\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nWHERE\n m.maybe_creator_user_token = ?\n AND m.media_class = 'project'\n AND m.maybe_project_type IS NOT NULL\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n AND NOT m.is_intermediate_system_file\n AND m.id < ?\nORDER BY m.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "media_class: enums::by_table::media_files::media_file_class::MediaFileClass",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "media_type: enums::by_table::media_files::media_file_type::MediaFileType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "97e4bc3ab037126e3f4e213cdb7535c2ad233809fbeb6607c34fb02ec45cfe47"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO media_files\nSET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n maybe_project_type = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n\n maybe_engine_category = ?,\n maybe_animation_type = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n maybe_prompt_token = ?,\n maybe_batch_token = ?,\n\n maybe_title = ?,\n maybe_duration_millis = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n maybe_scene_source_media_file_token = ?,\n\n is_intermediate_system_file = ?,\n is_user_upload = ?,\n\n maybe_generation_provider = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?,\n\n maybe_origin_model_type = NULL,\n maybe_origin_model_token = NULL\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 28
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a25fe977f51329ed078e2441446ef7ff16683dcad8b81c8d0a0a4540b5e985bc"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nUPDATE media_files\nSET\n media_class = ?,\n media_type = ?,\n maybe_project_type = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n checksum_sha2 = ?,\n\n creator_ip_address = ?\nWHERE token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 11
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a3a86db1b77af3973bb37751d797a7dc5ed34b0f0fa156845e3b4b805e397f9d"
|
||||
}
|
||||
+43
-54
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_media_subtype as `maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype`,\n\n m.maybe_mime_type,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.is_user_upload,\n m.is_intermediate_system_file,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.extra_file_modification_info,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n ",
|
||||
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.maybe_engine_category as `maybe_engine_category: enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory`,\n m.maybe_animation_type as `maybe_animation_type: enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType`,\n\n m.maybe_mime_type,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n m.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n\n m.maybe_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_style_transfer_source_media_file_token as `maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n m.maybe_scene_source_media_file_token as `maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n\n\n m.maybe_title,\n m.maybe_text_transcript,\n\n m.maybe_origin_filename,\n\n m.maybe_duration_millis,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n prompts.maybe_other_args as maybe_other_prompt_args,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.is_user_upload,\n m.is_intermediate_system_file,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n model_weight_cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n model_weight_cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n model_weight_cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.extra_file_modification_info,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n featured_items.entity_token IS NOT NULL AS is_featured,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN model_weights\n ON m.maybe_origin_model_token = model_weights.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nLEFT OUTER JOIN media_files as model_weight_cover_image\n ON model_weight_cover_image.token = model_weights.maybe_cover_image_media_file_token\nLEFT OUTER JOIN users as model_weight_creator\n ON model_weight_creator.token = model_weights.creator_user_token\nLEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"media_file\"\n AND entity_stats.entity_token = m.token\nLEFT OUTER JOIN prompts\n ON prompts.token = m.maybe_prompt_token\nLEFT OUTER JOIN featured_items\n ON featured_items.entity_type = 'media_file'\n AND featured_items.entity_token = m.token\n AND featured_items.deleted_at IS NULL\nWHERE\n m.token = ?\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -55,16 +55,6 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "maybe_media_subtype: enums::by_table::media_files::media_file_subtype::MediaFileSubtype",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_mime_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -74,7 +64,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"ordinal": 6,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -84,7 +74,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 7,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -94,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -104,7 +94,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -114,7 +104,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -124,7 +114,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 11,
|
||||
"name": "maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -134,7 +124,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 12,
|
||||
"name": "maybe_style_transfer_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -144,7 +134,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 13,
|
||||
"name": "maybe_scene_source_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -154,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 14,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -164,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 15,
|
||||
"name": "maybe_text_transcript",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -174,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"ordinal": 16,
|
||||
"name": "maybe_origin_filename",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -184,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 17,
|
||||
"name": "maybe_duration_millis",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -194,7 +184,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 18,
|
||||
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -204,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 19,
|
||||
"name": "maybe_other_prompt_args",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -214,7 +204,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"ordinal": 20,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -224,7 +214,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"ordinal": 21,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -234,7 +224,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"ordinal": 22,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -244,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"ordinal": 23,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -254,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 24,
|
||||
"name": "is_user_upload",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
@@ -264,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 25,
|
||||
"name": "is_intermediate_system_file",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
@@ -274,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 26,
|
||||
"name": "maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -284,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"ordinal": 27,
|
||||
"name": "maybe_model_weights_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -294,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"ordinal": 28,
|
||||
"name": "maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -304,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"ordinal": 29,
|
||||
"name": "maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -314,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"ordinal": 30,
|
||||
"name": "maybe_model_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -324,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"ordinal": 31,
|
||||
"name": "maybe_model_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -334,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 33,
|
||||
"ordinal": 32,
|
||||
"name": "maybe_model_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -344,7 +334,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 34,
|
||||
"ordinal": 33,
|
||||
"name": "maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -354,7 +344,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 35,
|
||||
"ordinal": 34,
|
||||
"name": "maybe_model_weight_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -364,7 +354,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 36,
|
||||
"ordinal": 35,
|
||||
"name": "maybe_model_weight_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -374,7 +364,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 37,
|
||||
"ordinal": 36,
|
||||
"name": "maybe_model_weight_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
@@ -384,7 +374,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 38,
|
||||
"ordinal": 37,
|
||||
"name": "extra_file_modification_info",
|
||||
"type_info": {
|
||||
"type": "Blob",
|
||||
@@ -394,7 +384,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 39,
|
||||
"ordinal": 38,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -404,7 +394,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 40,
|
||||
"ordinal": 39,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -414,7 +404,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 41,
|
||||
"ordinal": 40,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -424,7 +414,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 42,
|
||||
"ordinal": 41,
|
||||
"name": "maybe_ratings_positive_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -434,7 +424,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 43,
|
||||
"ordinal": 42,
|
||||
"name": "maybe_ratings_negative_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -444,7 +434,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 44,
|
||||
"ordinal": 43,
|
||||
"name": "maybe_bookmark_count",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
@@ -454,7 +444,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 45,
|
||||
"ordinal": 44,
|
||||
"name": "is_featured",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
@@ -464,7 +454,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 46,
|
||||
"ordinal": 45,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -474,7 +464,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 47,
|
||||
"ordinal": 46,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -511,7 +501,6 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -538,5 +527,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "57fa22e6cd4e82b801605c96eac21babd78df3df361b3be566993b78a46efef2"
|
||||
"hash": "ad217c26087b2ebed6f2c9f79b16ead63727107dfce3366f3c1d12bc9d565c2c"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n INSERT INTO media_files\n SET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n is_user_upload = ?,\n is_intermediate_system_file = ?,\n\n origin_category = ?, \n origin_product_category = ?, \n maybe_origin_model_type = ?, \n maybe_origin_model_token = ?, \n maybe_origin_filename = ?,\n\n is_batch_generated = ?,\n maybe_batch_token = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n maybe_duration_millis = ?,\n maybe_audio_encoding = ?, \n maybe_video_encoding = ?, \n maybe_frame_width = ?, \n maybe_frame_height = ?,\n maybe_prompt_token = ?,\n checksum_sha2 = ?,\n \n maybe_engine_category = ?,\n\n maybe_title = ?,\n maybe_text_transcript = ?,\n\n maybe_scene_source_media_file_token = ?,\n\n public_bucket_directory_hash = ?, \n maybe_public_bucket_prefix = ?, \n maybe_public_bucket_extension = ?, \n\n maybe_creator_user_token = ?, \n maybe_creator_anonymous_visitor_token = ?, \n\n creator_ip_address = ?, \n creator_set_visibility = ?, \n\n maybe_creator_file_synthetic_id = ?, \n maybe_creator_category_synthetic_id = ?,\n\n extra_file_modification_info = ?,\n\n maybe_generation_provider = ?,\n\n platform_type = ?,\n\n maybe_cover_image_media_file_token = ?,\n\n maybe_mod_user_token = ?,\n is_generated_on_prem = ?,\n generated_by_worker = ?,\n generated_by_cluster = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 42
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "ad2ffbd9f48e52678a5c61817bec043bf1df4033463e5c5a18468c04af391e6a"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n UPDATE media_files\n SET\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n creator_ip_address = ?\n WHERE token = ?\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "ad311b4aa95a71b1dc37aa09c27850a0e963380c6e7780f47a9fc5a95ab70583"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO tags\nSET\n token = ?,\n tag_value = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "c7e848e4c906a34ac5a4ad8cc73354baa8d5cd81170dd06d66d7f414505d538b"
|
||||
}
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n m.id as `id: u64`,\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_class as `media_class: enums::by_table::media_files::media_file_class::MediaFileClass`,\n m.maybe_project_type as `project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType`,\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n users.token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n users.username as maybe_creator_username,\n users.display_name as maybe_creator_display_name,\n users.email_gravatar_hash as maybe_creator_gravatar_hash,\n\n media_file_cover_image.public_bucket_directory_hash as maybe_file_cover_image_public_bucket_hash,\n media_file_cover_image.maybe_public_bucket_prefix as maybe_file_cover_image_public_bucket_prefix,\n media_file_cover_image.maybe_public_bucket_extension as maybe_file_cover_image_public_bucket_extension,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n m.maybe_title,\n\n m.created_at,\n m.updated_at\n\nFROM media_files AS m FORCE INDEX (fk_maybe_creator_user_token)\nLEFT OUTER JOIN users\n ON m.maybe_creator_user_token = users.token\nLEFT OUTER JOIN media_files as media_file_cover_image\n ON media_file_cover_image.token = m.maybe_cover_image_media_file_token\nWHERE\n m.maybe_creator_user_token = ?\n AND m.media_class = 'project'\n AND m.maybe_project_type IS NOT NULL\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n AND NOT m.is_intermediate_system_file\n AND m.id > ?\nORDER BY m.id ASC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "media_class: enums::by_table::media_files::media_file_class::MediaFileClass",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "project_type!: enums::by_table::media_files::media_file_project_type::MediaFileProjectType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "media_type: enums::by_table::media_files::media_file_type::MediaFileType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "maybe_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_creator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_creator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_creator_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_file_cover_image_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_file_cover_image_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "maybe_file_cover_image_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "creator_set_visibility: enums::common::visibility::Visibility",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 28
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "maybe_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "d8f4ce4e1026c71a7be8fd87f00f6f8858c401701da1ca3316eed1ed971d4bb2"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n UPDATE media_files\n SET\n media_class = ?,\n maybe_project_type = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n creator_ip_address = ?\n WHERE token = ?\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 9
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "e33fa6280a39fff22b2e8c2731b7b6058b4705b5b557f34dba52a6440c22529b"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
ADD COLUMN has_watermark BOOLEAN NOT NULL DEFAULT FALSE
|
||||
AFTER checksum_sha2;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- NB: MySQL 8.0.29+ performs DROP COLUMN with ALGORITHM=INSTANT (metadata-only).
|
||||
-- On older versions this is an INPLACE table rebuild that still permits
|
||||
-- concurrent reads and writes. No ALGORITHM clause so the server picks the
|
||||
-- best available.
|
||||
ALTER TABLE media_files
|
||||
DROP COLUMN has_watermark;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
ADD COLUMN is_in_aws BOOLEAN NOT NULL DEFAULT FALSE
|
||||
AFTER maybe_public_bucket_extension;
|
||||
|
||||
ALTER TABLE media_files
|
||||
ADD INDEX index_is_in_aws (is_in_aws);
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
DROP INDEX index_is_in_aws,
|
||||
DROP COLUMN is_in_aws;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- NB: anchored to maybe_public_bucket_extension (not is_in_aws) so this works
|
||||
-- whether or not the is_in_aws drop migration has been reverted yet.
|
||||
ALTER TABLE media_files
|
||||
ADD COLUMN is_not_in_gcp BOOLEAN NOT NULL DEFAULT FALSE
|
||||
AFTER maybe_public_bucket_extension;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
DROP COLUMN is_not_in_gcp;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
ADD COLUMN nsfw_status VARCHAR(32) NOT NULL DEFAULT 'unknown'
|
||||
AFTER maybe_scene_source_media_file_token;
|
||||
|
||||
ALTER TABLE media_files
|
||||
ADD INDEX index_nsfw_status (nsfw_status);
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
DROP INDEX index_nsfw_status,
|
||||
DROP COLUMN nsfw_status;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
ADD COLUMN is_batch_generated BOOLEAN NOT NULL DEFAULT FALSE
|
||||
AFTER maybe_origin_filename;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
DROP COLUMN is_batch_generated;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
ADD COLUMN maybe_media_subtype VARCHAR(32) DEFAULT NULL
|
||||
AFTER media_class;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
DROP COLUMN maybe_media_subtype;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE media_files
|
||||
DROP INDEX index_maybe_project_type,
|
||||
DROP COLUMN maybe_project_type;
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Which kind of internal Artcraft project document this media file is
|
||||
-- ('scene_3d', 'mood_board', 'workflow', 'video_timeline', ...).
|
||||
-- Only set when media_class = 'project'. The file format lives in media_type;
|
||||
-- the JSON payload carries its own schema version.
|
||||
ALTER TABLE media_files
|
||||
ADD COLUMN maybe_project_type VARCHAR(32) DEFAULT NULL
|
||||
AFTER media_class;
|
||||
|
||||
-- For "list my mood boards"-style filtered queries.
|
||||
-- The column is all-NULL at creation time, so the index build is cheap.
|
||||
ALTER TABLE media_files
|
||||
ADD INDEX index_maybe_project_type (maybe_project_type);
|
||||
@@ -99,12 +99,6 @@ CREATE TABLE media_files (
|
||||
-- The original filename of the media (if uploaded by a user)
|
||||
maybe_origin_filename VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- TODO: Remove after `maybe_batch_token` gains use.
|
||||
-- Whether this media file was generated as part of a batch
|
||||
-- If so, we can look up the batch in a separate query/call to the `batch_generations` table.
|
||||
-- We won't hold the batch token in this table since it'll be very sparsely populated.
|
||||
is_batch_generated BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- If the media file is generated as part of a batch, this designates the batch.
|
||||
maybe_batch_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
@@ -138,9 +132,6 @@ CREATE TABLE media_files (
|
||||
-- The token is a media file token.
|
||||
maybe_scene_source_media_file_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- A flag for NSFW status.
|
||||
nsfw_status VARCHAR(32) NOT NULL DEFAULT "unknown",
|
||||
|
||||
-- ========== MEDIA DETAILS ==========
|
||||
|
||||
-- Type of media file:
|
||||
@@ -166,20 +157,19 @@ CREATE TABLE media_files (
|
||||
-- This is especially helpful with engine types that map to specific semantics.
|
||||
-- * 'unknown' (TODO: This is the default until all records are backfilled.)
|
||||
-- * 'audio' for wav, mp3, etc.
|
||||
-- * 'image' for a variety of video types.
|
||||
-- * 'image' for a variety of image types.
|
||||
-- * 'video' for a variety of video types.
|
||||
-- * 'dimensional' for a variety of 3d types
|
||||
-- * 'dimensional' (DEPRECATED) split into 'mesh', 'splat', and 'project'; read-only until backfilled
|
||||
-- * 'mesh' for 3d mesh assets (glb, gltf, fbx, obj, pmx, pmd, etc.)
|
||||
-- * 'splat' for Gaussian splats (spz, etc.)
|
||||
-- * 'project' for internal Artcraft project documents (see maybe_project_type)
|
||||
media_class VARCHAR(16) NOT NULL DEFAULT "unknown",
|
||||
|
||||
-- DEPRECATED / DO NOT USE. THIS FIELD IS NO LONGER RELEVANT.
|
||||
-- A media file's possible subtype. Typically used for Storyteller Studio.
|
||||
-- * 'mixamo' for mixamo animations (eg. for BVH, GLB, FBX, etc. files)
|
||||
-- * 'mocap_net' for mocapnet animations (eg. for BVH files)
|
||||
-- * 'scene'
|
||||
-- * 'character'
|
||||
-- * 'animation'
|
||||
-- DO NOT USE THE `maybe_media_subtype` FIELD!
|
||||
maybe_media_subtype VARCHAR(32) DEFAULT NULL,
|
||||
-- Which kind of internal Artcraft project document this media file is
|
||||
-- ('scene_3d', 'mood_board', 'workflow', 'video_timeline', ...).
|
||||
-- Only set when media_class = 'project'. The file format lives in media_type;
|
||||
-- the JSON payload carries its own schema version.
|
||||
maybe_project_type VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- The file's mime type.
|
||||
maybe_mime_type VARCHAR(32) DEFAULT NULL,
|
||||
@@ -227,10 +217,6 @@ CREATE TABLE media_files (
|
||||
-- and produces different lengths output depending on the choice of algorithm.
|
||||
checksum_sha2 CHAR(64) NOT NULL,
|
||||
|
||||
-- Whether the image or video has a visible watermark.
|
||||
-- If so, we may not need to add a watermark downstream in further processing steps.
|
||||
has_watermark BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Tracks the thumbnail algorithm/type used for this media file.
|
||||
-- NULL = no thumbnail generated yet.
|
||||
-- 1 = video thumbnail.
|
||||
@@ -259,13 +245,6 @@ CREATE TABLE media_files (
|
||||
-- `[{maybe_public_bucket_prefix}]{public_bucket_directory_hash}[{maybe_public_bucket_extension}]`
|
||||
maybe_public_bucket_extension VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
-- This is a migration flag that denotes whether this media file is stored in AWS.
|
||||
-- If not, it's stored in GCP.
|
||||
is_in_aws BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- This is a migration flag that denotes that weight is not stored in GCP.
|
||||
is_not_in_gcp BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- NB: Removed, since this can be derived.
|
||||
-- The directory this media is uploaded to will be exclusive for this file.
|
||||
-- Only this given record will live in this bucket, but the directory may include
|
||||
@@ -351,13 +330,12 @@ CREATE TABLE media_files (
|
||||
KEY index_is_user_upload (is_user_upload),
|
||||
KEY index_is_intermediate_system_file (is_intermediate_system_file),
|
||||
KEY index_maybe_scene_source_media_file_token (maybe_scene_source_media_file_token),
|
||||
KEY index_nsfw_status (nsfw_status),
|
||||
KEY index_media_type (media_type),
|
||||
KEY index_media_class (media_class),
|
||||
KEY index_maybe_project_type (maybe_project_type),
|
||||
KEY index_maybe_engine_category (maybe_engine_category),
|
||||
KEY fk_maybe_prompt_token (maybe_prompt_token),
|
||||
KEY index_checksum_sha2 (checksum_sha2),
|
||||
KEY index_is_in_aws (is_in_aws),
|
||||
KEY fk_maybe_creator_user_token (maybe_creator_user_token),
|
||||
KEY fk_maybe_mod_user_token (maybe_mod_user_token),
|
||||
KEY index_creator_ip_address (creator_ip_address),
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
{
|
||||
"title": "[GET] /v1/engine/scene/{token}",
|
||||
"description": "Auto-generated per-endpoint dashboard for `GET /v1/engine/scene/{token}`.\n\nFilters all metrics on `service:storyteller-web,route:/v1/engine/scene/_token,method:get`.\n\nSource: `script/metrics/generate_endpoint_dashboards.py`. Do not hand-edit; changes will be overwritten on the next regeneration.",
|
||||
"layout_type": "ordered",
|
||||
"notify_list": [],
|
||||
"reflow_type": "fixed",
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Top-line health",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Requests/sec",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": true,
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:get}.as_rate()",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "5xx error rate (%)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": false,
|
||||
"custom_unit": "%",
|
||||
"requests": [
|
||||
{
|
||||
"q": "(sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:get,status_class:5xx}.as_count() / sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:get}.as_count()) * 100",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 5.0,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p95 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:get}",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1000,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 250,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 250,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p99 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:get}",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 9,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 12,
|
||||
"height": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Trends",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Requests/sec by status class",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:get} by {status_class}.as_rate()",
|
||||
"display_type": "bars",
|
||||
"style": {
|
||||
"palette": "semantic",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Latency percentiles",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p50:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:get}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "cool",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:get}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:get}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "dashed",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true,
|
||||
"label": "ms"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"width": 12,
|
||||
"height": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "toplist",
|
||||
"title": "Status code distribution",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"requests": [
|
||||
{
|
||||
"q": "top(sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:get} by {status_code}.as_count(), 25, 'sum', 'desc')"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 8,
|
||||
"width": 12,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "24m-c4g-btm"
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
{
|
||||
"title": "[POST] /v1/engine/create_scene",
|
||||
"description": "Auto-generated per-endpoint dashboard for `POST /v1/engine/create_scene`.\n\nFilters all metrics on `service:storyteller-web,route:/v1/engine/create_scene,method:post`.\n\nSource: `script/metrics/generate_endpoint_dashboards.py`. Do not hand-edit; changes will be overwritten on the next regeneration.",
|
||||
"layout_type": "ordered",
|
||||
"notify_list": [],
|
||||
"reflow_type": "fixed",
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Top-line health",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Requests/sec",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": true,
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/engine/create_scene,method:post}.as_rate()",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "5xx error rate (%)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": false,
|
||||
"custom_unit": "%",
|
||||
"requests": [
|
||||
{
|
||||
"q": "(sum:http.server.request.count{service:storyteller-web,route:/v1/engine/create_scene,method:post,status_class:5xx}.as_count() / sum:http.server.request.count{service:storyteller-web,route:/v1/engine/create_scene,method:post}.as_count()) * 100",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 5.0,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p95 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/create_scene,method:post}",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1000,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 250,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 250,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p99 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/create_scene,method:post}",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 9,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 12,
|
||||
"height": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Trends",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Requests/sec by status class",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/engine/create_scene,method:post} by {status_class}.as_rate()",
|
||||
"display_type": "bars",
|
||||
"style": {
|
||||
"palette": "semantic",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Latency percentiles",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p50:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/create_scene,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "cool",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/create_scene,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/create_scene,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "dashed",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true,
|
||||
"label": "ms"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"width": 12,
|
||||
"height": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "toplist",
|
||||
"title": "Status code distribution",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"requests": [
|
||||
{
|
||||
"q": "top(sum:http.server.request.count{service:storyteller-web,route:/v1/engine/create_scene,method:post} by {status_code}.as_count(), 25, 'sum', 'desc')"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 8,
|
||||
"width": 12,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "z9c-89r-p57"
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
{
|
||||
"title": "[POST] /v1/engine/scene/{token}",
|
||||
"description": "Auto-generated per-endpoint dashboard for `POST /v1/engine/scene/{token}`.\n\nFilters all metrics on `service:storyteller-web,route:/v1/engine/scene/_token,method:post`.\n\nSource: `script/metrics/generate_endpoint_dashboards.py`. Do not hand-edit; changes will be overwritten on the next regeneration.",
|
||||
"layout_type": "ordered",
|
||||
"notify_list": [],
|
||||
"reflow_type": "fixed",
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Top-line health",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Requests/sec",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": true,
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:post}.as_rate()",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "5xx error rate (%)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": false,
|
||||
"custom_unit": "%",
|
||||
"requests": [
|
||||
{
|
||||
"q": "(sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:post,status_class:5xx}.as_count() / sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:post}.as_count()) * 100",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 5.0,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p95 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:post}",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1000,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 250,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 250,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p99 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:post}",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 9,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 12,
|
||||
"height": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Trends",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Requests/sec by status class",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:post} by {status_class}.as_rate()",
|
||||
"display_type": "bars",
|
||||
"style": {
|
||||
"palette": "semantic",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Latency percentiles",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p50:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "cool",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/engine/scene/_token,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "dashed",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true,
|
||||
"label": "ms"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"width": 12,
|
||||
"height": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "toplist",
|
||||
"title": "Status code distribution",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"requests": [
|
||||
{
|
||||
"q": "top(sum:http.server.request.count{service:storyteller-web,route:/v1/engine/scene/_token,method:post} by {status_code}.as_count(), 25, 'sum', 'desc')"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 8,
|
||||
"width": 12,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "bxf-r4f-xfs"
|
||||
}
|
||||
-267
@@ -1,267 +0,0 @@
|
||||
{
|
||||
"title": "[POST] /v1/media_files/upload/engine_asset",
|
||||
"description": "Auto-generated per-endpoint dashboard for `POST /v1/media_files/upload/engine_asset`.\n\nFilters all metrics on `service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post`.\n\nSource: `script/metrics/generate_endpoint_dashboards.py`. Do not hand-edit; changes will be overwritten on the next regeneration.",
|
||||
"layout_type": "ordered",
|
||||
"notify_list": [],
|
||||
"reflow_type": "fixed",
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Top-line health",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Requests/sec",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": true,
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post}.as_rate()",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "5xx error rate (%)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": false,
|
||||
"custom_unit": "%",
|
||||
"requests": [
|
||||
{
|
||||
"q": "(sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post,status_class:5xx}.as_count() / sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post}.as_count()) * 100",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 5.0,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p95 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post}",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1000,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 250,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 250,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p99 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post}",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 9,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 12,
|
||||
"height": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Trends",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Requests/sec by status class",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post} by {status_class}.as_rate()",
|
||||
"display_type": "bars",
|
||||
"style": {
|
||||
"palette": "semantic",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Latency percentiles",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p50:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "cool",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "dashed",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true,
|
||||
"label": "ms"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"width": 12,
|
||||
"height": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "toplist",
|
||||
"title": "Status code distribution",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"requests": [
|
||||
{
|
||||
"q": "top(sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/upload/engine_asset,method:post} by {status_code}.as_count(), 25, 'sum', 'desc')"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 8,
|
||||
"width": 12,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "7nm-j6w-9tz"
|
||||
}
|
||||
-267
@@ -1,267 +0,0 @@
|
||||
{
|
||||
"title": "[POST] /v1/media_files/write/engine_asset",
|
||||
"description": "Auto-generated per-endpoint dashboard for `POST /v1/media_files/write/engine_asset`.\n\nFilters all metrics on `service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post`.\n\nSource: `script/metrics/generate_endpoint_dashboards.py`. Do not hand-edit; changes will be overwritten on the next regeneration.",
|
||||
"layout_type": "ordered",
|
||||
"notify_list": [],
|
||||
"reflow_type": "fixed",
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Top-line health",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Requests/sec",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": true,
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post}.as_rate()",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "5xx error rate (%)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": false,
|
||||
"custom_unit": "%",
|
||||
"requests": [
|
||||
{
|
||||
"q": "(sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post,status_class:5xx}.as_count() / sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post}.as_count()) * 100",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 5.0,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p95 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post}",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1000,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 250,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 250,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p99 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post}",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 9,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 12,
|
||||
"height": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Trends",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Requests/sec by status class",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post} by {status_class}.as_rate()",
|
||||
"display_type": "bars",
|
||||
"style": {
|
||||
"palette": "semantic",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Latency percentiles",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p50:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "cool",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "dashed",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true,
|
||||
"label": "ms"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"width": 12,
|
||||
"height": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "toplist",
|
||||
"title": "Status code distribution",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"requests": [
|
||||
{
|
||||
"q": "top(sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/engine_asset,method:post} by {status_code}.as_count(), 25, 'sum', 'desc')"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 8,
|
||||
"width": 12,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "xv7-2ca-2c5"
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
{
|
||||
"title": "[POST] /v1/media_files/write/scene_file",
|
||||
"description": "Auto-generated per-endpoint dashboard for `POST /v1/media_files/write/scene_file`.\n\nFilters all metrics on `service:storyteller-web,route:/v1/media_files/write/scene_file,method:post`.\n\nSource: `script/metrics/generate_endpoint_dashboards.py`. Do not hand-edit; changes will be overwritten on the next regeneration.",
|
||||
"layout_type": "ordered",
|
||||
"notify_list": [],
|
||||
"reflow_type": "fixed",
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Top-line health",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Requests/sec",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": true,
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post}.as_rate()",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "5xx error rate (%)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 2,
|
||||
"autoscale": false,
|
||||
"custom_unit": "%",
|
||||
"requests": [
|
||||
{
|
||||
"q": "(sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post,status_class:5xx}.as_count() / sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post}.as_count()) * 100",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 5.0,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 1.0,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p95 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post}",
|
||||
"aggregator": "avg",
|
||||
"conditional_formats": [
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 1000,
|
||||
"palette": "white_on_red"
|
||||
},
|
||||
{
|
||||
"comparator": ">",
|
||||
"value": 250,
|
||||
"palette": "white_on_yellow"
|
||||
},
|
||||
{
|
||||
"comparator": "<=",
|
||||
"value": 250,
|
||||
"palette": "white_on_green"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "query_value",
|
||||
"title": "Latency p99 (ms)",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"precision": 0,
|
||||
"autoscale": true,
|
||||
"custom_unit": "ms",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post}",
|
||||
"aggregator": "avg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 9,
|
||||
"y": 0,
|
||||
"width": 3,
|
||||
"height": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 12,
|
||||
"height": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "group",
|
||||
"layout_type": "ordered",
|
||||
"title": "Trends",
|
||||
"show_title": true,
|
||||
"widgets": [
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Requests/sec by status class",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post} by {status_class}.as_rate()",
|
||||
"display_type": "bars",
|
||||
"style": {
|
||||
"palette": "semantic",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "timeseries",
|
||||
"title": "Latency percentiles",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"show_legend": true,
|
||||
"legend_layout": "horizontal",
|
||||
"requests": [
|
||||
{
|
||||
"q": "p50:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "cool",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p95:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "solid",
|
||||
"line_width": "normal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"q": "p99:http.server.request.duration_ms{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post}",
|
||||
"display_type": "line",
|
||||
"style": {
|
||||
"palette": "warm",
|
||||
"line_type": "dashed",
|
||||
"line_width": "normal"
|
||||
}
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"scale": "linear",
|
||||
"include_zero": true,
|
||||
"label": "ms"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"width": 6,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"width": 12,
|
||||
"height": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"type": "toplist",
|
||||
"title": "Status code distribution",
|
||||
"title_size": "16",
|
||||
"title_align": "left",
|
||||
"requests": [
|
||||
{
|
||||
"q": "top(sum:http.server.request.count{service:storyteller-web,route:/v1/media_files/write/scene_file,method:post} by {status_code}.as_count(), 25, 'sum', 'desc')"
|
||||
}
|
||||
]
|
||||
},
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 8,
|
||||
"width": 12,
|
||||
"height": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "c8z-t2z-nk4"
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
$kind: collection
|
||||
order: 8000
|
||||
@@ -1,15 +0,0 @@
|
||||
$kind: http-request
|
||||
name: Edit Tags
|
||||
url: "{{api_host}}/v1/tags/edit/model_weight/weight_84t9zeafn72wkje1x59f9rm81"
|
||||
method: POST
|
||||
headers:
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
Cookie: ""
|
||||
body:
|
||||
type: json
|
||||
content: |-
|
||||
{
|
||||
"tags": "video games, legend of zelda"
|
||||
}
|
||||
order: 1000
|
||||
@@ -1,6 +0,0 @@
|
||||
$kind: http-request
|
||||
url: "{{api_host}}/v1/tags/list/model_weight/weight_84t9zeafn72wkje1x59f9rm81"
|
||||
method: GET
|
||||
headers:
|
||||
Accept: application/json
|
||||
order: 2000
|
||||
@@ -2,6 +2,7 @@ pub mod cover_image_links;
|
||||
pub mod job_details;
|
||||
pub mod media_file_cover_image_details;
|
||||
pub mod media_links;
|
||||
pub mod pagination_cursors;
|
||||
pub mod simple_entity_stats;
|
||||
pub mod simple_generic_json_success;
|
||||
pub mod user_details_light;
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
// TODO(bt,2026-07-09): Replace the storyteller-web version of this.
|
||||
|
||||
/// Pagination by cursors
|
||||
/// These types of pagination are for "infinite scrolling", which do not reveal a number of pages.
|
||||
/// This is good so that investors and competitors cannot reveal how many database records we have.
|
||||
/// This is typically used for "discovery" type pages, not user profiles.
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct PaginationCursors {
|
||||
/// The "next" cursor.
|
||||
/// This is an opaque (typically even encrypted) handle.
|
||||
pub maybe_next: Option<String>,
|
||||
|
||||
/// The "previous" cursor.
|
||||
/// This is an opaque (typically even encrypted) handle.
|
||||
pub maybe_previous: Option<String>,
|
||||
|
||||
/// Details whether we're walking forward or backward.
|
||||
pub cursor_is_reversed: bool,
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
use enums::by_table::media_files::media_file_class::MediaFileClass;
|
||||
use enums::by_table::media_files::media_file_project_type::MediaFileProjectType;
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::common::visibility::Visibility;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
use crate::common::responses::media_file_cover_image_details::MediaFileCoverImageDetails;
|
||||
use crate::common::responses::media_links::MediaLinks;
|
||||
use crate::common::responses::pagination_cursors::PaginationCursors;
|
||||
use crate::common::responses::user_details_light::UserDetailsLight;
|
||||
|
||||
pub const LIST_SESSION_PROJECT_MEDIA_FILES_URL_PATH: &str = "/v1/media_files/project/list";
|
||||
|
||||
/// Query string parameters for listing the session user's project files.
|
||||
#[derive(Deserialize, IntoParams)]
|
||||
pub struct ListSessionProjectMediaFilesQueryParams {
|
||||
pub sort_ascending: Option<bool>,
|
||||
pub page_size: Option<usize>,
|
||||
pub cursor: Option<String>,
|
||||
pub cursor_is_reversed: Option<bool>,
|
||||
|
||||
/// Optional filter on the specific project document type.
|
||||
///
|
||||
/// Usage:
|
||||
/// - `?filter_project_type=scene_3d`
|
||||
/// - `?filter_project_type=mood_board`
|
||||
/// - `?filter_project_type=workflow`
|
||||
/// - `?filter_project_type=video_timeline`
|
||||
pub filter_project_type: Option<MediaFileProjectType>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct ListSessionProjectMediaFilesSuccessResponse {
|
||||
pub success: bool,
|
||||
pub results: Vec<ProjectMediaFileInfo>,
|
||||
pub pagination: PaginationCursors,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct ProjectMediaFileInfo {
|
||||
/// Primary key identifier
|
||||
pub token: MediaFileToken,
|
||||
|
||||
/// The coarse-grained class of media file.
|
||||
/// Always `project` for this endpoint.
|
||||
pub media_class: MediaFileClass,
|
||||
|
||||
/// The specific kind of project document: 3D scene, mood board, etc.
|
||||
pub project_type: MediaFileProjectType,
|
||||
|
||||
/// Type of media will dictate which fields are populated and what
|
||||
/// the frontend should display (eg. video player vs audio player).
|
||||
/// This is closer in meaning to a "mime type".
|
||||
pub media_type: MediaFileType,
|
||||
|
||||
/// Rich CDN links to the media, including thumbnails, previews, and more.
|
||||
pub media_links: MediaLinks,
|
||||
|
||||
/// Information about the cover image. Many media files do not require a cover image,
|
||||
/// e.g. image files, video files with thumbnails, audio files, etc.
|
||||
/// 3D files require them.
|
||||
pub cover_image: MediaFileCoverImageDetails,
|
||||
|
||||
/// User info
|
||||
pub maybe_creator_user: Option<UserDetailsLight>,
|
||||
|
||||
pub creator_set_visibility: Visibility,
|
||||
|
||||
/// The name or title of the media file (optional)
|
||||
pub maybe_title: Option<String>,
|
||||
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
@@ -1,2 +1,4 @@
|
||||
pub mod delete_media_file;
|
||||
pub mod list_batch_generated_media_files;
|
||||
pub mod list_batch_generated_media_files;
|
||||
pub mod list_session_project_media_files;
|
||||
pub mod project;
|
||||
@@ -0,0 +1,8 @@
|
||||
pub mod upload_new_editor_2d_project;
|
||||
pub mod upload_new_mood_board_project;
|
||||
pub mod upload_new_scene_3d_project;
|
||||
pub mod upload_new_video_timeline_project;
|
||||
pub mod upload_updated_editor_2d_project;
|
||||
pub mod upload_updated_mood_board_project;
|
||||
pub mod upload_updated_scene_3d_project;
|
||||
pub mod upload_updated_video_timeline_project;
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_NEW_EDITOR_2D_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/editor_2d/new";
|
||||
|
||||
/// Response for saving a new 2D editor document project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadNewEditor2dProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token for the newly created project media file. Use it to query the
|
||||
/// project and to save subsequent updates via the update endpoint.
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_NEW_MOOD_BOARD_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/mood_board/new";
|
||||
|
||||
/// Response for saving a new mood board project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadNewMoodBoardProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token for the newly created project media file. Use it to query the
|
||||
/// project and to save subsequent updates via the update endpoint.
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_NEW_SCENE_3D_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/scene_3d/new";
|
||||
|
||||
/// Response for saving a new 3D scene project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadNewScene3dProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token for the newly created project media file. Use it to query the
|
||||
/// project and to save subsequent updates via the update endpoint.
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_NEW_VIDEO_TIMELINE_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/video_timeline/new";
|
||||
|
||||
/// Response for saving a new video editor timeline project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadNewVideoTimelineProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token for the newly created project media file. Use it to query the
|
||||
/// project and to save subsequent updates via the update endpoint.
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_UPDATED_EDITOR_2D_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/editor_2d/update/{token}";
|
||||
|
||||
/// For the URL PathInfo
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedEditor2dProjectPathInfo {
|
||||
pub token: MediaFileToken,
|
||||
}
|
||||
|
||||
/// Response for overwriting an existing 2D editor project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedEditor2dProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token of the updated project media file (unchanged by the update).
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_UPDATED_MOOD_BOARD_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/mood_board/update/{token}";
|
||||
|
||||
/// For the URL PathInfo
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedMoodBoardProjectPathInfo {
|
||||
pub token: MediaFileToken,
|
||||
}
|
||||
|
||||
/// Response for overwriting an existing mood board project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedMoodBoardProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token of the updated project media file (unchanged by the update).
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_UPDATED_SCENE_3D_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/scene_3d/update/{token}";
|
||||
|
||||
/// For the URL PathInfo
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedScene3dProjectPathInfo {
|
||||
pub token: MediaFileToken,
|
||||
}
|
||||
|
||||
/// Response for overwriting an existing 3D scene project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedScene3dProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token of the updated project media file (unchanged by the update).
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
pub const UPLOAD_UPDATED_VIDEO_TIMELINE_PROJECT_URL_PATH: &str = "/v1/media_files/upload/project/video_timeline/update/{token}";
|
||||
|
||||
/// For the URL PathInfo
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedVideoTimelineProjectPathInfo {
|
||||
pub token: MediaFileToken,
|
||||
}
|
||||
|
||||
/// Response for overwriting an existing video editor timeline project.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct UploadUpdatedVideoTimelineProjectSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Token of the updated project media file (unchanged by the update).
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Response body for the omni-gen video cost estimate endpoint.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct OmniGenVideoCostResponse {
|
||||
pub success: bool,
|
||||
|
||||
|
||||
-5
@@ -76,11 +76,6 @@ pub struct MediaFileInfo {
|
||||
/// this describes the animation regime used or supported.
|
||||
pub maybe_animation_type: Option<MediaFileAnimationType>,
|
||||
|
||||
// /// If the media file has a subtype, we'll report it.
|
||||
// /// This is mostly used for Bevy engine files.
|
||||
// #[deprecated(note="This was for the Bevy engine. Do not use.")]
|
||||
// pub maybe_media_subtype: Option<MediaFileSubtype>,
|
||||
|
||||
// /// Extension for the engine to load over remote:// URLs.
|
||||
// #[deprecated(note="This was for the Bevy engine. Do not use.")]
|
||||
// pub maybe_engine_extension: Option<String>,
|
||||
|
||||
@@ -24,6 +24,10 @@ pub enum RouterSplatModel {
|
||||
|
||||
#[serde(rename = "marble_1p1_plus")]
|
||||
Marble1p1Plus,
|
||||
|
||||
/// TripoSplat: single-image to 3D Gaussian splat (via Fal).
|
||||
#[serde(rename = "triposplat")]
|
||||
TripoSplat,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -40,6 +44,7 @@ mod tests {
|
||||
assert_serde_round_trip(RouterSplatModel::Marble1p0Draft, "marble_1p0_draft");
|
||||
assert_serde_round_trip(RouterSplatModel::Marble1p1, "marble_1p1");
|
||||
assert_serde_round_trip(RouterSplatModel::Marble1p1Plus, "marble_1p1_plus");
|
||||
assert_serde_round_trip(RouterSplatModel::TripoSplat, "triposplat");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -53,6 +58,7 @@ mod tests {
|
||||
(RouterSplatModel::Marble1p0Draft, CommonSplatModel::Marble1p0Draft),
|
||||
(RouterSplatModel::Marble1p1, CommonSplatModel::Marble1p1),
|
||||
(RouterSplatModel::Marble1p1Plus, CommonSplatModel::Marble1p1Plus),
|
||||
(RouterSplatModel::TripoSplat, CommonSplatModel::TripoSplat),
|
||||
];
|
||||
for (router_model, expected_common) in cases {
|
||||
let json = serde_json::to_string(&router_model).unwrap();
|
||||
|
||||
+5
@@ -8,6 +8,8 @@ use crate::generate::generate_splat::providers::artcraft::marble_1p0::build::bui
|
||||
use crate::generate::generate_splat::providers::artcraft::marble_1p0_draft::build::build_artcraft_marble_1p0_draft;
|
||||
use crate::generate::generate_splat::providers::artcraft::marble_1p1::build::build_artcraft_marble_1p1;
|
||||
use crate::generate::generate_splat::providers::artcraft::marble_1p1_plus::build::build_artcraft_marble_1p1_plus;
|
||||
use crate::generate::generate_splat::providers::artcraft::triposplat::build::build_artcraft_triposplat;
|
||||
use crate::generate::generate_splat::providers::fal::triposplat::build::build_fal_triposplat;
|
||||
use crate::generate::generate_splat::providers::worldlabs::marble_1p0::build::build_worldlabs_marble_1p0;
|
||||
use crate::generate::generate_splat::providers::worldlabs::marble_1p0_draft::build::build_worldlabs_marble_1p0_draft;
|
||||
use crate::generate::generate_splat::providers::worldlabs::marble_1p1::build::build_worldlabs_marble_1p1;
|
||||
@@ -79,6 +81,9 @@ impl GenerateSplatRequestBuilder {
|
||||
(RouterProvider::Artcraft, RouterSplatModel::Marble1p0Draft | RouterSplatModel::Marble0p1Mini) => build_artcraft_marble_1p0_draft(self),
|
||||
(RouterProvider::Artcraft, RouterSplatModel::Marble1p1) => build_artcraft_marble_1p1(self),
|
||||
(RouterProvider::Artcraft, RouterSplatModel::Marble1p1Plus) => build_artcraft_marble_1p1_plus(self),
|
||||
(RouterProvider::Artcraft, RouterSplatModel::TripoSplat) => build_artcraft_triposplat(self),
|
||||
// Fal
|
||||
(RouterProvider::Fal, RouterSplatModel::TripoSplat) => build_fal_triposplat(self),
|
||||
// World Labs
|
||||
(RouterProvider::WorldLabs, RouterSplatModel::Marble1p0 | RouterSplatModel::Marble0p1Plus) => build_worldlabs_marble_1p0(self),
|
||||
(RouterProvider::WorldLabs, RouterSplatModel::Marble1p0Draft | RouterSplatModel::Marble0p1Mini) => build_worldlabs_marble_1p0_draft(self),
|
||||
|
||||
+31
@@ -1,3 +1,6 @@
|
||||
use std::fmt::Debug;
|
||||
use std::sync::Arc;
|
||||
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -13,9 +16,30 @@ pub struct WorldLabsSplatResponsePayload {
|
||||
pub done: bool,
|
||||
}
|
||||
|
||||
/// Fal's queue/webhook submission receipt for a splat generation.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FalSplatResponsePayload {
|
||||
/// Fal's ID for the queued request. Present on queue submissions and on
|
||||
/// most webhook submissions.
|
||||
pub request_id: Option<String>,
|
||||
|
||||
/// Gateway request ID (webhook submissions).
|
||||
pub gateway_request_id: Option<String>,
|
||||
|
||||
/// Queue-mode status polling URL.
|
||||
pub maybe_status_url: Option<String>,
|
||||
|
||||
/// Queue-mode response URL.
|
||||
pub maybe_response_url: Option<String>,
|
||||
|
||||
/// The outbound request we sent, for debug logging.
|
||||
pub maybe_outbound_request: Option<Arc<dyn Debug + Send + Sync>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum GenerateSplatResponse {
|
||||
Artcraft(ArtcraftSplatResponsePayload),
|
||||
Fal(FalSplatResponsePayload),
|
||||
WorldLabs(WorldLabsSplatResponsePayload),
|
||||
}
|
||||
|
||||
@@ -27,6 +51,13 @@ impl GenerateSplatResponse {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_fal_payload(&self) -> Option<FalSplatResponsePayload> {
|
||||
match self {
|
||||
Self::Fal(p) => Some(p.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_worldlabs_payload(&self) -> Option<WorldLabsSplatResponsePayload> {
|
||||
match self {
|
||||
Self::WorldLabs(p) => Some(p.clone()),
|
||||
|
||||
+1
@@ -6,3 +6,4 @@ pub mod marble_1p0;
|
||||
pub mod marble_1p0_draft;
|
||||
pub mod marble_1p1;
|
||||
pub mod marble_1p1_plus;
|
||||
pub mod triposplat;
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
use enums::common::generation::common_splat_model::CommonSplatModel as CommonSplatModelEnum;
|
||||
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::generate::generate_splat::generate_splat_request_builder::GenerateSplatRequestBuilder;
|
||||
use crate::generate::generate_splat::providers::artcraft::build_common::build_artcraft_omni_splat_request;
|
||||
use crate::generate::generate_splat::providers::artcraft::triposplat::request::ArtcraftTripoSplatRequestState;
|
||||
use crate::generate::generate_splat::splat_generation_draft_or_request::SplatGenerationDraftOrRequest;
|
||||
use crate::generate::generate_splat::splat_generation_request::SplatGenerationRequest;
|
||||
|
||||
pub fn build_artcraft_triposplat(builder: GenerateSplatRequestBuilder) -> Result<SplatGenerationDraftOrRequest, ArtcraftRouterError> {
|
||||
let request = build_artcraft_omni_splat_request(builder, CommonSplatModelEnum::TripoSplat)?;
|
||||
let state = ArtcraftTripoSplatRequestState { request };
|
||||
Ok(SplatGenerationDraftOrRequest::Request(SplatGenerationRequest::ArtcraftTripoSplat(state)))
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
use crate::generate::generate_splat::providers::artcraft::cost_common::artcraft_splat_cost_estimate;
|
||||
use crate::generate::generate_splat::providers::artcraft::triposplat::request::ArtcraftTripoSplatRequestState;
|
||||
use crate::generate::generate_splat::splat_generation_cost_estimate::SplatGenerationCostEstimate;
|
||||
|
||||
const FLAT_COST_IN_USD_CENTS: u64 = 7;
|
||||
|
||||
/// TripoSplat via Artcraft is flat priced: it takes a single input image and
|
||||
/// no option affects the price.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ArtcraftTripoSplatCostState {
|
||||
pub cost_in_usd_cents: u64,
|
||||
}
|
||||
|
||||
impl ArtcraftTripoSplatCostState {
|
||||
pub fn from_request(_request: &ArtcraftTripoSplatRequestState) -> Self {
|
||||
Self { cost_in_usd_cents: FLAT_COST_IN_USD_CENTS }
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> SplatGenerationCostEstimate {
|
||||
artcraft_splat_cost_estimate(self.cost_in_usd_cents)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::api::router_provider::RouterProvider;
|
||||
use crate::api::router_splat_model::RouterSplatModel;
|
||||
use crate::generate::generate_splat::generate_splat_request_builder::GenerateSplatRequestBuilder;
|
||||
|
||||
#[test]
|
||||
fn flat_seven_cents() {
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
model: RouterSplatModel::TripoSplat,
|
||||
provider: RouterProvider::Artcraft,
|
||||
reference_images: Some(ImageListRef::MediaFileTokens(vec![
|
||||
MediaFileToken::new("mf_test123".to_string()),
|
||||
])),
|
||||
..Default::default()
|
||||
};
|
||||
let cost = builder.build2()
|
||||
.expect("build should succeed")
|
||||
.estimate_cost()
|
||||
.expect("estimate should succeed")
|
||||
.cost_in_usd_cents
|
||||
.expect("cost should be present");
|
||||
assert_eq!(cost, 7);
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
pub mod build;
|
||||
pub mod cost;
|
||||
pub mod request;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
use artcraft_api_defs::omni_gen::cost_and_generate_requests::omni_gen_splat_cost_and_generate_request::OmniGenSplatCostAndGenerateRequest;
|
||||
|
||||
use crate::client::router_artcraft_client::RouterArtcraftClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::generate::generate_splat::generate_splat_response::GenerateSplatResponse;
|
||||
use crate::generate::generate_splat::providers::artcraft::request_common::send_artcraft_omni_splat_request;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ArtcraftTripoSplatRequestState {
|
||||
pub request: OmniGenSplatCostAndGenerateRequest,
|
||||
}
|
||||
|
||||
impl ArtcraftTripoSplatRequestState {
|
||||
pub async fn send(&self, client: &RouterArtcraftClient) -> Result<GenerateSplatResponse, ArtcraftRouterError> {
|
||||
send_artcraft_omni_splat_request(&self.request, client).await
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
pub(crate) mod request_common;
|
||||
pub mod triposplat;
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
use std::fmt::Debug;
|
||||
use std::sync::Arc;
|
||||
|
||||
use fal_client::requests::traits::fal_endpoint_trait::FalEndpoint;
|
||||
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::generate::generate_splat::generate_splat_response::{
|
||||
FalSplatResponsePayload, GenerateSplatResponse,
|
||||
};
|
||||
|
||||
/// Send a splat request to fal using the client's dispatch mode (webhook or
|
||||
/// queue). Shared by all Fal splat request states.
|
||||
pub(crate) async fn send_fal_splat_request<R>(
|
||||
request: &R,
|
||||
client: &RouterFalClient,
|
||||
) -> Result<GenerateSplatResponse, ArtcraftRouterError>
|
||||
where
|
||||
R: FalEndpoint + Clone + Debug + Send + Sync + 'static,
|
||||
{
|
||||
let outbound: Arc<dyn Debug + Send + Sync> = Arc::new(request.clone());
|
||||
|
||||
let payload = if let Some(webhook_url) = &client.webhook_url {
|
||||
let response = request.send_webhook_request(&client.api_key, webhook_url).await?;
|
||||
FalSplatResponsePayload {
|
||||
request_id: response.request_id,
|
||||
gateway_request_id: response.gateway_request_id,
|
||||
maybe_status_url: None,
|
||||
maybe_response_url: None,
|
||||
maybe_outbound_request: Some(outbound),
|
||||
}
|
||||
} else {
|
||||
let response = request.send_queue_request(&client.api_key).await?;
|
||||
FalSplatResponsePayload {
|
||||
request_id: Some(response.request_id),
|
||||
gateway_request_id: None,
|
||||
maybe_status_url: Some(response.status_url),
|
||||
maybe_response_url: Some(response.response_url),
|
||||
maybe_outbound_request: Some(outbound),
|
||||
}
|
||||
};
|
||||
|
||||
Ok(GenerateSplatResponse::Fal(payload))
|
||||
}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
use fal_client::requests::api::splat::image::triposplat_image_to_splat::api::{
|
||||
TripoSplatImageToSplatRequest, TripoSplatOutputFormat,
|
||||
};
|
||||
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_mesh::providers::reject_unsupported::reject_unsupported_option;
|
||||
use crate::generate::generate_splat::generate_splat_request_builder::GenerateSplatRequestBuilder;
|
||||
use crate::generate::generate_splat::providers::fal::triposplat::request::FalTripoSplatRequestState;
|
||||
use crate::generate::generate_splat::splat_generation_draft_or_request::SplatGenerationDraftOrRequest;
|
||||
use crate::generate::generate_splat::splat_generation_request::SplatGenerationRequest;
|
||||
|
||||
/// TripoSplat takes exactly one input image and nothing else. Prompts,
|
||||
/// videos, panorama and recaption flags are unsupported: rejected under
|
||||
/// `ErrorOut`, dropped otherwise.
|
||||
pub fn build_fal_triposplat(builder: GenerateSplatRequestBuilder) -> Result<SplatGenerationDraftOrRequest, ArtcraftRouterError> {
|
||||
let state = build_fal_triposplat_state(builder)?;
|
||||
Ok(SplatGenerationDraftOrRequest::Request(SplatGenerationRequest::FalTripoSplat(state)))
|
||||
}
|
||||
|
||||
pub(crate) fn build_fal_triposplat_state(
|
||||
mut builder: GenerateSplatRequestBuilder,
|
||||
) -> Result<FalTripoSplatRequestState, ArtcraftRouterError> {
|
||||
let strategy = builder.request_mismatch_mitigation_strategy;
|
||||
|
||||
reject_unsupported_option("prompt", builder.prompt.as_ref(), strategy)?;
|
||||
reject_unsupported_option("reference_video", builder.reference_video.as_ref(), strategy)?;
|
||||
if builder.is_panoramic == Some(true) {
|
||||
reject_unsupported_option("is_panoramic", builder.is_panoramic.as_ref(), strategy)?;
|
||||
}
|
||||
reject_unsupported_option("disable_recaption", builder.disable_recaption.as_ref(), strategy)?;
|
||||
|
||||
let image_url = plan_single_image_url(builder.reference_images.take(), strategy)?
|
||||
.ok_or_else(|| {
|
||||
ArtcraftRouterError::InvalidInput(
|
||||
"TripoSplat requires an input image".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let request = TripoSplatImageToSplatRequest {
|
||||
image_url,
|
||||
num_gaussians: None,
|
||||
num_inference_steps: None,
|
||||
guidance_scale: None,
|
||||
// Always request PLY output — it's the format our pipeline stores.
|
||||
output_format: Some(TripoSplatOutputFormat::Ply),
|
||||
seed: None,
|
||||
enable_safety_checker: None,
|
||||
};
|
||||
Ok(FalTripoSplatRequestState { request })
|
||||
}
|
||||
|
||||
/// Resolve the single input image from `reference_images`. More than one
|
||||
/// image rejects under `ErrorOut`; the other strategies keep the first.
|
||||
/// Fal only takes URLs; media file tokens are rejected.
|
||||
fn plan_single_image_url(
|
||||
reference_images: Option<ImageListRef>,
|
||||
strategy: RequestMismatchMitigationStrategy,
|
||||
) -> Result<Option<String>, ArtcraftRouterError> {
|
||||
let urls = match reference_images {
|
||||
None => return Ok(None),
|
||||
Some(ImageListRef::Urls(urls)) => urls,
|
||||
Some(ImageListRef::MediaFileTokens(tokens)) if tokens.is_empty() => return Ok(None),
|
||||
Some(ImageListRef::MediaFileTokens(_)) => {
|
||||
return Err(ArtcraftRouterError::Client(ClientError::FalOnlySupportsUrls));
|
||||
}
|
||||
};
|
||||
|
||||
if urls.len() > 1 {
|
||||
if let RequestMismatchMitigationStrategy::ErrorOut = strategy {
|
||||
return Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "reference_images",
|
||||
value: format!("Expected at most 1 image, got {}", urls.len()),
|
||||
}));
|
||||
}
|
||||
}
|
||||
Ok(urls.into_iter().next())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::router_provider::RouterProvider;
|
||||
use crate::api::router_splat_model::RouterSplatModel;
|
||||
use crate::api::video_ref::VideoRef;
|
||||
|
||||
use super::*;
|
||||
|
||||
const IMAGE_URL: &str = "https://example.com/object.png";
|
||||
|
||||
mod input_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn single_image_builds() {
|
||||
let state = build_fal_triposplat_state(image_builder()).expect("build");
|
||||
assert_eq!(state.request.image_url, IMAGE_URL);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn output_format_is_always_ply() {
|
||||
let state = build_fal_triposplat_state(image_builder()).expect("build");
|
||||
assert_eq!(state.request.output_format, Some(TripoSplatOutputFormat::Ply));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_image_is_rejected() {
|
||||
let result = build_fal_triposplat_state(base_builder());
|
||||
assert!(matches!(result, Err(ArtcraftRouterError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn media_tokens_are_rejected() {
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
reference_images: Some(ImageListRef::MediaFileTokens(vec![
|
||||
MediaFileToken::new("mf_test123".to_string()),
|
||||
])),
|
||||
..base_builder()
|
||||
};
|
||||
assert!(matches!(
|
||||
build_fal_triposplat_state(builder),
|
||||
Err(ArtcraftRouterError::Client(ClientError::FalOnlySupportsUrls))
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_images_error_out_under_error_out() {
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
reference_images: Some(ImageListRef::Urls(vec![
|
||||
IMAGE_URL.to_string(),
|
||||
"https://example.com/second.png".to_string(),
|
||||
])),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
..base_builder()
|
||||
};
|
||||
assert!(build_fal_triposplat_state(builder).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_images_keep_the_first_under_lenient_strategies() {
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
reference_images: Some(ImageListRef::Urls(vec![
|
||||
IMAGE_URL.to_string(),
|
||||
"https://example.com/second.png".to_string(),
|
||||
])),
|
||||
..base_builder()
|
||||
};
|
||||
let state = build_fal_triposplat_state(builder).expect("build");
|
||||
assert_eq!(state.request.image_url, IMAGE_URL);
|
||||
}
|
||||
}
|
||||
|
||||
mod unsupported_option_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn unsupported_options_error_out_under_error_out() {
|
||||
let cases = [
|
||||
GenerateSplatRequestBuilder {
|
||||
prompt: Some("a cozy cabin".to_string()),
|
||||
..strict_image_builder()
|
||||
},
|
||||
GenerateSplatRequestBuilder {
|
||||
reference_video: Some(VideoRef::Url("https://example.com/v.mp4".to_string())),
|
||||
..strict_image_builder()
|
||||
},
|
||||
GenerateSplatRequestBuilder {
|
||||
is_panoramic: Some(true),
|
||||
..strict_image_builder()
|
||||
},
|
||||
GenerateSplatRequestBuilder {
|
||||
disable_recaption: Some(true),
|
||||
..strict_image_builder()
|
||||
},
|
||||
];
|
||||
for builder in cases {
|
||||
assert!(build_fal_triposplat_state(builder).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsupported_options_are_dropped_under_lenient_strategies() {
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
prompt: Some("a cozy cabin".to_string()),
|
||||
is_panoramic: Some(true),
|
||||
disable_recaption: Some(true),
|
||||
..image_builder()
|
||||
};
|
||||
assert!(build_fal_triposplat_state(builder).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_panoramic_false_is_not_a_mismatch() {
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
is_panoramic: Some(false),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
..image_builder()
|
||||
};
|
||||
assert!(build_fal_triposplat_state(builder).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
// ── Helpers ──
|
||||
|
||||
fn base_builder() -> GenerateSplatRequestBuilder {
|
||||
GenerateSplatRequestBuilder {
|
||||
model: RouterSplatModel::TripoSplat,
|
||||
provider: RouterProvider::Fal,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn image_builder() -> GenerateSplatRequestBuilder {
|
||||
GenerateSplatRequestBuilder {
|
||||
reference_images: Some(ImageListRef::Urls(vec![IMAGE_URL.to_string()])),
|
||||
..base_builder()
|
||||
}
|
||||
}
|
||||
|
||||
fn strict_image_builder() -> GenerateSplatRequestBuilder {
|
||||
GenerateSplatRequestBuilder {
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
..image_builder()
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
|
||||
use crate::generate::generate_splat::providers::fal::triposplat::request::FalTripoSplatRequestState;
|
||||
use crate::generate::generate_splat::splat_generation_cost_estimate::SplatGenerationCostEstimate;
|
||||
|
||||
/// Cost math is owned by fal_client's `FalRequestCostCalculator` — the
|
||||
/// router state just forwards the result so router cost ≡ fal_client cost
|
||||
/// by construction. TripoSplat is flat 5¢.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FalTripoSplatCostState {
|
||||
pub cost_in_usd_cents: u64,
|
||||
}
|
||||
|
||||
impl FalTripoSplatCostState {
|
||||
pub fn from_request(request: &FalTripoSplatRequestState) -> Self {
|
||||
Self {
|
||||
cost_in_usd_cents: request.request.calculate_cost_in_cents(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> SplatGenerationCostEstimate {
|
||||
SplatGenerationCostEstimate {
|
||||
cost_in_credits: Some(self.cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(self.cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
failures_are_refunded: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::api::router_provider::RouterProvider;
|
||||
use crate::api::router_splat_model::RouterSplatModel;
|
||||
use crate::generate::generate_splat::generate_splat_request_builder::GenerateSplatRequestBuilder;
|
||||
|
||||
#[test]
|
||||
fn flat_five_cents() {
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
model: RouterSplatModel::TripoSplat,
|
||||
provider: RouterProvider::Fal,
|
||||
reference_images: Some(ImageListRef::Urls(vec![
|
||||
"https://example.com/object.png".to_string(),
|
||||
])),
|
||||
..Default::default()
|
||||
};
|
||||
let cost = builder.build2()
|
||||
.expect("build should succeed")
|
||||
.estimate_cost()
|
||||
.expect("estimate should succeed")
|
||||
.cost_in_usd_cents
|
||||
.expect("cost should be present");
|
||||
assert_eq!(cost, 5);
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
pub mod build;
|
||||
pub mod cost;
|
||||
pub mod request;
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
use fal_client::requests::api::splat::image::triposplat_image_to_splat::api::TripoSplatImageToSplatRequest;
|
||||
|
||||
use crate::client::router_fal_client::RouterFalClient;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::generate::generate_splat::generate_splat_response::GenerateSplatResponse;
|
||||
use crate::generate::generate_splat::providers::fal::request_common::send_fal_splat_request;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FalTripoSplatRequestState {
|
||||
/// Final materialized request; ready to fire.
|
||||
pub request: TripoSplatImageToSplatRequest,
|
||||
}
|
||||
|
||||
impl FalTripoSplatRequestState {
|
||||
pub async fn send(&self, client: &RouterFalClient) -> Result<GenerateSplatResponse, ArtcraftRouterError> {
|
||||
send_fal_splat_request(&self.request, client).await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test_data::web::image_urls::ERNEST_SCARED_STUPID_IMAGE_URL;
|
||||
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::api::router_provider::RouterProvider;
|
||||
use crate::api::router_splat_model::RouterSplatModel;
|
||||
use crate::generate::generate_splat::generate_splat_request_builder::GenerateSplatRequestBuilder;
|
||||
use crate::generate::generate_splat::generate_splat_response::GenerateSplatResponse;
|
||||
use crate::generate::generate_splat::splat_generation_draft_or_request::SplatGenerationDraftOrRequest;
|
||||
use crate::test_helpers::get_fal_client;
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // requires real API key, incurs cost
|
||||
async fn send_triposplat_image_to_splat() {
|
||||
let client = get_fal_client();
|
||||
|
||||
let builder = GenerateSplatRequestBuilder {
|
||||
model: RouterSplatModel::TripoSplat,
|
||||
provider: RouterProvider::Fal,
|
||||
reference_images: Some(ImageListRef::Urls(vec![
|
||||
ERNEST_SCARED_STUPID_IMAGE_URL.to_string(),
|
||||
])),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let draft_or_request = builder.build2().expect("build2 should succeed");
|
||||
let request = match draft_or_request {
|
||||
SplatGenerationDraftOrRequest::Request(r) => r,
|
||||
_ => panic!("expected Request variant (Fal splat skips draft)"),
|
||||
};
|
||||
|
||||
let response = request.send_request(&client).await.expect("send_request should succeed");
|
||||
println!("response: {:?}", response);
|
||||
|
||||
let payload = match response {
|
||||
GenerateSplatResponse::Fal(p) => p,
|
||||
other => panic!("expected Fal payload, got {other:?}"),
|
||||
};
|
||||
assert!(payload.request_id.is_some() || payload.gateway_request_id.is_some());
|
||||
assert_eq!(1, 2, "Inspect output above");
|
||||
}
|
||||
}
|
||||
+1
@@ -1,2 +1,3 @@
|
||||
pub mod artcraft;
|
||||
pub mod fal;
|
||||
pub mod worldlabs;
|
||||
|
||||
+18
@@ -10,6 +10,10 @@ use crate::generate::generate_splat::providers::artcraft::marble_1p1::cost::Artc
|
||||
use crate::generate::generate_splat::providers::artcraft::marble_1p1::request::ArtcraftMarble1p1RequestState;
|
||||
use crate::generate::generate_splat::providers::artcraft::marble_1p1_plus::cost::ArtcraftMarble1p1PlusCostState;
|
||||
use crate::generate::generate_splat::providers::artcraft::marble_1p1_plus::request::ArtcraftMarble1p1PlusRequestState;
|
||||
use crate::generate::generate_splat::providers::artcraft::triposplat::cost::ArtcraftTripoSplatCostState;
|
||||
use crate::generate::generate_splat::providers::artcraft::triposplat::request::ArtcraftTripoSplatRequestState;
|
||||
use crate::generate::generate_splat::providers::fal::triposplat::cost::FalTripoSplatCostState;
|
||||
use crate::generate::generate_splat::providers::fal::triposplat::request::FalTripoSplatRequestState;
|
||||
use crate::generate::generate_splat::providers::worldlabs::marble_1p0::cost::WorldLabsMarble1p0CostState;
|
||||
use crate::generate::generate_splat::providers::worldlabs::marble_1p0::request::WorldLabsMarble1p0RequestState;
|
||||
use crate::generate::generate_splat::providers::worldlabs::marble_1p0_draft::cost::WorldLabsMarble1p0DraftModelCostState;
|
||||
@@ -26,6 +30,8 @@ pub enum SplatGenerationRequest {
|
||||
ArtcraftMarble1p0Draft(ArtcraftMarble1p0DraftRequestState),
|
||||
ArtcraftMarble1p1(ArtcraftMarble1p1RequestState),
|
||||
ArtcraftMarble1p1Plus(ArtcraftMarble1p1PlusRequestState),
|
||||
ArtcraftTripoSplat(ArtcraftTripoSplatRequestState),
|
||||
FalTripoSplat(FalTripoSplatRequestState),
|
||||
WorldLabsMarble1p0(WorldLabsMarble1p0RequestState),
|
||||
WorldLabsMarble1p0Draft(WorldLabsMarble1p0DraftModelRequestState),
|
||||
WorldLabsMarble1p1(WorldLabsMarble1p1RequestState),
|
||||
@@ -40,6 +46,8 @@ impl SplatGenerationRequest {
|
||||
Self::ArtcraftMarble1p0Draft(_) => RouterProvider::Artcraft,
|
||||
Self::ArtcraftMarble1p1(_) => RouterProvider::Artcraft,
|
||||
Self::ArtcraftMarble1p1Plus(_) => RouterProvider::Artcraft,
|
||||
Self::ArtcraftTripoSplat(_) => RouterProvider::Artcraft,
|
||||
Self::FalTripoSplat(_) => RouterProvider::Fal,
|
||||
Self::WorldLabsMarble1p0(_) => RouterProvider::WorldLabs,
|
||||
Self::WorldLabsMarble1p0Draft(_) => RouterProvider::WorldLabs,
|
||||
Self::WorldLabsMarble1p1(_) => RouterProvider::WorldLabs,
|
||||
@@ -54,6 +62,8 @@ impl SplatGenerationRequest {
|
||||
SplatGenerationRequest::ArtcraftMarble1p0Draft(request) => Ok(ArtcraftMarble1p0DraftCostState::from_request(request).estimate_cost()),
|
||||
SplatGenerationRequest::ArtcraftMarble1p1(request) => Ok(ArtcraftMarble1p1CostState::from_request(request).estimate_cost()),
|
||||
SplatGenerationRequest::ArtcraftMarble1p1Plus(request) => Ok(ArtcraftMarble1p1PlusCostState::from_request(request).estimate_cost()),
|
||||
SplatGenerationRequest::ArtcraftTripoSplat(request) => Ok(ArtcraftTripoSplatCostState::from_request(request).estimate_cost()),
|
||||
SplatGenerationRequest::FalTripoSplat(request) => Ok(FalTripoSplatCostState::from_request(request).estimate_cost()),
|
||||
SplatGenerationRequest::WorldLabsMarble1p0(request) => Ok(WorldLabsMarble1p0CostState::from_request(request).estimate_cost()),
|
||||
SplatGenerationRequest::WorldLabsMarble1p0Draft(request) => Ok(WorldLabsMarble1p0DraftModelCostState::from_request(request).estimate_cost()),
|
||||
SplatGenerationRequest::WorldLabsMarble1p1(request) => Ok(WorldLabsMarble1p1CostState::from_request(request).estimate_cost()),
|
||||
@@ -81,6 +91,14 @@ impl SplatGenerationRequest {
|
||||
let client_ref = client.get_artcraft_client_ref()?;
|
||||
request.send(client_ref).await
|
||||
},
|
||||
SplatGenerationRequest::ArtcraftTripoSplat(request) => {
|
||||
let client_ref = client.get_artcraft_client_ref()?;
|
||||
request.send(client_ref).await
|
||||
},
|
||||
SplatGenerationRequest::FalTripoSplat(request) => {
|
||||
let client_ref = client.get_fal_client_ref()?;
|
||||
request.send(client_ref).await
|
||||
},
|
||||
SplatGenerationRequest::WorldLabsMarble1p0(request) => {
|
||||
let client_ref = client.get_worldlabs_client_ref()?;
|
||||
request.send(client_ref).await
|
||||
|
||||
+13
-18
@@ -1,7 +1,6 @@
|
||||
use enums::common::generation::common_video_model::CommonVideoModel as CommonVideoModelEnum;
|
||||
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_video::generate_video_request_builder::GenerateVideoRequestBuilder;
|
||||
use crate::generate::generate_video::providers::artcraft::build_common::{
|
||||
build_artcraft_omni_video_request, SupportedResolutions, UltraWideSupport,
|
||||
@@ -27,17 +26,10 @@ pub fn build_artcraft_grok_imagine_video_1p5(
|
||||
UltraWideSupport::Unsupported,
|
||||
)?;
|
||||
|
||||
// xAI's v1.5 model rejects text-to-video at the server. Bounce here rather
|
||||
// than spending an upstream call to learn the same thing.
|
||||
if request.start_frame_image_media_token.is_none()
|
||||
&& request.reference_image_media_tokens.as_ref().map_or(true, |v| v.is_empty())
|
||||
{
|
||||
return Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_inputs",
|
||||
value: "text-to-video isn't supported by grok-imagine-video-1.5; supply a start_frame or at least one reference image".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
// NB: xAI's v1.5 model rejects text-to-video at the server, but that is
|
||||
// NOT enforced here — the cost path builds image-less requests to price
|
||||
// them while the user is still composing. The generate endpoints reject
|
||||
// image-less v1.5 requests at the handler layer (validate_when_image_required).
|
||||
let state = ArtcraftGrokImagineVideo1p5RequestState { request };
|
||||
|
||||
Ok(VideoGenerationDraftOrRequest::Request(
|
||||
@@ -129,6 +121,15 @@ mod tests {
|
||||
mod media_token_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn builds_without_any_image_inputs() {
|
||||
// The cost path prices image-less requests while the user is still
|
||||
// composing; the generate endpoints enforce the image requirement.
|
||||
let req = unwrap_request(make_builder(|_| {}));
|
||||
assert!(req.request.start_frame_image_media_token.is_none());
|
||||
assert!(req.request.reference_image_media_tokens.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn start_frame_token_passed_through() {
|
||||
let token = MediaFileToken::new("mf_start".to_string());
|
||||
@@ -180,12 +181,6 @@ mod tests {
|
||||
fn make_builder(f: impl FnOnce(&mut GenerateVideoRequestBuilder)) -> GenerateVideoRequestBuilder {
|
||||
let mut builder = base_builder();
|
||||
f(&mut builder);
|
||||
// v1.5 requires an input image; tests that don't explicitly exercise the
|
||||
// image-handling paths get a default MediaFileToken start_frame so they
|
||||
// sail past the no-image guard in `build()`.
|
||||
if builder.start_frame.is_none() && builder.reference_images.is_none() {
|
||||
builder.start_frame = Some(ImageRef::MediaFileToken(MediaFileToken::new("mf_default".to_string())));
|
||||
}
|
||||
builder
|
||||
}
|
||||
|
||||
|
||||
+37
-24
@@ -9,7 +9,6 @@ use grok_api_client::api::types::video_types::video_model::VideoModel as GrokVid
|
||||
use grok_api_client::api::types::video_types::video_resolution::VideoResolution as GrokResolution;
|
||||
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::client_error::ClientError;
|
||||
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
|
||||
use crate::generate::generate_video::providers::artcraft::grok_imagine_video_1p5::request::ArtcraftGrokImagineVideo1p5RequestState;
|
||||
|
||||
@@ -65,16 +64,10 @@ impl ArtcraftGrokImagineVideo1p5CostState {
|
||||
}
|
||||
|
||||
pub fn estimate_cost(&self) -> Result<VideoGenerationCostEstimate, ArtcraftRouterError> {
|
||||
// Defense in depth: `build()` already enforces this, but a state
|
||||
// constructed by hand must not get a quote for an operation xAI will
|
||||
// reject.
|
||||
if self.input_image_count == 0 {
|
||||
return Err(ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption {
|
||||
field: "image_inputs",
|
||||
value: "text-to-video isn't supported by grok-imagine-video-1.5; supply a start_frame or at least one reference image".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
// NB: Image-less requests DO get a quote even though xAI's v1.5 rejects
|
||||
// text-to-video — the cost path prices requests the user is still
|
||||
// composing. The image requirement is enforced at send time (request.rs)
|
||||
// and by the generate endpoints.
|
||||
let base = self.base_cost_in_cents_for_batch();
|
||||
// 5% markup, ceil so the user is always charged enough to cover the
|
||||
// upstream grok cost regardless of rounding.
|
||||
@@ -204,24 +197,23 @@ mod tests {
|
||||
assert_eq!(state.estimate_cost().expect("estimate_cost").cost_in_usd_cents.unwrap(), 150);
|
||||
}
|
||||
|
||||
/// v1.5 doesn't support text-to-video. The cost calculator must refuse
|
||||
/// to quote an image-less request even if a state is constructed
|
||||
/// directly.
|
||||
/// v1.5 doesn't support text-to-video at generation time, but the cost
|
||||
/// calculator still quotes an image-less request — the cost UI prices
|
||||
/// requests before the user has attached an image. The requirement is
|
||||
/// enforced at send time and by the generate endpoints.
|
||||
#[test]
|
||||
fn estimate_cost_rejects_text_only_request() {
|
||||
fn estimate_cost_quotes_text_only_request() {
|
||||
let state = ArtcraftGrokImagineVideo1p5CostState {
|
||||
resolution: CommonResolution::SevenTwentyP,
|
||||
duration_seconds: 5,
|
||||
batch_count: 1,
|
||||
input_image_count: 0,
|
||||
};
|
||||
let err = state.estimate_cost().expect_err("text-only should be rejected");
|
||||
match err {
|
||||
ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption { field, .. }) => {
|
||||
assert_eq!(field, "image_inputs");
|
||||
}
|
||||
other => panic!("expected Client(ModelDoesNotSupportOption), got {:?}", other),
|
||||
}
|
||||
let base = state.base_cost_in_cents_for_batch();
|
||||
let want = base.saturating_mul(MARKUP_NUMERATOR).div_ceil(MARKUP_DENOMINATOR);
|
||||
let got = state.estimate_cost().expect("estimate_cost").cost_in_usd_cents.unwrap();
|
||||
assert_eq!(got, want);
|
||||
assert!(got > 0);
|
||||
}
|
||||
|
||||
// (resolution, duration, image_count, batch) — every case has at least
|
||||
@@ -326,6 +318,28 @@ mod tests {
|
||||
.cost_in_usd_cents.unwrap();
|
||||
assert!(p1080 > p720, "1080p ({p1080}) should cost more than 720p ({p720})");
|
||||
}
|
||||
|
||||
/// Regression: an image-less v1.5 request must get a quote through the
|
||||
/// full public builder path (build2 → estimate_cost). The cost UI polls
|
||||
/// for a price before the user has attached an image; the image
|
||||
/// requirement is enforced at send time and by the generate endpoints,
|
||||
/// NOT here.
|
||||
#[test]
|
||||
fn image_less_request_gets_a_quote_through_the_builder() {
|
||||
let builder = GenerateVideoRequestBuilder {
|
||||
model: RouterVideoModel::GrokImagineVideo1p5,
|
||||
provider: RouterProvider::Artcraft,
|
||||
duration_seconds: Some(5),
|
||||
video_batch_count: Some(1),
|
||||
..Default::default()
|
||||
};
|
||||
let cost = builder.build2()
|
||||
.expect("build2 should succeed without an image")
|
||||
.estimate_cost()
|
||||
.expect("estimate_cost should succeed without an image");
|
||||
assert!(cost.cost_in_usd_cents.unwrap() > 0);
|
||||
assert_eq!(cost.cost_in_credits, cost.cost_in_usd_cents);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────────
|
||||
@@ -390,8 +404,7 @@ mod tests {
|
||||
resolution,
|
||||
duration_seconds: Some(duration_seconds),
|
||||
video_batch_count: Some(video_batch_count),
|
||||
// v1.5 requires an input image — the no-image guard in build()
|
||||
// rejects T2V.
|
||||
// These cases price the image-to-video tier (one input image).
|
||||
start_frame: Some(ImageRef::MediaFileToken(MediaFileToken::new("mf_default".to_string()))),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
+57
-2
@@ -13,8 +13,11 @@ pub struct ArtcraftGrokImagineVideo1p5RequestState {
|
||||
|
||||
impl ArtcraftGrokImagineVideo1p5RequestState {
|
||||
pub async fn send(&self, client: &RouterArtcraftClient) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
// Defense in depth: `build()` already enforces this. Bouncing here costs
|
||||
// nothing and avoids an upstream call we know will fail.
|
||||
// xAI's v1.5 model rejects text-to-video at the server. This is the
|
||||
// GENERATION-time guard — `build()` and `estimate_cost()` deliberately
|
||||
// allow image-less states so the cost path can quote a request the user
|
||||
// is still composing. Bouncing here costs nothing and avoids an upstream
|
||||
// call we know will fail.
|
||||
if self.request.start_frame_image_media_token.is_none()
|
||||
&& self.request.reference_image_media_tokens.as_ref().map_or(true, |v| v.is_empty())
|
||||
{
|
||||
@@ -27,3 +30,55 @@ impl ArtcraftGrokImagineVideo1p5RequestState {
|
||||
send_artcraft_omni_video_request(&self.request, client).await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use artcraft_client::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use artcraft_client::utils::api_host::ApiHost;
|
||||
use enums::common::generation::common_video_model::CommonVideoModel as CommonVideoModelEnum;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// Generation must never reach xAI with an image-less v1.5 request. The
|
||||
/// build/cost layers allow that state (the cost path quotes it), so the
|
||||
/// send-time guard is the router's last line of defense.
|
||||
#[tokio::test]
|
||||
async fn send_rejects_image_less_request_before_any_network_call() {
|
||||
let state = ArtcraftGrokImagineVideo1p5RequestState {
|
||||
request: OmniGenVideoCostAndGenerateRequest {
|
||||
idempotency_token: Some("a1b2c3d4-e5f6-7890-abcd-ef1234567890".to_string()),
|
||||
model: Some(CommonVideoModelEnum::GrokImagineVideo1p5),
|
||||
prompt: Some("a corgi running through a field".to_string()),
|
||||
negative_prompt: None,
|
||||
start_frame_image_media_token: None,
|
||||
end_frame_image_media_token: None,
|
||||
reference_image_media_tokens: None,
|
||||
reference_video_media_tokens: None,
|
||||
reference_audio_media_tokens: None,
|
||||
reference_character_tokens: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
bitrate: None,
|
||||
quality: None,
|
||||
duration_seconds: Some(5),
|
||||
video_batch_count: Some(1),
|
||||
generate_audio: None,
|
||||
},
|
||||
};
|
||||
|
||||
// The guard fires before the client is used, so an unroutable localhost
|
||||
// client with empty credentials proves no network call happens.
|
||||
let client = RouterArtcraftClient::new(
|
||||
ApiHost::Localhost { port: 1 },
|
||||
StorytellerCredentialSet::empty(),
|
||||
);
|
||||
|
||||
let err = state.send(&client).await.expect_err("image-less send should be rejected");
|
||||
match err {
|
||||
ArtcraftRouterError::Client(ClientError::ModelDoesNotSupportOption { field, .. }) => {
|
||||
assert_eq!(field, "image_inputs");
|
||||
}
|
||||
other => panic!("expected Client(ModelDoesNotSupportOption), got {:?}", other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod audio;
|
||||
pub mod image;
|
||||
pub mod mesh;
|
||||
pub mod splat;
|
||||
pub mod video;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod triposplat_image_to_splat;
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
use crate::error::fal_error_plus::FalErrorPlus;
|
||||
use crate::requests::api::splat::image::triposplat_image_to_splat::raw_request::{
|
||||
TripoSplatImageToSplatInput, TripoSplatImageToSplatOutput,
|
||||
};
|
||||
use crate::requests::traits::fal_endpoint_trait::FalEndpoint;
|
||||
|
||||
/// TripoSplat image-to-Gaussian-splat: reconstructs a 3D Gaussian splat from
|
||||
/// a single input image.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TripoSplatImageToSplatRequest {
|
||||
/// URL of the input image (required).
|
||||
pub image_url: String,
|
||||
|
||||
/// Number of Gaussians to generate. Range 32768-262144;
|
||||
/// fal's default is 262144 when `None`.
|
||||
pub num_gaussians: Option<u32>,
|
||||
|
||||
/// Number of inference steps. Range 1-50; fal's default is 20 when `None`.
|
||||
pub num_inference_steps: Option<u32>,
|
||||
|
||||
/// Guidance scale. Range 0-10; fal's default is 3 when `None`.
|
||||
pub guidance_scale: Option<f32>,
|
||||
|
||||
/// Output file format. fal's default is `Ply` when `None`.
|
||||
pub output_format: Option<TripoSplatOutputFormat>,
|
||||
|
||||
/// Seed for reproducibility. fal picks a random seed when `None`.
|
||||
pub seed: Option<i64>,
|
||||
|
||||
/// fal's default is true when `None`.
|
||||
pub enable_safety_checker: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum TripoSplatOutputFormat {
|
||||
Ply,
|
||||
Splat,
|
||||
}
|
||||
|
||||
impl TripoSplatOutputFormat {
|
||||
pub(crate) fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Ply => "ply",
|
||||
Self::Splat => "splat",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FalEndpoint for TripoSplatImageToSplatRequest {
|
||||
const ENDPOINT: &str = "tripo3d/triposplat";
|
||||
|
||||
type RawRequest = TripoSplatImageToSplatInput;
|
||||
type RawResponse = TripoSplatImageToSplatOutput;
|
||||
|
||||
fn to_raw_request(&self) -> Result<Self::RawRequest, FalErrorPlus> {
|
||||
Ok(Self::RawRequest {
|
||||
image_url: self.image_url.clone(),
|
||||
num_gaussians: self.num_gaussians,
|
||||
num_inference_steps: self.num_inference_steps,
|
||||
guidance_scale: self.guidance_scale,
|
||||
output_format: self.output_format.map(|f| f.to_str().to_string()),
|
||||
seed: self.seed,
|
||||
enable_safety_checker: self.enable_safety_checker,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::traits::fal_endpoint_trait::FalEndpoint;
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
use test_data::web::image_urls::ERNEST_SCARED_STUPID_IMAGE_URL;
|
||||
|
||||
mod serialization_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn minimal_request_serializes_image_url_only() {
|
||||
let raw = base_request().to_raw_request().expect("to_raw_request");
|
||||
let json = serde_json::to_value(&raw).unwrap();
|
||||
let obj = json.as_object().unwrap();
|
||||
assert_eq!(obj.len(), 1, "only image_url should serialize: {json}");
|
||||
assert_eq!(json["image_url"], "https://example.com/input.png");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn output_format_wire_values() {
|
||||
assert_eq!(TripoSplatOutputFormat::Ply.to_str(), "ply");
|
||||
assert_eq!(TripoSplatOutputFormat::Splat.to_str(), "splat");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn full_request_serializes_all_fields() {
|
||||
let request = TripoSplatImageToSplatRequest {
|
||||
num_gaussians: Some(131_072),
|
||||
num_inference_steps: Some(30),
|
||||
guidance_scale: Some(5.0),
|
||||
output_format: Some(TripoSplatOutputFormat::Ply),
|
||||
seed: Some(42),
|
||||
enable_safety_checker: Some(false),
|
||||
..base_request()
|
||||
};
|
||||
let raw = request.to_raw_request().expect("to_raw_request");
|
||||
let json = serde_json::to_value(&raw).unwrap();
|
||||
assert_eq!(json["num_gaussians"], 131_072);
|
||||
assert_eq!(json["num_inference_steps"], 30);
|
||||
assert_eq!(json["guidance_scale"], 5.0);
|
||||
assert_eq!(json["output_format"], "ply");
|
||||
assert_eq!(json["seed"], 42);
|
||||
assert_eq!(json["enable_safety_checker"], false);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Helpers ──
|
||||
|
||||
fn base_request() -> TripoSplatImageToSplatRequest {
|
||||
TripoSplatImageToSplatRequest {
|
||||
image_url: "https://example.com/input.png".to_string(),
|
||||
num_gaussians: None,
|
||||
num_inference_steps: None,
|
||||
guidance_scale: None,
|
||||
output_format: None,
|
||||
seed: None,
|
||||
enable_safety_checker: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request and incurs cost
|
||||
async fn test_image_to_splat_webhook() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
let request = TripoSplatImageToSplatRequest {
|
||||
image_url: ERNEST_SCARED_STUPID_IMAGE_URL.to_string(),
|
||||
..base_request()
|
||||
};
|
||||
let result = request.send_webhook_request(&api_key, "https://example.com/webhook").await?;
|
||||
println!("Webhook result: {:?}", result);
|
||||
assert!(result.request_id.is_some() || result.gateway_request_id.is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request and incurs cost
|
||||
async fn test_image_to_splat_queue() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
let request = TripoSplatImageToSplatRequest {
|
||||
image_url: ERNEST_SCARED_STUPID_IMAGE_URL.to_string(),
|
||||
..base_request()
|
||||
};
|
||||
let result = request.send_queue_request(&api_key).await?;
|
||||
println!("Queue result — request_id: {}", result.request_id);
|
||||
assert!(!result.request_id.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
use crate::requests::api::splat::image::triposplat_image_to_splat::api::TripoSplatImageToSplatRequest;
|
||||
use crate::requests::traits::fal_request_cost_calculator_trait::{FalRequestCostCalculator, UsdCents};
|
||||
|
||||
impl FalRequestCostCalculator for TripoSplatImageToSplatRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Pricing (see https://fal.ai/models/tripo3d/triposplat):
|
||||
// "Price: $0.05 per generations"
|
||||
5
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::requests::api::splat::image::triposplat_image_to_splat::api::TripoSplatOutputFormat;
|
||||
|
||||
fn base_request() -> TripoSplatImageToSplatRequest {
|
||||
TripoSplatImageToSplatRequest {
|
||||
image_url: "https://example.com/input.png".to_string(),
|
||||
num_gaussians: None,
|
||||
num_inference_steps: None,
|
||||
guidance_scale: None,
|
||||
output_format: None,
|
||||
seed: None,
|
||||
enable_safety_checker: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flat_five_cents() {
|
||||
assert_eq!(base_request().calculate_cost_in_cents(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn options_do_not_change_cost() {
|
||||
let request = TripoSplatImageToSplatRequest {
|
||||
num_gaussians: Some(32_768),
|
||||
num_inference_steps: Some(50),
|
||||
guidance_scale: Some(10.0),
|
||||
output_format: Some(TripoSplatOutputFormat::Splat),
|
||||
seed: Some(7),
|
||||
enable_safety_checker: Some(false),
|
||||
..base_request()
|
||||
};
|
||||
assert_eq!(request.calculate_cost_in_cents(), 5);
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
pub mod api;
|
||||
pub mod cost;
|
||||
pub mod raw_request;
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Over-the-wire input shape for `tripo3d/triposplat` (image-to-Gaussian-splat).
|
||||
/// fal's schema: <https://fal.ai/models/tripo3d/triposplat/api>
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct TripoSplatImageToSplatInput {
|
||||
/// URL of the input image.
|
||||
pub image_url: String,
|
||||
|
||||
/// Number of Gaussians to generate. Range 32768-262144.
|
||||
/// fal default: 262144.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub num_gaussians: Option<u32>,
|
||||
|
||||
/// Number of inference steps. Range 1-50. fal default: 20.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub num_inference_steps: Option<u32>,
|
||||
|
||||
/// Guidance scale. Range 0-10. fal default: 3.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub guidance_scale: Option<f32>,
|
||||
|
||||
/// Options: "ply", "splat". fal default: "ply".
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub output_format: Option<String>,
|
||||
|
||||
/// Seed for reproducibility. fal default: random.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub seed: Option<i64>,
|
||||
|
||||
/// fal default: true.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub enable_safety_checker: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct TripoSplatImageToSplatOutput {}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod image;
|
||||
@@ -26,7 +26,7 @@ pub async fn seed_test_videos(mysql_pool: &Pool<MySql>, user_token: UserToken) -
|
||||
let media1 = InsertArgs {
|
||||
pool: &mysql_pool,
|
||||
maybe_use_apriori_media_token: Some(&model_weight_token1),
|
||||
media_file_type: MediaFileType::Video,
|
||||
media_file_type: MediaFileType::Mp4,
|
||||
maybe_mime_type: Some(&*metadata1.mimetype),
|
||||
file_size_bytes: metadata1.file_size_bytes,
|
||||
sha256_checksum: &metadata1.sha256_checksum,
|
||||
|
||||
@@ -29,16 +29,16 @@ pub async fn seed_media_files(mysql_pool: &Pool<MySql>, maybe_bucket_clients: Op
|
||||
// Delete the records if you want to re-seed.
|
||||
let media_files = [
|
||||
// Audio
|
||||
(HANASHI_USER_TOKEN, "m_21jxt406aattq2cna1xtgf5m4mjyyr", MediaFileType::Audio, "media/audio/voice-samples/biden.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_cxzabpxf88h10rshqraksxbqmhs41h", MediaFileType::Audio, "media/audio/voice-samples/brandon1.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_sq2vhrrmmbr079afk21543aa2jg53g", MediaFileType::Audio, "media/audio/voice-samples/brandon2.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_s61a8g3jnddr3xdg3gctsjxxk9jwja", MediaFileType::Audio, "media/audio/voice-samples/elon.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_e59fh75g76pvebx4qe4r4aymd93q30", MediaFileType::Audio, "media/audio/voice-samples/goku.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_ttq0ym8ht4v0z87zqz27fhadp0743c", MediaFileType::Audio, "media/audio/voice-samples/hillary.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_300bv6f141hv553fjf287p5gb76k37", MediaFileType::Audio, "media/audio/voice-samples/mario_impersonator.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_rd1ey2jem8a37r3vna2h9mht6zevs5", MediaFileType::Audio, "media/audio/voice-samples/rick.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_8n5epqfvs2vh60khap0s3ezem4epkc", MediaFileType::Audio, "media/audio/voice-samples/trump.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_g6dpwcpq51e6kvmpbbkdvgxfan9k1k", MediaFileType::Audio, "media/audio/voice-samples/trump_tts.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_21jxt406aattq2cna1xtgf5m4mjyyr", MediaFileType::Wav, "media/audio/voice-samples/biden.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_cxzabpxf88h10rshqraksxbqmhs41h", MediaFileType::Wav, "media/audio/voice-samples/brandon1.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_sq2vhrrmmbr079afk21543aa2jg53g", MediaFileType::Wav, "media/audio/voice-samples/brandon2.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_s61a8g3jnddr3xdg3gctsjxxk9jwja", MediaFileType::Wav, "media/audio/voice-samples/elon.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_e59fh75g76pvebx4qe4r4aymd93q30", MediaFileType::Wav, "media/audio/voice-samples/goku.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_ttq0ym8ht4v0z87zqz27fhadp0743c", MediaFileType::Wav, "media/audio/voice-samples/hillary.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_300bv6f141hv553fjf287p5gb76k37", MediaFileType::Wav, "media/audio/voice-samples/mario_impersonator.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_rd1ey2jem8a37r3vna2h9mht6zevs5", MediaFileType::Wav, "media/audio/voice-samples/rick.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_8n5epqfvs2vh60khap0s3ezem4epkc", MediaFileType::Wav, "media/audio/voice-samples/trump.wav"),
|
||||
(HANASHI_USER_TOKEN, "m_g6dpwcpq51e6kvmpbbkdvgxfan9k1k", MediaFileType::Wav, "media/audio/voice-samples/trump_tts.wav"),
|
||||
// Images
|
||||
(HANASHI_USER_TOKEN, "m_cn5t6ywm9k1ge9qzzxst5krc5tm08m", MediaFileType::Jpg, "media/image/face-animator-inputs/bill.jpg"),
|
||||
(HANASHI_USER_TOKEN, "m_nf9xebrr8hd1bxkfy7src5k8nv2dzy", MediaFileType::Jpg, "media/image/face-animator-inputs/elon.jpg"),
|
||||
@@ -48,18 +48,18 @@ pub async fn seed_media_files(mysql_pool: &Pool<MySql>, maybe_bucket_clients: Op
|
||||
(HANASHI_USER_TOKEN, "m_we7mnzbd76g4yn19dm6m53er0pjvew", MediaFileType::Png, "media/image/face-animator-inputs/san.png"),
|
||||
(HANASHI_USER_TOKEN, "m_wahwz92nxxfg0x42dw9fdrhwq30yk0", MediaFileType::Jpg, "media/image/face-animator-inputs/zelda.jpg"),
|
||||
// Video
|
||||
(HANASHI_USER_TOKEN, "m_gedarcfdkxx3zv8zz2wmwsnc1r8jbp", MediaFileType::Video, "media/video/storyteller-studio-renders/girl-rotating-room.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_3s74yyd4jwrjdp17yx1694n29jv5gr", MediaFileType::Video, "media/video/storyteller-studio-renders/hanashi-run.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_p6d64gm1wawz25bmdahfded3366b9f", MediaFileType::Video, "media/video/storyteller-studio-renders/mocap-kiss.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_szp2c77z6je965k44vc22xn9432a88", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-mocap-girl.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_mdwspz81zymw9hvmb1d3jm830t25xe", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-mocap-m.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_prcs6xkm8phs5y4a2dfwemwjy6n6z3", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-girl.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_5j889dzw08vn9pbrscx1sncff43ekp", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-jww.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_fwm2w6wbssez274ayz6x8ta0h1a9qp", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-pascal.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_yqqkrt2srep6a35xg78114jn9epwg1", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-pop.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_m4r043kez14pm6vaamsecpz8fafh7g", MediaFileType::Video, "media/video/video-style-transfer/man-explaining.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_81gq3hygqvrahg6ncxbtcpjap4f9nv", MediaFileType::Video, "media/video/video-style-transfer/woman-gradient-background.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_dp9ykj3yasjx69g2fx2bpd26wwjz0f", MediaFileType::Video, "media/video/video-style-transfer/woman-red-hair.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_gedarcfdkxx3zv8zz2wmwsnc1r8jbp", MediaFileType::Mp4, "media/video/storyteller-studio-renders/girl-rotating-room.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_3s74yyd4jwrjdp17yx1694n29jv5gr", MediaFileType::Mp4, "media/video/storyteller-studio-renders/hanashi-run.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_p6d64gm1wawz25bmdahfded3366b9f", MediaFileType::Mp4, "media/video/storyteller-studio-renders/mocap-kiss.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_szp2c77z6je965k44vc22xn9432a88", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-mocap-girl.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_mdwspz81zymw9hvmb1d3jm830t25xe", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-mocap-m.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_prcs6xkm8phs5y4a2dfwemwjy6n6z3", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-girl.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_5j889dzw08vn9pbrscx1sncff43ekp", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-jww.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_fwm2w6wbssez274ayz6x8ta0h1a9qp", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-pascal.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_yqqkrt2srep6a35xg78114jn9epwg1", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-pop.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_m4r043kez14pm6vaamsecpz8fafh7g", MediaFileType::Mp4, "media/video/video-style-transfer/man-explaining.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_81gq3hygqvrahg6ncxbtcpjap4f9nv", MediaFileType::Mp4, "media/video/video-style-transfer/woman-gradient-background.mp4"),
|
||||
(HANASHI_USER_TOKEN, "m_dp9ykj3yasjx69g2fx2bpd26wwjz0f", MediaFileType::Mp4, "media/video/video-style-transfer/woman-red-hair.mp4"),
|
||||
];
|
||||
|
||||
let seed_tool_data_root = get_seed_tool_data_root();
|
||||
|
||||
@@ -73,14 +73,14 @@ pub async fn main() -> AnyhowResult<()> {
|
||||
match mimetype {
|
||||
Some("audio/wav") |
|
||||
Some("audio/x-wav") => {
|
||||
media_file_type = MediaFileType::Video;
|
||||
media_file_type = MediaFileType::Wav;
|
||||
maybe_mime_type = Some("audio/wav");
|
||||
maybe_public_bucket_prefix = Some("dev_upload_");
|
||||
maybe_public_bucket_extension = Some(".wav");
|
||||
|
||||
}
|
||||
Some("video/mp4") => {
|
||||
media_file_type = MediaFileType::Video;
|
||||
media_file_type = MediaFileType::Mp4;
|
||||
maybe_mime_type = mimetype;
|
||||
maybe_public_bucket_prefix = Some("dev_upload_");
|
||||
maybe_public_bucket_extension = Some(".mp4");
|
||||
|
||||
-1
@@ -105,7 +105,6 @@ async fn create_document_from_record(elasticsearch: &Elasticsearch, record: Medi
|
||||
|
||||
media_class: record.media_class,
|
||||
media_type: record.media_type,
|
||||
maybe_media_subtype: record.maybe_media_subtype,
|
||||
maybe_engine_category: record.maybe_engine_category,
|
||||
maybe_animation_type: record.maybe_animation_type,
|
||||
|
||||
|
||||
-1
@@ -264,7 +264,6 @@ async fn upload_grok_video(
|
||||
// TODO: media_files.maybe_generation_provider
|
||||
// TODO: media_files.maybe_origin_model_type
|
||||
// TODO: media_files.maybe_origin_model_token (sref?)
|
||||
// TODO: media_files.is_batch_generated
|
||||
// TODO: media_files.maybe_batch_token
|
||||
// TODO: media_files.is_user_upload
|
||||
|
||||
|
||||
-1
@@ -294,7 +294,6 @@ async fn upload_midjourney_batch(
|
||||
// TODO: media_files.maybe_generation_provider
|
||||
// TODO: media_files.maybe_origin_model_type
|
||||
// TODO: media_files.maybe_origin_model_token (sref?)
|
||||
// TODO: media_files.is_batch_generated
|
||||
// TODO: media_files.maybe_batch_token
|
||||
// TODO: media_files.is_user_upload
|
||||
|
||||
|
||||
-1
@@ -254,7 +254,6 @@ async fn upload_spz_splat(
|
||||
// TODO: media_files.maybe_generation_provider
|
||||
// TODO: media_files.maybe_origin_model_type
|
||||
// TODO: media_files.maybe_origin_model_token (sref?)
|
||||
// TODO: media_files.is_batch_generated
|
||||
// TODO: media_files.maybe_batch_token
|
||||
// TODO: media_files.is_user_upload
|
||||
|
||||
|
||||
@@ -59,6 +59,9 @@ mod init;
|
||||
mod logging;
|
||||
pub (crate) mod types;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests_common;
|
||||
|
||||
/// Re-export of env_logger
|
||||
pub mod env_logger {
|
||||
pub use env_logger::Builder;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//! Test utilities shared across easyenv test modules.
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use std::env;
|
||||
|
||||
pub(crate) struct EnvVarGuard {
|
||||
name: &'static str,
|
||||
}
|
||||
|
||||
impl EnvVarGuard {
|
||||
pub(crate) fn set(name: &'static str, value: &str) -> Self {
|
||||
env::remove_var(name);
|
||||
env::set_var(name, value);
|
||||
Self { name }
|
||||
}
|
||||
|
||||
pub(crate) fn unset(name: &'static str) -> Self {
|
||||
env::remove_var(name);
|
||||
Self { name }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EnvVarGuard {
|
||||
fn drop(&mut self) {
|
||||
env::remove_var(self.name);
|
||||
}
|
||||
}
|
||||
@@ -75,3 +75,87 @@ fn get_env_bool_internal(env_name: &str) -> Result<Option<bool>, EnvError> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::tests_common::EnvVarGuard;
|
||||
|
||||
#[test]
|
||||
fn literals_round_trip_through_optional_required_and_or_default() {
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_TRUE_LOWER", "true");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_TRUE_LOWER"), Some(true));
|
||||
assert_eq!(get_env_bool_required("BOOLEAN_TEST_TRUE_LOWER").unwrap(), true);
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_TRUE_LOWER", false), true);
|
||||
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_TRUE_UPPER", "TRUE");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_TRUE_UPPER"), Some(true));
|
||||
assert_eq!(get_env_bool_required("BOOLEAN_TEST_TRUE_UPPER").unwrap(), true);
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_TRUE_UPPER", false), true);
|
||||
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_FALSE_LOWER", "false");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_FALSE_LOWER"), Some(false));
|
||||
assert_eq!(get_env_bool_required("BOOLEAN_TEST_FALSE_LOWER").unwrap(), false);
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_FALSE_LOWER", true), false);
|
||||
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_FALSE_UPPER", "FALSE");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_FALSE_UPPER"), Some(false));
|
||||
assert_eq!(get_env_bool_required("BOOLEAN_TEST_FALSE_UPPER").unwrap(), false);
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_FALSE_UPPER", true), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_returns_none_required_error_and_default() {
|
||||
let _g = EnvVarGuard::unset("BOOLEAN_TEST_MISSING");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_MISSING"), None);
|
||||
assert!(matches!(get_env_bool_required("BOOLEAN_TEST_MISSING"), Err(EnvError::RequiredNotPresent { .. })));
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_MISSING", true), true);
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_MISSING", false), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn yes_is_unparseable() {
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_YES", "yes");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_YES"), None);
|
||||
assert!(matches!(get_env_bool_required("BOOLEAN_TEST_YES"), Err(EnvError::ParseError { .. })));
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_YES", true), true);
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_YES", false), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one_is_not_treated_as_true() {
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_ONE", "1");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_ONE"), None);
|
||||
assert!(matches!(get_env_bool_required("BOOLEAN_TEST_ONE"), Err(EnvError::ParseError { .. })));
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_ONE", true), true);
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_ONE", false), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_string_is_unparseable() {
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_EMPTY", "");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_EMPTY"), None);
|
||||
assert!(matches!(get_env_bool_required("BOOLEAN_TEST_EMPTY"), Err(EnvError::ParseError { .. })));
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_EMPTY", true), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mixed_case_true_is_unparseable() {
|
||||
let _g = EnvVarGuard::set("BOOLEAN_TEST_MIXED_CASE", "TrUe");
|
||||
assert_eq!(get_env_bool_optional("BOOLEAN_TEST_MIXED_CASE"), None);
|
||||
assert!(matches!(get_env_bool_required("BOOLEAN_TEST_MIXED_CASE"), Err(EnvError::ParseError { .. })));
|
||||
assert_eq!(get_env_bool_or_default("BOOLEAN_TEST_MIXED_CASE", false), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_not_present_carries_env_var_name() {
|
||||
let _g = EnvVarGuard::unset("BOOLEAN_TEST_REQUIRED_NAME");
|
||||
match get_env_bool_required("BOOLEAN_TEST_REQUIRED_NAME") {
|
||||
Err(EnvError::RequiredNotPresent { name }) => {
|
||||
assert_eq!(name, "BOOLEAN_TEST_REQUIRED_NAME");
|
||||
},
|
||||
other => panic!("unexpected result: {:?}", other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,3 +63,42 @@ fn get_env_duration_seconds_internal(env_name: &str) -> Result<Option<Duration>,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::tests_common::EnvVarGuard;
|
||||
|
||||
#[test]
|
||||
fn zero_seconds_round_trips() {
|
||||
let _g = EnvVarGuard::set("DURATION_TEST_ZERO", "0");
|
||||
assert_eq!(get_env_duration_seconds_optional("DURATION_TEST_ZERO"), Some(Duration::from_secs(0)));
|
||||
assert_eq!(get_env_duration_seconds_required("DURATION_TEST_ZERO").unwrap(), Duration::from_secs(0));
|
||||
assert_eq!(get_env_duration_seconds_or_default("DURATION_TEST_ZERO", Duration::from_secs(99)), Duration::from_secs(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u64_max_seconds_round_trips() {
|
||||
let _g = EnvVarGuard::set("DURATION_TEST_U64_MAX", &u64::MAX.to_string());
|
||||
assert_eq!(get_env_duration_seconds_optional("DURATION_TEST_U64_MAX"), Some(Duration::from_secs(u64::MAX)));
|
||||
assert_eq!(get_env_duration_seconds_required("DURATION_TEST_U64_MAX").unwrap(), Duration::from_secs(u64::MAX));
|
||||
assert_eq!(get_env_duration_seconds_or_default("DURATION_TEST_U64_MAX", Duration::from_secs(1)), Duration::from_secs(u64::MAX));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negative_is_unparseable() {
|
||||
let _g = EnvVarGuard::set("DURATION_TEST_NEGATIVE", "-1");
|
||||
assert_eq!(get_env_duration_seconds_optional("DURATION_TEST_NEGATIVE"), None);
|
||||
assert!(matches!(get_env_duration_seconds_required("DURATION_TEST_NEGATIVE"), Err(EnvError::ParseError { .. })));
|
||||
assert_eq!(get_env_duration_seconds_or_default("DURATION_TEST_NEGATIVE", Duration::from_secs(5)), Duration::from_secs(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_returns_none_required_error_and_default() {
|
||||
let _g = EnvVarGuard::unset("DURATION_TEST_MISSING");
|
||||
assert_eq!(get_env_duration_seconds_optional("DURATION_TEST_MISSING"), None);
|
||||
assert!(matches!(get_env_duration_seconds_required("DURATION_TEST_MISSING"), Err(EnvError::RequiredNotPresent { .. })));
|
||||
assert_eq!(get_env_duration_seconds_or_default("DURATION_TEST_MISSING", Duration::from_secs(42)), Duration::from_secs(42));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,3 +49,52 @@ pub fn try_get_env_num_optional<T>(env_name: &str) -> Result<Option<T>, EnvError
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::tests_common::EnvVarGuard;
|
||||
|
||||
#[test]
|
||||
fn parses_i32() {
|
||||
let _g = EnvVarGuard::set("NUM_TEST_I32", "-42");
|
||||
assert_eq!(get_env_num("NUM_TEST_I32", 0i32).unwrap(), -42);
|
||||
assert_eq!(try_get_env_num_optional::<i32>("NUM_TEST_I32").unwrap(), Some(-42));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_u64() {
|
||||
let _g = EnvVarGuard::set("NUM_TEST_U64", "18446744073709551615");
|
||||
assert_eq!(get_env_num("NUM_TEST_U64", 0u64).unwrap(), u64::MAX);
|
||||
assert_eq!(try_get_env_num_optional::<u64>("NUM_TEST_U64").unwrap(), Some(u64::MAX));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_f64() {
|
||||
let _g = EnvVarGuard::set("NUM_TEST_F64", "3.14");
|
||||
assert_eq!(get_env_num("NUM_TEST_F64", 0.0f64).unwrap(), 3.14);
|
||||
assert_eq!(try_get_env_num_optional::<f64>("NUM_TEST_F64").unwrap(), Some(3.14));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u8_overflow_returns_parse_error() {
|
||||
let _g = EnvVarGuard::set("NUM_TEST_U8_OVERFLOW", "256");
|
||||
assert!(get_env_num("NUM_TEST_U8_OVERFLOW", 0u8).is_err());
|
||||
assert!(try_get_env_num_optional::<u8>("NUM_TEST_U8_OVERFLOW").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_returns_default_and_none() {
|
||||
let _g = EnvVarGuard::unset("NUM_TEST_MISSING");
|
||||
assert_eq!(get_env_num("NUM_TEST_MISSING", 99i32).unwrap(), 99);
|
||||
assert_eq!(try_get_env_num_optional::<i32>("NUM_TEST_MISSING").unwrap(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unparseable_returns_parse_error() {
|
||||
let _g = EnvVarGuard::set("NUM_TEST_UNPARSEABLE", "not_a_number");
|
||||
assert!(get_env_num("NUM_TEST_UNPARSEABLE", 0i32).is_err());
|
||||
assert!(try_get_env_num_optional::<i32>("NUM_TEST_UNPARSEABLE").is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,3 +37,52 @@ pub fn get_env_string_required(env_name: &str) -> Result<String, EnvError> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::tests_common::EnvVarGuard;
|
||||
|
||||
#[test]
|
||||
fn returns_empty_string_when_set_to_empty() {
|
||||
let _g = EnvVarGuard::set("STRING_TEST_EMPTY", "");
|
||||
assert_eq!(get_env_string_optional("STRING_TEST_EMPTY"), Some("".to_string()));
|
||||
assert_eq!(get_env_string_required("STRING_TEST_EMPTY").unwrap(), "");
|
||||
assert_eq!(get_env_string_or_default("STRING_TEST_EMPTY", "default"), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_unicode() {
|
||||
let _g = EnvVarGuard::set("STRING_TEST_UNICODE", "café🎨");
|
||||
assert_eq!(get_env_string_optional("STRING_TEST_UNICODE"), Some("café🎨".to_string()));
|
||||
assert_eq!(get_env_string_required("STRING_TEST_UNICODE").unwrap(), "café🎨");
|
||||
assert_eq!(get_env_string_or_default("STRING_TEST_UNICODE", "default"), "café🎨");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_whitespace() {
|
||||
let _g = EnvVarGuard::set("STRING_TEST_WHITESPACE", " hello \t");
|
||||
assert_eq!(get_env_string_optional("STRING_TEST_WHITESPACE"), Some(" hello \t".to_string()));
|
||||
assert_eq!(get_env_string_required("STRING_TEST_WHITESPACE").unwrap(), " hello \t");
|
||||
assert_eq!(get_env_string_or_default("STRING_TEST_WHITESPACE", "default"), " hello \t");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_returns_none_required_error_and_default() {
|
||||
let _g = EnvVarGuard::unset("STRING_TEST_MISSING");
|
||||
assert_eq!(get_env_string_optional("STRING_TEST_MISSING"), None);
|
||||
assert!(matches!(get_env_string_required("STRING_TEST_MISSING"), Err(EnvError::RequiredNotPresent { .. })));
|
||||
assert_eq!(get_env_string_or_default("STRING_TEST_MISSING", "fallback"), "fallback");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_not_present_carries_env_var_name() {
|
||||
let _g = EnvVarGuard::unset("STRING_TEST_REQUIRED_NAME");
|
||||
match get_env_string_required("STRING_TEST_REQUIRED_NAME") {
|
||||
Err(EnvError::RequiredNotPresent { name }) => {
|
||||
assert_eq!(name, "STRING_TEST_REQUIRED_NAME");
|
||||
},
|
||||
other => panic!("unexpected result: {:?}", other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ pub (crate) static CUSTOM_INFER: LazyLock<Infer> = LazyLock::new(|| {
|
||||
fn add_custom_types(infer: &mut Infer) {
|
||||
infer.add("model/gltf-binary", "glb", gltf_matcher);
|
||||
infer.add("model/fbx", "fbx", fbx_matcher);
|
||||
infer.add("model/ply", "ply", ply_matcher);
|
||||
}
|
||||
|
||||
fn gltf_matcher(buf: &[u8]) -> bool {
|
||||
@@ -18,6 +19,14 @@ fn gltf_matcher(buf: &[u8]) -> bool {
|
||||
buf.len() >= 4 && buf[0] == 103 && buf[1] == 108 && buf[2] == 84 && buf[3] == 70
|
||||
}
|
||||
|
||||
fn ply_matcher(buf: &[u8]) -> bool {
|
||||
// PLY files (ASCII and binary alike) start with the line "ply".
|
||||
// https://paulbourke.net/dataformats/ply/
|
||||
buf.len() >= 4
|
||||
&& &buf[..3] == b"ply"
|
||||
&& (buf[3] == b'\n' || buf[3] == b'\r')
|
||||
}
|
||||
|
||||
fn fbx_matcher(buf: &[u8]) -> bool {
|
||||
// Binary FBX magic: "Kaydara FBX Binary " (two trailing spaces).
|
||||
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
|
||||
@@ -47,6 +56,19 @@ mod tests {
|
||||
assert_eq!(maybe_type.mime_type(), "model/fbx");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ply_magic() {
|
||||
let bytes = b"ply\nformat binary_little_endian 1.0\n".to_vec();
|
||||
let maybe_type = CUSTOM_INFER.get(&bytes).unwrap();
|
||||
assert_eq!(maybe_type.mime_type(), "model/ply");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ply_prefix_without_newline_is_not_detected() {
|
||||
let bytes = b"plywood texture".to_vec();
|
||||
assert!(CUSTOM_INFER.get(&bytes).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_fbx_is_not_detected() {
|
||||
// ASCII FBX files have no magic bytes.
|
||||
|
||||
@@ -17,6 +17,7 @@ pub enum FileExtension {
|
||||
Obj,
|
||||
Ogg,
|
||||
Opus,
|
||||
Ply,
|
||||
Png,
|
||||
Wav,
|
||||
Webm,
|
||||
@@ -37,6 +38,7 @@ impl FileExtension {
|
||||
"audio/mpeg" => Some(FileExtension::Mp3),
|
||||
"video/mp4" => Some(FileExtension::Mp4),
|
||||
"model/obj" => Some(FileExtension::Obj),
|
||||
"model/ply" => Some(FileExtension::Ply),
|
||||
"audio/ogg" => Some(FileExtension::Ogg),
|
||||
"audio/opus" => Some(FileExtension::Opus),
|
||||
"image/png" => Some(FileExtension::Png),
|
||||
@@ -69,6 +71,7 @@ impl FileExtension {
|
||||
FileExtension::Obj => (".obj", "obj"),
|
||||
FileExtension::Ogg => (".ogg", "ogg"),
|
||||
FileExtension::Opus => (".opus", "opus"),
|
||||
FileExtension::Ply => (".ply", "ply"),
|
||||
FileExtension::Png => (".png", "png"),
|
||||
FileExtension::Wav => (".wav", "wav"),
|
||||
FileExtension::Webm => (".webm", "webm"),
|
||||
|
||||
@@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize};
|
||||
use enums::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
|
||||
use enums::by_table::media_files::media_file_class::MediaFileClass;
|
||||
use enums::by_table::media_files::media_file_engine_category::MediaFileEngineCategory;
|
||||
use enums::by_table::media_files::media_file_subtype::MediaFileSubtype;
|
||||
use enums::by_table::media_files::media_file_type::MediaFileType;
|
||||
use enums::common::visibility::Visibility;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
@@ -25,7 +24,6 @@ pub struct MediaFileDocument {
|
||||
|
||||
pub media_class: MediaFileClass,
|
||||
pub media_type: MediaFileType,
|
||||
pub maybe_media_subtype: Option<MediaFileSubtype>,
|
||||
pub maybe_engine_category: Option<MediaFileEngineCategory>,
|
||||
|
||||
pub maybe_mime_type: Option<String>,
|
||||
|
||||
-4
@@ -117,8 +117,6 @@ pub async fn insert_media_file_generic(
|
||||
let mut maybe_creator_file_synthetic_id : Option<u64> = None;
|
||||
let mut maybe_creator_category_synthetic_id : Option<u64> = None;
|
||||
|
||||
let is_batch_generated = args.maybe_batch_token.is_some();
|
||||
|
||||
let mut maybe_generation_provider_str = None;
|
||||
let mut is_intermediate_system_file = args.is_intermediate_system_file;
|
||||
let mut is_user_upload = args.is_user_upload;
|
||||
@@ -172,7 +170,6 @@ pub async fn insert_media_file_generic(
|
||||
maybe_origin_model_token = ?,
|
||||
maybe_origin_filename = ?,
|
||||
|
||||
is_batch_generated = ?,
|
||||
maybe_batch_token = ?,
|
||||
|
||||
maybe_mime_type = ?,
|
||||
@@ -232,7 +229,6 @@ pub async fn insert_media_file_generic(
|
||||
args.maybe_origin_model_token.map(|t| t.to_string()),
|
||||
args.maybe_origin_filename,
|
||||
|
||||
is_batch_generated,
|
||||
args.maybe_batch_token.map(|t| t.as_str()),
|
||||
|
||||
args.maybe_mime_type,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user