Compare commits

..
Author SHA1 Message Date
Brandon Thomas d0c8dffecb state endpoint 2026-05-21 22:40:15 -04:00
Brandon Thomas a71c846634 readme 2026-05-21 22:30:37 -04:00
Brandon Thomas ec4d0bcb16 jitter 2026-05-21 22:19:44 -04:00
Brandon Thomas bfc6104e66 configure jitter 2026-05-21 22:13:01 -04:00
Brandon Thomas 4eb6f16123 enhanced behavior 2026-05-21 22:01:30 -04:00
Brandon Thomas 12f7f56928 better behavior 2026-05-21 21:53:40 -04:00
Brandon Thomas fab5fa97f8 instructions 2026-05-21 21:36:27 -04:00
Brandon Thomas 7f86cc8c42 update configs 2026-05-21 19:56:28 -04:00
Brandon Thomas d4a07af223 fix pathing, configs 2026-05-21 19:48:03 -04:00
Brandon Thomas 4c8a9dc62d new tool server 2026-05-21 19:42:46 -04:00
Brandon Thomas 9471f0e19a reorganize jobs queries (#1546) 2026-05-21 17:35:01 -04:00
Brandon Thomas 804e8e3f38 remove old wav2lip code (#1545) 2026-05-21 16:11:35 -04:00
BFlat 934a30c9e1 web/webapp: pricing plan ui update (#1544) 2026-05-21 21:29:28 +07:00
Brandon Thomas ce2e545bae storyteller web initialization cleanup (#1543) 2026-05-20 14:05:44 -04:00
Brandon Thomas 0d5d7c6fc8 byteplus enum rename (#1542) 2026-05-20 10:47:54 -04:00
258 changed files with 3277 additions and 13213 deletions
@@ -1,289 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l.token as template_token,\n w2l.template_type,\n w2l.creator_user_token,\n users.is_banned as creator_is_banned,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_gravatar_hash,\n w2l.title,\n w2l.description_markdown,\n w2l.description_rendered_html,\n w2l.frame_width,\n w2l.frame_height,\n w2l.duration_millis,\n w2l.maybe_public_bucket_preview_image_object_name,\n w2l.maybe_public_bucket_preview_video_object_name,\n w2l.creator_set_visibility,\n w2l.is_public_listing_approved,\n w2l.is_locked_from_use,\n w2l.is_locked_from_user_modification,\n w2l.creator_ip_address_creation,\n w2l.creator_ip_address_last_update,\n w2l.created_at,\n w2l.updated_at,\n w2l.user_deleted_at,\n w2l.mod_deleted_at\nFROM w2l_templates as w2l\nJOIN users\n ON users.token = w2l.creator_user_token\nWHERE w2l.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 2,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_is_banned",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 4,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 6,
"name": "creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 8,
"name": "description_markdown",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 9,
"name": "description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 10,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 11,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 12,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 13,
"name": "maybe_public_bucket_preview_image_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 14,
"name": "maybe_public_bucket_preview_video_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 15,
"name": "creator_set_visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 16,
"name": "is_public_listing_approved",
"type_info": {
"type": "Tiny",
"flags": "MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 17,
"name": "is_locked_from_use",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL | MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 18,
"name": "is_locked_from_user_modification",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL | MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 19,
"name": "creator_ip_address_creation",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 20,
"name": "creator_ip_address_last_update",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 21,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 22,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 23,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 24,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
false,
true,
false,
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "0033c76be0ea1c99069f1a8df1ce400c7064526feaf5dc88930da0718a885b19"
}
@@ -1,36 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n id,\n status\nFROM w2l_inference_jobs\nWHERE id = ?\nFOR UPDATE\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "status",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 64
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false
]
},
"hash": "02060ab9b8ca472a2bd4d4fa3120743e90148ccd6a4cb13bc491d00f36ed7a8f"
}
@@ -1,168 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l.token as template_token,\n w2l.template_type,\n w2l.creator_user_token,\n users.username as creator_username,\n users.display_name as creator_display_name,\n w2l.title,\n w2l.frame_width,\n w2l.frame_height,\n w2l.duration_millis,\n w2l.maybe_public_bucket_preview_image_object_name,\n w2l.maybe_public_bucket_preview_video_object_name,\n w2l.is_public_listing_approved,\n w2l.created_at,\n w2l.updated_at\nFROM w2l_templates as w2l\nJOIN users\nON\n users.token = w2l.creator_user_token\nWHERE\n users.username = ?\n AND w2l.user_deleted_at IS NULL\n AND w2l.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 2,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 6,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 8,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 9,
"name": "maybe_public_bucket_preview_image_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_public_bucket_preview_video_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "is_public_listing_approved",
"type_info": {
"type": "Tiny",
"flags": "MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 12,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 13,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false
]
},
"hash": "05c3ebf54cd8a5374d6f4bbe21b3c6027ce6314917af8acd0ed136d375d53342"
}
@@ -1,289 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l.token as template_token,\n w2l.template_type,\n w2l.creator_user_token,\n users.is_banned as creator_is_banned,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_gravatar_hash,\n w2l.title,\n w2l.description_markdown,\n w2l.description_rendered_html,\n w2l.frame_width,\n w2l.frame_height,\n w2l.duration_millis,\n w2l.maybe_public_bucket_preview_image_object_name,\n w2l.maybe_public_bucket_preview_video_object_name,\n w2l.creator_set_visibility,\n w2l.is_public_listing_approved,\n w2l.is_locked_from_use,\n w2l.is_locked_from_user_modification,\n w2l.creator_ip_address_creation,\n w2l.creator_ip_address_last_update,\n w2l.created_at,\n w2l.updated_at,\n w2l.user_deleted_at,\n w2l.mod_deleted_at\nFROM w2l_templates as w2l\nJOIN users\n ON users.token = w2l.creator_user_token\nWHERE\n w2l.token = ?\n AND w2l.user_deleted_at IS NULL\n AND w2l.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 2,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_is_banned",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 4,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 6,
"name": "creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 8,
"name": "description_markdown",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 9,
"name": "description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 10,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 11,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 12,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 13,
"name": "maybe_public_bucket_preview_image_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 14,
"name": "maybe_public_bucket_preview_video_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 15,
"name": "creator_set_visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 16,
"name": "is_public_listing_approved",
"type_info": {
"type": "Tiny",
"flags": "MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 17,
"name": "is_locked_from_use",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL | MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 18,
"name": "is_locked_from_user_modification",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL | MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 19,
"name": "creator_ip_address_creation",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 20,
"name": "creator_ip_address_last_update",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 21,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 22,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 23,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 24,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
false,
true,
false,
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "089986414149d2d189f4262f8aa7488d35f6a162a4e56f06c1b897092d37ea20"
}
@@ -1,25 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n next_id\nFROM\n w2l_result_synthetic_ids\nWHERE\n user_token = ?\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "next_id",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 20
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
},
"hash": "1236640a30d0d5177e13c31b61b791874f7c70026003a58ba6e07e7af46c30c1"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n is_public_listing_approved = ?,\n is_locked_from_user_modification = ?,\n is_locked_from_use = ?,\n maybe_mod_comments = ?,\n maybe_mod_user_token = ?,\n version = version + 1\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 6
},
"nullable": []
},
"hash": "17c8d210d93ee9c0d8e8422eed605c9150f19f9bf72affcf111b15a67a5b9e70"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO w2l_template_upload_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n title = ?,\n template_type = ?,\n download_url = ?,\n status = \"pending\"\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 8
},
"nullable": []
},
"hash": "25e7858d370ac1359deb42ef5292e85ccd1fe7debf3a1ba73303e5882523a4d0"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_template_upload_jobs\nSET\n status = ?,\n failure_reason = ?,\n retry_at = NOW() + interval 2 minute\nWHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "294c089b17fdd87d7e579c05a9d90e9bfa5b7465cafa9a95af08d58709212440"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_inference_jobs\nSET\n status = ?,\n failure_reason = ?,\n retry_at = NOW() + interval 2 minute\nWHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "2b04dd7db52ef3a97a6f420a22a4dbee7416ae58697438df69e87ffd47bbf350"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_results\nSET\n creator_set_visibility = ?,\n maybe_mod_user_token = ?\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "33cd0c0b8eaaf494ef97232ac89775b8eb6a22d310824b7aa7db310dd4fd41b1"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO w2l_result_synthetic_ids\nSET\n user_token = ?,\n next_id = 1\nON DUPLICATE KEY UPDATE\n user_token = ?,\n next_id = next_id + 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "34642399c3e91960768cb659b6006db291574d9cd07a5bace3db573eff20c3fb"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO w2l_results\nSET\n token = ?,\n maybe_w2l_template_token = ?,\n maybe_creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n maybe_creator_synthetic_id = ?,\n\n public_bucket_video_path = ?,\n\n file_size_bytes = ?,\n mime_type = ?,\n frame_width = ?,\n frame_height = ?,\n duration_millis = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 12
},
"nullable": []
},
"hash": "369a7576edc128cf2b310648d6fc45a2191c1263d433fe6d1461d15dbf26690e"
}
@@ -1,168 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l.token as template_token,\n w2l.template_type,\n w2l.creator_user_token,\n users.username as creator_username,\n users.display_name as creator_display_name,\n w2l.title,\n w2l.frame_width,\n w2l.frame_height,\n w2l.duration_millis,\n w2l.maybe_public_bucket_preview_image_object_name,\n w2l.maybe_public_bucket_preview_video_object_name,\n w2l.is_public_listing_approved,\n w2l.created_at,\n w2l.updated_at\nFROM w2l_templates as w2l\nJOIN users\n ON users.token = w2l.creator_user_token\nWHERE\n w2l.is_public_listing_approved IS TRUE\n AND w2l.user_deleted_at IS NULL\n AND w2l.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 2,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 6,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 8,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 9,
"name": "maybe_public_bucket_preview_image_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_public_bucket_preview_video_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "is_public_listing_approved",
"type_info": {
"type": "Tiny",
"flags": "MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 12,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 13,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false
]
},
"hash": "417dd070beeaf6ccd86852b7e99bf7fda5c5b15da4a3bcc066a0e2bb90ca7df1"
}
@@ -1,69 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n users.username,\n users.display_name,\n users.email_gravatar_hash as gravatar_hash,\n creator_user_token,\n count(*) as uploaded_count\nFROM w2l_templates\nJOIN users\nON\n users.token = creator_user_token\nWHERE\n is_public_listing_approved IS TRUE\n AND users.is_banned IS FALSE\n AND w2l_templates.user_deleted_at IS NULL\n AND w2l_templates.mod_deleted_at IS NULL\nGROUP BY creator_user_token\nORDER BY uploaded_count desc\nLIMIT 25;\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 1,
"name": "display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 2,
"name": "gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "uploaded_count",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | BINARY",
"char_set": 63,
"max_size": 21
}
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false
]
},
"hash": "4c7a92b6ac43e271096138f3594ca27b0ab6622b1e29a28f4a034c7732be9312"
}
@@ -1,300 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l_results.token as w2l_result_token,\n w2l_results.maybe_tts_inference_result_token,\n\n w2l_results.public_bucket_video_path,\n\n w2l_templates.token as maybe_w2l_template_token,\n w2l_templates.template_type,\n w2l_templates.title as template_title,\n\n users.token as maybe_creator_user_token,\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 users.is_banned as maybe_creator_is_banned,\n\n template_users.token as maybe_template_creator_user_token,\n template_users.username as maybe_template_creator_username,\n template_users.display_name as maybe_template_creator_display_name,\n template_users.email_gravatar_hash as maybe_template_creator_gravatar_hash,\n template_users.is_banned as maybe_template_creator_is_banned,\n\n w2l_results.creator_set_visibility,\n\n w2l_results.file_size_bytes,\n w2l_results.frame_width,\n w2l_results.frame_height,\n w2l_results.duration_millis,\n w2l_results.created_at,\n w2l_results.updated_at,\n\n w2l_results.creator_ip_address,\n w2l_results.user_deleted_at,\n w2l_results.mod_deleted_at\n\nFROM w2l_results\nLEFT OUTER JOIN w2l_templates\n ON w2l_results.maybe_w2l_template_token = w2l_templates.token\nLEFT OUTER JOIN users\n ON w2l_results.maybe_creator_user_token = users.token\nLEFT OUTER JOIN users as template_users\n ON w2l_templates.creator_user_token = template_users.token\nWHERE\n w2l_results.token = ?\n AND w2l_results.user_deleted_at IS NULL\n AND w2l_results.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "w2l_result_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "maybe_tts_inference_result_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "public_bucket_video_path",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 3,
"name": "maybe_w2l_template_token",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 5,
"name": "template_title",
"type_info": {
"type": "String",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 6,
"name": "maybe_creator_user_token",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "maybe_creator_username",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "maybe_creator_display_name",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 9,
"name": "maybe_creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 10,
"name": "maybe_creator_is_banned",
"type_info": {
"type": "Tiny",
"flags": "",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 11,
"name": "maybe_template_creator_user_token",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 12,
"name": "maybe_template_creator_username",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 13,
"name": "maybe_template_creator_display_name",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 14,
"name": "maybe_template_creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 15,
"name": "maybe_template_creator_is_banned",
"type_info": {
"type": "Tiny",
"flags": "",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 16,
"name": "creator_set_visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 17,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 18,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 19,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 20,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 21,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 22,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 23,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 24,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 25,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
true,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "4ff1b1e0cc36f6c2f1a9b099f38751ae7f35666be939b4074bdfc98e031cd6ac"
}
@@ -1,124 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n jobs.token as job_token,\n\n jobs.status,\n jobs.attempt_count,\n jobs.on_success_result_token as maybe_result_token,\n results.public_bucket_video_path as maybe_public_bucket_video_path,\n\n jobs.maybe_w2l_template_token,\n w2l.template_type as w2l_template_type,\n w2l.title,\n\n jobs.created_at,\n jobs.updated_at\n\nFROM w2l_inference_jobs as jobs\nJOIN w2l_templates as w2l\n ON w2l.token = jobs.maybe_w2l_template_token\nLEFT OUTER JOIN w2l_results as results\n ON jobs.on_success_result_token = results.token\n\nWHERE jobs.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "job_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "status",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 2,
"name": "attempt_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 3
}
},
{
"ordinal": 3,
"name": "maybe_result_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_public_bucket_video_path",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 5,
"name": "maybe_w2l_template_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "w2l_template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 7,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 8,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 9,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
true,
true,
false,
false,
false,
false
]
},
"hash": "57928b1001a10a88ac5a07f43b1dd30f6dee6edbc0808be99fe1233f9e276c56"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n title = ?,\n description_markdown = ?,\n description_rendered_html = ?,\n creator_set_visibility = ?,\n maybe_mod_user_token = ?,\n version = version + 1\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 6
},
"nullable": []
},
"hash": "60c06a507349919addb5d26b1c4a283a04f66fce86e84ed0a51db6001c9fc2b5"
}
@@ -1,135 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l_templates.token as template_token,\n w2l_templates.title,\n w2l_templates.template_type,\n w2l_templates.duration_millis,\n w2l_templates.frame_width,\n w2l_templates.frame_height,\n w2l_templates.creator_user_token,\n users.username AS creator_username,\n users.display_name AS creator_display_name,\n users.email_gravatar_hash AS creator_gravatar_hash,\n w2l_templates.created_at\nFROM\n w2l_templates\nJOIN\n users\nON\n users.token = w2l_templates.creator_user_token\nWHERE\n w2l_templates.is_public_listing_approved IS NULL\n AND w2l_templates.user_deleted_at IS NULL\n AND w2l_templates.mod_deleted_at IS NULL\n AND w2l_templates.is_locked_from_use IS FALSE\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 3,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 4,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 5,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 6,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 9,
"name": "creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 10,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "619d18c87075a86c01f1e0ac26744774293ff8ca6b0011ce611b3f47d8a97a0e"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_template_upload_jobs\nSET\n status = 'started',\n attempt_count = attempt_count + 1,\n retry_at = NOW() + interval 2 minute\nWHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "641253d4c621f75037877651bba044a21033f50a5e3f8fed9b06ec967a508853"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_results\nSET\n mod_deleted_at = CURRENT_TIMESTAMP,\n maybe_mod_user_token = ?\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "663506988f146de6f559e5df4f4a2b607e9421a69bb57db1f656774bf8b375db"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_template_upload_jobs\nSET\n status = ?,\n on_success_result_token = ?,\n failure_reason = NULL,\n retry_at = NULL\nWHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "73558104936aab6add2d9c789b368b5f155f1fe01d32e7314f2f120422866f54"
}
@@ -1,25 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n token as template_token\nFROM w2l_templates\nWHERE\n token = ?\n AND user_deleted_at IS NULL\n AND mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
},
"hash": "7622292c05fe1b5832136762042780a12a02048166bb1b4492dfd627c48c8968"
}
@@ -1,168 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l.token as template_token,\n w2l.template_type,\n w2l.creator_user_token,\n users.username as creator_username,\n users.display_name as creator_display_name,\n w2l.title,\n w2l.frame_width,\n w2l.frame_height,\n w2l.duration_millis,\n w2l.maybe_public_bucket_preview_image_object_name,\n w2l.maybe_public_bucket_preview_video_object_name,\n w2l.is_public_listing_approved,\n w2l.created_at,\n w2l.updated_at\nFROM w2l_templates as w2l\nJOIN users\n ON users.token = w2l.creator_user_token\nWHERE\n w2l.user_deleted_at IS NULL\n AND w2l.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 2,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 6,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 8,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 9,
"name": "maybe_public_bucket_preview_image_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_public_bucket_preview_video_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "is_public_listing_approved",
"type_info": {
"type": "Tiny",
"flags": "MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 12,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 13,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false
]
},
"hash": "7cd0ad5d7b9a2c393f799beadc1e0a6bc85d952e07a1b82a52115b99be40ff6d"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n creator_ip_address_last_update = ?,\n user_deleted_at = CURRENT_TIMESTAMP\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "8ff27fc5583db97f157f1b808f593a72c77dc5dcf5a633cd9c1162af6b97c011"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO w2l_templates\nSET\n token = ?,\n template_type = ?,\n title = ?,\n description_markdown = '',\n description_rendered_html = '',\n creator_user_token = ?,\n creator_ip_address_creation = ?,\n creator_ip_address_last_update = ?,\n original_download_url = ?,\n private_bucket_hash = ?,\n private_bucket_object_name = ?,\n private_bucket_cached_faces_object_name = ?,\n maybe_public_bucket_preview_image_object_name = ?,\n maybe_public_bucket_preview_video_object_name = ?,\n file_size_bytes = ?,\n mime_type = ?,\n frame_width = ?,\n frame_height = ?,\n frame_count = ?,\n fps = ?,\n duration_millis = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 19
},
"nullable": []
},
"hash": "9a879f76345ef5682b995f99026fac8b2f4c64c8ec4bb078187d1e53effcfbaf"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_results\nSET\n creator_set_visibility = ?,\n creator_ip_address = ?\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "9cc5f697350814199344d3d9a0ff026e0d1e09e9097648400d4b63cfcbd31178"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO w2l_inference_jobs\nSET\n maybe_w2l_template_token = ?,\n maybe_tts_inference_result_token = ?,\n maybe_public_audio_bucket_location = NULL,\n maybe_public_image_bucket_location = NULL,\n maybe_creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n status = \"pending\"\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 5
},
"nullable": []
},
"hash": "9d4932baa4023accc2d28af98b58a47149d37c4937cd0171e6b955c09855c5f8"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_inference_jobs\nSET\n status = ?,\n on_success_result_token = ?,\n failure_reason = NULL,\n retry_at = NULL\nWHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "a125f183f7ae5627fc2118e7302cea73d967200ba1cbb12550f5880187b7db5e"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_template_upload_jobs\nSET\n status = \"dead\",\n failure_reason = ?,\n retry_at = NULL\nWHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "ab981965f518a8986aaaba41ed821fcb438db4c6156cbb26f639921225a88d59"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_results\nSET\n mod_deleted_at = NULL,\n maybe_mod_user_token = ?\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "adf2d5eb967fa2bc00fad1c8fcc2e1bf4384d39dc54e8240d78bb4ca6fcc3409"
}
@@ -1,91 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n jobs.token as job_token,\n\n jobs.status,\n jobs.attempt_count,\n jobs.on_success_result_token as maybe_template_token,\n\n jobs.failure_reason as maybe_failure_reason,\n\n jobs.created_at,\n jobs.updated_at\n\nFROM w2l_template_upload_jobs as jobs\n\nWHERE jobs.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "job_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "status",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 2,
"name": "attempt_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 3
}
},
{
"ordinal": 3,
"name": "maybe_template_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_failure_reason",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 5,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 6,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
true,
false,
false
]
},
"hash": "ae04054c4d32e581dd183fd7ebb8e48fc7df856d2ffd8036d9ce6006bb7a296a"
}
@@ -1,190 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT *\nFROM w2l_template_upload_jobs\nWHERE\n (\n status IN (\"pending\", \"attempt_failed\")\n )\n AND\n (\n retry_at IS NULL\n OR\n retry_at < CURRENT_TIMESTAMP\n )\n LIMIT ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "uuid_idempotency_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 144
}
},
{
"ordinal": 3,
"name": "on_success_result_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 5,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 6,
"name": "download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 7,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 8,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 9,
"name": "creator_set_visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 10,
"name": "status",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 11,
"name": "attempt_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 3
}
},
{
"ordinal": 12,
"name": "failure_reason",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 13,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 14,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 15,
"name": "retry_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
false,
false,
true,
false,
false,
false,
false,
false,
true,
false,
false,
true
]
},
"hash": "b7535ecf2e63b7f02b5b96f833fd8cd28285b24473df6f89795ff360c1723215"
}
@@ -1,300 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l_results.token as w2l_result_token,\n w2l_results.maybe_tts_inference_result_token,\n\n w2l_results.public_bucket_video_path,\n\n w2l_templates.token as maybe_w2l_template_token,\n w2l_templates.template_type,\n w2l_templates.title as template_title,\n\n users.token as maybe_creator_user_token,\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 users.is_banned as maybe_creator_is_banned,\n\n template_users.token as maybe_template_creator_user_token,\n template_users.username as maybe_template_creator_username,\n template_users.display_name as maybe_template_creator_display_name,\n template_users.email_gravatar_hash as maybe_template_creator_gravatar_hash,\n template_users.is_banned as maybe_template_creator_is_banned,\n\n w2l_results.creator_set_visibility,\n\n w2l_results.file_size_bytes,\n w2l_results.frame_width,\n w2l_results.frame_height,\n w2l_results.duration_millis,\n w2l_results.created_at,\n w2l_results.updated_at,\n\n w2l_results.creator_ip_address,\n w2l_results.user_deleted_at,\n w2l_results.mod_deleted_at\n\nFROM w2l_results\nLEFT OUTER JOIN w2l_templates\n ON w2l_results.maybe_w2l_template_token = w2l_templates.token\nLEFT OUTER JOIN users\n ON w2l_results.maybe_creator_user_token = users.token\nLEFT OUTER JOIN users as template_users\n ON w2l_templates.creator_user_token = template_users.token\nWHERE\n w2l_results.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "w2l_result_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "maybe_tts_inference_result_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "public_bucket_video_path",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 3,
"name": "maybe_w2l_template_token",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 5,
"name": "template_title",
"type_info": {
"type": "String",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 6,
"name": "maybe_creator_user_token",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "maybe_creator_username",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "maybe_creator_display_name",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 9,
"name": "maybe_creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 10,
"name": "maybe_creator_is_banned",
"type_info": {
"type": "Tiny",
"flags": "",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 11,
"name": "maybe_template_creator_user_token",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 12,
"name": "maybe_template_creator_username",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 13,
"name": "maybe_template_creator_display_name",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 14,
"name": "maybe_template_creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 15,
"name": "maybe_template_creator_is_banned",
"type_info": {
"type": "Tiny",
"flags": "",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 16,
"name": "creator_set_visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 17,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 18,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 19,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 20,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 21,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 22,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 23,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 24,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 25,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
true,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "ba31fefd3e96fd238fc2bcdfab64f390a17293f2c0996ae891ed8821e57512cd"
}
@@ -1,168 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l.token as template_token,\n w2l.template_type,\n w2l.creator_user_token,\n users.username as creator_username,\n users.display_name as creator_display_name,\n w2l.title,\n w2l.frame_width,\n w2l.frame_height,\n w2l.duration_millis,\n w2l.private_bucket_hash,\n w2l.maybe_public_bucket_preview_image_object_name,\n w2l.maybe_public_bucket_preview_video_object_name,\n w2l.created_at,\n w2l.updated_at\nFROM w2l_templates as w2l\nJOIN users\nON users.token = w2l.creator_user_token\nWHERE w2l.token = ?\nAND w2l.user_deleted_at IS NULL\nAND w2l.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 2,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 6,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 8,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 9,
"name": "private_bucket_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 10,
"name": "maybe_public_bucket_preview_image_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "maybe_public_bucket_preview_video_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 12,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 13,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
false,
false
]
},
"hash": "bc9c6b57b2578b8163956d11a5f6a9a77ddab6098d2c4207e1a70502db30c9d1"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n is_public_listing_approved = ?,\n maybe_mod_user_token = ?\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "bee13160674414391587f56e8fb0aa3629e3dfcead0afa5759bff1e161f1bb6e"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n maybe_mod_user_token = ?,\n mod_deleted_at = NULL\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "c4640a618e1d179fa95adce67a329818f8b1626ac88fa76dbb871b8788136191"
}
@@ -1,256 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n id,\n token AS inference_job_token,\n uuid_idempotency_token,\n\n maybe_w2l_template_token,\n maybe_public_image_bucket_location,\n maybe_tts_inference_result_token,\n maybe_public_audio_bucket_hash,\n maybe_public_audio_bucket_location,\n\n maybe_original_audio_filename,\n maybe_original_audio_download_url,\n maybe_audio_mime_type,\n\n creator_ip_address,\n maybe_creator_user_token,\n\n creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n disable_end_bump,\n disable_watermark,\n\n status,\n attempt_count,\n failure_reason,\n created_at,\n updated_at,\n retry_at\nFROM w2l_inference_jobs\nWHERE\n (\n status IN (\"pending\", \"attempt_failed\")\n )\n AND\n (\n retry_at IS NULL\n OR\n retry_at < CURRENT_TIMESTAMP\n )\n LIMIT ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "inference_job_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "uuid_idempotency_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 144
}
},
{
"ordinal": 3,
"name": "maybe_w2l_template_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_public_image_bucket_location",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 5,
"name": "maybe_tts_inference_result_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "maybe_public_audio_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 7,
"name": "maybe_public_audio_bucket_location",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 8,
"name": "maybe_original_audio_filename",
"type_info": {
"type": "String",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 9,
"name": "maybe_original_audio_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 10,
"name": "maybe_audio_mime_type",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 11,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 12,
"name": "maybe_creator_user_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 14,
"name": "disable_end_bump",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 15,
"name": "disable_watermark",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 16,
"name": "status",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 17,
"name": "attempt_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 3
}
},
{
"ordinal": 18,
"name": "failure_reason",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 19,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 20,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 21,
"name": "retry_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
true,
true,
true,
true,
true,
true,
true,
false,
true,
false,
false,
false,
false,
false,
true,
false,
false,
true
]
},
"hash": "ce8560e2ff8c879647c7b9f154a8987765272c53f95b9e6a8b8ee5c4ad7b1f17"
}
@@ -1,36 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n id,\n status\nFROM w2l_template_upload_jobs\nWHERE id = ?\nFOR UPDATE\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "status",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 64
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false
]
},
"hash": "d12757abef811cd6951e0e1427fdb496a8931b547519d320f5ade56007d3eb5d"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n title = ?,\n description_markdown = ?,\n description_rendered_html = ?,\n creator_set_visibility = ?,\n creator_ip_address_last_update = ?,\n version = version + 1\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 6
},
"nullable": []
},
"hash": "d2ef33027abc15b6ec00260f7d30a8c66a3190229ea103ecb571d4957af63525"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO w2l_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n maybe_w2l_template_token = ?,\n maybe_public_audio_bucket_hash = ?,\n maybe_public_audio_bucket_location = ?,\n\n maybe_original_audio_filename = ?,\n maybe_audio_mime_type = ?,\n\n maybe_creator_user_token = ?,\n creator_ip_address = ?,\n disable_end_bump = false,\n creator_set_visibility = ?,\n status = \"pending\"\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 10
},
"nullable": []
},
"hash": "d850784ca167e686b91fdd4d3cce20c7a00e4e38e4da629733114a1c55ba4ab3"
}
@@ -1,36 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n NOW() - t2.created_at AS seconds_since_first,\n (\n SELECT\n count(t1.id) as pending_count\n FROM w2l_inference_jobs AS t1\n WHERE t1.status = \"pending\"\n ) as pending_count\nFROM w2l_inference_jobs AS t2\nWHERE t2.status = \"pending\"\nORDER BY t2.id ASC\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "seconds_since_first",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | BINARY",
"char_set": 63,
"max_size": 16
}
},
{
"ordinal": 1,
"name": "pending_count",
"type_info": {
"type": "LongLong",
"flags": "BINARY",
"char_set": 63,
"max_size": 21
}
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
true
]
},
"hash": "dfe818ab849c5f6e2a5931142aab640d249aa96cb85dc06bfffae4d7feef541e"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n creator_ip_address_last_update = ?,\n user_deleted_at = NULL\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "e0ad2a7fe4ae795e4f097f604d5cfcf9605298b58cde5ca23bdf9c8ec7383b00"
}
@@ -1,168 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w2l.token as template_token,\n w2l.template_type,\n w2l.creator_user_token,\n users.username as creator_username,\n users.display_name as creator_display_name,\n w2l.title,\n w2l.frame_width,\n w2l.frame_height,\n w2l.duration_millis,\n w2l.maybe_public_bucket_preview_image_object_name,\n w2l.maybe_public_bucket_preview_video_object_name,\n w2l.is_public_listing_approved,\n w2l.created_at,\n w2l.updated_at\nFROM w2l_templates as w2l\nJOIN users\nON\n users.token = w2l.creator_user_token\nWHERE\n users.username = ?\n AND w2l.is_public_listing_approved IS TRUE\n AND w2l.user_deleted_at IS NULL\n AND w2l.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "template_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "template_type",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 2,
"name": "creator_user_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "title",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 6,
"name": "frame_width",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "frame_height",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 8,
"name": "duration_millis",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 9,
"name": "maybe_public_bucket_preview_image_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_public_bucket_preview_video_object_name",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "is_public_listing_approved",
"type_info": {
"type": "Tiny",
"flags": "MULTIPLE_KEY",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 12,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 13,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false
]
},
"hash": "e3a0bd8073c3c0d84b9ab0e2e1ad8371f14b10801b7e4658b73c42ce1b27fa0b"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_templates\nSET\n maybe_mod_user_token = ?,\n mod_deleted_at = CURRENT_TIMESTAMP\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "e4e5be790f087b9aa6bee87e2315140bf621e4919362ebe72ab070163f18e9c8"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_results\nSET\n user_deleted_at = NULL\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "e9ec861d6eb135370f9baf3a866282ec5686d4b299fc4ec10900ab32ea8577d8"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_inference_jobs\nSET\n status = 'started',\n attempt_count = attempt_count + 1,\n retry_at = NOW() + interval 2 minute\nWHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "ee05f95e45f7aaa5811d70b1f00d3f40a361536dfc6451affcad97586dc3338f"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE w2l_results\nSET\n user_deleted_at = CURRENT_TIMESTAMP\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "ffa85f7c65101a43653c724479ee080e0a74577d2ae37863b039f3a452493d1e"
}
Generated
+361 -110
View File
@@ -420,6 +420,23 @@ dependencies = [
"cpufeatures",
]
[[package]]
name = "agent-notify-server"
version = "0.0.1"
dependencies = [
"actix-web",
"anyhow",
"env_logger 0.11.9",
"log",
"rand 0.9.2",
"rodio",
"serde",
"serde_derive",
"serde_yaml",
"tokio",
"workspace-build-acceleration",
]
[[package]]
name = "ahash"
version = "0.7.8"
@@ -492,6 +509,18 @@ dependencies = [
"nix 0.23.2",
]
[[package]]
name = "alsa"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43"
dependencies = [
"alsa-sys",
"bitflags 2.11.0",
"cfg-if",
"libc",
]
[[package]]
name = "alsa-sys"
version = "0.3.1"
@@ -602,7 +631,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.60.2",
"windows-sys 0.61.2",
]
[[package]]
@@ -2610,6 +2639,17 @@ dependencies = [
"coreaudio-sys",
]
[[package]]
name = "coreaudio-rs"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace"
dependencies = [
"bitflags 1.3.2",
"core-foundation-sys",
"coreaudio-sys",
]
[[package]]
name = "coreaudio-sys"
version = "0.2.17"
@@ -2625,9 +2665,9 @@ version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74117836a5124f3629e4b474eed03e479abaf98988b4bb317e29f08cfe0e4116"
dependencies = [
"alsa",
"alsa 0.6.0",
"core-foundation-sys",
"coreaudio-rs",
"coreaudio-rs 0.10.0",
"jni 0.19.0",
"js-sys",
"lazy_static",
@@ -2636,7 +2676,7 @@ dependencies = [
"ndk 0.6.0",
"ndk-glue",
"nix 0.23.2",
"oboe",
"oboe 0.4.6",
"parking_lot 0.11.2",
"stdweb",
"thiserror 1.0.63",
@@ -2644,6 +2684,29 @@ dependencies = [
"winapi",
]
[[package]]
name = "cpal"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779"
dependencies = [
"alsa 0.9.1",
"core-foundation-sys",
"coreaudio-rs 0.11.3",
"dasp_sample",
"jni 0.21.1",
"js-sys",
"libc",
"mach2",
"ndk 0.8.0",
"ndk-context",
"oboe 0.6.1",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows 0.54.0",
]
[[package]]
name = "cpufeatures"
version = "0.2.12"
@@ -2957,6 +3020,12 @@ dependencies = [
"parking_lot_core 0.9.12",
]
[[package]]
name = "dasp_sample"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
[[package]]
name = "data-encoding"
version = "2.5.0"
@@ -3291,7 +3360,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -3996,6 +4065,12 @@ dependencies = [
"zune-inflate",
]
[[package]]
name = "extended"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365"
[[package]]
name = "fal_client"
version = "0.0.1"
@@ -6372,7 +6447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.52.6",
]
[[package]]
@@ -6665,6 +6740,15 @@ dependencies = [
"libc",
]
[[package]]
name = "mach2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44"
dependencies = [
"libc",
]
[[package]]
name = "magic-crypt"
version = "3.1.13"
@@ -6812,7 +6896,7 @@ version = "0.0.1"
dependencies = [
"errors",
"log",
"symphonia",
"symphonia 0.5.0",
"workspace-build-acceleration",
]
@@ -7202,6 +7286,20 @@ dependencies = [
"thiserror 1.0.63",
]
[[package]]
name = "ndk"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7"
dependencies = [
"bitflags 2.11.0",
"jni-sys",
"log",
"ndk-sys 0.5.0+25.2.9519653",
"num_enum 0.7.2",
"thiserror 1.0.63",
]
[[package]]
name = "ndk"
version = "0.9.0"
@@ -7260,6 +7358,15 @@ dependencies = [
"jni-sys",
]
[[package]]
name = "ndk-sys"
version = "0.5.0+25.2.9519653"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691"
dependencies = [
"jni-sys",
]
[[package]]
name = "ndk-sys"
version = "0.6.0+11769913"
@@ -7789,7 +7896,21 @@ dependencies = [
"ndk-context",
"num-derive 0.3.3",
"num-traits",
"oboe-sys",
"oboe-sys 0.4.5",
]
[[package]]
name = "oboe"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb"
dependencies = [
"jni 0.21.1",
"ndk 0.8.0",
"ndk-context",
"num-derive 0.4.2",
"num-traits",
"oboe-sys 0.6.1",
]
[[package]]
@@ -7801,6 +7922,15 @@ dependencies = [
"cc",
]
[[package]]
name = "oboe-sys"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d"
dependencies = [
"cc",
]
[[package]]
name = "once_cell"
version = "1.21.4"
@@ -9674,6 +9804,16 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "rodio"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1"
dependencies = [
"cpal 0.15.3",
"symphonia 0.5.5",
]
[[package]]
name = "rootly_client"
version = "0.0.1"
@@ -9887,7 +10027,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.12.1",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -10004,7 +10144,7 @@ dependencies = [
"security-framework 3.7.0",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -11569,19 +11709,38 @@ name = "symphonia"
version = "0.5.0"
dependencies = [
"lazy_static",
"symphonia-bundle-flac",
"symphonia-bundle-mp3",
"symphonia-codec-aac",
"symphonia-bundle-flac 0.5.0",
"symphonia-bundle-mp3 0.5.0",
"symphonia-codec-aac 0.5.0",
"symphonia-codec-alac",
"symphonia-codec-opus",
"symphonia-codec-pcm",
"symphonia-codec-vorbis",
"symphonia-core",
"symphonia-format-isomp4",
"symphonia-codec-pcm 0.5.0",
"symphonia-codec-vorbis 0.5.0",
"symphonia-core 0.5.0",
"symphonia-format-isomp4 0.5.0",
"symphonia-format-mkv",
"symphonia-format-ogg",
"symphonia-format-wav",
"symphonia-metadata",
"symphonia-metadata 0.5.0",
]
[[package]]
name = "symphonia"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5773a4c030a19d9bfaa090f49746ff35c75dfddfa700df7a5939d5e076a57039"
dependencies = [
"lazy_static",
"symphonia-bundle-flac 0.5.5",
"symphonia-bundle-mp3 0.5.5",
"symphonia-codec-aac 0.5.5",
"symphonia-codec-adpcm",
"symphonia-codec-pcm 0.5.5",
"symphonia-codec-vorbis 0.5.5",
"symphonia-core 0.5.5",
"symphonia-format-isomp4 0.5.5",
"symphonia-format-riff",
"symphonia-metadata 0.5.5",
]
[[package]]
@@ -11589,9 +11748,21 @@ name = "symphonia-bundle-flac"
version = "0.5.0"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
"symphonia-core 0.5.0",
"symphonia-metadata 0.5.0",
"symphonia-utils-xiph 0.5.0",
]
[[package]]
name = "symphonia-bundle-flac"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c91565e180aea25d9b80a910c546802526ffd0072d0b8974e3ebe59b686c9976"
dependencies = [
"log",
"symphonia-core 0.5.5",
"symphonia-metadata 0.5.5",
"symphonia-utils-xiph 0.5.5",
]
[[package]]
@@ -11601,8 +11772,20 @@ dependencies = [
"bitflags 1.3.2",
"lazy_static",
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-core 0.5.0",
"symphonia-metadata 0.5.0",
]
[[package]]
name = "symphonia-bundle-mp3"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4872dd6bb56bf5eac799e3e957aa1981086c3e613b27e0ac23b176054f7c57ed"
dependencies = [
"lazy_static",
"log",
"symphonia-core 0.5.5",
"symphonia-metadata 0.5.5",
]
[[package]]
@@ -11611,7 +11794,28 @@ version = "0.5.0"
dependencies = [
"lazy_static",
"log",
"symphonia-core",
"symphonia-core 0.5.0",
]
[[package]]
name = "symphonia-codec-aac"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c263845aa86881416849c1729a54c7f55164f8b96111dba59de46849e73a790"
dependencies = [
"lazy_static",
"log",
"symphonia-core 0.5.5",
]
[[package]]
name = "symphonia-codec-adpcm"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dddc50e2bbea4cfe027441eece77c46b9f319748605ab8f3443350129ddd07f"
dependencies = [
"log",
"symphonia-core 0.5.5",
]
[[package]]
@@ -11619,7 +11823,7 @@ name = "symphonia-codec-alac"
version = "0.5.0"
dependencies = [
"log",
"symphonia-core",
"symphonia-core 0.5.0",
]
[[package]]
@@ -11627,7 +11831,7 @@ name = "symphonia-codec-opus"
version = "0.0.1"
dependencies = [
"log",
"symphonia-core",
"symphonia-core 0.5.0",
]
[[package]]
@@ -11635,7 +11839,17 @@ name = "symphonia-codec-pcm"
version = "0.5.0"
dependencies = [
"log",
"symphonia-core",
"symphonia-core 0.5.0",
]
[[package]]
name = "symphonia-codec-pcm"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e89d716c01541ad3ebe7c91ce4c8d38a7cf266a3f7b2f090b108fb0cb031d95"
dependencies = [
"log",
"symphonia-core 0.5.5",
]
[[package]]
@@ -11643,8 +11857,19 @@ name = "symphonia-codec-vorbis"
version = "0.5.0"
dependencies = [
"log",
"symphonia-core",
"symphonia-utils-xiph",
"symphonia-core 0.5.0",
"symphonia-utils-xiph 0.5.0",
]
[[package]]
name = "symphonia-codec-vorbis"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f025837c309cd69ffef572750b4a2257b59552c5399a5e49707cc5b1b85d1c73"
dependencies = [
"log",
"symphonia-core 0.5.5",
"symphonia-utils-xiph 0.5.5",
]
[[package]]
@@ -11652,7 +11877,7 @@ name = "symphonia-codec-wavpack"
version = "0.0.1"
dependencies = [
"log",
"symphonia-core",
"symphonia-core 0.5.0",
]
[[package]]
@@ -11666,15 +11891,41 @@ dependencies = [
"log",
]
[[package]]
name = "symphonia-core"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea00cc4f79b7f6bb7ff87eddc065a1066f3a43fe1875979056672c9ef948c2af"
dependencies = [
"arrayvec",
"bitflags 1.3.2",
"bytemuck",
"lazy_static",
"log",
]
[[package]]
name = "symphonia-format-isomp4"
version = "0.5.0"
dependencies = [
"encoding_rs",
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
"symphonia-core 0.5.0",
"symphonia-metadata 0.5.0",
"symphonia-utils-xiph 0.5.0",
]
[[package]]
name = "symphonia-format-isomp4"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "243739585d11f81daf8dac8d9f3d18cc7898f6c09a259675fc364b382c30e0a5"
dependencies = [
"encoding_rs",
"log",
"symphonia-core 0.5.5",
"symphonia-metadata 0.5.5",
"symphonia-utils-xiph 0.5.5",
]
[[package]]
@@ -11683,9 +11934,9 @@ version = "0.5.0"
dependencies = [
"lazy_static",
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
"symphonia-core 0.5.0",
"symphonia-metadata 0.5.0",
"symphonia-utils-xiph 0.5.0",
]
[[package]]
@@ -11693,9 +11944,21 @@ name = "symphonia-format-ogg"
version = "0.5.0"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
"symphonia-core 0.5.0",
"symphonia-metadata 0.5.0",
"symphonia-utils-xiph 0.5.0",
]
[[package]]
name = "symphonia-format-riff"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2d7c3df0e7d94efb68401d81906eae73c02b40d5ec1a141962c592d0f11a96f"
dependencies = [
"extended",
"log",
"symphonia-core 0.5.5",
"symphonia-metadata 0.5.5",
]
[[package]]
@@ -11703,8 +11966,8 @@ name = "symphonia-format-wav"
version = "0.5.0"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-core 0.5.0",
"symphonia-metadata 0.5.0",
]
[[package]]
@@ -11714,7 +11977,19 @@ dependencies = [
"encoding_rs",
"lazy_static",
"log",
"symphonia-core",
"symphonia-core 0.5.0",
]
[[package]]
name = "symphonia-metadata"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36306ff42b9ffe6e5afc99d49e121e0bd62fe79b9db7b9681d48e29fa19e6b16"
dependencies = [
"encoding_rs",
"lazy_static",
"log",
"symphonia-core 0.5.5",
]
[[package]]
@@ -11722,22 +11997,32 @@ name = "symphonia-play"
version = "0.5.0"
dependencies = [
"clap 3.2.25",
"cpal",
"cpal 0.13.5",
"lazy_static",
"libpulse-binding",
"libpulse-simple-binding",
"log",
"pretty_env_logger",
"rb",
"symphonia",
"symphonia 0.5.0",
]
[[package]]
name = "symphonia-utils-xiph"
version = "0.5.0"
dependencies = [
"symphonia-core",
"symphonia-metadata",
"symphonia-core 0.5.0",
"symphonia-metadata 0.5.0",
]
[[package]]
name = "symphonia-utils-xiph"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee27c85ab799a338446b68eec77abf42e1a6f1bb490656e121c6e27bfbab9f16"
dependencies = [
"symphonia-core 0.5.5",
"symphonia-metadata 0.5.5",
]
[[package]]
@@ -12285,7 +12570,7 @@ dependencies = [
"getrandom 0.4.1",
"once_cell",
"rustix 1.1.4",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -13507,69 +13792,6 @@ dependencies = [
"libc",
]
[[package]]
name = "w2l-download-job"
version = "0.0.1"
dependencies = [
"anyhow",
"bucket_paths",
"chrono",
"cloud_storage",
"config",
"dotenv",
"easyenv",
"errors",
"filesys",
"google_drive_downloader",
"hashing",
"hostname 0.4.0",
"hyper 1.6.0",
"jobs_common",
"log",
"mysql_queries",
"r2d2_redis",
"serde",
"serde_derive",
"serde_json",
"shared_env_var_config",
"sqlx",
"subprocess",
"tempdir",
"tokio",
"workspace-build-acceleration",
]
[[package]]
name = "w2l-inference-job"
version = "0.0.1"
dependencies = [
"anyhow",
"bucket_paths",
"chrono",
"cloud_storage",
"config",
"dotenv",
"easyenv",
"errors",
"filesys",
"google_drive_downloader",
"hostname 0.4.0",
"hyper 1.6.0",
"jobs_common",
"log",
"mysql_queries",
"r2d2_redis",
"serde",
"serde_derive",
"serde_json",
"shared_env_var_config",
"sqlx",
"subprocess",
"tempdir",
"tokio",
"workspace-build-acceleration",
]
[[package]]
name = "waker-fn"
version = "1.1.1"
@@ -14051,6 +14273,16 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
dependencies = [
"windows-core 0.54.0",
"windows-targets 0.52.6",
]
[[package]]
name = "windows"
version = "0.58.0"
@@ -14101,6 +14333,16 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
dependencies = [
"windows-result 0.1.2",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.58.0"
@@ -14215,6 +14457,15 @@ dependencies = [
"windows-strings 0.4.2",
]
[[package]]
name = "windows-result"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-result"
version = "0.2.0"
+3 -2
View File
@@ -139,8 +139,6 @@ members = [
"crates/service/job/deprecated/inference_job",
"crates/service/job/deprecated/tts_download_job",
"crates/service/job/deprecated/tts_inference_job",
"crates/service/job/deprecated/w2l_download_job",
"crates/service/job/deprecated/w2l_inference_job",
# Service Plugins: complete subsystems that can be plugged into services (users, billing, etc.)
"crates/service/plugins/billing",
@@ -152,6 +150,9 @@ members = [
"crates/testing/test_data",
"crates/testing/test_utils",
# Standalone tool servers
"crates/tools/servers/agent_notify_server",
# Vendored code
"crates/vendor/limitation",
"crates/vendor/tauri-plugin-http",
@@ -9,7 +9,7 @@ use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue_with_apriori_job_token::{insert_generic_inference_job_for_fal_queue_with_apriori_job_token, InsertGenericInferenceForFalWithAprioriJobTokenArgs};
use crate::queries::generic_inference::api_providers::fal::insert_generic_inference_job_for_fal_queue_with_apriori_job_token::{insert_generic_inference_job_for_fal_queue_with_apriori_job_token, InsertGenericInferenceForFalWithAprioriJobTokenArgs};
#[derive(Debug, Clone, Copy)]
pub enum FalCategory {
@@ -12,8 +12,8 @@ use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
use crate::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue_with_apriori_job_token::{
use crate::queries::generic_inference::api_providers::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
use crate::queries::generic_inference::api_providers::fal::insert_generic_inference_job_for_fal_queue_with_apriori_job_token::{
insert_generic_inference_job_for_fal_queue_with_apriori_job_token,
InsertGenericInferenceForFalWithAprioriJobTokenArgs,
};
@@ -19,7 +19,7 @@ use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
use crate::queries::generic_inference::api_providers::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
pub struct InsertGenericInferenceForFalWithAprioriJobTokenArgs<'e, 'c, E>
@@ -0,0 +1,5 @@
pub mod beeble;
pub mod fal;
pub mod gmicloud;
pub mod seedance2pro;
pub mod worldlabs;
@@ -1,8 +1,4 @@
pub mod beeble;
pub mod fal;
pub mod gmicloud;
pub mod api_providers;
pub mod job;
pub mod moderation;
pub mod seedance2pro;
pub mod web;
pub mod worldlabs;
@@ -43,7 +43,6 @@ pub mod vocoder;
pub mod voice_clone_requests;
pub mod voice_conversion;
pub mod voice_designer;
pub mod w2l;
pub mod wallet_ledger_entries;
pub mod wallets;
pub mod web_referrals;
@@ -1,6 +0,0 @@
pub mod stats;
pub mod w2l_download_jobs;
pub mod w2l_inference_jobs;
pub mod w2l_results;
pub mod w2l_template_upload_jobs;
pub mod w2l_templates;
@@ -1,87 +0,0 @@
use anyhow::anyhow;
use log::warn;
use sqlx::MySql;
use sqlx::pool::PoolConnection;
use errors::AnyhowResult;
#[derive(Serialize, Clone)]
pub struct W2lLeaderboardRecordForList {
pub username: String,
pub display_name: String,
pub gravatar_hash: String,
pub creator_user_token: String,
pub uploaded_count: i64,
}
#[derive(Serialize)]
struct W2lLeaderboardRecordForListRaw {
pub username: String,
pub display_name: String,
pub gravatar_hash: String,
pub creator_user_token: String,
pub uploaded_count: i64,
}
// NB: This may need to become an offline query if it is expensive.
pub async fn calculate_w2l_template_leaderboard(
mysql_pool: &mut PoolConnection<MySql>
) -> AnyhowResult<Vec<W2lLeaderboardRecordForList>> {
// NB: We're requiring "is_public_listing_approved IS TRUE" for W2L templates!
// This is the opposite for TTS models (for now at least)
let maybe_results = sqlx::query_as!(
W2lLeaderboardRecordForListRaw,
r#"
SELECT
users.username,
users.display_name,
users.email_gravatar_hash as gravatar_hash,
creator_user_token,
count(*) as uploaded_count
FROM w2l_templates
JOIN users
ON
users.token = creator_user_token
WHERE
is_public_listing_approved IS TRUE
AND users.is_banned IS FALSE
AND w2l_templates.user_deleted_at IS NULL
AND w2l_templates.mod_deleted_at IS NULL
GROUP BY creator_user_token
ORDER BY uploaded_count desc
LIMIT 25;
"#,
)
.fetch_all(&mut **mysql_pool)
.await;
let results : Vec<W2lLeaderboardRecordForListRaw> = match maybe_results {
Ok(results) => results,
Err(err) => {
warn!("Error: {:?}", err);
match err {
sqlx::Error::RowNotFound => {
return Ok(Vec::new());
},
_ => {
warn!("w2l leaderboard query error: {:?}", err);
return Err(anyhow!("w2l leaderboard query error"));
}
}
}
};
Ok(results.into_iter()
.map(|result| {
W2lLeaderboardRecordForList {
username: result.username.to_string(),
display_name: result.display_name.to_string(),
gravatar_hash: result.gravatar_hash.to_string(),
creator_user_token: result.creator_user_token.to_string(),
uploaded_count: result.uploaded_count,
}
})
.collect::<Vec<W2lLeaderboardRecordForList>>())
}
@@ -1 +0,0 @@
pub mod calculate_w2l_template_leaderboard;
@@ -1,2 +0,0 @@
// TODO: The "job queries" were moved here; now break them down into several files.
pub mod w2l_download_job_queries;
@@ -1,307 +0,0 @@
//! NB: This seems required for sqlx to generate the cached queries.
//! Sqlx's prepare needs a *single* binary to work against, so we need to
//! include these in the main binary to generate all the queries.
use anyhow::anyhow;
use chrono::Utc;
use sqlx::MySqlPool;
use errors::AnyhowResult;
use tokens::tokens::w2l_templates::W2lTemplateToken;
// TODO(2022-08-04): These were moved into the 'mysql_queries' crate, but they need
// to be split up into several modules for better maintainability. cf the already moved
// `tts_inference_job` queries.
/// table: w2l_template_upload_jobs
#[derive(Debug)]
pub struct W2lTemplateUploadJobRecord {
pub id: i64,
pub token: String,
pub uuid_idempotency_token: String,
pub on_success_result_token: Option<String>,
pub creator_user_token: String,
pub creator_ip_address: String,
pub creator_set_visibility: String, // TODO
pub title: String,
pub template_type: String, // TODO
pub download_url: Option<String>,
pub status: String, // TODO
pub attempt_count: i32,
pub failure_reason: Option<String>,
pub created_at: chrono::DateTime<Utc>,
pub updated_at: chrono::DateTime<Utc>,
pub retry_at: Option<chrono::DateTime<Utc>>,
}
pub async fn query_w2l_template_upload_job_records(pool: &MySqlPool, num_records: u32)
-> AnyhowResult<Vec<W2lTemplateUploadJobRecord>>
{
let job_records = sqlx::query_as!(
W2lTemplateUploadJobRecord,
r#"
SELECT *
FROM w2l_template_upload_jobs
WHERE
(
status IN ("pending", "attempt_failed")
)
AND
(
retry_at IS NULL
OR
retry_at < CURRENT_TIMESTAMP
)
LIMIT ?
"#,
num_records,
)
.fetch_all(pool)
.await?;
Ok(job_records)
}
pub struct W2lDownloadLockRecord {
id: i64,
status: String,
}
pub async fn grab_job_lock_and_mark_pending(
pool: &MySqlPool,
job: &W2lTemplateUploadJobRecord
) -> AnyhowResult<bool> {
// NB: We use transactions and "SELECT ... FOR UPDATE" to simulate mutexes.
let mut transaction = pool.begin().await?;
let maybe_record = sqlx::query_as!(
W2lDownloadLockRecord,
r#"
SELECT
id,
status
FROM w2l_template_upload_jobs
WHERE id = ?
FOR UPDATE
"#,
job.id,
)
.fetch_one(&mut *transaction)
.await;
let record : W2lDownloadLockRecord = match maybe_record {
Ok(record) => record,
Err(err) => {
match err {
sqlx::Error::RowNotFound => {
return Err(anyhow!("could not job"));
},
_ => {
return Err(anyhow!("query error"));
}
}
}
};
let can_transact = match record.status.as_ref() {
"pending" => true, // It's okay for us to take the lock.
"attempt_failed" => true, // We can retry.
"started" => false, // Job in progress (another job beat us, and we can't take the lock)
"complete_success" => false, // Job already complete
"complete_failure" => false, // Job already complete (permanently dead; no need to retry)
"dead" => false, // Job already complete (permanently dead; retries exhausted)
_ => false, // Future-proof
};
if !can_transact {
transaction.rollback().await?;
return Ok(false);
}
let _acquire_lock = sqlx::query!(
r#"
UPDATE w2l_template_upload_jobs
SET
status = 'started',
attempt_count = attempt_count + 1,
retry_at = NOW() + interval 2 minute
WHERE id = ?
"#,
job.id,
)
.execute(&mut *transaction)
.await?;
transaction.commit().await?;
Ok(true)
}
pub async fn mark_w2l_template_upload_job_failure(
pool: &MySqlPool,
job: &W2lTemplateUploadJobRecord,
failure_reason: &str,
max_attempts: i32
) -> AnyhowResult<()> {
// statuses: "attempt_failed", "complete_failure", "dead"
let mut next_status = "attempt_failed";
if job.attempt_count >= max_attempts {
// NB: Job attempt count is incremented at start
next_status = "dead";
}
let _query_result = sqlx::query!(
r#"
UPDATE w2l_template_upload_jobs
SET
status = ?,
failure_reason = ?,
retry_at = NOW() + interval 2 minute
WHERE id = ?
"#,
next_status,
failure_reason.to_string(),
job.id,
)
.execute(pool)
.await?;
Ok(())
}
pub async fn mark_w2l_template_upload_job_permanently_dead(
pool: &MySqlPool,
job: &W2lTemplateUploadJobRecord,
failure_reason: &str,
) -> AnyhowResult<()> {
let _query_result = sqlx::query!(
r#"
UPDATE w2l_template_upload_jobs
SET
status = "dead",
failure_reason = ?,
retry_at = NULL
WHERE id = ?
"#,
failure_reason.to_string(),
job.id,
)
.execute(pool)
.await?;
Ok(())
}
pub async fn mark_w2l_template_upload_job_done(
pool: &MySqlPool,
job: &W2lTemplateUploadJobRecord,
success: bool,
maybe_model_token: Option<&str>
) -> AnyhowResult<()>
{
let status = if success { "complete_success" } else { "complete_failure" };
let _query_result = sqlx::query!(
r#"
UPDATE w2l_template_upload_jobs
SET
status = ?,
on_success_result_token = ?,
failure_reason = NULL,
retry_at = NULL
WHERE id = ?
"#,
status,
maybe_model_token,
job.id,
)
.execute(pool)
.await?;
Ok(())
}
pub async fn insert_w2l_template(
pool: &MySqlPool,
template_type: &str, // TODO: ENUM!
job: &W2lTemplateUploadJobRecord,
private_bucket_hash: &str,
private_bucket_object_name: &str,
private_bucket_cached_faces_object_name: &str,
maybe_image_preview_object_name: Option<&str>,
maybe_video_preview_object_name: Option<&str>,
file_size_bytes: u64,
maybe_mime_type: Option<&str>,
frame_width: u32,
frame_height: u32,
frame_count: u64,
fps: f32,
duration_millis: u64
) -> AnyhowResult<(u64, String)> {
let model_token = W2lTemplateToken::generate().to_string();
let query_result = sqlx::query!(
r#"
INSERT INTO w2l_templates
SET
token = ?,
template_type = ?,
title = ?,
description_markdown = '',
description_rendered_html = '',
creator_user_token = ?,
creator_ip_address_creation = ?,
creator_ip_address_last_update = ?,
original_download_url = ?,
private_bucket_hash = ?,
private_bucket_object_name = ?,
private_bucket_cached_faces_object_name = ?,
maybe_public_bucket_preview_image_object_name = ?,
maybe_public_bucket_preview_video_object_name = ?,
file_size_bytes = ?,
mime_type = ?,
frame_width = ?,
frame_height = ?,
frame_count = ?,
fps = ?,
duration_millis = ?
"#,
model_token,
template_type,
job.title.to_string(),
job.creator_user_token.clone(),
job.creator_ip_address.clone(),
job.creator_ip_address.clone(),
job.download_url.clone(),
private_bucket_hash.to_string(),
private_bucket_object_name.to_string(),
private_bucket_cached_faces_object_name.to_string(),
maybe_image_preview_object_name,
maybe_video_preview_object_name,
file_size_bytes,
maybe_mime_type.unwrap_or(""),
frame_width,
frame_height,
frame_count,
fps,
duration_millis
)
.execute(pool)
.await;
let record_id = match query_result {
Ok(res) => {
res.last_insert_id()
},
Err(err) => {
// TODO: handle better
return Err(anyhow!("Mysql error: {:?}", err));
}
};
Ok((record_id, model_token.clone()))
}
@@ -1,46 +0,0 @@
use anyhow::anyhow;
use sqlx::MySqlPool;
use errors::AnyhowResult;
#[derive(Debug)]
pub struct PendingCountResult {
pub pending_count: Option<i64>,
pub seconds_since_first: i64,
}
pub async fn get_pending_w2l_inference_job_detailed_stats(mysql_pool: &MySqlPool) -> AnyhowResult<Option<PendingCountResult>> {
// NB: Lookup failure is Err(RowNotFound).
let maybe_result = sqlx::query_as!(
PendingCountResult,
r#"
SELECT
NOW() - t2.created_at AS seconds_since_first,
(
SELECT
count(t1.id) as pending_count
FROM w2l_inference_jobs AS t1
WHERE t1.status = "pending"
) as pending_count
FROM w2l_inference_jobs AS t2
WHERE t2.status = "pending"
ORDER BY t2.id ASC
LIMIT 1
"#,
)
.fetch_one(mysql_pool)
.await;
match maybe_result {
Ok(result) => Ok(Some(result)),
Err(ref err) => match err {
sqlx::Error::RowNotFound => {
// NB: Not Found for null results means nothing is pending in the queue (not an error!)
Ok(None)
},
_ => {
Err(anyhow!("get w2l pending count error: {:?}", err))
}
}
}
}
@@ -1,68 +0,0 @@
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use sqlx::MySqlPool;
use errors::AnyhowResult;
pub struct W2lInferenceJobStatusRecord {
pub job_token: String,
pub status: String,
pub attempt_count: i32,
pub maybe_result_token: Option<String>,
pub maybe_public_bucket_video_path: Option<String>,
pub maybe_w2l_template_token: Option<String>,
pub w2l_template_type: String,
pub title: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
pub async fn get_w2l_inference_job_status(
job_token: &str,
mysql_pool: &MySqlPool,
) -> AnyhowResult<Option<W2lInferenceJobStatusRecord>> {
// NB: Lookup failure is Err(RowNotFound).
// NB: Since this is publicly exposed, we don't query sensitive data.
let maybe_status = sqlx::query_as!(
W2lInferenceJobStatusRecord,
r#"
SELECT
jobs.token as job_token,
jobs.status,
jobs.attempt_count,
jobs.on_success_result_token as maybe_result_token,
results.public_bucket_video_path as maybe_public_bucket_video_path,
jobs.maybe_w2l_template_token,
w2l.template_type as w2l_template_type,
w2l.title,
jobs.created_at,
jobs.updated_at
FROM w2l_inference_jobs as jobs
JOIN w2l_templates as w2l
ON w2l.token = jobs.maybe_w2l_template_token
LEFT OUTER JOIN w2l_results as results
ON jobs.on_success_result_token = results.token
WHERE jobs.token = ?
"#,
job_token
)
.fetch_one(mysql_pool)
.await;
match maybe_status {
Ok(record) => Ok(Some(record)),
Err(err) => match err {
sqlx::Error::RowNotFound => Ok(None),
_ => Err(anyhow!("w2l template query error: {:?}", err)),
}
}
}
@@ -1,74 +0,0 @@
use anyhow::anyhow;
use log::error;
use sqlx::error::Error::Database;
use sqlx::MySqlPool;
use errors::AnyhowResult;
// FIXME: NB: This is an old query that was somewhat modernized when moved.
// All the same, do not copy this example!
pub struct InsertW2lInferenceJobArgs<'a> {
pub w2l_template_token: &'a str,
pub tts_inference_result_token: &'a str,
pub maybe_user_token: Option<&'a str>,
pub ip_address: &'a str,
//pub creator_set_visibility: Visibility,
pub creator_set_visibility: &'a str,
pub mysql_pool: &'a MySqlPool,
}
pub async fn insert_w2l_inference_job(args: InsertW2lInferenceJobArgs<'_>) -> AnyhowResult<()> {
let query_result = sqlx::query!(
r#"
INSERT INTO w2l_inference_jobs
SET
maybe_w2l_template_token = ?,
maybe_tts_inference_result_token = ?,
maybe_public_audio_bucket_location = NULL,
maybe_public_image_bucket_location = NULL,
maybe_creator_user_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
status = "pending"
"#,
args.w2l_template_token,
args.tts_inference_result_token,
args.maybe_user_token,
args.ip_address,
args.creator_set_visibility
)
.execute(args.mysql_pool)
.await;
let _record_id = match query_result {
Ok(res) => {
res.last_insert_id()
},
Err(err) => {
error!("New w2l inference job creation DB error: {:?}", err);
// NB: SQLSTATE[23000]: Integrity constraint violation
// NB: MySQL Error Code 1062: Duplicate key insertion (this is harder to access)
match err {
Database(ref err) => {
let _maybe_code = err.code().map(|c| c.into_owned());
/*match maybe_code.as_deref() {
Some("23000") => {
if err.message().contains("username") {
return Err(UsernameTaken);
} else if err.message().contains("email_address") {
return Err(EmailTaken);
}
}
_ => {},
}*/
},
_ => {},
}
return Err(anyhow!("error with query: {:?}", &err));
}
};
Ok(())
}
@@ -1,69 +0,0 @@
use anyhow::anyhow;
use sqlx::MySqlPool;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use tokens::tokens::w2l_inference_jobs::W2lInferenceJobToken;
pub struct InsertW2lInferenceJobExtendedArgs<'a> {
pub uuid_idempotency_token: &'a str,
pub maybe_template_token: Option<&'a str>,
pub audio_upload_bucket_hash: Option<&'a str>,
pub audio_upload_bucket_path: Option<&'a str>,
pub maybe_audio_file_name: Option<&'a str>,
pub audio_type: Option<&'a str>,
pub maybe_user_token: Option<&'a str>,
pub ip_address: &'a str,
pub set_visibility: Visibility,
pub mysql_pool: &'a MySqlPool,
}
/// Returns the new job's token on success
pub async fn insert_w2l_inference_job_extended(args: InsertW2lInferenceJobExtendedArgs<'_>) -> AnyhowResult<String> {
// This token is returned to the client.
let job_token = W2lInferenceJobToken::generate().to_string();
let query_result = sqlx::query!(
r#"
INSERT INTO w2l_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
maybe_w2l_template_token = ?,
maybe_public_audio_bucket_hash = ?,
maybe_public_audio_bucket_location = ?,
maybe_original_audio_filename = ?,
maybe_audio_mime_type = ?,
maybe_creator_user_token = ?,
creator_ip_address = ?,
disable_end_bump = false,
creator_set_visibility = ?,
status = "pending"
"#,
&job_token,
args.uuid_idempotency_token.to_string(),
args.maybe_template_token.clone(),
args.audio_upload_bucket_hash.clone(),
args.audio_upload_bucket_path.clone(),
args.maybe_audio_file_name.clone(),
args.audio_type.clone(),
args.maybe_user_token.clone(),
args.ip_address.to_string(),
args.set_visibility.to_str(),
)
.execute(args.mysql_pool)
.await;
let _record_id = match query_result {
Ok(res) => res.last_insert_id(),
Err(err) => {
return Err(anyhow!("New w2l template upload creation DB error: {:?}", err));
}
};
Ok(job_token)
}
@@ -1,7 +0,0 @@
pub mod get_pending_w2l_inference_job_detailed_stats;
pub mod get_w2l_inference_job_status;
pub mod insert_w2l_inference_job;
pub mod insert_w2l_inference_job_extended;
// TODO: The grab bag of "job queries" were moved here; now break them down into several files.
pub mod w2l_inference_job_queries;
@@ -1,458 +0,0 @@
//! NB: This seems required for sqlx to generate the cached queries.
//! Sqlx's prepare needs a *single* binary to work against, so we need to
//! include these in the main binary to generate all the queries.
use std::path::Path;
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::warn;
use sqlx::MySqlPool;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use tokens::tokens::w2l_results::W2lResultToken;
// TODO(2022-08-04): These were moved into the 'mysql_queries' crate, but they need
// to be split up into several modules for better maintainability. cf the already moved
// `tts_inference_job` queries.
/// table: w2l_inference_jobs
#[derive(Debug)]
pub struct W2lInferenceJobRecord {
pub id: i64,
pub inference_job_token: String,
pub uuid_idempotency_token: String,
// ===== FACE TEMPLATE OPTIONS =====
pub maybe_w2l_template_token: Option<String>,
pub maybe_public_image_bucket_location: Option<String>,
// ===== AUDIO SOURCE OPTIONS =====
pub maybe_tts_inference_result_token: Option<String>,
pub maybe_public_audio_bucket_hash: Option<String>,
pub maybe_public_audio_bucket_location: Option<String>,
pub maybe_original_audio_filename: Option<String>,
pub maybe_original_audio_download_url: Option<String>,
pub maybe_audio_mime_type: Option<String>,
pub creator_ip_address: String,
pub maybe_creator_user_token: Option<String>,
pub creator_set_visibility: Visibility,
pub disable_end_bump: i8, // bool
pub disable_watermark: i8, // bool
//pub maybe_subject_token: Option<String>,
//pub maybe_actor_subject_token: Option<String>,
pub status: String, // TODO
pub attempt_count: i32,
pub failure_reason: Option<String>,
pub created_at: chrono::DateTime<Utc>,
pub updated_at: chrono::DateTime<Utc>,
pub retry_at: Option<chrono::DateTime<Utc>>,
}
pub async fn query_w2l_inference_job_records(pool: &MySqlPool, num_records: u32)
-> AnyhowResult<Vec<W2lInferenceJobRecord>>
{
let job_records = sqlx::query_as!(
W2lInferenceJobRecord,
r#"
SELECT
id,
token AS inference_job_token,
uuid_idempotency_token,
maybe_w2l_template_token,
maybe_public_image_bucket_location,
maybe_tts_inference_result_token,
maybe_public_audio_bucket_hash,
maybe_public_audio_bucket_location,
maybe_original_audio_filename,
maybe_original_audio_download_url,
maybe_audio_mime_type,
creator_ip_address,
maybe_creator_user_token,
creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
disable_end_bump,
disable_watermark,
status,
attempt_count,
failure_reason,
created_at,
updated_at,
retry_at
FROM w2l_inference_jobs
WHERE
(
status IN ("pending", "attempt_failed")
)
AND
(
retry_at IS NULL
OR
retry_at < CURRENT_TIMESTAMP
)
LIMIT ?
"#,
num_records,
)
.fetch_all(pool)
.await?;
Ok(job_records)
}
pub struct W2lInferenceLockRecord {
id: i64,
status: String,
}
pub async fn grab_job_lock_and_mark_pending(
pool: &MySqlPool,
job: &W2lInferenceJobRecord
) -> AnyhowResult<bool> {
// NB: We use transactions and "SELECT ... FOR UPDATE" to simulate mutexes.
let mut transaction = pool.begin().await?;
let maybe_record = sqlx::query_as!(
W2lInferenceLockRecord,
r#"
SELECT
id,
status
FROM w2l_inference_jobs
WHERE id = ?
FOR UPDATE
"#,
job.id,
)
.fetch_one(&mut *transaction)
.await;
let record : W2lInferenceLockRecord = match maybe_record {
Ok(record) => record,
Err(err) => {
match err {
sqlx::Error::RowNotFound => {
return Err(anyhow!("could not job"));
},
_ => {
return Err(anyhow!("query error"));
}
}
}
};
let can_transact = match record.status.as_ref() {
"pending" => true, // It's okay for us to take the lock.
"attempt_failed" => true, // We can retry.
"started" => false, // Job in progress (another job beat us, and we can't take the lock)
"complete_success" => false, // Job already complete
"complete_failure" => false, // Job already complete (permanently dead; no need to retry)
"dead" => false, // Job already complete (permanently dead; retries exhausted)
_ => false, // Future-proof
};
if !can_transact {
transaction.rollback().await?;
return Ok(false);
}
let _acquire_lock = sqlx::query!(
r#"
UPDATE w2l_inference_jobs
SET
status = 'started',
attempt_count = attempt_count + 1,
retry_at = NOW() + interval 2 minute
WHERE id = ?
"#,
job.id,
)
.execute(&mut *transaction)
.await?;
transaction.commit().await?;
Ok(true)
}
pub async fn mark_w2l_inference_job_failure(
pool: &MySqlPool,
job: &W2lInferenceJobRecord,
failure_reason: &str,
max_attempts: i32
) -> AnyhowResult<()> {
// statuses: "attempt_failed", "complete_failure", "dead"
let mut next_status = "attempt_failed";
if job.attempt_count >= max_attempts {
// NB: Job attempt count is incremented at start
next_status = "dead";
}
let _query_result = sqlx::query!(
r#"
UPDATE w2l_inference_jobs
SET
status = ?,
failure_reason = ?,
retry_at = NOW() + interval 2 minute
WHERE id = ?
"#,
next_status,
failure_reason.to_string(),
job.id,
)
.execute(pool)
.await?;
Ok(())
}
pub async fn mark_w2l_inference_job_done(
pool: &MySqlPool,
job: &W2lInferenceJobRecord,
success: bool,
maybe_result_token: Option<&str>
) -> AnyhowResult<()> {
let status = if success { "complete_success" } else { "complete_failure" };
let _query_result = sqlx::query!(
r#"
UPDATE w2l_inference_jobs
SET
status = ?,
on_success_result_token = ?,
failure_reason = NULL,
retry_at = NULL
WHERE id = ?
"#,
status,
maybe_result_token,
job.id,
)
.execute(pool)
.await?;
Ok(())
}
pub struct SyntheticIdRecord {
pub next_id: i64,
}
pub async fn insert_w2l_result<P: AsRef<Path>>(
pool: &MySqlPool,
job: &W2lInferenceJobRecord,
bucket_video_results_path: P,
file_size_bytes: u64,
maybe_mime_type: Option<&str>,
frame_width: u32,
frame_height: u32,
duration_millis: u64
) -> AnyhowResult<(u64, String)>
{
let inference_result_token = W2lResultToken::generate().to_string();
let bucket_video_result_path = &bucket_video_results_path
.as_ref()
.display()
.to_string();
let maybe_creator_user_token = job.maybe_creator_user_token.clone();
let mut maybe_creator_synthetic_id : Option<u64> = None;
let mut transaction = pool.begin().await?;
if let Some(creator_user_token) = maybe_creator_user_token.as_deref() {
let query_result = sqlx::query!(
r#"
INSERT INTO w2l_result_synthetic_ids
SET
user_token = ?,
next_id = 1
ON DUPLICATE KEY UPDATE
user_token = ?,
next_id = next_id + 1
"#,
creator_user_token,
creator_user_token
)
.execute(&mut *transaction)
.await;
match query_result {
Ok(_) => {},
Err(err) => {
//transaction.rollback().await?;
warn!("Transaction failure: {:?}", err);
}
}
let query_result = sqlx::query_as!(
SyntheticIdRecord,
r#"
SELECT
next_id
FROM
w2l_result_synthetic_ids
WHERE
user_token = ?
LIMIT 1
"#,
creator_user_token,
)
.fetch_one(&mut *transaction)
.await;
let record : SyntheticIdRecord = match query_result {
Ok(record) => record,
Err(err) => {
warn!("Transaction failure: {:?}", err);
//transaction.rollback().await?;
return Err(anyhow!("Transaction failure: {:?}", err));
}
};
let next_id = record.next_id as u64;
maybe_creator_synthetic_id = Some(next_id);
}
let record_id = {
let query_result = sqlx::query!(
r#"
INSERT INTO w2l_results
SET
token = ?,
maybe_w2l_template_token = ?,
maybe_creator_user_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
maybe_creator_synthetic_id = ?,
public_bucket_video_path = ?,
file_size_bytes = ?,
mime_type = ?,
frame_width = ?,
frame_height = ?,
duration_millis = ?
"#,
inference_result_token,
job.maybe_w2l_template_token.clone(),
job.maybe_creator_user_token.clone(),
job.creator_ip_address.clone(),
job.creator_set_visibility.to_str(),
maybe_creator_synthetic_id,
bucket_video_result_path,
file_size_bytes,
maybe_mime_type.unwrap_or(""),
frame_width,
frame_height,
duration_millis
)
.execute(&mut *transaction)
.await;
let record_id = match query_result {
Ok(res) => {
res.last_insert_id()
},
Err(err) => {
// TODO: handle better
transaction.rollback().await?;
return Err(anyhow!("Mysql error: {:?}", err));
}
};
record_id
};
transaction.commit().await?;
Ok((record_id, inference_result_token.clone()))
}
pub struct W2lTemplateRecord2 {
pub template_token: String,
pub template_type: String,
pub creator_user_token: String,
pub creator_username: String,
pub private_bucket_hash: String,
pub creator_display_name: String,
pub title: String,
pub frame_width: i32,
pub frame_height: i32,
pub duration_millis: i32,
pub maybe_public_bucket_preview_image_object_name: Option<String>,
pub maybe_public_bucket_preview_video_object_name: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
pub async fn get_w2l_template_by_token(pool: &MySqlPool, template_token: &str)
-> AnyhowResult<Option<W2lTemplateRecord2>>
{
// NB: Lookup failure is Err(RowNotFound).
// NB: Since this is publicly exposed, we don't query sensitive data.
let maybe_template = sqlx::query_as!(
W2lTemplateRecord2,
r#"
SELECT
w2l.token as template_token,
w2l.template_type,
w2l.creator_user_token,
users.username as creator_username,
users.display_name as creator_display_name,
w2l.title,
w2l.frame_width,
w2l.frame_height,
w2l.duration_millis,
w2l.private_bucket_hash,
w2l.maybe_public_bucket_preview_image_object_name,
w2l.maybe_public_bucket_preview_video_object_name,
w2l.created_at,
w2l.updated_at
FROM w2l_templates as w2l
JOIN users
ON users.token = w2l.creator_user_token
WHERE w2l.token = ?
AND w2l.user_deleted_at IS NULL
AND w2l.mod_deleted_at IS NULL
"#,
&template_token
)
.fetch_one(pool)
.await; // TODO: This will return error if it doesn't exist
match maybe_template {
Ok(template) => Ok(Some(template)),
Err(err) => {
match err {
sqlx::Error::RowNotFound => {
Ok(None)
},
_ => {
warn!("w2l template query error: {:?}", err);
Err(anyhow!("Mysql error: {:?}", err))
}
}
}
}
}
@@ -1,89 +0,0 @@
use sqlx::MySqlPool;
use errors::AnyhowResult;
pub async fn delete_w2l_inference_result_as_user(
inference_result_token: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_results
SET
user_deleted_at = CURRENT_TIMESTAMP
WHERE
token = ?
LIMIT 1
"#,
inference_result_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
pub async fn delete_w2l_inference_result_as_mod(
inference_result_token: &str,
mod_user_token: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_results
SET
mod_deleted_at = CURRENT_TIMESTAMP,
maybe_mod_user_token = ?
WHERE
token = ?
LIMIT 1
"#,
mod_user_token,
inference_result_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
pub async fn undelete_w2l_inference_result_as_user(
inference_result_token: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_results
SET
user_deleted_at = NULL
WHERE
token = ?
LIMIT 1
"#,
inference_result_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
pub async fn undelete_w2l_inference_result_as_mod(
inference_result_token: &str,
mod_user_token: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_results
SET
mod_deleted_at = NULL,
maybe_mod_user_token = ?
WHERE
token = ?
LIMIT 1
"#,
mod_user_token,
inference_result_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
@@ -1,76 +0,0 @@
use anyhow::anyhow;
use sqlx::MySqlPool;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
pub struct EditW2lResultArgs<'a> {
pub w2l_result_token: &'a str,
pub creator_set_visibility: Visibility,
pub role_dependent_fields: CreatorOrModFields<'a>,
pub mysql_pool: &'a MySqlPool,
}
pub enum CreatorOrModFields<'a> {
CreatorFields {
creator_ip_address: &'a str,
},
ModFields {
mod_user_token: &'a str,
}
}
pub async fn edit_w2l_result(args: EditW2lResultArgs<'_>) -> AnyhowResult<()> {
let query_result = match args.role_dependent_fields {
//
// Creator
CreatorOrModFields::CreatorFields { creator_ip_address } => {
// TODO: Don't update the original IP address. Create a new field.
// We need to store the IP address details.
sqlx::query!(
r#"
UPDATE w2l_results
SET
creator_set_visibility = ?,
creator_ip_address = ?
WHERE token = ?
LIMIT 1
"#,
args.creator_set_visibility.to_str(),
creator_ip_address,
args.w2l_result_token,
)
.execute(args.mysql_pool)
.await
},
//
// Moderator
CreatorOrModFields::ModFields { mod_user_token } => {
// We need to store the moderator details.
sqlx::query!(
r#"
UPDATE w2l_results
SET
creator_set_visibility = ?,
maybe_mod_user_token = ?
WHERE token = ?
LIMIT 1
"#,
args.creator_set_visibility.to_str(),
mod_user_token,
args.w2l_result_token,
)
.execute(args.mysql_pool)
.await
},
};
match query_result {
Ok(_) => Ok(()),
Err(err) => Err(anyhow!("Update W2L result DB error: {:?}", err)),
}
}
@@ -1,665 +0,0 @@
// NB: Incrementally getting rid of build warnings...
#![forbid(unused_imports)]
#![forbid(unused_mut)]
#![forbid(unused_variables)]
use chrono::{DateTime, Utc};
use sqlx::MySqlPool;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use crate::config::shared_constants::DEFAULT_MYSQL_QUERY_RESULT_PAGE_SIZE;
#[derive(Serialize)]
pub struct W2lInferenceListPage {
pub inference_records: Vec<W2lInferenceRecordForList>,
pub sort_ascending: bool,
/// ID of the first record in `inference_records`.
pub first_id: Option<i64>,
/// ID of the last record in `inference_records`.
pub last_id: Option<i64>,
}
#[derive(Serialize)]
pub struct W2lInferenceRecordForList {
pub w2l_result_token: String,
pub maybe_w2l_template_token: Option<String>,
pub maybe_tts_inference_result_token: Option<String>,
pub template_type: Option<String>,
pub template_title: Option<String>,
pub maybe_creator_user_token: Option<String>,
pub maybe_creator_username: Option<String>,
pub maybe_creator_display_name: Option<String>,
pub maybe_creator_result_id: Option<u64>,
pub file_size_bytes: u32,
pub frame_width: u32,
pub frame_height: u32,
pub duration_millis: u32,
pub visibility: Visibility,
//pub template_is_mod_approved: bool, // converted
//pub maybe_mod_user_token: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
/// Query Builder for listing W2L results.
/// These are very difficult queries, so the builder helps for
/// testability, construction, and correctness.
pub struct ListW2lResultsQueryBuilder {
scope_creator_username: Option<String>,
include_user_hidden: bool,
include_mod_deleted_results: bool,
include_user_deleted_results: bool,
include_templates_not_approved_for_public_listing: bool,
sort_ascending: bool,
offset: Option<u64>,
limit: u16,
cursor_is_reversed: bool,
}
impl ListW2lResultsQueryBuilder {
pub fn new() -> Self {
Self {
scope_creator_username: None,
include_user_hidden: false,
include_mod_deleted_results: false,
include_user_deleted_results: false,
include_templates_not_approved_for_public_listing: false,
sort_ascending: false,
offset: None,
limit: DEFAULT_MYSQL_QUERY_RESULT_PAGE_SIZE,
cursor_is_reversed: false,
}
}
pub fn scope_creator_username(mut self, scope_creator_username: Option<&str>) -> Self {
self.scope_creator_username = scope_creator_username.map(|u| u.to_string());
self
}
pub fn include_user_hidden(mut self, include_user_hidden: bool) -> Self {
self.include_user_hidden = include_user_hidden;
self
}
pub fn include_mod_deleted_results(mut self, include_mod_deleted_results: bool) -> Self {
self.include_mod_deleted_results = include_mod_deleted_results;
self
}
pub fn include_user_deleted_results(mut self, include_user_deleted_results: bool) -> Self {
self.include_user_deleted_results = include_user_deleted_results;
self
}
pub fn include_templates_not_approved_for_public_listing(mut self, include_templates_not_approved_for_public_listing: bool) -> Self {
self.include_templates_not_approved_for_public_listing = include_templates_not_approved_for_public_listing;
self
}
pub fn sort_ascending(mut self, sort_ascending: bool) -> Self {
self.sort_ascending = sort_ascending;
self
}
pub fn offset(mut self, offset: Option<u64>) -> Self {
self.offset = offset;
self
}
pub fn limit(mut self, limit: u16) -> Self {
self.limit = limit;
self
}
pub fn cursor_is_reversed(mut self, cursor_is_reversed: bool) -> Self {
self.cursor_is_reversed = cursor_is_reversed;
self
}
/// Perform the query based on the set predicates.
/// Wrap the results in a "Page" we can return to the frontend.
/// This will remove any IDs from the records, but the ids themselves also need scrubbing.
pub async fn perform_query_for_page(
&self,
mysql_pool: &MySqlPool
) -> AnyhowResult<W2lInferenceListPage> {
let internal_results = self.perform_internal_query(mysql_pool).await?;
let first_id = internal_results.first()
.map(|raw_result| raw_result.w2l_result_id);
let last_id = internal_results.last()
.map(|raw_result| raw_result.w2l_result_id);
let inference_results = internal_results
.iter()
.map(|r| {
W2lInferenceRecordForList {
w2l_result_token: r.w2l_result_token.clone(),
maybe_w2l_template_token: r.maybe_w2l_template_token.clone(),
maybe_tts_inference_result_token: r.maybe_tts_inference_result_token.clone(),
template_type: r.template_type.clone(),
template_title: r.template_title.clone(),
maybe_creator_user_token: r.maybe_creator_user_token.clone(),
maybe_creator_username: r.maybe_creator_username.clone(),
maybe_creator_display_name: r.maybe_creator_display_name.clone(),
maybe_creator_result_id: r.maybe_creator_result_id.map(|v| v as u64),
file_size_bytes: if r.file_size_bytes > 0 { r.file_size_bytes as u32 } else { 0 },
frame_width: if r.frame_width > 0 { r.frame_width as u32 } else { 0 },
frame_height: if r.frame_height > 0 { r.frame_height as u32 } else { 0 },
duration_millis: if r.duration_millis > 0 { r.duration_millis as u32 } else { 0 },
visibility: Visibility::from_str(&r.creator_set_visibility).unwrap_or(Visibility::Public),
created_at: r.created_at,
updated_at: r.updated_at,
}
})
.collect::<Vec<W2lInferenceRecordForList>>();
Ok(W2lInferenceListPage {
inference_records: inference_results,
sort_ascending: self.sort_ascending,
first_id,
last_id,
})
}
/// Perform the query based on the set predicates.
/// The records contain IDs, which we should not expose to the frontend.
pub async fn perform_internal_query(
&self,
mysql_pool: &MySqlPool
) -> AnyhowResult<Vec<RawInternalTtsRecord>> {
let query = self.build_query_string();
let mut query = sqlx::query_as::<_, RawInternalTtsRecord>(&query);
// NB: The following bindings must match the order of the query builder !!
if let Some(offset) = self.offset {
query = query.bind(offset);
}
if let Some(username) = self.scope_creator_username.as_deref() {
query = query.bind(username);
}
query = query.bind(self.limit);
let mut results = query.fetch_all(mysql_pool)
.await?;
if self.cursor_is_reversed {
results.reverse()
}
Ok(results)
}
pub fn build_query_string(&self) -> String {
// TODO: I haven't figured out how to get field name disambiguation and type coercion working here.
// (1) w2l_results.creator_set_visibility `creator_set_visibility: crate::database::enums::record_visibility::RecordVisibility`,
// Query error: no column found for name: creator_set_visibility
// (2) creator_set_visibility `creator_set_visibility: crate::database::enums::record_visibility::RecordVisibility`,
// Column 'creator_set_visibility' in field list is ambiguous
// TODO/NB: Unfortunately SQLx can't statically typecheck this query
let mut query = r#"
SELECT
w2l_results.id as w2l_result_id,
w2l_results.token as w2l_result_token,
w2l_results.maybe_tts_inference_result_token,
w2l_templates.token as maybe_w2l_template_token,
w2l_templates.template_type,
w2l_templates.title as template_title,
users.token as maybe_creator_user_token,
users.username as maybe_creator_username,
users.display_name as maybe_creator_display_name,
w2l_results.maybe_creator_synthetic_id as maybe_creator_result_id,
w2l_results.file_size_bytes,
w2l_results.frame_width,
w2l_results.frame_height,
w2l_results.duration_millis,
w2l_results.creator_set_visibility,
w2l_results.created_at,
w2l_results.updated_at
FROM w2l_results
LEFT OUTER JOIN w2l_templates
ON w2l_results.maybe_w2l_template_token = w2l_templates.token
LEFT OUTER JOIN users
ON w2l_results.maybe_creator_user_token = users.token
"#.to_string();
query.push_str(&self.build_predicates());
query
}
pub fn build_predicates(&self) -> String {
// NB: Reverse cursors require us to invert the sort direction.
let mut sort_ascending = self.sort_ascending;
let mut first_predicate_added = false;
let mut query = "".to_string();
if let Some(_offset) = self.offset {
if !first_predicate_added {
query.push_str(" WHERE");
first_predicate_added = true;
} else {
query.push_str(" AND");
}
if sort_ascending {
if self.cursor_is_reversed {
// NB: We're searching backwards.
query.push_str(" w2l_results.id < ?");
sort_ascending = !sort_ascending;
} else {
query.push_str(" w2l_results.id > ?");
}
} else {
if self.cursor_is_reversed {
// NB: We're searching backwards.
query.push_str(" w2l_results.id > ?");
sort_ascending = !sort_ascending;
} else {
query.push_str(" w2l_results.id < ?");
}
}
}
if let Some(_username) = self.scope_creator_username.as_deref() {
if !first_predicate_added {
query.push_str(" WHERE users.username = ?");
first_predicate_added = true;
} else {
query.push_str(" AND users.username = ?");
}
}
if !self.include_templates_not_approved_for_public_listing {
if !first_predicate_added {
query.push_str(" WHERE w2l_templates.is_public_listing_approved IS TRUE");
first_predicate_added = true;
} else {
query.push_str(" AND w2l_templates.is_public_listing_approved IS TRUE");
}
}
if !self.include_user_hidden {
if !first_predicate_added {
query.push_str(" WHERE w2l_results.creator_set_visibility = 'public'");
first_predicate_added = true;
} else {
query.push_str(" AND w2l_results.creator_set_visibility = 'public'");
}
}
if !self.include_mod_deleted_results {
if !first_predicate_added {
query.push_str(" WHERE w2l_results.mod_deleted_at IS NULL");
first_predicate_added = true;
} else {
query.push_str(" AND w2l_results.mod_deleted_at IS NULL");
}
}
if !self.include_user_deleted_results {
if !first_predicate_added {
query.push_str(" WHERE w2l_results.user_deleted_at IS NULL");
first_predicate_added = true;
} else {
query.push_str(" AND w2l_results.user_deleted_at IS NULL");
}
}
if sort_ascending {
query.push_str(" ORDER BY w2l_results.id ASC");
} else {
query.push_str(" ORDER BY w2l_results.id DESC");
}
query.push_str(" LIMIT ?");
query
}
}
#[derive(sqlx::FromRow)]
pub struct RawInternalTtsRecord {
pub w2l_result_id: i64,
pub w2l_result_token: String,
pub maybe_w2l_template_token: Option<String>,
pub maybe_tts_inference_result_token: Option<String>,
pub template_type: Option<String>,
pub template_title: Option<String>, // from field `w2l_templates.title`
pub maybe_creator_user_token: Option<String>,
pub maybe_creator_username: Option<String>,
pub maybe_creator_display_name: Option<String>,
pub maybe_creator_result_id: Option<i64>,
pub file_size_bytes: i32,
pub frame_width: i32,
pub frame_height: i32,
pub duration_millis: i32,
pub creator_set_visibility: String,
//pub template_is_mod_approved: i8, // needs convert
//pub maybe_mod_user_token: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[cfg(test)]
mod tests {
use crate::queries::w2l::w2l_results::list_w2l_inference_results_query_builder::ListW2lResultsQueryBuilder;
#[test]
fn predicates_without_scoping() {
let query_builder = ListW2lResultsQueryBuilder::new();
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_scoped_to_user() {
let query_builder = ListW2lResultsQueryBuilder::new()
.scope_creator_username(Some("echelon"));
assert_eq!(&query_builder.build_predicates(),
" WHERE users.username = ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_user_hidden() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_user_hidden(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_mod_deleted() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_mod_deleted_results(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_user_deleted() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_user_deleted_results(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_mod_deleted_and_user_deleted() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_mod_deleted_results(true)
.include_user_deleted_results(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_unapproved() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_templates_not_approved_for_public_listing(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_unapproved_and_mod_deleted() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_templates_not_approved_for_public_listing(true)
.include_mod_deleted_results(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.creator_set_visibility = 'public' \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_unapproved_and_user_deleted() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_templates_not_approved_for_public_listing(true)
.include_user_deleted_results(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_mod_deleted_user_deleted_and_unapproved() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_mod_deleted_results(true)
.include_user_deleted_results(true)
.include_templates_not_approved_for_public_listing(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.creator_set_visibility = 'public' \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_sort_ascending() {
let query_builder = ListW2lResultsQueryBuilder::new()
.sort_ascending(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id ASC \
LIMIT ?");
}
#[test]
fn predicates_offset() {
let query_builder = ListW2lResultsQueryBuilder::new()
.offset(Some(100));
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_offset_and_sort_ascending() {
let query_builder = ListW2lResultsQueryBuilder::new()
.sort_ascending(true)
.offset(Some(100));
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id > ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id ASC \
LIMIT ?");
}
#[test]
fn predicates_limit() {
let query_builder = ListW2lResultsQueryBuilder::new()
.limit(15);
// NB: Does not change the query itself! Just the downstream binding.
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_cursor_is_reversed_without_cursor() {
let query_builder = ListW2lResultsQueryBuilder::new()
.cursor_is_reversed(true);
// NB: Without a cursor, nothing happens.
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_offset_cursor_is_reversed() {
let query_builder = ListW2lResultsQueryBuilder::new()
.offset(Some(100))
.cursor_is_reversed(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id > ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id ASC \
LIMIT ?");
}
#[test]
fn predicates_offset_cursor_is_reversed_sort_ascending() {
let query_builder = ListW2lResultsQueryBuilder::new()
.offset(Some(100))
.cursor_is_reversed(true)
.sort_ascending(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_limit_scope_user_offset_cursor_is_reversed_sort_ascending() {
let query_builder = ListW2lResultsQueryBuilder::new()
.limit(1000)
.scope_creator_username(Some("pikachu"))
.offset(Some(100))
.cursor_is_reversed(true)
.sort_ascending(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
AND users.username = ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_limit_scope_user_show_hidden_offset_cursor_is_reversed_sort_ascending() {
let query_builder = ListW2lResultsQueryBuilder::new()
.limit(1000)
.include_user_hidden(true)
.scope_creator_username(Some("pikachu"))
.offset(Some(100))
.cursor_is_reversed(true)
.sort_ascending(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
AND users.username = ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
}
@@ -1,4 +0,0 @@
pub mod delete_w2l_result_various_scopes;
pub mod edit_w2l_result;
pub mod list_w2l_inference_results_query_builder;
pub mod query_w2l_result;
@@ -1,298 +0,0 @@
// NB: Incrementally getting rid of build warnings...
#![forbid(unused_imports)]
#![forbid(unused_mut)]
#![forbid(unused_variables)]
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::warn;
use sqlx::MySqlPool;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use crate::helpers::boolean_converters::nullable_i8_to_bool;
#[derive(Serialize)]
pub struct W2lResultRecordForResponse {
pub w2l_result_token: String,
pub maybe_w2l_template_token: Option<String>,
pub maybe_tts_inference_result_token: Option<String>,
pub public_bucket_video_path: String,
pub template_type: Option<String>,
pub template_title: Option<String>,
pub maybe_creator_user_token: Option<String>,
pub maybe_creator_username: Option<String>,
pub maybe_creator_display_name: Option<String>,
pub maybe_creator_gravatar_hash: Option<String>,
pub maybe_template_creator_user_token: Option<String>,
pub maybe_template_creator_username: Option<String>,
pub maybe_template_creator_display_name: Option<String>,
pub maybe_template_creator_gravatar_hash: Option<String>,
pub creator_set_visibility: Visibility,
pub file_size_bytes: u32,
pub frame_width: u32,
pub frame_height: u32,
pub duration_millis: u32,
//pub template_is_mod_approved: bool, // converted
//pub maybe_mod_user_token: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub maybe_moderator_fields: Option<W2lResultModeratorFields>,
}
/// "Moderator-only fields" that we wouldn't want to expose to ordinary users.
/// It's the web endpoint controller's responsibility to clear these for non-mods.
#[derive(Serialize)]
pub struct W2lResultModeratorFields {
pub template_creator_is_banned: bool,
pub result_creator_is_banned_if_user: bool,
pub result_creator_ip_address: String,
pub result_creator_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
#[derive(Serialize)]
pub struct W2lResultRecordRaw {
pub w2l_result_token: String, // from field `w2l_results.token`
pub maybe_w2l_template_token: Option<String>,
pub maybe_tts_inference_result_token: Option<String>,
pub public_bucket_video_path: String,
pub template_type: Option<String>,
pub template_title: Option<String>, // from field `w2l_templates.title`
pub maybe_creator_is_banned: Option<i8>,
pub maybe_creator_user_token: Option<String>,
pub maybe_creator_username: Option<String>,
pub maybe_creator_display_name: Option<String>,
pub maybe_creator_gravatar_hash: Option<String>,
pub maybe_template_creator_is_banned: Option<i8>,
pub maybe_template_creator_user_token: Option<String>,
pub maybe_template_creator_username: Option<String>,
pub maybe_template_creator_display_name: Option<String>,
pub maybe_template_creator_gravatar_hash: Option<String>,
pub creator_set_visibility: String,
pub file_size_bytes: i32,
pub frame_width: i32,
pub frame_height: i32,
pub duration_millis: i32,
//pub template_is_mod_approved: i8, // needs convert
//pub maybe_mod_user_token: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub creator_ip_address: String,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
pub async fn select_w2l_result_by_token(
w2l_result_token: &str,
can_see_deleted: bool,
mysql_pool: &MySqlPool
) -> AnyhowResult<Option<W2lResultRecordForResponse>> {
let maybe_record = if can_see_deleted {
select_including_deleted(w2l_result_token, mysql_pool).await
} else {
select_without_deleted(w2l_result_token, mysql_pool).await
};
let ir : W2lResultRecordRaw = match maybe_record {
Ok(inference_result) => inference_result,
Err(ref err) => {
match err {
sqlx::Error::RowNotFound => {
warn!("w2l result not found: {:?}", &err);
return Ok(None);
},
_ => {
warn!("w2l result query error: {:?}", &err);
return Err(anyhow!("database error"));
}
}
}
};
let ir_for_response = W2lResultRecordForResponse {
w2l_result_token: ir.w2l_result_token,
maybe_w2l_template_token: ir.maybe_w2l_template_token,
maybe_tts_inference_result_token: ir.maybe_tts_inference_result_token,
public_bucket_video_path: ir.public_bucket_video_path,
template_type: ir.template_type,
template_title: ir.template_title,
maybe_creator_user_token: ir.maybe_creator_user_token,
maybe_creator_username: ir.maybe_creator_username,
maybe_creator_display_name: ir.maybe_creator_display_name,
maybe_creator_gravatar_hash: ir.maybe_creator_gravatar_hash,
maybe_template_creator_user_token: ir.maybe_template_creator_user_token,
maybe_template_creator_username: ir.maybe_template_creator_username,
maybe_template_creator_display_name: ir.maybe_template_creator_display_name,
maybe_template_creator_gravatar_hash: ir.maybe_template_creator_gravatar_hash,
// NB: Fail open/public since we're already looking at it
creator_set_visibility: Visibility::from_str(&ir.creator_set_visibility)
.unwrap_or(Visibility::Public),
//template_is_mod_approved: if ir.template_is_mod_approved == 0 { false } else { true },
file_size_bytes: if ir.file_size_bytes > 0 { ir.file_size_bytes as u32 } else { 0 },
frame_width: if ir.frame_width > 0 { ir.frame_width as u32 } else { 0 },
frame_height: if ir.frame_height > 0 { ir.frame_height as u32 } else { 0 },
duration_millis: if ir.duration_millis > 0 { ir.duration_millis as u32 } else { 0 },
created_at: ir.created_at,
updated_at: ir.updated_at,
maybe_moderator_fields: Some(W2lResultModeratorFields {
template_creator_is_banned:
nullable_i8_to_bool(ir.maybe_template_creator_is_banned, false),
result_creator_is_banned_if_user:
nullable_i8_to_bool(ir.maybe_creator_is_banned, false),
result_creator_ip_address: ir.creator_ip_address,
result_creator_deleted_at: ir.user_deleted_at,
mod_deleted_at: ir.mod_deleted_at,
}),
};
Ok(Some(ir_for_response))
}
async fn select_including_deleted(
w2l_result_token: &str,
mysql_pool: &MySqlPool
) -> Result<W2lResultRecordRaw, sqlx::Error> {
sqlx::query_as!(
W2lResultRecordRaw,
r#"
SELECT
w2l_results.token as w2l_result_token,
w2l_results.maybe_tts_inference_result_token,
w2l_results.public_bucket_video_path,
w2l_templates.token as maybe_w2l_template_token,
w2l_templates.template_type,
w2l_templates.title as template_title,
users.token as maybe_creator_user_token,
users.username as maybe_creator_username,
users.display_name as maybe_creator_display_name,
users.email_gravatar_hash as maybe_creator_gravatar_hash,
users.is_banned as maybe_creator_is_banned,
template_users.token as maybe_template_creator_user_token,
template_users.username as maybe_template_creator_username,
template_users.display_name as maybe_template_creator_display_name,
template_users.email_gravatar_hash as maybe_template_creator_gravatar_hash,
template_users.is_banned as maybe_template_creator_is_banned,
w2l_results.creator_set_visibility,
w2l_results.file_size_bytes,
w2l_results.frame_width,
w2l_results.frame_height,
w2l_results.duration_millis,
w2l_results.created_at,
w2l_results.updated_at,
w2l_results.creator_ip_address,
w2l_results.user_deleted_at,
w2l_results.mod_deleted_at
FROM w2l_results
LEFT OUTER JOIN w2l_templates
ON w2l_results.maybe_w2l_template_token = w2l_templates.token
LEFT OUTER JOIN users
ON w2l_results.maybe_creator_user_token = users.token
LEFT OUTER JOIN users as template_users
ON w2l_templates.creator_user_token = template_users.token
WHERE
w2l_results.token = ?
"#,
w2l_result_token
)
.fetch_one(mysql_pool)
.await // TODO: This will return error if it doesn't exist
}
async fn select_without_deleted(
w2l_result_token: &str,
mysql_pool: &MySqlPool
) -> Result<W2lResultRecordRaw, sqlx::Error> {
sqlx::query_as!(
W2lResultRecordRaw,
r#"
SELECT
w2l_results.token as w2l_result_token,
w2l_results.maybe_tts_inference_result_token,
w2l_results.public_bucket_video_path,
w2l_templates.token as maybe_w2l_template_token,
w2l_templates.template_type,
w2l_templates.title as template_title,
users.token as maybe_creator_user_token,
users.username as maybe_creator_username,
users.display_name as maybe_creator_display_name,
users.email_gravatar_hash as maybe_creator_gravatar_hash,
users.is_banned as maybe_creator_is_banned,
template_users.token as maybe_template_creator_user_token,
template_users.username as maybe_template_creator_username,
template_users.display_name as maybe_template_creator_display_name,
template_users.email_gravatar_hash as maybe_template_creator_gravatar_hash,
template_users.is_banned as maybe_template_creator_is_banned,
w2l_results.creator_set_visibility,
w2l_results.file_size_bytes,
w2l_results.frame_width,
w2l_results.frame_height,
w2l_results.duration_millis,
w2l_results.created_at,
w2l_results.updated_at,
w2l_results.creator_ip_address,
w2l_results.user_deleted_at,
w2l_results.mod_deleted_at
FROM w2l_results
LEFT OUTER JOIN w2l_templates
ON w2l_results.maybe_w2l_template_token = w2l_templates.token
LEFT OUTER JOIN users
ON w2l_results.maybe_creator_user_token = users.token
LEFT OUTER JOIN users as template_users
ON w2l_templates.creator_user_token = template_users.token
WHERE
w2l_results.token = ?
AND w2l_results.user_deleted_at IS NULL
AND w2l_results.mod_deleted_at IS NULL
"#,
w2l_result_token
)
.fetch_one(mysql_pool)
.await // TODO: This will return error if it doesn't exist
}
@@ -1,58 +0,0 @@
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use sqlx::MySqlPool;
use errors::AnyhowResult;
pub struct W2lUploadTemplateJobStatusRecord {
pub job_token: String,
pub status: String,
pub attempt_count: i32,
pub maybe_template_token: Option<String>,
pub maybe_failure_reason: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
pub async fn get_w2l_template_upload_job_status(
job_token: &str,
mysql_pool: &MySqlPool,
) -> AnyhowResult<Option<W2lUploadTemplateJobStatusRecord>> {
// NB: Lookup failure is Err(RowNotFound).
// NB: Since this is publicly exposed, we don't query sensitive data.
let maybe_status = sqlx::query_as!(
W2lUploadTemplateJobStatusRecord,
r#"
SELECT
jobs.token as job_token,
jobs.status,
jobs.attempt_count,
jobs.on_success_result_token as maybe_template_token,
jobs.failure_reason as maybe_failure_reason,
jobs.created_at,
jobs.updated_at
FROM w2l_template_upload_jobs as jobs
WHERE jobs.token = ?
"#,
job_token
)
.fetch_one(mysql_pool)
.await; // TODO: This will return error if it doesn't exist
match maybe_status {
Ok(record) => Ok(Some(record)),
Err(err) => match err {
sqlx::Error::RowNotFound => Ok(None),
_ => Err(anyhow!("w2l template query error: {:?}", err)),
}
}
}
@@ -1,57 +0,0 @@
use anyhow::anyhow;
use sqlx::MySqlPool;
use errors::AnyhowResult;
use tokens::tokens::w2l_template_upload_jobs::W2lTemplateUploadJobToken;
pub struct InsertW2lTemplateUploadJobArgs<'a> {
pub uuid: &'a str,
pub creator_user_token: &'a str,
pub creator_ip_address: &'a str,
pub creator_set_visibility: &'a str,
pub title: &'a str,
pub template_type: &'a str,
pub download_url: &'a str,
pub mysql_pool: &'a MySqlPool,
}
// NB: Returns the new token
pub async fn insert_w2l_template_upload_job(args: InsertW2lTemplateUploadJobArgs<'_>) -> AnyhowResult<String> {
// This token is returned to the client.
let job_token = W2lTemplateUploadJobToken::generate().to_string();
let query_result = sqlx::query!(
r#"
INSERT INTO w2l_template_upload_jobs
SET
token = ?,
uuid_idempotency_token = ?,
creator_user_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
title = ?,
template_type = ?,
download_url = ?,
status = "pending"
"#,
&job_token,
args.uuid.to_string(),
args.creator_user_token.to_string(),
args.creator_ip_address.to_string(),
args.creator_set_visibility.to_string(),
args.title.to_string(),
args.template_type,
args.download_url,
)
.execute(args.mysql_pool)
.await;
let _record_id = match query_result {
Ok(res) => res.last_insert_id(),
Err(err) => {
return Err(anyhow!("failure to create w2l template upload job: {:?}", err));
}
};
Ok(job_token)
}
@@ -1,2 +0,0 @@
pub mod get_w2l_template_upload_job_status;
pub mod insert_w2l_template_upload_job;
@@ -1,46 +0,0 @@
use anyhow::anyhow;
use sqlx::MySqlPool;
use errors::AnyhowResult;
/// Just to query for existence
pub (crate) struct W2lTemplateExistenceRecord {
pub template_token: String,
}
pub async fn check_w2l_template_exists(template_token: &str, mysql_pool: &MySqlPool) -> AnyhowResult<bool>
{
let maybe_template = sqlx::query_as!(
W2lTemplateExistenceRecord,
r#"
SELECT
token as template_token
FROM w2l_templates
WHERE
token = ?
AND user_deleted_at IS NULL
AND mod_deleted_at IS NULL
"#,
&template_token
)
.fetch_one(mysql_pool)
.await;
let record_exists = match maybe_template {
Ok(_record) => {
true
},
Err(err) => {
match err {
sqlx::Error::RowNotFound => {
false
},
_ => {
return Err(anyhow!("query w2l template existence query error: {:?}", err));
}
}
}
};
Ok(record_exists)
}
@@ -1,95 +0,0 @@
use sqlx::MySqlPool;
use errors::AnyhowResult;
pub async fn delete_w2l_template_as_user(
template_token: &str,
creator_ip_address: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_templates
SET
creator_ip_address_last_update = ?,
user_deleted_at = CURRENT_TIMESTAMP
WHERE
token = ?
LIMIT 1
"#,
creator_ip_address,
template_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
pub async fn delete_w2l_template_as_mod(
template_token: &str,
mod_user_token: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_templates
SET
maybe_mod_user_token = ?,
mod_deleted_at = CURRENT_TIMESTAMP
WHERE
token = ?
LIMIT 1
"#,
mod_user_token,
template_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
pub async fn undelete_w2l_template_as_user(
template_token: &str,
creator_ip_address: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_templates
SET
creator_ip_address_last_update = ?,
user_deleted_at = NULL
WHERE
token = ?
LIMIT 1
"#,
creator_ip_address,
template_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
pub async fn undelete_w2l_template_as_mod(
template_token: &str,
mod_user_token: &str,
mysql_pool: &MySqlPool
) -> AnyhowResult<()> {
let _r = sqlx::query!(
r#"
UPDATE w2l_templates
SET
maybe_mod_user_token = ?,
mod_deleted_at = NULL
WHERE
token = ?
LIMIT 1
"#,
mod_user_token,
template_token,
)
.execute(mysql_pool)
.await?;
Ok(())
}
@@ -1,123 +0,0 @@
use anyhow::anyhow;
use sqlx::MySqlPool;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
pub struct EditW2lTemplateArgs<'a> {
pub w2l_template_token: &'a str,
pub title: Option<&'a str>,
pub description_markdown: Option<&'a str>,
pub description_rendered_html: Option<&'a str>,
pub creator_set_visibility: Visibility,
pub role_dependent_fields: CreatorOrModFields<'a>,
pub mysql_pool: &'a MySqlPool,
}
pub enum CreatorOrModFields<'a> {
CreatorFields {
creator_ip_address: &'a str,
},
ModFields(ModFields<'a>)
}
pub struct ModFields<'a> {
pub mod_user_token: &'a str,
pub is_public_listing_approved: bool,
pub is_locked_from_user_modification: bool,
pub is_locked_from_use: bool,
pub maybe_mod_comments: Option<&'a str>,
}
pub async fn edit_w2l_template(args: EditW2lTemplateArgs<'_>) -> AnyhowResult<()> {
let query_results = match args.role_dependent_fields {
CreatorOrModFields::CreatorFields { creator_ip_address } => {
// We need to store the IP address details.
sqlx::query!(
r#"
UPDATE w2l_templates
SET
title = ?,
description_markdown = ?,
description_rendered_html = ?,
creator_set_visibility = ?,
creator_ip_address_last_update = ?,
version = version + 1
WHERE token = ?
LIMIT 1
"#,
args.title,
args.description_markdown,
args.description_rendered_html,
args.creator_set_visibility.to_str(),
creator_ip_address,
args.w2l_template_token,
)
.execute(args.mysql_pool)
.await
},
CreatorOrModFields::ModFields(ref mod_fields) => {
sqlx::query!(
r#"
UPDATE w2l_templates
SET
title = ?,
description_markdown = ?,
description_rendered_html = ?,
creator_set_visibility = ?,
maybe_mod_user_token = ?,
version = version + 1
WHERE token = ?
LIMIT 1
"#,
args.title,
args.description_markdown,
args.description_rendered_html,
args.creator_set_visibility.to_str(),
mod_fields.mod_user_token,
args.w2l_template_token,
)
.execute(args.mysql_pool)
.await
.map_err(|err| {
anyhow!("update W2L template mod details (first query) error: {:?}", err)
})?;
// TODO: This is lazy and suboptimal af to UPDATE again.
// The reason we're doing this is because `sqlx` only does static type checking of queries
// with string literals. It does not support dynamic query building, thus the PREDICATES
// MUST BE HELD CONSTANT (at least in type signature). :(
sqlx::query!(
r#"
UPDATE w2l_templates
SET
is_public_listing_approved = ?,
is_locked_from_user_modification = ?,
is_locked_from_use = ?,
maybe_mod_comments = ?,
maybe_mod_user_token = ?,
version = version + 1
WHERE token = ?
LIMIT 1
"#,
mod_fields.is_public_listing_approved,
mod_fields.is_locked_from_user_modification,
mod_fields.is_locked_from_use,
mod_fields.maybe_mod_comments,
mod_fields.mod_user_token,
args.w2l_template_token
)
.execute(args.mysql_pool)
.await
},
};
match query_results {
Ok(_) => Ok(()),
Err(err) => Err(anyhow!("Update W2L template DB error: {:?}", err))
}
}
@@ -1,236 +0,0 @@
// NB: Incrementally getting rid of build warnings...
#![forbid(unused_imports)]
#![forbid(unused_mut)]
#![forbid(unused_variables)]
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::warn;
use sqlx::MySqlPool;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use crate::helpers::boolean_converters::{i8_to_bool, nullable_i8_to_optional_bool};
// FIXME: This is the old style of query scoping and shouldn't be copied.
// The moderator-only fields are good practice, though.
#[derive(Serialize)]
pub struct W2lTemplateRecordForResponse {
pub template_token: String,
pub template_type: String,
pub creator_user_token: String,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub title: String,
pub description_markdown: String,
pub description_rendered_html: String,
pub frame_width: u32,
pub frame_height: u32,
pub duration_millis: u32,
pub maybe_image_object_name: Option<String>,
pub maybe_video_object_name: Option<String>,
pub creator_set_visibility: Visibility,
pub is_public_listing_approved: Option<bool>,
pub is_locked_from_use: bool,
pub is_locked_from_user_modification: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub maybe_moderator_fields: Option<W2lTemplateModeratorFields>,
}
/// "Moderator-only fields" that we wouldn't want to expose to ordinary users.
/// It's the web endpoint controller's responsibility to clear these for non-mods.
#[derive(Serialize)]
pub struct W2lTemplateModeratorFields {
pub creator_is_banned: bool,
pub creator_ip_address_creation: String,
pub creator_ip_address_last_update: String,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
#[derive(Serialize)]
pub struct W2lTemplateRecordRaw {
pub template_token: String,
pub template_type: String,
pub creator_user_token: String,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub creator_is_banned: i8,
pub title: String,
pub description_markdown: String,
pub description_rendered_html: String,
pub frame_width: i32,
pub frame_height: i32,
pub duration_millis: i32,
pub maybe_public_bucket_preview_image_object_name: Option<String>,
pub maybe_public_bucket_preview_video_object_name: Option<String>,
pub creator_set_visibility: String,
pub is_public_listing_approved: Option<i8>,
pub is_locked_from_use: i8,
pub is_locked_from_user_modification: i8,
pub creator_ip_address_creation: String,
pub creator_ip_address_last_update: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
pub async fn select_w2l_template_by_token(
w2l_template_token: &str,
can_see_deleted: bool,
mysql_pool: &MySqlPool
) -> AnyhowResult<Option<W2lTemplateRecordForResponse>> {
let maybe_record = if can_see_deleted {
select_including_deleted(w2l_template_token, mysql_pool).await
} else {
select_without_deleted(w2l_template_token, mysql_pool).await
};
let template : W2lTemplateRecordRaw = match maybe_record {
Ok(template) => template,
Err(ref err) => {
match err {
sqlx::Error::RowNotFound => {
warn!("w2l template not found: {:?}", &err);
return Ok(None);
},
_ => {
warn!("w2l template query error: {:?}", &err);
return Err(anyhow!("database error"));
}
}
}
};
let template_for_response = W2lTemplateRecordForResponse {
template_token: template.template_token,
template_type: template.template_type,
creator_user_token: template.creator_user_token,
creator_username: template.creator_username,
creator_display_name: template.creator_display_name,
creator_gravatar_hash: template.creator_gravatar_hash,
title: template.title,
description_markdown: template.description_markdown,
description_rendered_html: template.description_rendered_html,
frame_width: if template.frame_width > 0 { template.frame_width as u32 } else { 0 },
frame_height: if template.frame_height > 0 { template.frame_height as u32 } else { 0 },
duration_millis: if template.duration_millis > 0 { template.duration_millis as u32 } else { 0 },
maybe_image_object_name: template.maybe_public_bucket_preview_image_object_name,
maybe_video_object_name: template.maybe_public_bucket_preview_video_object_name,
// NB: Fail open/public with creator_set_visibility since we're already looking at it
creator_set_visibility: Visibility::from_str(&template.creator_set_visibility)
.unwrap_or(Visibility::Public),
is_public_listing_approved: nullable_i8_to_optional_bool(template.is_public_listing_approved),
is_locked_from_use: i8_to_bool(template.is_locked_from_use),
is_locked_from_user_modification: i8_to_bool(template.is_locked_from_user_modification),
created_at: template.created_at,
updated_at: template.updated_at,
maybe_moderator_fields: Some(W2lTemplateModeratorFields {
creator_is_banned: i8_to_bool(template.creator_is_banned),
creator_ip_address_creation: template.creator_ip_address_creation,
creator_ip_address_last_update: template.creator_ip_address_last_update,
user_deleted_at: template.user_deleted_at,
mod_deleted_at: template.mod_deleted_at,
}),
};
Ok(Some(template_for_response))
}
async fn select_including_deleted(
w2l_template_token: &str,
mysql_pool: &MySqlPool
) -> Result<W2lTemplateRecordRaw, sqlx::Error> {
sqlx::query_as!(
W2lTemplateRecordRaw,
r#"
SELECT
w2l.token as template_token,
w2l.template_type,
w2l.creator_user_token,
users.is_banned as creator_is_banned,
users.username as creator_username,
users.display_name as creator_display_name,
users.email_gravatar_hash as creator_gravatar_hash,
w2l.title,
w2l.description_markdown,
w2l.description_rendered_html,
w2l.frame_width,
w2l.frame_height,
w2l.duration_millis,
w2l.maybe_public_bucket_preview_image_object_name,
w2l.maybe_public_bucket_preview_video_object_name,
w2l.creator_set_visibility,
w2l.is_public_listing_approved,
w2l.is_locked_from_use,
w2l.is_locked_from_user_modification,
w2l.creator_ip_address_creation,
w2l.creator_ip_address_last_update,
w2l.created_at,
w2l.updated_at,
w2l.user_deleted_at,
w2l.mod_deleted_at
FROM w2l_templates as w2l
JOIN users
ON users.token = w2l.creator_user_token
WHERE w2l.token = ?
"#,
w2l_template_token
)
.fetch_one(mysql_pool)
.await // TODO: This will return error if it doesn't exist
}
async fn select_without_deleted(
w2l_template_token: &str,
mysql_pool: &MySqlPool
) -> Result<W2lTemplateRecordRaw, sqlx::Error> {
sqlx::query_as!(
W2lTemplateRecordRaw,
r#"
SELECT
w2l.token as template_token,
w2l.template_type,
w2l.creator_user_token,
users.is_banned as creator_is_banned,
users.username as creator_username,
users.display_name as creator_display_name,
users.email_gravatar_hash as creator_gravatar_hash,
w2l.title,
w2l.description_markdown,
w2l.description_rendered_html,
w2l.frame_width,
w2l.frame_height,
w2l.duration_millis,
w2l.maybe_public_bucket_preview_image_object_name,
w2l.maybe_public_bucket_preview_video_object_name,
w2l.creator_set_visibility,
w2l.is_public_listing_approved,
w2l.is_locked_from_use,
w2l.is_locked_from_user_modification,
w2l.creator_ip_address_creation,
w2l.creator_ip_address_last_update,
w2l.created_at,
w2l.updated_at,
w2l.user_deleted_at,
w2l.mod_deleted_at
FROM w2l_templates as w2l
JOIN users
ON users.token = w2l.creator_user_token
WHERE
w2l.token = ?
AND w2l.user_deleted_at IS NULL
AND w2l.mod_deleted_at IS NULL
"#,
w2l_template_token
)
.fetch_one(mysql_pool)
.await // TODO: This will return error if it doesn't exist
}
@@ -1,103 +0,0 @@
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use sqlx::MySqlPool;
use errors::AnyhowResult;
pub struct PendingW2lTemplateRow {
pub template_token: String,
pub title: String,
pub template_type: String,
pub duration_millis: i32,
pub frame_width: i32,
pub frame_height: i32,
pub creator_user_token: String,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub created_at: DateTime<Utc>,
}
pub async fn list_pending_w2l_templates(
mysql_pool: &MySqlPool
) -> AnyhowResult<Vec<PendingW2lTemplateRow>> {
// NB: Lookup failure is Err(RowNotFound).
let maybe_results = sqlx::query_as!(
PendingW2lTemplatesRaw,
r#"
SELECT
w2l_templates.token as template_token,
w2l_templates.title,
w2l_templates.template_type,
w2l_templates.duration_millis,
w2l_templates.frame_width,
w2l_templates.frame_height,
w2l_templates.creator_user_token,
users.username AS creator_username,
users.display_name AS creator_display_name,
users.email_gravatar_hash AS creator_gravatar_hash,
w2l_templates.created_at
FROM
w2l_templates
JOIN
users
ON
users.token = w2l_templates.creator_user_token
WHERE
w2l_templates.is_public_listing_approved IS NULL
AND w2l_templates.user_deleted_at IS NULL
AND w2l_templates.mod_deleted_at IS NULL
AND w2l_templates.is_locked_from_use IS FALSE
"#,
)
.fetch_all(mysql_pool)
.await;
let results : Vec<PendingW2lTemplatesRaw> = match maybe_results {
Ok(results) => results,
Err(err) => {
match err {
sqlx::Error::RowNotFound => {
Vec::new()
},
_ => {
return Err(anyhow!("database err listing pending w2l templates: {:?}", err));
}
}
}
};
let results = results.into_iter().map(|r| {
PendingW2lTemplateRow {
template_token: r.template_token,
title: r.title,
template_type: r.template_type,
duration_millis: r.duration_millis,
frame_width: r.frame_width,
frame_height: r.frame_height,
creator_user_token: r.creator_user_token,
creator_username: r.creator_username,
creator_display_name: r.creator_display_name,
creator_gravatar_hash: r.creator_gravatar_hash,
created_at: r.created_at,
}
}).collect::<Vec<PendingW2lTemplateRow>>();
Ok(results)
}
#[derive(Serialize)]
pub (crate) struct PendingW2lTemplatesRaw {
pub template_token: String,
pub title: String,
pub template_type: String,
pub duration_millis: i32,
pub frame_width: i32,
pub frame_height: i32,
pub creator_user_token: String,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub created_at: DateTime<Utc>,
}
@@ -1,251 +0,0 @@
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::{info, warn};
use sqlx::{Error, MySqlPool};
use errors::AnyhowResult;
use crate::helpers::boolean_converters::nullable_i8_to_optional_bool;
// FIXME: This is the old style of query scoping and shouldn't be copied.
#[derive(Serialize, Clone)]
pub struct W2lTemplateRecordForList {
pub template_token: String,
pub template_type: String,
pub creator_user_token: String,
pub creator_username: String,
pub creator_display_name: String,
pub title: String,
pub frame_width: u32,
pub frame_height: u32,
pub duration_millis: u32,
pub maybe_image_object_name: Option<String>,
pub maybe_video_object_name: Option<String>,
pub is_public_listing_approved: Option<bool>, // converted
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
struct RawW2lTemplateRecordForList {
pub template_token: String,
pub template_type: String,
pub creator_user_token: String,
pub creator_username: String,
pub creator_display_name: String,
pub title: String,
pub frame_width: i32,
pub frame_height: i32,
pub duration_millis: i32,
pub maybe_public_bucket_preview_image_object_name: Option<String>,
pub maybe_public_bucket_preview_video_object_name: Option<String>,
pub is_public_listing_approved: Option<i8>, // NB: needs conversion
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
pub async fn list_w2l_templates(
mysql_pool: &MySqlPool,
scope_creator_username: Option<&str>,
require_mod_approved: bool
) -> AnyhowResult<Vec<W2lTemplateRecordForList>> {
let maybe_templates = match scope_creator_username {
Some(username) => {
list_w2l_templates_creator_scoped(mysql_pool, username, require_mod_approved)
.await
},
None => {
list_w2l_templates_for_all_creators(mysql_pool, require_mod_approved)
.await
},
};
let templates : Vec<RawW2lTemplateRecordForList> = match maybe_templates {
Ok(templates) => {
info!("Template length: {}", templates.len());
templates
},
Err(err) => {
warn!("Error: {:?}", err);
return match err {
Error::RowNotFound => {
Ok(Vec::new())
},
_ => {
warn!("w2l template list query error: {:?}", err);
Err(anyhow!("w2l template list query error"))
}
}
}
};
Ok(templates.into_iter()
.map(|template| {
W2lTemplateRecordForList {
template_token: template.template_token,
template_type: template.template_type,
creator_user_token: template.creator_user_token,
creator_username: template.creator_username,
creator_display_name: template.creator_display_name,
title: template.title,
frame_width: if template.frame_width > 0 { template.frame_width as u32 } else { 0 },
frame_height: if template.frame_height > 0 { template.frame_height as u32 } else { 0 },
duration_millis: if template.duration_millis > 0 { template.duration_millis as u32 } else { 0 },
maybe_image_object_name: template.maybe_public_bucket_preview_image_object_name,
maybe_video_object_name: template.maybe_public_bucket_preview_video_object_name,
is_public_listing_approved: nullable_i8_to_optional_bool(template.is_public_listing_approved),
created_at: template.created_at,
updated_at: template.updated_at,
}
})
.collect::<Vec<W2lTemplateRecordForList>>())
}
async fn list_w2l_templates_for_all_creators(
mysql_pool: &MySqlPool,
require_mod_approved: bool
) -> Result<Vec<RawW2lTemplateRecordForList>, Error> {
// TODO: There has to be a better way.
// Sqlx doesn't like anything except string literals.
let maybe_templates = if require_mod_approved {
info!("listing w2l templates for everyone; mod-approved only");
sqlx::query_as!(
RawW2lTemplateRecordForList,
r#"
SELECT
w2l.token as template_token,
w2l.template_type,
w2l.creator_user_token,
users.username as creator_username,
users.display_name as creator_display_name,
w2l.title,
w2l.frame_width,
w2l.frame_height,
w2l.duration_millis,
w2l.maybe_public_bucket_preview_image_object_name,
w2l.maybe_public_bucket_preview_video_object_name,
w2l.is_public_listing_approved,
w2l.created_at,
w2l.updated_at
FROM w2l_templates as w2l
JOIN users
ON users.token = w2l.creator_user_token
WHERE
w2l.is_public_listing_approved IS TRUE
AND w2l.user_deleted_at IS NULL
AND w2l.mod_deleted_at IS NULL
"#)
.fetch_all(mysql_pool)
.await?
} else {
info!("listing w2l templates for everyone; all");
sqlx::query_as!(
RawW2lTemplateRecordForList,
r#"
SELECT
w2l.token as template_token,
w2l.template_type,
w2l.creator_user_token,
users.username as creator_username,
users.display_name as creator_display_name,
w2l.title,
w2l.frame_width,
w2l.frame_height,
w2l.duration_millis,
w2l.maybe_public_bucket_preview_image_object_name,
w2l.maybe_public_bucket_preview_video_object_name,
w2l.is_public_listing_approved,
w2l.created_at,
w2l.updated_at
FROM w2l_templates as w2l
JOIN users
ON users.token = w2l.creator_user_token
WHERE
w2l.user_deleted_at IS NULL
AND w2l.mod_deleted_at IS NULL
"#)
.fetch_all(mysql_pool)
.await?
};
Ok(maybe_templates)
}
async fn list_w2l_templates_creator_scoped(
mysql_pool: &MySqlPool,
scope_creator_username: &str,
require_mod_approved: bool
) -> Result<Vec<RawW2lTemplateRecordForList>, Error> {
// TODO: There has to be a better way.
// Sqlx doesn't like anything except string literals.
let maybe_templates = if require_mod_approved {
info!("listing w2l templates for user; mod-approved only");
sqlx::query_as!(
RawW2lTemplateRecordForList,
r#"
SELECT
w2l.token as template_token,
w2l.template_type,
w2l.creator_user_token,
users.username as creator_username,
users.display_name as creator_display_name,
w2l.title,
w2l.frame_width,
w2l.frame_height,
w2l.duration_millis,
w2l.maybe_public_bucket_preview_image_object_name,
w2l.maybe_public_bucket_preview_video_object_name,
w2l.is_public_listing_approved,
w2l.created_at,
w2l.updated_at
FROM w2l_templates as w2l
JOIN users
ON
users.token = w2l.creator_user_token
WHERE
users.username = ?
AND w2l.is_public_listing_approved IS TRUE
AND w2l.user_deleted_at IS NULL
AND w2l.mod_deleted_at IS NULL
"#,
scope_creator_username)
.fetch_all(mysql_pool)
.await?
} else {
info!("listing w2l templates for user; all");
sqlx::query_as!(
RawW2lTemplateRecordForList,
r#"
SELECT
w2l.token as template_token,
w2l.template_type,
w2l.creator_user_token,
users.username as creator_username,
users.display_name as creator_display_name,
w2l.title,
w2l.frame_width,
w2l.frame_height,
w2l.duration_millis,
w2l.maybe_public_bucket_preview_image_object_name,
w2l.maybe_public_bucket_preview_video_object_name,
w2l.is_public_listing_approved,
w2l.created_at,
w2l.updated_at
FROM w2l_templates as w2l
JOIN users
ON
users.token = w2l.creator_user_token
WHERE
users.username = ?
AND w2l.user_deleted_at IS NULL
AND w2l.mod_deleted_at IS NULL
"#,
scope_creator_username)
.fetch_all(mysql_pool)
.await?
};
Ok(maybe_templates)
}
@@ -1,7 +0,0 @@
pub mod check_w2l_template_exists;
pub mod delete_w2l_template_various_scopes;
pub mod edit_w2l_template;
pub mod get_w2l_template;
pub mod list_pending_w2l_templates;
pub mod list_w2l_templates;
pub mod set_w2l_template_mod_approval;
@@ -1,35 +0,0 @@
use anyhow::anyhow;
use sqlx::MySqlPool;
use errors::AnyhowResult;
pub async fn set_w2l_template_mod_approval(
w2l_template_token: &str,
mod_user_token: &str,
is_approved: bool,
mysql_pool: &MySqlPool,
) -> AnyhowResult<()> {
let query_result = sqlx::query!(
r#"
UPDATE w2l_templates
SET
is_public_listing_approved = ?,
maybe_mod_user_token = ?
WHERE
token = ?
LIMIT 1
"#,
is_approved,
mod_user_token,
w2l_template_token,
)
.execute(mysql_pool)
.await;
match query_result {
Ok(_) => Ok(()),
Err(err) => Err(anyhow!("error setting w2l mod approval status: {:?}", err)),
}
}
@@ -1,60 +0,0 @@
[package]
name = "w2l-download-job"
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
publish = false
[[bin]]
name = "w2l-download-job"
path = "src/main.rs"
[package.metadata.cargo-udeps.ignore]
normal = ["workspace-build-acceleration"]
[dependencies]
# Workspace hack (faster compile times)
workspace-build-acceleration.workspace = true
# Internal
bucket_paths.workspace = true
cloud_storage = { path = "../../../../api_clients/cloud_storage" }
config = { path = "../../../../lib/deprecated/config" }
easyenv = { path = "../../../../lib/easyenv" }
errors.workspace = true
filesys.workspace = true
google_drive_downloader = { path = "../../../../api_clients/google_drive_downloader" }
hashing = { path = "../../../../lib/files/hashing" }
jobs_common = { path = "../../../../lib/jobs_common" }
mysql_queries = { path = "../../../../schema/database/mysql_queries" }
shared_env_var_config.workspace = true
# External
anyhow.workspace = true
chrono.workspace = true
dotenv.workspace = true
hostname.workspace = true
log.workspace = true
subprocess = "0.2.9"
tempdir.workspace = true
sqlx = { version = "0.7.4", features = [ "mysql", "runtime-tokio-rustls", "chrono" ] }
# Redis
r2d2_redis.workspace = true
# Runtime
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
tokio.workspace = true
# NB: Hyper is just for HTTP client use in jobs. I'd use Actix client, but I need tokio runtime
# NB: Furthermore, the Tokio runtime is old, so I have to use an older Hyper.
hyper = { version = "1.3.1" }
# Serialization
serde.workspace = true
serde_derive.workspace = true
serde_json.workspace = true

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