Compare commits

...
Author SHA1 Message Date
arensc 7e52fbd2a5 Comfy dep update 2024-03-12 19:29:35 -04:00
Brandon Thomas 9fd9cf5cc9 add watermark to comfy 2024-03-01 05:25:29 -05:00
Brandon Thomas 889aebea09 more logging 2024-03-01 03:41:45 -05:00
Brandon Thomas 51666827ac allow deleted SD + lora in comfy 2024-03-01 03:32:04 -05:00
Brandon Thomas 51dfddf789 more error logging 2024-03-01 03:31:21 -05:00
Brandon Thomas 26f37629ca more error logging 2024-03-01 03:23:08 -05:00
Brandon Thomas 2972d54077 debugging errors 2024-03-01 03:14:24 -05:00
Brandon Thomas 23f7f0a539 codegen mysql 2024-03-01 02:43:37 -05:00
Brandon Thomas 422c92f392 more logging for comfyui 2024-03-01 02:42:37 -05:00
Brandon Thomas e023a27c18 fix logging 2024-02-29 23:19:55 -05:00
Brandon Thomas ea4887a41c name file based on type 2024-02-29 23:06:56 -05:00
Brandon Thomas b45a80142a optional env vars 2024-02-29 19:46:05 -05:00
Brandon Thomas e428f0ae9d logging for debug (why is r2d2 breaking?) 2024-02-29 19:34:29 -05:00
salt 44f6226088 add dino as a comfyui dependency 2024-02-28 17:53:58 -08:00
ArEnSc 5ee73d3feb Merge pull request #312 from storytold/feature/premium-timing
Editor added self by accident removing
2024-02-28 17:45:52 -05:00
arensc dcb2765b07 Editor added self by accident removing 2024-02-28 17:43:33 -05:00
ArEnSc 5e80eab10f Merge pull request #311 from storytold/feature/premium-timing
Premium V2V gating
2024-02-28 17:33:16 -05:00
arensc 66930695cd Premium V2V gating 2024-02-28 17:32:24 -05:00
salt 54f08192ed remove cropping arg from comfyui 2024-02-28 14:11:47 -08:00
Brandon Thomas 061cae7378 enroll gateway 2024-02-28 12:28:13 -05:00
Brandon Thomas af1b87c2c8 user access queries 2024-02-27 19:56:29 -05:00
salt f4800f7aaf process video for comfyui 2024-02-27 06:58:25 -08:00
Brandon Thomas e049c22fdd migrate mocapnet type 2024-02-26 20:47:30 -05:00
Brandon Thomas 45e54da9c1 add video upload handler to docs 2024-02-26 18:29:24 -05:00
Brandon Thomas f9fad82134 fix api docs 2024-02-26 18:18:08 -05:00
Brandon Thomas 5a64fced89 fix storyteller-web 2024-02-26 18:11:18 -05:00
Brandon Thomas 368a2a823e Merge pull request #310 from storytold/brandon-framerate-1
Framerate on video files
2024-02-26 18:01:05 -05:00
Brandon Thomas 207ef544ee Framerate on video files 2024-02-26 18:00:05 -05:00
ArEnSc bef677175b Merge pull request #309 from storytold/feature/comfyui-ffmeg
Comfy ui enqueue updates with trimming
2024-02-26 17:28:29 -05:00
arensc 1e64f2f01b Comfy ui enqueue updates with trimming 2024-02-26 17:24:59 -05:00
Brandon Thomas a444c84e12 enroll staff as admins query 2024-02-26 14:13:26 -05:00
Brandon Thomas 00102793dc comma-separated query param for media type selector 2024-02-26 01:02:41 -05:00
salt 9a7d369828 remove redundant check 2024-02-25 21:58:08 -08:00
salt c932b26b29 new comfyUI dependency 2024-02-25 16:32:41 -08:00
Brandon Thomas 3b13603f1f scope user media files by *multiple* types 2024-02-25 18:02:36 -05:00
salt 6b054d3b37 download lora to correct folder 2024-02-24 23:20:54 -08:00
Brandon Thomas 55db590e73 rename package 2024-02-24 02:33:10 -05:00
Brandon Thomas 2dd02272f9 tool to soft delete anonymous user images
- We'll need to go back and clean up the buckets for some of these
- Some of these are probably just for face animator and could help with
  training a better face detection model
2024-02-24 02:26:25 -05:00
Brandon Thomas 6c6debe64b additional safety features 2024-02-24 00:35:26 -05:00
Brandon Thomas 814209949e fix storyteller engine cors 2024-02-23 22:21:39 -05:00
Brandon Thomas 4fbb8ef335 fix endpoint 2024-02-23 00:16:25 -05:00
Brandon Thomas 25b512c7d8 codegen db 2024-02-22 23:54:43 -05:00
Brandon Thomas d3ae68dc14 get prompt API 2024-02-22 23:53:02 -05:00
Brandon Thomas 203ae33adb actually, we don't need that table anymore 2024-02-22 23:12:08 -05:00
Brandon Thomas d543ac3a33 forgot to commit the transaction 🤦 2024-02-22 23:10:37 -05:00
Brandon Thomas cd132b694c codegen 2024-02-22 21:37:42 -05:00
Brandon Thomas be7315b28d insert prompt records in SD inference job 2024-02-22 21:36:43 -05:00
Brandon Thomas 14fbb2e29c Queries for insert and get prompt 2024-02-22 19:37:49 -05:00
Brandon Thomas ef2f827fed add extra localhost port to cors (storyteller studio) 2024-02-22 18:29:40 -05:00
Brandon Thomas 172de887b7 squashed migrations for docs 2024-02-22 18:15:22 -05:00
Brandon Thomas 896fae0ef5 Bevy-specific "create scene" upload endpoint 2024-02-22 16:58:30 -05:00
salt 7cad80ad05 dont crash if workflow doesnt exist 2024-02-22 13:31:07 -08:00
Brandon Thomas e1fd39d003 fix lints 2024-02-22 04:57:00 -05:00
Brandon Thomas ea3df73e0f prompt token in media_files, enums, tokens 2024-02-22 04:21:26 -05:00
ArEnSc 8b3c139704 Merge pull request #307 from storytold/feature/properties-prompt
Adding properties to prompts
2024-02-22 02:35:40 -05:00
Brandon Thomas a1c01a2f3c new tables for usages and prompts 2024-02-21 22:54:07 -05:00
arensc 29a137e4fe Adding properties to prompts 2024-02-21 20:40:48 -05:00
Brandon Thomas b8270b0235 fix lints 2024-02-21 17:48:14 -05:00
Brandon Thomas 7dbae4c166 fix build error 2024-02-21 17:30:47 -05:00
Brandon Thomas 170c0afef5 analytics query 2024-02-21 17:24:06 -05:00
saltacc 4af67113b2 Merge pull request #306 from storytold/feature/upload-workflow
Feature/upload workflow
2024-02-21 14:07:22 -08:00
Brandon Thomas c6555b88d5 one or two more terms 2024-02-21 05:14:32 -05:00
Brandon Thomas ce4c9a1d42 doc 2024-02-20 23:36:04 -05:00
Brandon Thomas d85fe3fb3d CLI tool to delete users' files 2024-02-20 23:19:08 -05:00
Brandon Thomas d601164b5b rename two cli apps 2024-02-20 22:12:11 -05:00
Brandon Thomas 73b6b6585e refactor CLI tools 2024-02-20 22:10:18 -05:00
Brandon Thomas 368c216c07 rename CLI binary 2024-02-20 21:57:26 -05:00
Brandon Thomas d31eb74344 named number classifier 2024-02-20 21:46:35 -05:00
Brandon Thomas 2dab930226 additional test cases for italian 2024-02-20 21:40:08 -05:00
Brandon Thomas 9fc6e4adf6 split up tests 2024-02-20 21:28:23 -05:00
Brandon Thomas 77c22336e6 codegen db 2024-02-20 20:27:09 -05:00
Brandon Thomas 4ae7e61b7e additional safety 2024-02-20 19:26:21 -05:00
Brandon Thomas 16a3f74105 "1girl" is a false positive and used frequently in safe contexts 2024-02-20 19:09:03 -05:00
Brandon Thomas 4ad90b31df stop racism too 2024-02-20 18:56:24 -05:00
Brandon Thomas 5cc90d1001 better classifier 2024-02-20 18:49:20 -05:00
Brandon Thomas c6a5f0694f spanish + tests 2024-02-20 18:43:12 -05:00
Brandon Thomas 688efffcb8 improve classifier 2024-02-20 18:37:01 -05:00
Brandon Thomas 767191871d improved filter 2024-02-20 18:28:21 -05:00
Brandon Thomas 7d963deb38 move text classification to own crate (about to build out more) 2024-02-20 16:14:47 -05:00
167 changed files with 4902 additions and 1064 deletions
+1
View File
@@ -9,6 +9,7 @@
<w>cheermote</w>
<w>cidrs</w>
<w>crockford</w>
<w>csam</w>
<w>culted</w>
<w>dalle</w>
<w>demuxer</w>
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO prompts\nSET\n token = ?,\n prompt_type = ?,\n\n maybe_creator_user_token = ?,\n\n maybe_positive_prompt = ?,\n maybe_negative_prompt = ?,\n maybe_other_args = ?,\n\n creator_ip_address = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 7
},
"nullable": []
},
"hash": "13ca06bcbb4a576f8a2229a8554b7488d379baa381d8d5cb60972750e81b2173"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\n INSERT INTO media_files\n SET\n token = ?,\n media_type = ?,\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 public_bucket_directory_hash = ?, \n maybe_public_bucket_prefix = ?, \n maybe_public_bucket_extension = ?, \n extra_file_modification_info = ?, \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 maybe_mod_user_token = ?, \n is_generated_on_prem = ?, \n generated_by_worker = ?, \n generated_by_cluster = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 32
},
"nullable": []
},
"hash": "23061975280d3357a453705c90824001ff5023031a69425b8ec9b6ccff57aa8c"
}
@@ -1,6 +1,6 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\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_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_text_transcript,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n 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 cover_image\n ON 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\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_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\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_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_text_transcript,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n 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 cover_image\n ON 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\nWHERE\n m.token = ?\n AND m.user_deleted_at IS NULL\n AND m.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
@@ -85,6 +85,16 @@
},
{
"ordinal": 8,
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
@@ -94,7 +104,7 @@
}
},
{
"ordinal": 9,
"ordinal": 10,
"name": "maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
@@ -104,7 +114,7 @@
}
},
{
"ordinal": 10,
"ordinal": 11,
"name": "maybe_model_weights_title",
"type_info": {
"type": "VarString",
@@ -114,7 +124,7 @@
}
},
{
"ordinal": 11,
"ordinal": 12,
"name": "maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
@@ -124,7 +134,7 @@
}
},
{
"ordinal": 12,
"ordinal": 13,
"name": "maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
@@ -134,7 +144,7 @@
}
},
{
"ordinal": 13,
"ordinal": 14,
"name": "maybe_model_cover_image_public_bucket_hash",
"type_info": {
"type": "VarString",
@@ -144,7 +154,7 @@
}
},
{
"ordinal": 14,
"ordinal": 15,
"name": "maybe_model_cover_image_public_bucket_prefix",
"type_info": {
"type": "VarString",
@@ -154,7 +164,7 @@
}
},
{
"ordinal": 15,
"ordinal": 16,
"name": "maybe_model_cover_image_public_bucket_extension",
"type_info": {
"type": "VarString",
@@ -164,7 +174,7 @@
}
},
{
"ordinal": 16,
"ordinal": 17,
"name": "maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
@@ -174,7 +184,7 @@
}
},
{
"ordinal": 17,
"ordinal": 18,
"name": "maybe_model_weight_creator_username",
"type_info": {
"type": "VarString",
@@ -184,7 +194,7 @@
}
},
{
"ordinal": 18,
"ordinal": 19,
"name": "maybe_model_weight_creator_display_name",
"type_info": {
"type": "VarString",
@@ -194,7 +204,7 @@
}
},
{
"ordinal": 19,
"ordinal": 20,
"name": "maybe_model_weight_creator_gravatar_hash",
"type_info": {
"type": "String",
@@ -204,7 +214,7 @@
}
},
{
"ordinal": 20,
"ordinal": 21,
"name": "public_bucket_directory_hash",
"type_info": {
"type": "VarString",
@@ -214,7 +224,7 @@
}
},
{
"ordinal": 21,
"ordinal": 22,
"name": "maybe_public_bucket_prefix",
"type_info": {
"type": "VarString",
@@ -224,7 +234,7 @@
}
},
{
"ordinal": 22,
"ordinal": 23,
"name": "maybe_public_bucket_extension",
"type_info": {
"type": "VarString",
@@ -234,7 +244,7 @@
}
},
{
"ordinal": 23,
"ordinal": 24,
"name": "maybe_ratings_positive_count",
"type_info": {
"type": "Long",
@@ -244,7 +254,7 @@
}
},
{
"ordinal": 24,
"ordinal": 25,
"name": "maybe_ratings_negative_count",
"type_info": {
"type": "Long",
@@ -254,7 +264,7 @@
}
},
{
"ordinal": 25,
"ordinal": 26,
"name": "maybe_bookmark_count",
"type_info": {
"type": "Long",
@@ -264,7 +274,7 @@
}
},
{
"ordinal": 26,
"ordinal": 27,
"name": "created_at",
"type_info": {
"type": "Timestamp",
@@ -274,7 +284,7 @@
}
},
{
"ordinal": 27,
"ordinal": 28,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
@@ -296,6 +306,7 @@
true,
true,
true,
true,
false,
true,
true,
@@ -318,5 +329,5 @@
false
]
},
"hash": "f077f7692f4d79809534506dfde0dba28f4fdaa3d0b8cc2ebad2a594188429eb"
"hash": "2c5083331bf226ef10c419f6a2b6dee6ee776a3d41eea06de1eafd1d1bd41791"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\n INSERT INTO media_files\n SET\n token = ?,\n media_type = ?,\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 checksum_sha2 = ?,\n\n public_bucket_directory_hash = ?, \n maybe_public_bucket_prefix = ?, \n maybe_public_bucket_extension = ?, \n extra_file_modification_info = ?, \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 maybe_mod_user_token = ?, \n is_generated_on_prem = ?, \n generated_by_worker = ?, \n generated_by_cluster = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 31
},
"nullable": []
},
"hash": "38b93187e20b51c7950bf9c5500890c15a00eec76a1bdf7501f349125ce7e4c4"
}
@@ -0,0 +1,102 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n p.token as `token: tokens::tokens::prompts::PromptToken`,\n\n p.prompt_type as `prompt_type: enums::by_table::prompts::prompt_type::PromptType`,\n\n p.maybe_creator_user_token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n\n p.maybe_positive_prompt,\n p.maybe_negative_prompt,\n p.maybe_other_args,\n\n p.creator_ip_address,\n p.created_at\n\nFROM prompts as p\nWHERE\n p.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::prompts::PromptToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "prompt_type: enums::by_table::prompts::prompt_type::PromptType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 2,
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "maybe_positive_prompt",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 4,
"name": "maybe_negative_prompt",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 5,
"name": "maybe_other_args",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 7,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
true,
true,
true,
true,
false,
false
]
},
"hash": "61744bbf83f7cf00348bcc21e868d9c506fec46da4a33ac50d63c6d9e00c0cec"
}
@@ -1,6 +1,6 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\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_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_text_transcript,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n 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 cover_image\n ON 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\nWHERE\n m.token = ?\n ",
"query": "\nSELECT\n m.token as `token: tokens::tokens::media_files::MediaFileToken`,\n\n m.media_type as `media_type: enums::by_table::media_files::media_file_type::MediaFileType`,\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_batch_token as `maybe_batch_token: tokens::tokens::batch_generations::BatchGenerationToken`,\n\n m.maybe_text_transcript,\n\n m.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n\n m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n model_weights.token as `maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken`,\n model_weights.title as maybe_model_weights_title,\n model_weights.weights_type as `maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n model_weights.weights_category as `maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n cover_image.public_bucket_directory_hash as maybe_model_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_model_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_model_cover_image_public_bucket_extension,\n\n model_weight_creator.token as `maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken`,\n model_weight_creator.username as maybe_model_weight_creator_username,\n model_weight_creator.display_name as maybe_model_weight_creator_display_name,\n model_weight_creator.email_gravatar_hash as maybe_model_weight_creator_gravatar_hash,\n\n m.public_bucket_directory_hash,\n m.maybe_public_bucket_prefix,\n m.maybe_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n 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 cover_image\n ON 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\nWHERE\n m.token = ?\n ",
"describe": {
"columns": [
{
@@ -85,6 +85,16 @@
},
{
"ordinal": 8,
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
@@ -94,7 +104,7 @@
}
},
{
"ordinal": 9,
"ordinal": 10,
"name": "maybe_model_weights_token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
@@ -104,7 +114,7 @@
}
},
{
"ordinal": 10,
"ordinal": 11,
"name": "maybe_model_weights_title",
"type_info": {
"type": "VarString",
@@ -114,7 +124,7 @@
}
},
{
"ordinal": 11,
"ordinal": 12,
"name": "maybe_model_weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
@@ -124,7 +134,7 @@
}
},
{
"ordinal": 12,
"ordinal": 13,
"name": "maybe_model_weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
@@ -134,7 +144,7 @@
}
},
{
"ordinal": 13,
"ordinal": 14,
"name": "maybe_model_cover_image_public_bucket_hash",
"type_info": {
"type": "VarString",
@@ -144,7 +154,7 @@
}
},
{
"ordinal": 14,
"ordinal": 15,
"name": "maybe_model_cover_image_public_bucket_prefix",
"type_info": {
"type": "VarString",
@@ -154,7 +164,7 @@
}
},
{
"ordinal": 15,
"ordinal": 16,
"name": "maybe_model_cover_image_public_bucket_extension",
"type_info": {
"type": "VarString",
@@ -164,7 +174,7 @@
}
},
{
"ordinal": 16,
"ordinal": 17,
"name": "maybe_model_weight_creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
@@ -174,7 +184,7 @@
}
},
{
"ordinal": 17,
"ordinal": 18,
"name": "maybe_model_weight_creator_username",
"type_info": {
"type": "VarString",
@@ -184,7 +194,7 @@
}
},
{
"ordinal": 18,
"ordinal": 19,
"name": "maybe_model_weight_creator_display_name",
"type_info": {
"type": "VarString",
@@ -194,7 +204,7 @@
}
},
{
"ordinal": 19,
"ordinal": 20,
"name": "maybe_model_weight_creator_gravatar_hash",
"type_info": {
"type": "String",
@@ -204,7 +214,7 @@
}
},
{
"ordinal": 20,
"ordinal": 21,
"name": "public_bucket_directory_hash",
"type_info": {
"type": "VarString",
@@ -214,7 +224,7 @@
}
},
{
"ordinal": 21,
"ordinal": 22,
"name": "maybe_public_bucket_prefix",
"type_info": {
"type": "VarString",
@@ -224,7 +234,7 @@
}
},
{
"ordinal": 22,
"ordinal": 23,
"name": "maybe_public_bucket_extension",
"type_info": {
"type": "VarString",
@@ -234,7 +244,7 @@
}
},
{
"ordinal": 23,
"ordinal": 24,
"name": "maybe_ratings_positive_count",
"type_info": {
"type": "Long",
@@ -244,7 +254,7 @@
}
},
{
"ordinal": 24,
"ordinal": 25,
"name": "maybe_ratings_negative_count",
"type_info": {
"type": "Long",
@@ -254,7 +264,7 @@
}
},
{
"ordinal": 25,
"ordinal": 26,
"name": "maybe_bookmark_count",
"type_info": {
"type": "Long",
@@ -264,7 +274,7 @@
}
},
{
"ordinal": 26,
"ordinal": 27,
"name": "created_at",
"type_info": {
"type": "Timestamp",
@@ -274,7 +284,7 @@
}
},
{
"ordinal": 27,
"ordinal": 28,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
@@ -296,6 +306,7 @@
true,
true,
true,
true,
false,
true,
true,
@@ -318,5 +329,5 @@
false
]
},
"hash": "00a60f2949c7e639eb5cead57615c9806d815c64ffdbe38bf06f6646fae0e065"
"hash": "726a6c62dc20e8372e950a10ecd5a438769448c7ce315bc8743b728e80179420"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO media_files\nSET\n token = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n maybe_origin_model_type = ?,\n\n media_type = ?,\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n maybe_prompt_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 creator_ip_address = ?,\n\n creator_set_visibility = ?,\n extra_file_modification_info = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?,\n\n is_generated_on_prem = ?,\n generated_by_worker = ?,\n generated_by_cluster = ?\n\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 22
},
"nullable": []
},
"hash": "ca7db50451b04da0b5521ebc12416280d4fe6cbc1da47b7fa314d810b5f3a6fd"
}
Generated
+77 -29
View File
@@ -1727,34 +1727,6 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
[[package]]
name = "database-backup"
version = "0.0.1"
dependencies = [
"anyhow",
"container_common",
"dotenv",
"easyenv",
"log",
"my-workspace-hack",
"serde",
"serde_derive",
]
[[package]]
name = "database-cleanup"
version = "0.0.1"
dependencies = [
"anyhow",
"container_common",
"dotenv",
"easyenv",
"log",
"my-workspace-hack",
"serde",
"serde_derive",
]
[[package]]
name = "datetimes"
version = "0.0.1"
@@ -1764,6 +1736,43 @@ dependencies = [
"once_cell",
]
[[package]]
name = "db-backup"
version = "0.0.1"
dependencies = [
"anyhow",
"container_common",
"dotenv",
"easyenv",
"log",
"my-workspace-hack",
"serde",
"serde_derive",
]
[[package]]
name = "db-cleanup"
version = "0.0.1"
dependencies = [
"buckets",
"clap",
"container_common",
"dotenv",
"easyenv",
"enums",
"errors",
"log",
"my-workspace-hack",
"mysql_queries",
"serde",
"serde_derive",
"serde_json",
"sqlx",
"storyteller_root",
"tokens",
"tokio",
]
[[package]]
name = "debug-helper"
version = "0.3.13"
@@ -3925,6 +3934,20 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "mp4"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9ef834d5ed55e494a2ae350220314dc4aacd1c43a9498b00e320e0ea352a5c3"
dependencies = [
"byteorder",
"bytes 1.5.0",
"num-rational 0.4.1",
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "my-workspace-hack"
version = "0.1.0"
@@ -4251,6 +4274,7 @@ dependencies = [
"num-bigint 0.4.4",
"num-integer",
"num-traits",
"serde",
]
[[package]]
@@ -4792,6 +4816,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "prompt_engineering"
version = "0.1.0"
dependencies = [
"errors",
"my-workspace-hack",
"once_cell",
"regex",
"speculoos 0.11.0",
]
[[package]]
name = "prost"
version = "0.11.9"
@@ -5530,7 +5565,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "scrape_test"
name = "scrape-test"
version = "0.0.1"
dependencies = [
"clap",
@@ -6387,6 +6422,7 @@ dependencies = [
"native-tls",
"once_cell",
"pin-project-lite",
"prompt_engineering",
"pulldown-cmark",
"r2d2_redis",
"rand 0.8.5",
@@ -6420,6 +6456,7 @@ dependencies = [
"utoipa",
"utoipa-swagger-ui",
"uuid 0.8.2",
"videos",
]
[[package]]
@@ -7750,6 +7787,17 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "videos"
version = "0.0.1"
dependencies = [
"errors",
"log",
"mp4",
"my-workspace-hack",
"testing",
]
[[package]]
name = "void"
version = "1.0.2"
+12 -10
View File
@@ -11,22 +11,22 @@ members = [
"crates/_types/tokens",
# CLI tools for operations, etc.
"crates/cli/database-backup",
"crates/cli/database-cleanup",
"crates/cli/dev-database-seed",
"crates/cli/dev-upload-media-file",
"crates/cli/elasticsearch-cli",
"crates/cli/kubectl-pod-cleanup",
"crates/cli/lru-delete-models",
"crates/cli/migration-tool",
"crates/cli/scrape_test",
"crates/cli/devenv/dev-database-seed",
"crates/cli/devenv/dev-upload-media-file",
"crates/cli/devenv/scrape-test",
"crates/cli/production/db-backup",
"crates/cli/production/db-cleanup",
"crates/cli/production/elasticsearch-cli",
"crates/cli/production/kubectl-pod-cleanup",
"crates/cli/production/lru-delete-models",
"crates/cli/production/migration-tool",
# Shared libraries
"crates/lib/actix_helpers",
"crates/lib/api_clients/cloud_storage",
"crates/lib/api_clients/google_drive_common",
"crates/lib/api_clients/twitch_common",
"crates/lib/api_clients/thumbnail_generator",
"crates/lib/api_clients/twitch_common",
"crates/lib/bootstrap",
"crates/lib/caching/memory_caching",
"crates/lib/caching/redis_caching",
@@ -48,12 +48,14 @@ members = [
"crates/lib/files/images",
"crates/lib/files/media",
"crates/lib/files/mimetypes",
"crates/lib/files/videos",
"crates/lib/idempotency",
"crates/lib/jobs_common",
"crates/lib/logging",
"crates/lib/migration",
"crates/lib/mysql_queries",
"crates/lib/password",
"crates/lib/prompt_engineering",
"crates/lib/redis_common",
"crates/lib/server_environment",
"crates/lib/sqlx_mysql_helpers",
@@ -0,0 +1,24 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Staff
-- teddanson is victor's alt
-- SELECT token, username FROM users WHERE username IN (
UPDATE users SET user_role_slug = "admin" WHERE username IN (
'bflat',
'brandon',
'crossproduct',
'crossproduct1',
'echelon',
'fyscott',
'mrvintage',
'olivicmic',
'saltacc',
'teddanson',
'vegito1089',
'wilwong',
'yae_ph',
'zzz_last_item'
);
@@ -33,3 +33,35 @@ where token IN (
);
-- Staff
-- teddanson is victor's alt
-- endtimes is @sugarbro (testing)
-- el_cid_93 is for testing
-- NB: 'echelon' is absent
-- SELECT token, username FROM users WHERE username IN (
UPDATE users SET maybe_loyalty_program_key = 'fakeyou_contributor' WHERE username IN (
'bflat',
'brandon',
'crossproduct',
'crossproduct1',
'el_cid_93',
'endtimes',
'fyscott',
'gateway',
'jags111',
'mrvintage',
'olivicmic',
'rewin123',
'saltacc',
'teddanson',
'vegito1089',
'wilwong',
'yae_ph',
'zzz_last_item'
);
UPDATE users SET maybe_loyalty_program_key = 'fakeyou_contributor' WHERE username IN (
'endtimes',
'tropicalfun',
'zzz_last_item'
);
@@ -4,6 +4,8 @@
-- Staff
-- teddanson is victor's alt
-- endtimes is @sugarbro (testing)
-- el_cid_93 is for testing
-- SELECT token, username FROM users WHERE username IN (
UPDATE users SET can_access_studio = true WHERE username IN (
'bflat',
@@ -11,8 +13,14 @@ UPDATE users SET can_access_studio = true WHERE username IN (
'crossproduct',
'crossproduct1',
'echelon',
'el_cid_93',
'endtimes',
'fyscott',
'gateway',
'jags111',
'mrvintage',
'olivicmic',
'rewin123',
'saltacc',
'teddanson',
'vegito1089',
@@ -0,0 +1,22 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- This finds the top users of image generation within a given time range.
select
u.username,
u.email_address,
count(*) as use_count
from users as u
join
(
select maybe_creator_user_token as user_token
from generic_inference_jobs
where job_type = 'stable_diffusion'
AND created_at > NOW() - INTERVAL 24 HOUR
) as jobs
ON jobs.user_token = u.token
group by u.username, u.email_address
order by use_count desc
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP TABLE prompts;
@@ -0,0 +1,56 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Table to store prompts as a first class entity.
-- Duplication of the same prompt is totally fine.
CREATE TABLE prompts (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- ========== PRIMARY, FOREIGN KEYS, and POLYMORPHISM ==========
-- Effective "primary key" of the prompt
token VARCHAR(32) NOT NULL,
-- Original product to which the prompt applied.
-- Prompts may or may not be compatible across products.
-- Possible values:
-- * 'stable_diffusion'
-- * 'comfy_ui'
prompt_type VARCHAR(16) NOT NULL,
-- Whomever created the prompt
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
-- ========== PROMPT DETAILS ==========
-- The positive prompt (optional)
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_positive_prompt TEXT DEFAULT NULL,
-- The negative prompt (optional)
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_negative_prompt TEXT DEFAULT NULL,
-- Polymorphic arguments payload that depends on the type of inference job.
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_other_args TEXT DEFAULT NULL,
-- ========== ABUSE TRACKING ==========
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
KEY index_maybe_creator_user_token (maybe_creator_user_token),
KEY index_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table usages;
@@ -0,0 +1,46 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Usages of models and assets to create things
-- This should work for inference as well as 3D object/scene creation,
-- so the inputs can be models OR files.
CREATE TABLE usages (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- ========== PRIMARY AND FOREIGN KEYS ==========
-- Type of the entity created
-- This only denotes which table to join against, not the type of the entity within the join table.
-- Possible values:
-- * 'model_weight'
-- * 'media_file'
-- * (maybe future types)
created_type VARCHAR(16) NOT NULL,
-- Token of the entity created
created_token VARCHAR(32) NOT NULL,
-- Type of the entity used
-- This only denotes which table to join against, not the type of the entity within the join table.
-- Possible values:
-- * 'model_weight'
-- * 'media_file'
-- * (maybe future types)
used_type VARCHAR(16) NOT NULL,
-- Token of the entity used
used_token VARCHAR(32) NOT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (created_type, created_token, used_type, used_token),
KEY index_created_type_and_token (created_type, created_token),
KEY index_used_type_and_token (used_type, used_token)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files DROP COLUMN maybe_prompt_token;
@@ -0,0 +1,10 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files
ADD COLUMN maybe_prompt_token VARCHAR(32) DEFAULT NULL
AFTER maybe_text_transcript;
ALTER TABLE media_files
ADD INDEX fk_maybe_prompt_token (maybe_prompt_token);
+4
View File
@@ -107,6 +107,9 @@ CREATE TABLE media_files (
-- Optional text transcript for audio or video (especially TTS)
maybe_text_transcript TEXT DEFAULT NULL,
-- Optional pointer to the prompt that generated this media file, if relevant.
maybe_prompt_token VARCHAR(32) DEFAULT NULL,
-- Checksum of the original media
-- SHA1 hash [SHA2 = CHAR(64), SHA1 = CHAR(40), MD5 = CHAR(32)]
-- checksum_sha1 CHAR(40) NOT NULL,
@@ -221,6 +224,7 @@ CREATE TABLE media_files (
KEY fk_maybe_origin_model_type_and_token (maybe_origin_model_type, maybe_origin_model_token),
KEY index_maybe_batch_token (maybe_batch_token),
KEY index_media_type (media_type),
KEY fk_maybe_prompt_token (maybe_prompt_token),
KEY index_checksum_sha2 (checksum_sha2),
KEY fk_maybe_creator_user_token (maybe_creator_user_token),
KEY fk_maybe_mod_user_token (maybe_mod_user_token),
+59
View File
@@ -0,0 +1,59 @@
-- NB: This is a manually squashed view of all the CREATE and ALTER statements,
-- with comments attached to the fields for centralized documentation.
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Table to store prompts as a first class entity.
-- Duplication of the same prompt is totally fine.
CREATE TABLE prompts (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- ========== PRIMARY, FOREIGN KEYS, and POLYMORPHISM ==========
-- Effective "primary key" of the prompt
token VARCHAR(32) NOT NULL,
-- Original product to which the prompt applied.
-- Prompts may or may not be compatible across products.
-- Possible values:
-- * 'stable_diffusion'
-- * 'comfy_ui'
prompt_type VARCHAR(16) NOT NULL,
-- Whomever created the prompt
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
-- ========== PROMPT DETAILS ==========
-- The positive prompt (optional)
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_positive_prompt TEXT DEFAULT NULL,
-- The negative prompt (optional)
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_negative_prompt TEXT DEFAULT NULL,
-- Polymorphic arguments payload that depends on the type of inference job.
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_other_args TEXT DEFAULT NULL,
-- ========== ABUSE TRACKING ==========
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
KEY index_maybe_creator_user_token (maybe_creator_user_token),
KEY index_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+49
View File
@@ -0,0 +1,49 @@
-- NB: This is a manually squashed view of all the CREATE and ALTER statements,
-- with comments attached to the fields for centralized documentation.
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Usages of models and assets to create things
-- This should work for inference as well as 3D object/scene creation,
-- so the inputs can be models OR files.
CREATE TABLE usages (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- ========== PRIMARY AND FOREIGN KEYS ==========
-- Type of the entity created
-- This only denotes which table to join against, not the type of the entity within the join table.
-- Possible values:
-- * 'model_weight'
-- * 'media_file'
-- * (maybe future types)
created_type VARCHAR(16) NOT NULL,
-- Token of the entity created
created_token VARCHAR(32) NOT NULL,
-- Type of the entity used
-- This only denotes which table to join against, not the type of the entity within the join table.
-- Possible values:
-- * 'model_weight'
-- * 'media_file'
-- * (maybe future types)
used_type VARCHAR(16) NOT NULL,
-- Token of the entity used
used_token VARCHAR(32) NOT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (created_type, created_token, used_type, used_token),
KEY index_created_type_and_token (created_type, created_token),
KEY index_used_type_and_token (used_type, used_token)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -26,6 +26,9 @@ pub enum MediaFileOriginCategory {
/// User uploaded files recorded directly from their device (browser, mobile), typically using device APIs.
DeviceApi,
/// From Storyteller Studio Engine
StoryEngine,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -41,6 +44,7 @@ impl MediaFileOriginCategory {
Self::Processed => "processed",
Self::Upload => "upload",
Self::DeviceApi => "device_api",
Self::StoryEngine => "story_engine",
}
}
@@ -50,6 +54,7 @@ impl MediaFileOriginCategory {
"processed" => Ok(Self::Processed),
"upload" => Ok(Self::Upload),
"device_api" => Ok(Self::DeviceApi),
"story_engine" => Ok(Self::StoryEngine),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -62,6 +67,7 @@ impl MediaFileOriginCategory {
Self::Processed,
Self::Upload,
Self::DeviceApi,
Self::StoryEngine,
])
}
}
@@ -80,6 +86,7 @@ mod tests {
assert_serialization(MediaFileOriginCategory::Processed, "processed");
assert_serialization(MediaFileOriginCategory::Upload, "upload");
assert_serialization(MediaFileOriginCategory::DeviceApi, "device_api");
assert_serialization(MediaFileOriginCategory::StoryEngine, "story_engine");
}
#[test]
@@ -87,7 +94,7 @@ mod tests {
assert_eq!(MediaFileOriginCategory::Inference.to_str(), "inference");
assert_eq!(MediaFileOriginCategory::Processed.to_str(), "processed");
assert_eq!(MediaFileOriginCategory::Upload.to_str(), "upload");
assert_eq!(MediaFileOriginCategory::DeviceApi.to_str(), "device_api");
assert_eq!(MediaFileOriginCategory::StoryEngine.to_str(), "story_engine");
}
#[test]
@@ -96,17 +103,19 @@ mod tests {
assert_eq!(MediaFileOriginCategory::from_str("processed").unwrap(), MediaFileOriginCategory::Processed);
assert_eq!(MediaFileOriginCategory::from_str("upload").unwrap(), MediaFileOriginCategory::Upload);
assert_eq!(MediaFileOriginCategory::from_str("device_api").unwrap(), MediaFileOriginCategory::DeviceApi);
assert_eq!(MediaFileOriginCategory::from_str("story_engine").unwrap(), MediaFileOriginCategory::StoryEngine);
assert!(MediaFileOriginCategory::from_str("foo").is_err());
}
#[test]
fn all_variants() {
let mut variants = MediaFileOriginCategory::all_variants();
assert_eq!(variants.len(), 4);
assert_eq!(variants.len(), 5);
assert_eq!(variants.pop_first(), Some(MediaFileOriginCategory::Inference));
assert_eq!(variants.pop_first(), Some(MediaFileOriginCategory::Processed));
assert_eq!(variants.pop_first(), Some(MediaFileOriginCategory::Upload));
assert_eq!(variants.pop_first(), Some(MediaFileOriginCategory::DeviceApi));
assert_eq!(variants.pop_first(), Some(MediaFileOriginCategory::StoryEngine));
assert_eq!(variants.pop_first(), None);
}
}
@@ -128,5 +137,15 @@ mod tests {
assert_eq!(variant, MediaFileOriginCategory::from_str(&format!("{:?}", variant)).unwrap());
}
}
#[test]
fn serialized_length_ok_for_database() {
const MAX_LENGTH : usize = 16;
for variant in MediaFileOriginCategory::all_variants() {
let serialized = variant.to_str();
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long", variant);
}
}
}
}
@@ -10,8 +10,8 @@ use utoipa::ToSchema;
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "lowercase")]
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum MediaFileType {
/// Audio files: wav, mp3, etc.
Audio,
@@ -39,6 +39,10 @@ pub enum MediaFileType {
/// glTF files (for Bevy)
Gltf,
/// Bevy's scene files (in RON; Rusty Object Notation)
/// This will be replaced with another format in future versions of Bevy
SceneRon,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -58,6 +62,7 @@ impl MediaFileType {
Self::Fbx => "fbx",
Self::Glb => "glb",
Self::Gltf => "gltf",
Self::SceneRon => "scene_ron",
}
}
@@ -71,6 +76,7 @@ impl MediaFileType {
"fbx" => Ok(Self::Fbx),
"glb" => Ok(Self::Glb),
"gltf" => Ok(Self::Gltf),
"scene_ron" => Ok(Self::SceneRon),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -87,6 +93,7 @@ impl MediaFileType {
Self::Fbx,
Self::Glb,
Self::Gltf,
Self::SceneRon,
])
}
}
@@ -109,6 +116,7 @@ mod tests {
assert_serialization(MediaFileType::Fbx, "fbx");
assert_serialization(MediaFileType::Glb, "glb");
assert_serialization(MediaFileType::Gltf, "gltf");
assert_serialization(MediaFileType::SceneRon, "scene_ron");
}
}
@@ -120,10 +128,12 @@ mod tests {
assert_eq!(MediaFileType::Audio.to_str(), "audio");
assert_eq!(MediaFileType::Image.to_str(), "image");
assert_eq!(MediaFileType::Video.to_str(), "video");
assert_eq!(MediaFileType::Mocap.to_str(), "mocap");
assert_eq!(MediaFileType::Bvh.to_str(), "bvh");
assert_eq!(MediaFileType::Fbx.to_str(), "fbx");
assert_eq!(MediaFileType::Glb.to_str(), "glb");
assert_eq!(MediaFileType::Gltf.to_str(), "gltf");
assert_eq!(MediaFileType::SceneRon.to_str(), "scene_ron");
}
#[test]
@@ -136,6 +146,7 @@ mod tests {
assert_eq!(MediaFileType::from_str("fbx").unwrap(), MediaFileType::Fbx);
assert_eq!(MediaFileType::from_str("glb").unwrap(), MediaFileType::Glb);
assert_eq!(MediaFileType::from_str("gltf").unwrap(), MediaFileType::Gltf);
assert_eq!(MediaFileType::from_str("scene_ron").unwrap(), MediaFileType::SceneRon);
assert!(MediaFileType::from_str("foo").is_err());
}
}
@@ -146,7 +157,7 @@ mod tests {
#[test]
fn all_variants() {
let mut variants = MediaFileType::all_variants();
assert_eq!(variants.len(), 8);
assert_eq!(variants.len(), 9);
assert_eq!(variants.pop_first(), Some(MediaFileType::Audio));
assert_eq!(variants.pop_first(), Some(MediaFileType::Image));
assert_eq!(variants.pop_first(), Some(MediaFileType::Video));
@@ -155,6 +166,7 @@ mod tests {
assert_eq!(variants.pop_first(), Some(MediaFileType::Fbx));
assert_eq!(variants.pop_first(), Some(MediaFileType::Glb));
assert_eq!(variants.pop_first(), Some(MediaFileType::Gltf));
assert_eq!(variants.pop_first(), Some(MediaFileType::SceneRon));
assert_eq!(variants.pop_first(), None);
}
}
+2
View File
@@ -11,8 +11,10 @@ pub mod media_files;
pub mod media_uploads;
pub mod model_categories;
pub mod model_weights;
pub mod prompts;
pub mod trending_model_analytics;
pub mod tts_models;
pub mod usages;
pub mod user_bookmarks;
pub mod user_ratings;
pub mod voice_conversion_models;
@@ -0,0 +1 @@
pub mod prompt_type;
@@ -0,0 +1,128 @@
use std::collections::BTreeSet;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
use utoipa::ToSchema;
/// Used in the `prompts` table in a `VARCHAR(16)` field.
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum PromptType {
/// Stable diffusion
StableDiffusion,
/// Comfy UI
ComfyUi,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(PromptType);
impl_mysql_enum_coders!(PromptType);
impl_mysql_from_row!(PromptType);
/// NB: Legacy API for older code.
impl PromptType {
pub fn to_str(&self) -> &'static str {
match self {
Self::StableDiffusion => "stable_diffusion",
Self::ComfyUi => "comfy_ui",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"stable_diffusion" => Ok(Self::StableDiffusion),
"comfy_ui" => Ok(Self::ComfyUi),
_ => Err(format!("invalid value: {:?}", value)),
}
}
pub fn all_variants() -> BTreeSet<Self> {
// NB: BTreeSet is sorted
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
Self::StableDiffusion,
Self::ComfyUi,
])
}
}
#[cfg(test)]
mod tests {
use crate::by_table::prompts::prompt_type::PromptType;
use crate::test_helpers::assert_serialization;
mod serde {
use super::*;
#[test]
fn test_serialization() {
assert_serialization(PromptType::StableDiffusion, "stable_diffusion");
assert_serialization(PromptType::ComfyUi, "comfy_ui");
}
}
mod impl_methods {
use super::*;
#[test]
fn to_str() {
assert_eq!(PromptType::StableDiffusion.to_str(), "stable_diffusion");
assert_eq!(PromptType::ComfyUi.to_str(), "comfy_ui");
}
#[test]
fn from_str() {
assert_eq!(PromptType::from_str("stable_diffusion").unwrap(), PromptType::StableDiffusion);
assert_eq!(PromptType::from_str("comfy_ui").unwrap(), PromptType::ComfyUi);
assert!(PromptType::from_str("foo").is_err());
}
}
mod manual_variant_checks {
use super::*;
#[test]
fn all_variants() {
let mut variants = PromptType::all_variants();
assert_eq!(variants.len(), 2);
assert_eq!(variants.pop_first(), Some(PromptType::StableDiffusion));
assert_eq!(variants.pop_first(), Some(PromptType::ComfyUi));
assert_eq!(variants.pop_first(), None);
}
}
mod mechanical_checks {
use super::*;
#[test]
fn variant_length() {
use strum::IntoEnumIterator;
assert_eq!(PromptType::all_variants().len(), PromptType::iter().len());
}
#[test]
fn round_trip() {
for variant in PromptType::all_variants() {
assert_eq!(variant, PromptType::from_str(variant.to_str()).unwrap());
assert_eq!(variant, PromptType::from_str(&format!("{}", variant)).unwrap());
assert_eq!(variant, PromptType::from_str(&format!("{:?}", variant)).unwrap());
}
}
#[test]
fn serialized_length_ok_for_database() {
const MAX_LENGTH : usize = 16;
for variant in PromptType::all_variants() {
let serialized = variant.to_str();
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long", variant);
}
}
}
}
@@ -0,0 +1 @@
pub mod usages_type;
@@ -0,0 +1,128 @@
use std::collections::BTreeSet;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
use utoipa::ToSchema;
/// Used in the `usages` table in a `VARCHAR(16)` field. (Two fields!)
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum UsagesType {
/// Represents a foreign key link against a model_weights record
ModelWeight,
/// Represents a foreign key link against a media_files record
MediaFile,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(UsagesType);
impl_mysql_enum_coders!(UsagesType);
impl_mysql_from_row!(UsagesType);
/// NB: Legacy API for older code.
impl UsagesType {
pub fn to_str(&self) -> &'static str {
match self {
Self::ModelWeight => "model_weight",
Self::MediaFile => "media_file",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"model_weight" => Ok(Self::ModelWeight),
"media_file" => Ok(Self::MediaFile),
_ => Err(format!("invalid value: {:?}", value)),
}
}
pub fn all_variants() -> BTreeSet<Self> {
// NB: BTreeSet is sorted
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
Self::ModelWeight,
Self::MediaFile,
])
}
}
#[cfg(test)]
mod tests {
use crate::by_table::usages::usages_type::UsagesType;
use crate::test_helpers::assert_serialization;
mod serde {
use super::*;
#[test]
fn test_serialization() {
assert_serialization(UsagesType::ModelWeight, "model_weight");
assert_serialization(UsagesType::MediaFile, "media_file");
}
}
mod impl_methods {
use super::*;
#[test]
fn to_str() {
assert_eq!(UsagesType::ModelWeight.to_str(), "model_weight");
assert_eq!(UsagesType::MediaFile.to_str(), "media_file");
}
#[test]
fn from_str() {
assert_eq!(UsagesType::from_str("model_weight").unwrap(), UsagesType::ModelWeight);
assert_eq!(UsagesType::from_str("media_file").unwrap(), UsagesType::MediaFile);
assert!(UsagesType::from_str("foo").is_err());
}
}
mod manual_variant_checks {
use super::*;
#[test]
fn all_variants() {
let mut variants = UsagesType::all_variants();
assert_eq!(variants.len(), 2);
assert_eq!(variants.pop_first(), Some(UsagesType::ModelWeight));
assert_eq!(variants.pop_first(), Some(UsagesType::MediaFile));
assert_eq!(variants.pop_first(), None);
}
}
mod mechanical_checks {
use super::*;
#[test]
fn variant_length() {
use strum::IntoEnumIterator;
assert_eq!(UsagesType::all_variants().len(), UsagesType::iter().len());
}
#[test]
fn round_trip() {
for variant in UsagesType::all_variants() {
assert_eq!(variant, UsagesType::from_str(variant.to_str()).unwrap());
assert_eq!(variant, UsagesType::from_str(&format!("{}", variant)).unwrap());
assert_eq!(variant, UsagesType::from_str(&format!("{:?}", variant)).unwrap());
}
}
#[test]
fn serialized_length_ok_for_database() {
const MAX_LENGTH : usize = 16;
for variant in UsagesType::all_variants() {
let serialized = variant.to_str();
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long", variant);
}
}
}
}
+2
View File
@@ -34,6 +34,7 @@ pub(crate) enum TokenPrefix {
ModelWeight,
NewsStory, // NB: aichatbot / sqlite
PasswordReset,
Prompt,
TtsRenderTask, // NB: aichatbot / sqlite
User,
UserBookmark,
@@ -101,6 +102,7 @@ impl PrefixGenerator for TokenPrefix {
Self::ModelWeight => "weight_",
Self::NewsStory => "news_story_",
Self::PasswordReset => "pw_reset_",
Self::Prompt => "prompt_",
Self::TtsRenderTask => "tts_task_",
Self::User => "user_", // NB: Previously "U:"
Self::UserBookmark => "ub_",
@@ -6,7 +6,7 @@ use utoipa::ToSchema;
use crate::prefixes::TokenPrefix;
/// The primary key for Audit Logs.
/// The primary key for Media Files
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize, ToSchema)]
#[sqlx(transparent)]
pub struct MediaFileToken(pub String);
+1
View File
@@ -13,6 +13,7 @@ pub mod media_uploads;
pub mod model_categories;
pub mod model_weights;
pub mod password_reset;
pub mod prompts;
pub mod sqlite;
pub mod tts_inference_jobs;
pub mod tts_model_upload_jobs;
@@ -0,0 +1,15 @@
use std::fmt::Debug;
use serde::Deserialize;
use serde::Serialize;
use utoipa::ToSchema;
use crate::prefixes::TokenPrefix;
/// The primary key for Prompts
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize, ToSchema)]
#[sqlx(transparent)]
pub struct PromptToken(pub String);
impl_string_token!(PromptToken);
impl_crockford_generator!(PromptToken, 32usize, TokenPrefix::Prompt, CrockfordLower);
-33
View File
@@ -1,33 +0,0 @@
[package]
name = "database-cleanup"
publish = false
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
[[bin]]
name = "database-cleanup"
path = "src/main.rs"
[dependencies]
# Internal
container_common = { path = "../../lib/deprecated/container_common" }
easyenv = { path = "../../lib/easyenv" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
# External
anyhow = "1.0.75"
# TODO/NB: Commenting out clap4 as it prevents windows builds
# clap4 = { package = "clap", version = "4.0" } # TODO/NB: We're using an older version of clap elsewhere, hence the naming.
dotenv = "0.15.0"
log = "0.4.14"
# Serialization
serde = "1.0.125"
serde_derive = "1.0.125"
-12
View File
@@ -1,12 +0,0 @@
use easyenv::init_all_with_default_logging;
use log::info;
use container_common::anyhow_result::AnyhowResult;
fn main() -> AnyhowResult<()> {
init_all_with_default_logging(None);
info!("TODO...");
Ok(())
}
-47
View File
@@ -1,47 +0,0 @@
[package]
name = "dev-database-seed"
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
publish = false
[[bin]]
name = "dev-database-seed"
path = "src/main.rs"
[dependencies]
# Internal
buckets = { path = "../../_types/buckets" }
cloud_storage = { path = "../../lib/api_clients/cloud_storage" }
config = { path = "../../lib/deprecated/config" }
easyenv = { path = "../../lib/easyenv" }
enums = { path = "../../_types/enums" }
errors = { path = "../../lib/errors" }
filesys = { path = "../../lib/files/filesys" }
hashing = { path = "../../lib/files/hashing" }
idempotency = { path = "../../lib/idempotency" }
mimetypes = { path = "../../lib/files/mimetypes" }
mysql_queries = { path = "../../lib/mysql_queries" }
storyteller_root = { path = "../../lib/storyteller_root" }
tokens = { path = "../../_types/tokens" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
# External
log = "0.4.14"
clap = "4.4.8"
rand = "0.8.5"
# Runtime
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
tokio = { version = "1.34.0", features = ["macros"] }
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
elasticsearch = "8.5.0-alpha.1"
[dev-dependencies]
# None yet
@@ -0,0 +1,47 @@
[package]
name = "dev-database-seed"
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
publish = false
[[bin]]
name = "dev-database-seed"
path = "src/main.rs"
[dependencies]
# Internal
buckets = { path = "../../../_types/buckets" }
cloud_storage = { path = "../../../lib/api_clients/cloud_storage" }
config = { path = "../../../lib/deprecated/config" }
easyenv = { path = "../../../lib/easyenv" }
enums = { path = "../../../_types/enums" }
errors = { path = "../../../lib/errors" }
filesys = { path = "../../../lib/files/filesys" }
hashing = { path = "../../../lib/files/hashing" }
idempotency = { path = "../../../lib/idempotency" }
mimetypes = { path = "../../../lib/files/mimetypes" }
mysql_queries = { path = "../../../lib/mysql_queries" }
storyteller_root = { path = "../../../lib/storyteller_root" }
tokens = { path = "../../../_types/tokens" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
log = "0.4.14"
clap = "4.4.8"
rand = "0.8.5"
# Runtime
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
tokio = { version = "1.34.0", features = ["macros"] }
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
elasticsearch = "8.5.0-alpha.1"
[dev-dependencies]
# None yet
@@ -14,19 +14,19 @@ path = "src/main.rs"
[dependencies]
# Internal
buckets = { path = "../../_types/buckets" }
cloud_storage = { path = "../../lib/api_clients/cloud_storage" }
config = { path = "../../lib/deprecated/config" }
easyenv = { path = "../../lib/easyenv" }
enums = { path = "../../_types/enums" }
errors = { path = "../../lib/errors" }
filesys = { path = "../../lib/files/filesys" }
mimetypes = { path = "../../lib/files/mimetypes" }
mysql_queries = { path = "../../lib/mysql_queries" }
tokens = { path = "../../_types/tokens" }
buckets = { path = "../../../_types/buckets" }
cloud_storage = { path = "../../../lib/api_clients/cloud_storage" }
config = { path = "../../../lib/deprecated/config" }
easyenv = { path = "../../../lib/easyenv" }
enums = { path = "../../../_types/enums" }
errors = { path = "../../../lib/errors" }
filesys = { path = "../../../lib/files/filesys" }
mimetypes = { path = "../../../lib/files/mimetypes" }
mysql_queries = { path = "../../../lib/mysql_queries" }
tokens = { path = "../../../_types/tokens" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
clap = "4.4.8"
@@ -1,5 +1,5 @@
[package]
name = "scrape_test"
name = "scrape-test"
publish = false
edition = "2021"
version = "0.0.1"
@@ -9,17 +9,17 @@ authors = [
]
[[bin]]
name = "scrape_test"
name = "scrape-test"
path = "src/main.rs"
[dependencies]
# Internal
errors = { path = "../../lib/errors" }
web_scrapers = { path = "../../lib/web_scrapers" }
errors = { path = "../../../lib/errors" }
web_scrapers = { path = "../../../lib/web_scrapers" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
clap = "4.4.8"
@@ -4,7 +4,7 @@ use errors::AnyhowResult;
use web_scrapers::scrape_supported_webpage::scrape_supported_webpage;
#[derive(Parser, Debug)]
#[command(name = "scrape_test")]
#[command(name = "scrape-test")]
pub struct Args {
#[arg(name="url", short='u', long = "url", help = "URL of the page to scrape", required = true)]
url: String,
@@ -1,5 +1,5 @@
[package]
name = "database-backup"
name = "db-backup"
publish = false
edition = "2018"
version = "0.0.1"
@@ -9,17 +9,17 @@ authors = [
]
[[bin]]
name = "database-backup"
name = "db-backup"
path = "src/main.rs"
[dependencies]
# Internal
container_common = { path = "../../lib/deprecated/container_common" }
easyenv = { path = "../../lib/easyenv" }
container_common = { path = "../../../lib/deprecated/container_common" }
easyenv = { path = "../../../lib/easyenv" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
anyhow = "1.0.75"
@@ -0,0 +1,44 @@
[package]
name = "db-cleanup"
publish = false
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
[[bin]]
name = "db-cleanup"
path = "src/main.rs"
[dependencies]
# Internal
buckets = { path = "../../../_types/buckets" }
container_common = { path = "../../../lib/deprecated/container_common" }
easyenv = { path = "../../../lib/easyenv" }
enums = { path = "../../../_types/enums" }
errors = { path = "../../../lib/errors" }
mysql_queries = { path = "../../../lib/mysql_queries" }
storyteller_root = { path = "../../../lib/storyteller_root" }
tokens = { path = "../../../_types/tokens" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
clap = "4.4.8"
dotenv = "0.15.0"
log = "0.4.14"
# Bigger pieces
tokio = { version = "1.34.0", features = ["macros"] }
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
# Serialization
serde = "1.0.125"
serde_derive = "1.0.125"
serde_json = "1.0.108"
[dev-dependencies]
# None yet
@@ -0,0 +1,37 @@
use clap::{Parser, ValueEnum};
use serde_derive::Deserialize;
use errors::AnyhowResult;
#[derive(Parser, Debug, Deserialize)]
#[command(name="db-cleanup")]
#[serde(rename_all = "snake_case")]
pub struct Args {
// The primary action to take
#[arg(name="action", long="action", help="the primary action to take", required=true)]
pub action: Action,
// Optional username for some actions
#[arg(name="username", long="username", help="optional username", required=false)]
pub username: Option<String>,
}
#[derive(Clone, Copy, Debug, Deserialize, ValueEnum)]
#[serde(rename_all = "snake_case")]
pub enum Action {
/// Delete all anonymous user images.
DeleteAllAnonymousUserImages,
/// Delete files for a particular user.
DeleteUserFiles,
}
pub fn parse_cli_args() -> AnyhowResult<Args> {
let mut args = Args::parse();
if let Some(username) = args.username.as_deref() {
args.username = Some(username.trim().to_string());
}
Ok(args)
}
@@ -0,0 +1,70 @@
use log::info;
use sqlx::{MySql, Pool};
use sqlx::mysql::MySqlPoolOptions;
use container_common::anyhow_result::AnyhowResult;
use easyenv::init_all_with_default_logging;
use crate::cli_args::Action;
use crate::operations::delete_all_anonymous_user_images::delete_all_anonymous_user_images::delete_all_anonymous_user_images;
use crate::operations::delete_user_files::delete_user_files::delete_user_files;
mod cli_args;
mod operations;
mod util;
/*
Users that have had files deleted:
- cheesetherat
- endtimes
- expandinggirl
- markiwrench
- regista2
- regista77
TODO:
- juanfra3567
- ceistin
- elfabro17
- sodoka
- fluffernater
*/
#[tokio::main]
async fn main() -> AnyhowResult<()> {
println!("db-cleanup: hard or soft delete database records");
init_all_with_default_logging(None);
// NB: This secrets file differs from the rest because we might want to delete from production.
// (Hopefully this isn't getting out of hand at this point.)
easyenv::from_filename(".env-db-cleanup-secrets")?;
let args = cli_args::parse_cli_args()?;
let mysql = get_mysql("MYSQL_PRODUCTION_URL").await?;
match args.action {
Action::DeleteAllAnonymousUserImages => {
delete_all_anonymous_user_images(&args, &mysql).await?;
}
Action::DeleteUserFiles => {
delete_user_files(&args, &mysql).await?;
}
}
Ok(())
}
async fn get_mysql(env_var_name: &str) -> errors::AnyhowResult<Pool<MySql>> {
info!("Connecting to MySQL {env_var_name}...");
let pool = MySqlPoolOptions::new()
.max_connections(easyenv::get_env_num("MYSQL_MAX_CONNECTIONS", 3)?)
.connect(&easyenv::get_env_string_required(env_var_name)?)
.await?;
Ok(pool)
}
@@ -0,0 +1,66 @@
use std::thread;
use std::time::Duration;
use log::info;
use sqlx::{MySql, Pool};
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::common::view_as::ViewAs;
use errors::{anyhow, AnyhowResult};
use mysql_queries::queries::media_files::delete_media_file::delete_media_file_as_mod;
use mysql_queries::queries::media_files::list::list_media_files::{list_media_files, ListMediaFilesArgs};
use mysql_queries::queries::media_files::list::list_media_files_for_user::{list_media_files_for_user, ListMediaFileForUserArgs};
use mysql_queries::queries::users::user_profiles::get_user_profile_by_username::get_user_profile_by_username;
use crate::cli_args::Args;
use crate::util::constants::ECHELON_USER_TOKEN;
pub async fn delete_all_anonymous_user_images(_args: &Args, mysql: &Pool<MySql>) -> AnyhowResult<()> {
info!("delete anonymous user images");
let mut page_index = 0;
let mut maybe_offset = None;
loop {
info!("Querying page {page_index} of files...");
let media_files = list_media_files(ListMediaFilesArgs {
limit: 100,
maybe_filter_media_type: Some(MediaFileType::Image),
maybe_offset,
cursor_is_reversed: false,
sort_ascending: false,
view_as: ViewAs::Moderator,
mysql_pool: &mysql,
}).await?;
if media_files.records.is_empty() {
break;
}
for file in media_files.records {
if file.maybe_creator_user_token.is_some() {
info!("Skipping file: {:?} , which has author: {:?}", &file.token, &file.maybe_creator_user_token);
continue;
}
match file.media_type {
MediaFileType::Image => {},
_ => {
info!("Skipping file: {:?} , which is not an image", &file.token);
continue;
}
}
info!("Deleting image file: {:?}", &file.token);
delete_media_file_as_mod(&file.token, ECHELON_USER_TOKEN, &mysql).await?;
}
page_index += 1;
maybe_offset = media_files.last_id.map(|id| id as usize);
thread::sleep(Duration::from_millis(1000));
}
Ok(())
}
@@ -0,0 +1 @@
pub mod delete_all_anonymous_user_images;
@@ -0,0 +1,68 @@
use std::thread;
use std::time::Duration;
use log::info;
use sqlx::{MySql, Pool};
use enums::common::view_as::ViewAs;
use errors::{anyhow, AnyhowResult};
use mysql_queries::queries::media_files::delete_media_file::delete_media_file_as_mod;
use mysql_queries::queries::media_files::list::list_media_files_for_user::{list_media_files_for_user, ListMediaFileForUserArgs};
use mysql_queries::queries::users::user_profiles::get_user_profile_by_username::get_user_profile_by_username;
use crate::cli_args::Args;
use crate::util::constants::ECHELON_USER_TOKEN;
pub async fn delete_user_files(args: &Args, mysql: &Pool<MySql>) -> AnyhowResult<()> {
info!("delete user files for username: {:?}", args.username);
let username = match args.username.as_deref() {
Some(username) => username,
None => return Err(anyhow!("username is required")),
};
let maybe_user_profile = get_user_profile_by_username(username, mysql).await?;
let user_profile = match maybe_user_profile {
Some(user_profile) => user_profile,
None => return Err(anyhow!("user not found")),
};
info!("user_profile: {:?}", &user_profile);
delete_all_files(username, mysql).await?;
Ok(())
}
pub async fn delete_all_files(username: &str, mysql: &Pool<MySql>) -> AnyhowResult<()> {
let mut page_index = 0;
loop {
info!("Querying page {page_index} of files...");
let media_files = list_media_files_for_user(ListMediaFileForUserArgs {
username,
maybe_filter_media_types: None,
page_size: 100,
page_index,
sort_ascending: false,
view_as: ViewAs::Moderator,
mysql_pool: &mysql,
}).await?;
if media_files.records.is_empty() {
break;
}
for file in media_files.records {
info!("Deleting file: {:?}", &file.token);
delete_media_file_as_mod(&file.token, ECHELON_USER_TOKEN, &mysql).await?;
}
page_index += 1;
thread::sleep(Duration::from_millis(1000));
}
Ok(())
}
@@ -0,0 +1 @@
pub mod delete_user_files;
@@ -0,0 +1,2 @@
pub mod delete_all_anonymous_user_images;
pub mod delete_user_files;
@@ -0,0 +1,3 @@
/// User token to use as the moderator field when deleting files.
pub (crate) const ECHELON_USER_TOKEN : &str = "U:937C1VN0S5G8H";
@@ -0,0 +1 @@
pub (crate) mod constants;
@@ -14,30 +14,27 @@ path = "src/main.rs"
[dependencies]
# Internal
buckets = { path = "../../_types/buckets" }
config = { path = "../../lib/deprecated/config" }
easyenv = { path = "../../lib/easyenv" }
elasticsearch_schema = { path = "../../lib/elasticsearch_schema" }
enums = { path = "../../_types/enums" }
errors = { path = "../../lib/errors" }
mysql_queries = { path = "../../lib/mysql_queries" }
storyteller_root = { path = "../../lib/storyteller_root" }
tokens = { path = "../../_types/tokens" }
buckets = { path = "../../../_types/buckets" }
config = { path = "../../../lib/deprecated/config" }
easyenv = { path = "../../../lib/easyenv" }
elasticsearch_schema = { path = "../../../lib/elasticsearch_schema" }
enums = { path = "../../../_types/enums" }
errors = { path = "../../../lib/errors" }
mysql_queries = { path = "../../../lib/mysql_queries" }
storyteller_root = { path = "../../../lib/storyteller_root" }
tokens = { path = "../../../_types/tokens" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
log = "0.4.14"
clap = "4.4.8"
log = "0.4.14"
strum = { version = "0.25", features = ["derive"] }
# Runtime
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
# Bigger pieces
tokio = { version = "1.34.0", features = ["macros"] }
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
elasticsearch = "8.5.0-alpha.1"
# Serialization
@@ -14,12 +14,12 @@ path = "src/main.rs"
[dependencies]
# Internal
config = { path = "../../lib/deprecated/config" }
easyenv = { path = "../../lib/easyenv" }
errors = { path = "../../lib/errors" }
config = { path = "../../../lib/deprecated/config" }
easyenv = { path = "../../../lib/easyenv" }
errors = { path = "../../../lib/errors" }
# Workspace hack (faster compile yytimes)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
log = "0.4.20"
@@ -14,11 +14,11 @@ path = "src/main.rs"
[dependencies]
# Internal
errors = { path = "../../lib/errors" }
logging = { path = "../../lib/logging" }
errors = { path = "../../../lib/errors" }
logging = { path = "../../../lib/logging" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
clap = { version = "4.4.8", features = ["derive"] }
@@ -14,20 +14,20 @@ path = "src/main.rs"
[dependencies]
# Internal
buckets = { path = "../../_types/buckets" }
cloud_storage = { path = "../../lib/api_clients/cloud_storage" }
config = { path = "../../lib/deprecated/config" }
easyenv = { path = "../../lib/easyenv" }
enums = { path = "../../_types/enums" }
errors = { path = "../../lib/errors" }
filesys = { path = "../../lib/files/filesys" }
hashing = { path = "../../lib/files/hashing" }
mysql_queries = { path = "../../lib/mysql_queries" }
storyteller_root = { path = "../../lib/storyteller_root" }
tokens = { path = "../../_types/tokens" }
buckets = { path = "../../../_types/buckets" }
cloud_storage = { path = "../../../lib/api_clients/cloud_storage" }
config = { path = "../../../lib/deprecated/config" }
easyenv = { path = "../../../lib/easyenv" }
enums = { path = "../../../_types/enums" }
errors = { path = "../../../lib/errors" }
filesys = { path = "../../../lib/files/filesys" }
hashing = { path = "../../../lib/files/hashing" }
mysql_queries = { path = "../../../lib/mysql_queries" }
storyteller_root = { path = "../../../lib/storyteller_root" }
tokens = { path = "../../../_types/tokens" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
clap = "4.4.8"
@@ -3,7 +3,6 @@
//! Migrate database records.
//!
use std::time::Duration;
use log::info;
@@ -56,6 +56,8 @@ pub fn add_fakeyou(cors: Cors, is_production: bool) -> Cors {
.allowed_origin("http://fakeyou.com")
.allowed_origin("https://api.fakeyou.com")
.allowed_origin("https://fakeyou.com")
// Storyteller Engine (Production)
.allowed_origin("https://engine.fakeyou.com")
// FakeYou (Staging)
.allowed_origin("http://staging.fakeyou.com")
.allowed_origin("https://staging.fakeyou.com")
@@ -72,6 +74,8 @@ pub fn add_fakeyou(cors: Cors, is_production: bool) -> Cors {
.allowed_origin("https://dev.fakeyou.com:7000") // Yarn default port
.allowed_origin("https://dev.fakeyou.com:7001") // NB: Mac frontend
.allowed_origin("https://development.fakeyou.com")
// Storyteller Engine (Development)
.allowed_origin("https://engine.fakeyou.com") // NB: We use prod for integration testing
}
}
@@ -176,9 +180,8 @@ pub fn add_legacy_trumped(cors: Cors, is_production: bool) -> Cors {
pub fn add_development_only(cors: Cors) -> Cors {
cors
// Local Development (Localhost)
.allowed_origin("http://localhost:12345")
.allowed_origin("http://localhost:3000")
.allowed_origin("http://localhost:54321")
.allowed_origin("http://localhost:4200")
.allowed_origin("http://localhost:5555")
.allowed_origin("http://localhost:7000")
.allowed_origin("http://localhost:7001")
@@ -192,6 +195,8 @@ pub fn add_development_only(cors: Cors) -> Cors {
.allowed_origin("http://localhost:7009")
.allowed_origin("http://localhost:8000")
.allowed_origin("http://localhost:8080")
.allowed_origin("http://localhost:12345")
.allowed_origin("http://localhost:54321")
// Local Development (JungleHorse)
.allowed_origin("http://api.jungle.horse")
.allowed_origin("http://jungle.horse")
+29
View File
@@ -0,0 +1,29 @@
[package]
name = "videos"
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
publish = false
[lib]
# NB: Public "videos" crate doesn't exist; "video" crate looks like it's not useful
name = "videos"
path = "src/lib.rs"
[dependencies]
# Internal
errors = { path = "../../errors" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
# External
mp4 = "0.14.0"
log = "0.4.20"
[dev-dependencies]
testing = { path = "../../testing" }
@@ -0,0 +1,80 @@
use std::io::{BufReader, Cursor, Read, Seek};
use std::time::Duration;
use log::warn;
use mp4::TrackType;
use errors::AnyhowResult;
pub struct Mp4Info {
/// Framerate of the longest video track.
pub framerate: f64,
/// Duration of the entire mp4.
pub duration_millis: u128,
}
pub fn get_mp4_info_for_bytes(file_bytes: &[u8], file_size: u64) -> AnyhowResult<Mp4Info> {
let reader = BufReader::new(Cursor::new(file_bytes));
get_mp4_info(reader, file_size)
}
pub fn get_mp4_info<T: Seek + Read>(reader: T, file_size: u64) -> AnyhowResult<Mp4Info> {
let mp4 = mp4::Mp4Reader::read_header(reader, file_size)?;
let mut framerate = 0.0;
let mut longest_duration = Duration::from_secs(0);
for track in mp4.tracks().values() {
match track.track_type() {
Ok(TrackType::Video) => {
if track.duration() > longest_duration {
longest_duration = track.duration();
framerate = track.frame_rate();
}
}
Err(err) => {
warn!("Error determining track type: {:?}", err);
continue;
},
_ => continue,
}
}
Ok(Mp4Info {
framerate,
duration_millis: mp4.duration().as_millis(),
})
}
#[cfg(test)]
pub mod tests {
use std::fs::File;
use std::io::BufReader;
use std::path::PathBuf;
use testing::test_file_path::test_file_path;
use crate::get_mp4_info::get_mp4_info;
fn test_file(path_from_repo_root: &str) -> PathBuf {
// https://doc.rust-lang.org/cargo/reference/environment-variables.html
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push(format!("../../../{}", path_from_repo_root));
path
}
#[test]
pub fn test_decode_mp4() {
let filename = test_file_path("test_data/video/mp4/golden_sun_garoh.mp4")
.expect("path should exist");
let file = File::open(filename).expect("file should open");
let size = file.metadata().expect("should be able to grab metadata").len();
let reader = BufReader::new(file);
let info = get_mp4_info(reader, size).expect("mp4 reader should work");
assert_eq!(info.framerate, 30.0);
assert_eq!(info.duration_millis, 15168);
}
}
+21
View File
@@ -0,0 +1,21 @@
//! videos
//!
//! Library functions related to processing videos.
//!
// Never allow these
#![forbid(private_bounds)]
#![forbid(private_interfaces)]
#![forbid(unused_must_use)] // NB: It's unsafe to not close/check some things
// Okay to toggle
#![forbid(unreachable_patterns)]
#![forbid(unused_imports)]
#![forbid(unused_mut)]
#![forbid(unused_variables)]
// Always allow
#![allow(dead_code)]
#![allow(non_snake_case)]
pub mod get_mp4_info;
@@ -1,6 +1,7 @@
use std::collections::HashMap;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::model_weights::ModelWeightToken;
use enums::common::visibility::Visibility;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
@@ -11,6 +12,17 @@ pub enum NewValue {
Bool(bool),
}
impl NewValue {
pub fn to_string(&self) -> String {
match self {
NewValue::String(s) => s.to_string(),
NewValue::Int(s) => s.to_string(),
NewValue::Float(s) => s.to_string(),
NewValue::Bool(s) => s.to_string(),
}
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct WorkflowArgs {
#[serde(rename = "sd")]
@@ -37,8 +49,45 @@ pub struct WorkflowArgs {
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_output_path: Option<String>,
// Upload information
// google drive link for uploads
#[serde(rename = "gd")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_google_drive_link: Option<String>
pub maybe_google_drive_link: Option<String>,
#[serde(rename = "ti")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_title: Option<String>,
#[serde(rename = "de")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_description: Option<String>,
#[serde(rename = "ch")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_commit_hash: Option<String>,
#[serde(rename = "cv")]
#[serde(skip_serializing_if = "Option::is_none")]
pub creator_visibility: Option<Visibility>,
#[serde(rename = "ts")]
#[serde(skip_serializing_if = "Option::is_none")]
pub trim_start_seconds: Option<u32>,
#[serde(rename = "te")]
#[serde(skip_serializing_if = "Option::is_none")]
pub trim_end_seconds: Option<u32>,
#[serde(rename = "tf")]
#[serde(skip_serializing_if = "Option::is_none")]
pub target_fps: Option<u32>,
// #[serde(rename = "sw")]
// #[serde(skip_serializing_if = "Option::is_none")]
// pub scale_width: Option<u32>,
//
// #[serde(rename = "sh")]
// #[serde(skip_serializing_if = "Option::is_none")]
// pub scale_height: Option<u32>
}
@@ -11,6 +11,7 @@ use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::users::UserToken;
use crate::helpers::boolean_converters::i8_to_bool;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
@@ -42,6 +43,8 @@ pub struct AvailableInferenceJob {
// User information to propagate downstream
pub maybe_creator_user_token: Option<String>,
/// Same user token, but a `UserToken`.
pub maybe_creator_user_token_typed: Option<UserToken>,
pub maybe_creator_anonymous_visitor_token: Option<String>,
pub creator_ip_address: String,
pub creator_set_visibility: Visibility,
@@ -102,12 +105,17 @@ pub async fn list_available_generic_inference_jobs(
let job_records : Vec<AvailableInferenceJob> = job_records.into_iter()
.map(|record : AvailableInferenceJobRawInternal| {
let record = AvailableInferenceJob {
let maybe_creator_user_token_typed = record.maybe_creator_user_token
.as_ref()
.map(|s| UserToken::new_from_str(s));
Ok(AvailableInferenceJob {
id: GenericInferenceJobId(record.id),
inference_job_token: InferenceJobToken::new(record.inference_job_token),
uuid_idempotency_token: record.uuid_idempotency_token,
creator_ip_address: record.creator_ip_address,
maybe_creator_user_token: record.maybe_creator_user_token,
maybe_creator_user_token: record.maybe_creator_user_token.clone(),
maybe_creator_user_token_typed,
maybe_creator_anonymous_visitor_token: record.maybe_creator_anonymous_visitor_token,
maybe_cover_image_media_file_token: record.maybe_cover_image_media_file_token
.map(|s| MediaFileToken::new_from_str(&s)),
@@ -143,8 +151,7 @@ pub async fn list_available_generic_inference_jobs(
updated_at: record.updated_at,
retry_at: record.retry_at,
database_clock: record.database_clock,
};
Ok(record)
})
})
// NB: Magic Vec<Result> -> Result<Vec<>>
// https://stackoverflow.com/a/63798748
@@ -9,6 +9,7 @@ use enums::by_table::media_files::media_file_origin_product_category::MediaFileO
use enums::by_table::media_files::media_file_type::MediaFileType;
use errors::AnyhowResult;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::prompts::PromptToken;
use tokens::tokens::users::UserToken;
use crate::queries::generic_inference::job::list_available_generic_inference_jobs::AvailableInferenceJob;
@@ -24,6 +25,8 @@ pub struct InsertArgs<'a> {
// TODO: Media duration.
//pub duration_millis: u64,
pub maybe_prompt_token: Option<&'a PromptToken>,
pub public_bucket_directory_hash: &'a str,
pub maybe_public_bucket_prefix: Option<&'a str>,
pub maybe_public_bucket_extension: Option<&'a str>,
@@ -85,6 +88,8 @@ SET
checksum_sha2 = ?,
maybe_prompt_token = ?,
public_bucket_directory_hash = ?,
maybe_public_bucket_prefix = ?,
maybe_public_bucket_extension = ?,
@@ -116,6 +121,8 @@ SET
args.sha256_checksum,
args.maybe_prompt_token.map(|e| e.as_str()),
args.public_bucket_directory_hash,
args.maybe_public_bucket_prefix,
args.maybe_public_bucket_extension,

Some files were not shown because too many files have changed in this diff Show More