Compare commits

...
Author SHA1 Message Date
salt d39962491f fix some warnings (mostly unnecessary mut) 2023-12-07 18:36:51 -08:00
Brandon Thomas eedbc346fe Merge pull request #194 from storytold/brandon-tts-as-media-file
Save TTS results as media files
2023-12-06 23:33:51 -05:00
Brandon Thomas 7976f68fd0 Save TTS results as media files 2023-12-06 23:31:47 -05:00
Brandon Thomas 8a6678c7f5 move workspace-hack under crates/ 2023-12-06 02:12:57 -05:00
Brandon Thomas d9b1c8c36b Merge pull request #192 from storytold/brandon-upgrade-chrono-vendored-limitation
upgrade chrono with vendored limitation
2023-12-05 21:54:36 -05:00
Brandon Thomas fc122cb996 upgrade chrono with vendored limitation 2023-12-05 21:54:06 -05:00
Brandon Thomas e0e85fed5f Merge pull request #191 from storytold/brandon-vendor-limitation
vendor `limitation` crate
2023-12-05 20:58:27 -05:00
Brandon Thomas 092745166e vendor limitation crate
The limitation crate is four years old, stuck at 0.1.1. It looks unlikey
to be updated by the maintainer.

Upgrades to chrono and other libraries have broken limitation, so we're
likely now on the hook for maintaining this.
2023-12-05 20:56:22 -05:00
Brandon Thomas ea859bfc1e Merge pull request #190 from storytold/brandon-revert-chrono-upgrade
Revert "Bump chrono from 0.4.22 to 0.4.31"
2023-12-05 20:40:37 -05:00
Brandon Thomas 92e0b1e9f4 Revert "Bump chrono from 0.4.22 to 0.4.31"
This reverts commit 4856ac28aa.
2023-12-05 20:40:09 -05:00
ArEnSc d52d3f993a Merge pull request #189 from storytold/feature/api-spec
Feature/api spec
2023-12-05 20:27:57 -05:00
Michael Chung 0033af73ce Feedback addressed! 2023-12-05 20:26:07 -05:00
Brandon Thomas 514f80b884 Merge pull request #184 from storytold/dependabot/cargo/rustix-0.38.26
Bump rustix from 0.38.25 to 0.38.26
2023-12-05 19:22:24 -05:00
Brandon Thomas 74c548c02f Merge pull request #182 from storytold/dependabot/cargo/chrono-0.4.31
Bump chrono from 0.4.22 to 0.4.31
2023-12-05 19:21:53 -05:00
Brandon Thomas 5fe09a182f Merge pull request #185 from storytold/dependabot/cargo/lettre-0.11.2
Bump lettre from 0.11.1 to 0.11.2
2023-12-05 19:21:40 -05:00
dependabot[bot] 4856ac28aa Bump chrono from 0.4.22 to 0.4.31
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.22 to 0.4.31.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.22...v0.4.31)

---
updated-dependencies:
- dependency-name: chrono
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-06 00:19:36 +00:00
Brandon Thomas 404853e129 cleanup misleading old comment 2023-12-05 19:16:55 -05:00
Michael Chung b5fcc3cdfa Added documentation about the documentation 2023-12-05 19:14:02 -05:00
Brandon Thomas 300ac56ab7 Merge pull request #188 from storytold/brandon-media-files-global-list-fixed
global list of media files
2023-12-05 19:11:20 -05:00
Brandon Thomas e32f8094e5 global list of media files 2023-12-05 19:09:42 -05:00
Michael Chung e986a44e9d documentation system open api spec. 2023-12-05 19:00:44 -05:00
Brandon Thomas 642e17a77d Merge pull request #187 from storytold/brandon-fix-sqlx-query-builder
Fix QueryBuilder with respect to column names and type juggling
2023-12-05 18:31:13 -05:00
Brandon Thomas 36f3003576 Fix QueryBuilder with respect to column names and type juggling 2023-12-05 18:30:26 -05:00
Brandon Thomas b9f604dd18 reusable pagination types 2023-12-04 23:11:41 -05:00
Brandon Thomas e6f5ecb980 Merge pull request #186 from storytold/brandon-list-media-files-for-user
list media files for user
2023-12-04 22:02:53 -05:00
Brandon Thomas 2e3ff8a730 list media files for user 2023-12-04 21:59:39 -05:00
dependabot[bot] ac13be2900 Bump lettre from 0.11.1 to 0.11.2
Bumps [lettre](https://github.com/lettre/lettre) from 0.11.1 to 0.11.2.
- [Release notes](https://github.com/lettre/lettre/releases)
- [Changelog](https://github.com/lettre/lettre/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lettre/lettre/compare/v0.11.1...v0.11.2)

---
updated-dependencies:
- dependency-name: lettre
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 22:30:26 +00:00
dependabot[bot] b55435d992 Bump rustix from 0.38.25 to 0.38.26
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.38.25 to 0.38.26.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.25...v0.38.26)

---
updated-dependencies:
- dependency-name: rustix
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 22:30:06 +00:00
Brandon Thomas 28770ef736 fix query issue 2023-12-04 05:00:46 -05:00
Brandon Thomas 894084fba6 Merge pull request #181 from storytold/brandon-queue-controls
Kill inference jobs (mod endpoint)
2023-12-04 03:54:05 -05:00
Brandon Thomas 4bf1a25fbb Kill inference jobs (mod endpoint) 2023-12-04 03:46:29 -05:00
Brandon Thomas b0a9342194 updated queue stats 2023-12-01 07:09:23 -05:00
Brandon Thomas 3cc1ea6935 capture stderr for svc and rvc 2023-12-01 01:36:33 -05:00
Brandon Thomas b74cf7853d fix web break 2023-11-30 22:46:35 -05:00
Brandon Thomas 3cdce86162 warn on slow batch queries 2023-11-30 17:25:23 -05:00
Brandon Thomas b0a87e83a0 log batch index 2023-11-30 17:19:23 -05:00
Brandon Thomas 979c234ed2 cleanup logging 2023-11-30 16:27:25 -05:00
Brandon Thomas 4837106d37 distinguish logs 2023-11-30 16:10:01 -05:00
Brandon Thomas cfd92e814d Merge pull request #166 from storytold/dependabot/cargo/env_logger-0.10.1
Bump env_logger from 0.7.1 to 0.10.1
2023-11-30 16:02:23 -05:00
Brandon Thomas 6d27214a14 codegen 2023-11-30 15:50:05 -05:00
Brandon Thomas b628fb0a11 premium TTS duration 2023-11-30 15:21:07 -05:00
dependabot[bot] 456b9e1ce6 Bump env_logger from 0.7.1 to 0.10.1
Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.7.1 to 0.10.1.
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/v0.7.1...v0.10.1)

---
updated-dependencies:
- dependency-name: env_logger
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 09:35:18 +00:00
Brandon Thomas 6f7b6da595 Merge pull request #167 from storytold/dependabot/cargo/rand-0.8.5
Bump rand from 0.7.3 to 0.8.5
2023-11-30 04:33:54 -05:00
Brandon Thomas 18ad28135f safe delete 2023-11-30 02:36:33 -05:00
Brandon Thomas ff4a3115d2 clear up more directories when file system is full 2023-11-30 02:34:33 -05:00
dependabot[bot] ccae943037 Bump rand from 0.7.3 to 0.8.5
Bumps [rand](https://github.com/rust-random/rand) from 0.7.3 to 0.8.5.
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.7.3...0.8.5)

---
updated-dependencies:
- dependency-name: rand
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 07:32:36 +00:00
Brandon Thomas 12ef105ced fix errors 2023-11-30 02:27:08 -05:00
Brandon Thomas b27070e23e get rid of more of container_common 2023-11-30 02:25:16 -05:00
Brandon Thomas 8e45a4ea45 delete mod 2023-11-30 02:05:15 -05:00
Brandon Thomas a669ac7f03 move remaining container_common::files -> filesys crate 2023-11-30 02:04:41 -05:00
Brandon Thomas b5ed9acdd4 move check_directory_exists to filesys crate 2023-11-30 01:56:55 -05:00
Brandon Thomas ff2aaa9f3d move check_file_exists to filesys crate 2023-11-30 01:53:42 -05:00
Brandon Thomas f93421eadc keep IoError around; better casting 2023-11-30 01:35:48 -05:00
Brandon Thomas b82ffcce86 much more StorageFull error ! 2023-11-30 01:26:03 -05:00
Brandon Thomas e2c5839d01 surface storage full errors 2023-11-30 01:05:26 -05:00
Brandon Thomas 896e8591ba cleanup 2023-11-29 23:10:15 -05:00
Brandon Thomas 19dcfdc629 cleanup 2023-11-29 22:51:12 -05:00
Brandon Thomas cec7bce450 try copy instead 2023-11-29 22:49:00 -05:00
Brandon Thomas 6cc3062da8 don't fail if file is gone (not sure why this happens) 2023-11-29 22:01:53 -05:00
Brandon Thomas efdd03bbbd logging 2023-11-29 21:50:30 -05:00
Brandon Thomas c207356ac5 cleanup retry 2023-11-29 21:44:20 -05:00
Brandon Thomas 3243cc51b7 try to delete and re-copy 2023-11-29 21:36:47 -05:00
Brandon Thomas ee4af2976f flag to permit cold filesystem cache 2023-11-29 21:26:03 -05:00
Brandon Thomas 4fb2a38c68 report temp file size 2023-11-29 21:10:01 -05:00
Brandon Thomas a549ceb609 check vocoder and synthesizer sizes 2023-11-29 20:53:00 -05:00
Brandon Thomas 003f0cdeea struct args for downloader (safer) 2023-11-29 20:46:33 -05:00
Brandon Thomas 9e0772141a download file size check and logging 2023-11-29 20:25:37 -05:00
Brandon Thomas 542b79dd90 log http errors 2023-11-29 19:49:52 -05:00
Brandon Thomas 363f8cbc96 debug log statements, FileCacheDir (not yet used) 2023-11-29 19:28:32 -05:00
Brandon Thomas f2e75f8637 rename files across fs devices 2023-11-29 18:46:00 -05:00
Brandon Thomas f48cbb7978 fix 2023-11-29 18:16:45 -05:00
Brandon Thomas edd5cd6156 Merge pull request #179 from storytold/brandon-fix-job-pathing
Brandon fix job pathing
2023-11-29 17:49:39 -05:00
Brandon Thomas 37c016cecb "semi persistent dir" needs cleanup, this is confusing 2023-11-29 17:48:29 -05:00
Brandon Thomas 1a3e111dd6 Fix job pathing for outage and to make easier to manage 2023-11-29 17:30:03 -05:00
Brandon Thomas 0c456d957c fix build errors 2023-11-29 15:46:43 -05:00
Brandon Thomas 85ecce7b38 comments 2023-11-29 03:07:07 -05:00
Brandon Thomas 2f1d682438 Merge pull request #176 from storytold/nov-29-mithoo
fail model deleted inference jobs
2023-11-29 02:44:38 -05:00
Brandon Thomas c6fbfaa6ba fix test failures and nits 2023-11-29 02:43:31 -05:00
Brandon Thomas 038401bff4 Merge pull request #177 from storytold/brandon-revert-sha2-bump
Revert "Bump sha2 from 0.9.9 to 0.10.8"
2023-11-29 02:29:16 -05:00
Brandon Thomas e1c7231d96 Revert "Bump sha2 from 0.9.9 to 0.10.8"
This reverts commit 951afc2e5d.
2023-11-29 02:28:51 -05:00
kasisnu 1e11fdb35d fail model deleted inference jobs 2023-11-29 12:43:49 +05:30
Brandon Thomas 74c477b045 Merge pull request #169 from storytold/dependabot/cargo/sha2-0.10.8
Bump sha2 from 0.9.9 to 0.10.8
2023-11-28 21:37:50 -05:00
Brandon Thomas 042fa1574d Merge pull request #168 from storytold/dependabot/cargo/time-0.3.30
Bump time from 0.2.27 to 0.3.30
2023-11-28 21:37:26 -05:00
Brandon Thomas 4387e6326f LFU cache in TT2 inference-job 2023-11-28 17:47:46 -05:00
Brandon Thomas 3ad2b744b7 test comment out Dockerfile /etc/ssl copy 2023-11-28 15:42:24 -05:00
Brandon Thomas 8bf85b637b notes on dependencies 2023-11-28 15:40:26 -05:00
Brandon Thomas 50c3b5ed65 codegen db 2023-11-28 15:23:43 -05:00
Brandon Thomas df15395bf7 fix build error 2023-11-28 15:08:39 -05:00
Brandon Thomas 5666d58da0 fix SSL problem? 2023-11-28 14:54:53 -05:00
dependabot[bot] 0a85e9c581 Bump time from 0.2.27 to 0.3.30
Bumps [time](https://github.com/time-rs/time) from 0.2.27 to 0.3.30.
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.2.27...v0.3.30)

---
updated-dependencies:
- dependency-name: time
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 16:45:21 +00:00
ArEnSc bd0ce25d94 Merge pull request #151 from storytold/feature/weights_queries
Feature/weights queries
2023-11-28 11:43:00 -05:00
dependabot[bot] 951afc2e5d Bump sha2 from 0.9.9 to 0.10.8
Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.9 to 0.10.8.
- [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.9.9...sha2-v0.10.8)

---
updated-dependencies:
- dependency-name: sha2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 22:32:08 +00:00
236 changed files with 6990 additions and 1272 deletions
@@ -1,12 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n inference_category = ?,\n maybe_model_type = ?,\n maybe_model_token = ?,\n\n maybe_input_source_token = ?,\n maybe_input_source_token_type = ?,\n\n maybe_raw_inference_text = ?,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n priority_level = ?,\n is_keepalive_required = ?,\n\n is_debug_request = ?,\n maybe_routing_tag = ?,\n\n status = \"pending\"\n ",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n inference_category = ?,\n maybe_model_type = ?,\n maybe_model_token = ?,\n\n maybe_input_source_token = ?,\n maybe_input_source_token_type = ?,\n\n maybe_raw_inference_text = ?,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n priority_level = ?,\n is_keepalive_required = ?,\n max_duration_seconds = ?,\n\n is_debug_request = ?,\n maybe_routing_tag = ?,\n\n status = \"pending\"\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 17
"Right": 18
},
"nullable": []
},
"hash": "b1750559783bcd55b2ae139372a4782ae363787a840a32f5c17c8408dbf15bc7"
"hash": "0d780caac7560f84efb50bd2ed876cbdd728b32e26b73dfbb3009ada12985405"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\n INSERT INTO model_weights\n SET\n token = ?,\n weights_type = ?,\n weights_category = ?,\n title = ?,\n maybe_thumbnail_token = ?,\n description_markdown = ?,\n description_rendered_html = ?,\n creator_user_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n maybe_last_update_user_token = ?,\n original_download_url = ?,\n original_filename = ?,\n file_size_bytes = ?,\n file_checksum_sha2 = ?,\n private_bucket_hash = ?,\n maybe_private_bucket_prefix = ?,\n maybe_private_bucket_extension = ?,\n cached_user_ratings_total_count = ?,\n cached_user_ratings_positive_count = ?,\n cached_user_ratings_negative_count = ?,\n maybe_cached_user_ratings_ratio = ?,\n version = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 23
},
"nullable": []
},
"hash": "274cfb1e3caca706e3dbc3d95064e0f4b354c936f8de948070854920f265cc41"
}
@@ -0,0 +1,355 @@
{
"db_name": "MySQL",
"query": "\n SELECT \n mw.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n mw.title,\n mw.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n mw.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n mw.maybe_thumbnail_token,\n mw.description_markdown,\n mw.description_rendered_html,\n users.token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_email_gravatar_hash,\n mw.creator_ip_address,\n mw.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n mw.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n mw.original_download_url,\n mw.original_filename,\n mw.file_size_bytes,\n mw.file_checksum_sha2,\n mw.private_bucket_hash,\n mw.maybe_private_bucket_prefix,\n mw.maybe_private_bucket_extension,\n mw.cached_user_ratings_negative_count,\n mw.cached_user_ratings_positive_count,\n mw.cached_user_ratings_total_count,\n mw.maybe_cached_user_ratings_ratio,\n mw.cached_user_ratings_last_updated_at,\n mw.version,\n mw.created_at,\n mw.updated_at,\n mw.user_deleted_at,\n mw.mod_deleted_at\n FROM model_weights as mw\n JOIN users\n ON users.token = mw.creator_user_token\n WHERE\n users.username = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_thumbnail_token",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 5,
"name": "description_markdown",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 7,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 8,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 9,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 10,
"name": "creator_email_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 11,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 12,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 13,
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 14,
"name": "original_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 15,
"name": "original_filename",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 16,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 17,
"name": "file_checksum_sha2",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 18,
"name": "private_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 19,
"name": "maybe_private_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 20,
"name": "maybe_private_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 21,
"name": "cached_user_ratings_negative_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 22,
"name": "cached_user_ratings_positive_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 23,
"name": "cached_user_ratings_total_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 24,
"name": "maybe_cached_user_ratings_ratio",
"type_info": {
"type": "Float",
"flags": "",
"char_set": 63,
"max_size": 12
}
},
{
"ordinal": 25,
"name": "cached_user_ratings_last_updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 26,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 27,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 28,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 29,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 30,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
true,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
false,
true,
true,
false,
false,
false,
true,
false,
false,
false,
false,
true,
true
]
},
"hash": "3d586592422727dcc928574966bdf5081ac69fdbb856fffcbd68187fd99c4642"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nUPDATE model_weights\nSET\n mod_deleted_at = NULL\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "3dfc7f22c16543116c4ca17f5bee0336f5cfa1522681ba1bb6b1874cd8f13297"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\n UPDATE model_weights\n SET\n title = ?,\n description_markdown = ?,\n maybe_thumbnail_token = ?,\n description_rendered_html = ?,\n creator_set_visibility = ?,\n version = version + 1\n WHERE token = ?\n LIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 6
},
"nullable": []
},
"hash": "4ed42766cc0ca2234b7bc1837d645d05198d483564b39a2a8b8034df25e287a4"
}
@@ -0,0 +1,322 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_thumbnail_token,\n wt.description_markdown,\n wt.description_rendered_html,\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n wt.private_bucket_hash,\n wt.maybe_private_bucket_prefix,\n wt.maybe_private_bucket_extension,\n wt.cached_user_ratings_negative_count,\n wt.cached_user_ratings_positive_count,\n wt.cached_user_ratings_total_count,\n wt.maybe_cached_user_ratings_ratio,\n wt.cached_user_ratings_last_updated_at,\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n FROM model_weights as wt\n WHERE\n wt.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_thumbnail_token",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 5,
"name": "description_markdown",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 7,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 8,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 9,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 10,
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 11,
"name": "original_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 12,
"name": "original_filename",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 13,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 14,
"name": "file_checksum_sha2",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 15,
"name": "private_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 16,
"name": "maybe_private_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 17,
"name": "maybe_private_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 18,
"name": "cached_user_ratings_negative_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 19,
"name": "cached_user_ratings_positive_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 20,
"name": "cached_user_ratings_total_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 21,
"name": "maybe_cached_user_ratings_ratio",
"type_info": {
"type": "Float",
"flags": "",
"char_set": 63,
"max_size": 12
}
},
{
"ordinal": 22,
"name": "cached_user_ratings_last_updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 23,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 24,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 25,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 26,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 27,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
true,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
false,
true,
true,
false,
false,
false,
true,
false,
false,
false,
false,
true,
true
]
},
"hash": "6a94791c8a8f66ee54bb367a4e8c71106bbcbbb205f54c14e3657279e83dabb6"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nUPDATE model_weights\nSET\n user_deleted_at = CURRENT_TIMESTAMP\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "7487c997706788c670a76da81ce90532b9748c8afcc707436d1f04ed976ce30e"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nUPDATE model_weights\nSET\n user_deleted_at = NULL\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "7dbfbb21d502aad7859016fd287c57010296011928cf21b036a8dc57f1ef619d"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nUPDATE model_weights\nSET\n mod_deleted_at = CURRENT_TIMESTAMP\nWHERE\n token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "9d2c8d49cf9840a547230e5c6febc041f39cd069bcb7a4a94ffb4f1cb3be6d7c"
}
@@ -0,0 +1,355 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n mw.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n mw.title,\n mw.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n mw.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n mw.maybe_thumbnail_token,\n mw.description_markdown,\n mw.description_rendered_html,\n users.token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash as creator_email_gravatar_hash,\n mw.creator_ip_address,\n mw.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n mw.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n mw.original_download_url,\n mw.original_filename,\n mw.file_size_bytes,\n mw.file_checksum_sha2,\n mw.private_bucket_hash,\n mw.maybe_private_bucket_prefix,\n mw.maybe_private_bucket_extension,\n mw.cached_user_ratings_negative_count,\n mw.cached_user_ratings_positive_count,\n mw.cached_user_ratings_total_count,\n mw.maybe_cached_user_ratings_ratio,\n mw.cached_user_ratings_last_updated_at,\n mw.version,\n mw.created_at,\n mw.updated_at,\n mw.user_deleted_at,\n mw.mod_deleted_at\n FROM model_weights as mw\n JOIN users\n ON users.token = mw.creator_user_token\n WHERE\n users.username = ?\n AND mw.user_deleted_at IS NULL\n AND mw.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_thumbnail_token",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 5,
"name": "description_markdown",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 7,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 8,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 9,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 10,
"name": "creator_email_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 11,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 12,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 13,
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 14,
"name": "original_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 15,
"name": "original_filename",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 16,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 17,
"name": "file_checksum_sha2",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 18,
"name": "private_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 19,
"name": "maybe_private_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 20,
"name": "maybe_private_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 21,
"name": "cached_user_ratings_negative_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 22,
"name": "cached_user_ratings_positive_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 23,
"name": "cached_user_ratings_total_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 24,
"name": "maybe_cached_user_ratings_ratio",
"type_info": {
"type": "Float",
"flags": "",
"char_set": 63,
"max_size": 12
}
},
{
"ordinal": 25,
"name": "cached_user_ratings_last_updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 26,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 27,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 28,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 29,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 30,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
true,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
false,
true,
true,
false,
false,
false,
true,
false,
false,
false,
false,
true,
true
]
},
"hash": "a6ed8524fb5339fed17bec6611f8f56b6bdee35bac63c9eacbe21eb032a6a831"
}
@@ -0,0 +1,322 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_thumbnail_token,\n wt.description_markdown,\n wt.description_rendered_html,\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n wt.private_bucket_hash,\n wt.maybe_private_bucket_prefix,\n wt.maybe_private_bucket_extension,\n wt.cached_user_ratings_negative_count,\n wt.cached_user_ratings_positive_count,\n wt.cached_user_ratings_total_count,\n wt.maybe_cached_user_ratings_ratio,\n wt.cached_user_ratings_last_updated_at,\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n FROM model_weights as wt\n WHERE\n wt.token = ?\n AND wt.user_deleted_at IS NULL\n AND wt.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_thumbnail_token",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 5,
"name": "description_markdown",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 7,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 8,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 9,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 10,
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 11,
"name": "original_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 12,
"name": "original_filename",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 13,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 14,
"name": "file_checksum_sha2",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 15,
"name": "private_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 16,
"name": "maybe_private_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 17,
"name": "maybe_private_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 18,
"name": "cached_user_ratings_negative_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 19,
"name": "cached_user_ratings_positive_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 20,
"name": "cached_user_ratings_total_count",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 21,
"name": "maybe_cached_user_ratings_ratio",
"type_info": {
"type": "Float",
"flags": "",
"char_set": 63,
"max_size": 12
}
},
{
"ordinal": 22,
"name": "cached_user_ratings_last_updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 23,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 24,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 25,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 26,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 27,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
true,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
false,
true,
true,
false,
false,
false,
true,
false,
false,
false,
false,
true,
true
]
},
"hash": "f0b5767d52c389660d1859e628c746f6f33a9e1c25f21f66aeeb0784df768c8e"
}
Generated
+659 -370
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -27,6 +27,7 @@ members = [
"crates/lib/bootstrap",
"crates/lib/caching/memory_caching",
"crates/lib/caching/redis_caching",
"crates/lib/collections",
"crates/lib/concurrency",
"crates/lib/cookies",
"crates/lib/crockford",
@@ -85,8 +86,9 @@ members = [
"crates/service/plugins/users",
# Vendored code
"crates/vendor/limitation",
"crates/vendor/newrelic-telemetry-sdk-rust",
# Vendored code
"my-workspace-hack",
# cargo-hakari workspace hack (compilation speedup hack)
"crates/my-workspace-hack",
]
+3 -1
View File
@@ -29,7 +29,9 @@ Web API Overview
* `tts-inference-job` - (*deprecated*) Async TTS inference of Tacotron2 models only
* `w2l-download-job` - (*deprecated*) Async download of videos and images
* `w2l-inference-job` - (*deprecated*) Async W2L inference
* Documentation Server:
* `docs` - this will run a local swagger server with the endpoints that you have access to, http://127.0.0.1:8989/api-docs/openapi.json use this to port everything over to the post man.
### PowerStream
* [PowerStream](https://power.stream) (deprecated) is powered by the following applications:
@@ -380,3 +380,16 @@ of this error message. You can essentially ignore it.
### [Fix] Can't connect to local MySQL after install on Ubuntu
- If MySql in local dev can't be connected to, [reset the accounts](https://linuxconfig.org/how-to-reset-root-mysql-mariadb-password-on-ubuntu-20-04-focal-fossa-linux).
### API Server
```
cargo run --bin docs
```
This setups an api server with swagger docs to show you responses and requests with each associated endpoint
It is run at http://127.0.0.1:8989/
To obtain the json for the postman collection go to this url http://127.0.0.1:8989/api-docs/openapi.json
We use this: `https://github.com/juhaku/utoipa`
The documentation example is in:
`crates/service/web/storyteller_web/src/http_server/endpoints/voice_designer/inference/enqueue_tts_request.rs`
Write into the api doc to:
`crates/service/web/storyteller_web/src/api_doc.rs`
+14
View File
@@ -8,11 +8,25 @@ update generic_inference_jobs set status = 'dead' where maybe_routing_tag IS NOT
-- Get pending jobs
select count(*) from generic_inference_jobs where status = 'pending';
-- Kill outstanding jobs
update generic_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed');
-- Kill outstanding jobs of type
update generic_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed')
and maybe_model_type IN ('sad_talker', 'so_vits_svc');
-- Tacotron 2 TTS
update generic_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed')
and maybe_model_type IN ('tacotron2');
-- Sad Talker Face Animation
update generic_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed')
and maybe_model_type IN ('sad_talker');
+1 -1
View File
@@ -7,7 +7,7 @@ set -euxo pipefail
# NB: Database used by desktop app for AiChatBot sidecar.
# Make sure it has been migrated (use aichatbot-sidecar app directory as root).
SQLITE_DATABASE_PATH=./runtime_data/database.db
# SQLITE_DATABASE_PATH=./runtime_data/database.db
# NB: OpenSSL is broken on Ubuntu 22.04 (this is documented elsewhere)
# See https://askubuntu.com/a/1403961
+1 -1
View File
@@ -17,7 +17,7 @@ path = "src/lib.rs"
# Internal
crockford = { path = "../../lib/crockford" }
errors = { path = "../../lib/errors" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
# External
# (none yet)
+1 -5
View File
@@ -17,14 +17,10 @@ path = "src/lib.rs"
serde = "1.0.125"
serde_derive = "1.0.125"
# MySql Database
# "offline" supports typesafe builds without a live database
# "rustls" doesn't appear to work with IP addresses, per:
# https://github.com/launchbadge/sqlx/issues/1095#issuecomment-798050828
sqlx = { version = "0.7.2", features = [ "mysql", "sqlite", "runtime-tokio-native-tls", "chrono" ] }
sqlx-core = { version = "0.7.2" }
sqlx-mysql= { version = "0.7.2" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
@@ -13,10 +13,11 @@ use strum::EnumIter;
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, Default)]
pub enum InferenceCategory {
/// Eg. SadTalker and possibly Wav2Lip
#[serde(rename = "lipsync_animation")]
#[default]
LipsyncAnimation,
#[serde(rename = "text_to_speech")]
@@ -21,6 +21,11 @@ pub enum IdCategory {
#[serde(rename = "lipsync_animation")]
LipsyncAnimationResult,
/// Results from tacotron2
/// Applies for RVC and SVC
#[serde(rename = "tts_result")]
TtsResult,
/// Results from voice conversion (which may live in the media_files table)
/// Applies for RVC and SVC
#[serde(rename = "voice_conversion")]
@@ -52,6 +57,7 @@ impl IdCategory {
match self {
Self::MediaFile => "media_file",
Self::LipsyncAnimationResult => "lipsync_animation",
Self::TtsResult => "tts_result",
Self::VoiceConversionResult => "voice_conversion",
Self::ZeroShotVoiceDataset => "zs_dataset",
Self::ZeroShotVoiceEmbedding => "zs_voice",
@@ -64,6 +70,7 @@ impl IdCategory {
match value {
"media_file" => Ok(Self::MediaFile),
"lipsync_animation" => Ok(Self::LipsyncAnimationResult),
"tts_result" => Ok(Self::TtsResult),
"voice_conversion" => Ok(Self::VoiceConversionResult),
"zs_dataset" => Ok(Self::ZeroShotVoiceDataset),
"zs_voice" => Ok(Self::ZeroShotVoiceEmbedding),
@@ -79,6 +86,7 @@ impl IdCategory {
BTreeSet::from([
Self::MediaFile,
Self::LipsyncAnimationResult,
Self::TtsResult,
Self::VoiceConversionResult,
Self::ZeroShotTtsResult,
Self::ZeroShotVoiceDataset,
@@ -100,6 +108,7 @@ mod tests {
fn test_serialization() {
assert_serialization(IdCategory::MediaFile, "media_file");
assert_serialization(IdCategory::LipsyncAnimationResult, "lipsync_animation");
assert_serialization(IdCategory::TtsResult, "tts_result");
assert_serialization(IdCategory::VoiceConversionResult, "voice_conversion");
assert_serialization(IdCategory::ZeroShotVoiceDataset, "zs_dataset");
assert_serialization(IdCategory::ZeroShotVoiceEmbedding, "zs_voice");
@@ -111,6 +120,7 @@ mod tests {
fn to_str() {
assert_eq!(IdCategory::MediaFile.to_str(), "media_file");
assert_eq!(IdCategory::LipsyncAnimationResult.to_str(), "lipsync_animation");
assert_eq!(IdCategory::TtsResult.to_str(), "tts_result");
assert_eq!(IdCategory::VoiceConversionResult.to_str(), "voice_conversion");
assert_eq!(IdCategory::ZeroShotVoiceDataset.to_str(), "zs_dataset");
assert_eq!(IdCategory::ZeroShotVoiceEmbedding.to_str(), "zs_voice");
@@ -122,6 +132,7 @@ mod tests {
fn from_str() {
assert_eq!(IdCategory::from_str("media_file").unwrap(), IdCategory::MediaFile);
assert_eq!(IdCategory::from_str("lipsync_animation").unwrap(), IdCategory::LipsyncAnimationResult);
assert_eq!(IdCategory::from_str("tts_result").unwrap(), IdCategory::TtsResult);
assert_eq!(IdCategory::from_str("voice_conversion").unwrap(), IdCategory::VoiceConversionResult);
assert_eq!(IdCategory::from_str("zs_dataset").unwrap(), IdCategory::ZeroShotVoiceDataset);
assert_eq!(IdCategory::from_str("zs_voice").unwrap(), IdCategory::ZeroShotVoiceEmbedding);
@@ -133,9 +144,10 @@ mod tests {
fn all_variants() {
// Static check
let mut variants = IdCategory::all_variants();
assert_eq!(variants.len(), 6);
assert_eq!(variants.len(), 8);
assert_eq!(variants.pop_first(), Some(IdCategory::MediaFile));
assert_eq!(variants.pop_first(), Some(IdCategory::LipsyncAnimationResult));
assert_eq!(variants.pop_first(), Some(IdCategory::TtsResult));
assert_eq!(variants.pop_first(), Some(IdCategory::VoiceConversionResult));
assert_eq!(variants.pop_first(), Some(IdCategory::ZeroShotTtsResult));
assert_eq!(variants.pop_first(), Some(IdCategory::ZeroShotVoiceDataset));
@@ -1,4 +1,5 @@
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
#[cfg(test)]
@@ -29,6 +30,7 @@ pub enum MediaFileOriginCategory {
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(MediaFileOriginCategory);
impl_mysql_enum_coders!(MediaFileOriginCategory);
impl_mysql_from_row!(MediaFileOriginCategory);
/// NB: Legacy API for older code.
impl MediaFileOriginCategory {
@@ -24,6 +24,10 @@ pub enum MediaFileOriginModelType {
/// so-vits-svc voice conversion models
#[serde(rename = "so_vits_svc")]
SoVitsSvc,
#[serde(rename = "tacotron2")]
Tacotron2,
#[serde(rename = "vall_e_x")]
VallEX,
}
@@ -31,6 +35,7 @@ pub enum MediaFileOriginModelType {
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(MediaFileOriginModelType);
impl_mysql_enum_coders!(MediaFileOriginModelType);
impl_mysql_from_row!(MediaFileOriginModelType);
/// NB: Legacy API for older code.
impl MediaFileOriginModelType {
@@ -39,6 +44,7 @@ impl MediaFileOriginModelType {
Self::RvcV2 => "rvc_v2",
Self::SadTalker => "sad_talker",
Self::SoVitsSvc => "so_vits_svc",
Self::Tacotron2 => "tacotron2",
Self::VallEX => "vall_e_x"
}
}
@@ -48,6 +54,7 @@ impl MediaFileOriginModelType {
"rvc_v2" => Ok(Self::RvcV2),
"sad_talker" => Ok(Self::SadTalker),
"so_vits_svc" => Ok(Self::SoVitsSvc),
"tacotron2" => Ok(Self::Tacotron2),
"vall_e_x" => Ok(Self::VallEX),
_ => Err(format!("invalid value: {:?}", value)),
}
@@ -60,6 +67,7 @@ impl MediaFileOriginModelType {
Self::RvcV2,
Self::SadTalker,
Self::SoVitsSvc,
Self::Tacotron2,
Self::VallEX
])
}
@@ -83,6 +91,7 @@ mod tests {
assert_eq!(MediaFileOriginModelType::RvcV2.to_str(), "rvc_v2");
assert_eq!(MediaFileOriginModelType::SadTalker.to_str(), "sad_talker");
assert_eq!(MediaFileOriginModelType::SoVitsSvc.to_str(), "so_vits_svc");
assert_eq!(MediaFileOriginModelType::Tacotron2.to_str(), "tacotron2");
assert_eq!(MediaFileOriginModelType::VallEX.to_str(), "vall_e_x");
}
@@ -91,17 +100,19 @@ mod tests {
assert_eq!(MediaFileOriginModelType::from_str("rvc_v2").unwrap(), MediaFileOriginModelType::RvcV2);
assert_eq!(MediaFileOriginModelType::from_str("sad_talker").unwrap(), MediaFileOriginModelType::SadTalker);
assert_eq!(MediaFileOriginModelType::from_str("so_vits_svc").unwrap(), MediaFileOriginModelType::SoVitsSvc);
assert_eq!(MediaFileOriginModelType::from_str("tacotron2").unwrap(), MediaFileOriginModelType::Tacotron2);
assert_eq!(MediaFileOriginModelType::from_str("vall_e_x").unwrap(), MediaFileOriginModelType::VallEX);
assert!(MediaFileOriginModelType::from_str("foo").is_err());
assert!(MediaFileOriginModelType::from_str("foo").is_err());
}
#[test]
fn all_variants() {
let mut variants = MediaFileOriginModelType::all_variants();
assert_eq!(variants.len(), 4);
assert_eq!(variants.len(), 5);
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::RvcV2));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::SadTalker));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::SoVitsSvc));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::Tacotron2));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::VallEX));
assert_eq!(variants.pop_first(), None);
}
@@ -21,6 +21,10 @@ pub enum MediaFileOriginProductCategory {
#[serde(rename = "face_animator")]
FaceAnimator,
/// Text to speech (Tacotron2, not voice designer / VallE-X)
#[serde(rename = "tts")]
TextToSpeech,
// TODO: This should be a temporary category until we migrate the DB to remove this default value
/// Unknown which product is attached to the file (generated the file, the file was
/// uploaded on behalf of, etc.)
@@ -39,12 +43,14 @@ pub enum MediaFileOriginProductCategory {
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(MediaFileOriginProductCategory);
impl_mysql_enum_coders!(MediaFileOriginProductCategory);
impl_mysql_from_row!(MediaFileOriginProductCategory);
/// NB: Legacy API for older code.
impl MediaFileOriginProductCategory {
pub fn to_str(&self) -> &'static str {
match self {
Self::FaceAnimator => "face_animator",
Self::TextToSpeech => "tts",
Self::Unknown => "unknown",
Self::VoiceConversion => "voice_conversion",
Self::ZeroShotVoice => "zs_voice",
@@ -54,6 +60,7 @@ impl MediaFileOriginProductCategory {
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"face_animator" => Ok(Self::FaceAnimator),
"tts" => Ok(Self::TextToSpeech),
"unknown" => Ok(Self::Unknown),
"voice_conversion" => Ok(Self::VoiceConversion),
"zs_voice" => Ok(Self::ZeroShotVoice),
@@ -66,6 +73,7 @@ impl MediaFileOriginProductCategory {
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
Self::FaceAnimator,
Self::TextToSpeech,
Self::Unknown,
Self::VoiceConversion,
Self::ZeroShotVoice,
@@ -84,6 +92,7 @@ mod tests {
#[test]
fn test_serialization() {
assert_serialization(MediaFileOriginProductCategory::FaceAnimator, "face_animator");
assert_serialization(MediaFileOriginProductCategory::TextToSpeech, "tts");
assert_serialization(MediaFileOriginProductCategory::Unknown, "unknown");
assert_serialization(MediaFileOriginProductCategory::VoiceConversion, "voice_conversion");
assert_serialization(MediaFileOriginProductCategory::ZeroShotVoice, "zs_voice");
@@ -92,6 +101,7 @@ mod tests {
#[test]
fn to_str() {
assert_eq!(MediaFileOriginProductCategory::FaceAnimator.to_str(), "face_animator");
assert_eq!(MediaFileOriginProductCategory::TextToSpeech.to_str(), "tts");
assert_eq!(MediaFileOriginProductCategory::Unknown.to_str(), "unknown");
assert_eq!(MediaFileOriginProductCategory::VoiceConversion.to_str(), "voice_conversion");
assert_eq!(MediaFileOriginProductCategory::ZeroShotVoice.to_str(), "zs_voice");
@@ -100,6 +110,7 @@ mod tests {
#[test]
fn from_str() {
assert_eq!(MediaFileOriginProductCategory::from_str("face_animator").unwrap(), MediaFileOriginProductCategory::FaceAnimator);
assert_eq!(MediaFileOriginProductCategory::from_str("tts").unwrap(), MediaFileOriginProductCategory::TextToSpeech);
assert_eq!(MediaFileOriginProductCategory::from_str("unknown").unwrap(), MediaFileOriginProductCategory::Unknown);
assert_eq!(MediaFileOriginProductCategory::from_str("voice_conversion").unwrap(), MediaFileOriginProductCategory::VoiceConversion);
assert_eq!(MediaFileOriginProductCategory::from_str("zs_voice").unwrap(), MediaFileOriginProductCategory::ZeroShotVoice);
@@ -108,8 +119,9 @@ mod tests {
#[test]
fn all_variants() {
let mut variants = MediaFileOriginProductCategory::all_variants();
assert_eq!(variants.len(), 4);
assert_eq!(variants.len(), 5);
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::FaceAnimator));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::TextToSpeech));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::Unknown));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::VoiceConversion));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::ZeroShotVoice));
@@ -25,6 +25,7 @@ pub enum MediaFileType {
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(MediaFileType);
impl_mysql_enum_coders!(MediaFileType);
impl_mysql_from_row!(MediaFileType);
/// NB: Legacy API for older code.
impl MediaFileType {
@@ -34,6 +34,12 @@ impl_mysql_enum_coders!(JobStatusPlus);
// NB: We can derive `sqlx::Type` instead of using `impl_mysql_enum_coders`
impl Default for JobStatusPlus {
fn default() -> Self {
Self::Pending
}
}
impl JobStatusPlus {
pub fn to_str(&self) -> &'static str {
match self {
@@ -86,6 +92,11 @@ mod tests {
mod explicit_checks {
use super::*;
#[test]
fn test_default() {
assert_eq!(JobStatusPlus::default(), JobStatusPlus::Pending);
}
#[test]
fn test_serialization() {
assert_serialization(JobStatusPlus::Pending, "pending");
@@ -38,6 +38,7 @@ pub enum Visibility {
impl_enum_display_and_debug_using_to_str!(Visibility);
impl_mysql_from_row!(Visibility);
// For reference, here's what the serde implementation might be if manually written.
// This may be useful for designing composite types in the future:
+1
View File
@@ -32,3 +32,4 @@ mod macros;
pub mod by_table;
pub mod common;
pub mod traits;
@@ -0,0 +1,63 @@
/// Implement `MySqlFromRow` on a type.
macro_rules! impl_mysql_from_row {
($t:ident) => {
// Try to convert a MySQL row and named field into the value type (for non-nullable fields).
impl crate::traits::mysql_from_row::MySqlFromRow<$t> for $t {
fn try_from_mysql_row(row: &sqlx_mysql::MySqlRow, field_name: &str) -> Result<$t, sqlx::Error> {
use sqlx::{Error, Row};
// NB(bt,2023-12-05): For now only string encodings are considered.
// We may want to revisit in the future if we deal with binary data.
let value : String = row.try_get(field_name)?;
let output_type = Self::from_str(&value)
.map_err(|err| {
Error::ColumnDecode {
index: format!("mysql_from_row failure on field {}: {:?}", field_name, err),
source: format!("mysql_from_row failure on field {}: {:?}", field_name, err).into(),
}
})?;
Ok(output_type)
}
// Try to convert a MySQL row and named field into the value type (for nullable fields).
fn try_from_mysql_row_nullable(row: &sqlx_mysql::MySqlRow, field_name: &str) -> Result<Option<$t>, sqlx::Error> {
use sqlx::{Error, Row};
// NB(bt,2023-12-05): For now only string encodings are considered.
// We may want to revisit in the future if we deal with binary data.
// NB(2): Nullable fields decode as Option<T>.
let maybe_value : Option<String> = row.try_get(field_name)?;
let value = match maybe_value {
Some(value) => value,
None => return Ok(None),
};
let output_type = Self::from_str(&value)
.map_err(|err| {
Error::ColumnDecode {
index: format!("mysql_from_row failure on field {}: {:?}", field_name, err),
source: format!("mysql_from_row failure on field {}: {:?}", field_name, err).into(),
}
})?;
Ok(Some(output_type))
}
}
//// TODO: Tests.
//#[cfg(test)]
//#[test]
//fn test_name() {
// use strum::IntoEnumIterator;
// for variant in $t::iter() {
// assert_eq!(format!("{}", variant), variant.to_str());
// }
//}
}
}
+1
View File
@@ -1,3 +1,4 @@
#[macro_use] pub mod impl_enum_display_and_debug_using_to_str;
#[macro_use] pub mod impl_mysql_enum_coders;
#[macro_use] pub mod impl_mysql_from_row;
#[macro_use] pub mod impl_sqlite_enum_coders;
+1
View File
@@ -0,0 +1 @@
pub mod mysql_from_row;
@@ -0,0 +1,11 @@
use sqlx_mysql::MySqlRow;
/// This is a trait (in conjunction with the macro implementation) that makes up for sqlx's
/// QueryBuilder not playing well with FromRow implementation or derivation of named types.
pub trait MySqlFromRow<T> {
/// Attempt to parse a named column from a MySqlRow into the type.
fn try_from_mysql_row(row: &MySqlRow, field_name: &str) -> Result<T, sqlx::Error>;
fn try_from_mysql_row_nullable(row: &MySqlRow, field_name: &str) -> Result<Option<T>, sqlx::Error>;
}
+2 -2
View File
@@ -18,7 +18,7 @@ path = "src/lib.rs"
# (none)
# External
chrono = { version = "=0.4.22", features = ["serde"] }
chrono = { version = "0.4.22", features = ["serde"] }
# Serialization
serde = "1.0.125"
@@ -26,7 +26,7 @@ serde_derive = "1.0.125"
# MySql Database
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# Test serialization
+4 -6
View File
@@ -18,15 +18,13 @@ serde = "1.0.125"
serde_derive = "1.0.125"
# Random
rand = "0.8.3"
rand = "0.8.5"
# MySql Database
# "offline" supports typesafe builds without a live database
# "rustls" doesn't appear to work with IP addresses, per:
# https://github.com/launchbadge/sqlx/issues/1095#issuecomment-798050828
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
sqlx-core = { version = "0.7.2" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
utoipa = { version = "4", features = ["actix_extras"] }
[dev-dependencies]
@@ -8,7 +8,7 @@ use crate::prefixes::TokenPrefix;
/// A rare instance that is *not* a primary key.
/// These are generated as cookies to track users for a better logged out experience and for analytics.
/// We use these as indices into several columns (ML result types, uploads, etc.)
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize, Default)]
#[sqlx(transparent)]
pub struct AnonymousVisitorTrackingToken(pub String);
@@ -4,9 +4,10 @@ use serde::Deserialize;
use serde::Serialize;
use crate::prefixes::TokenPrefix;
use utoipa::ToSchema;
/// The primary key for "generic" inference jobs.
#[derive(Clone, PartialEq, Eq, sqlx::Type, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, sqlx::Type, Debug, Serialize, Deserialize, Default, ToSchema)]
#[sqlx(transparent)]
pub struct InferenceJobToken(String);
+1 -1
View File
@@ -6,7 +6,7 @@ use serde::Serialize;
use crate::prefixes::TokenPrefix;
/// The primary key for users.
#[derive(Clone, PartialEq, Eq, sqlx::Type, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, sqlx::Type, Debug, Serialize, Deserialize, Default)]
#[sqlx(transparent)]
pub struct UserToken(pub String);
+1 -1
View File
@@ -28,4 +28,4 @@ log = "0.4.14"
# Serialization
serde = "1.0.125"
serde_derive = "1.0.125"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
+1 -1
View File
@@ -28,4 +28,4 @@ log = "0.4.14"
# Serialization
serde = "1.0.125"
serde_derive = "1.0.125"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
+1 -5
View File
@@ -36,14 +36,10 @@ clap = "2.34.0" # TODO: This is really out of date, but has conflicts when updat
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
tokio = { version = "1.6.0", features = ["macros"] }
# MySql Database
# "offline" supports typesafe builds without a live database
# "rustls" doesn't appear to work with IP addresses, per:
# https://github.com/launchbadge/sqlx/issues/1095#issuecomment-798050828
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
elasticsearch = "8.5.0-alpha.1"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -6
View File
@@ -5,19 +5,14 @@ use sqlx::mysql::MySqlPoolOptions;
use config::shared_constants::{DEFAULT_MYSQL_CONNECTION_STRING, DEFAULT_RUST_LOG};
use errors::AnyhowResult;
use crate::seeding::model_weights::seed_weights;
use crate::seeding::model_weights::seed_weights_for_user_token;
use crate::bucket_clients::get_bucket_clients;
use crate::cli_args::parse_cli_args;
use crate::seeding::model_weights::seed_weights;
use crate::seeding::tts_tacotron2::seed_tts_tacotron2;
use crate::seeding::users::seed_user_accounts;
use crate::seeding::voice_conversion::seed_voice_conversion;
use crate::seeding::zero_shot_tts::seed_zero_shot_tts;
pub mod bucket_clients;
pub mod cli_args;
+1 -5
View File
@@ -33,12 +33,8 @@ log = "0.4.14"
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
tokio = { version = "1.6.0", features = ["macros"] }
# MySql Database
# "offline" supports typesafe builds without a live database
# "rustls" doesn't appear to work with IP addresses, per:
# https://github.com/launchbadge/sqlx/issues/1095#issuecomment-798050828
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -5
View File
@@ -33,10 +33,6 @@ strum = { version = "0.25", features = ["derive"] }
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
tokio = { version = "1.6.0", features = ["macros"] }
# MySql Database
# "offline" supports typesafe builds without a live database
# "rustls" doesn't appear to work with IP addresses, per:
# https://github.com/launchbadge/sqlx/issues/1095#issuecomment-798050828
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
elasticsearch = "8.5.0-alpha.1"
@@ -45,7 +41,7 @@ elasticsearch = "8.5.0-alpha.1"
serde = "1.0.125"
serde_derive = "1.0.125"
serde_json = "1.0.108"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+2 -2
View File
@@ -21,9 +21,9 @@ errors = { path = "../../lib/errors" }
# External
log = "0.4.20"
once_cell = "1.18.0"
rand = "0.8.1"
rand = "0.8.5"
regex = "1.10.0"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
# Async Runtime
# NB: Not using Tokio here since everything is blocking so far.
+1 -1
View File
@@ -20,7 +20,7 @@ logging = { path = "../../lib/logging" }
# External
clap = { version = "4.4.7", features = ["derive"] }
walkdir = "2.4.0"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -1
View File
@@ -21,4 +21,4 @@ web_scrapers = { path = "../../lib/web_scrapers" }
# External
clap = "2.34.0" # TODO: This is really out of date, but has conflicts when updated
tokio = { version = "1.6.0", features = ["macros"] }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
+1 -1
View File
@@ -34,7 +34,7 @@ futures-util = "0.3.29"
# Serialization
serde = "1.0.125"
serde_json = "1.0.108"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
@@ -28,4 +28,4 @@ rust-s3 = { version = "0.33.0" }
# Runtime
# NB: We switched to Tokio from `async-std` for broader ecosystem support.
tokio = { version = "1.6.0", features = ["macros"] }
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
@@ -20,7 +20,7 @@ tokens = { path = "../../../_types/tokens" }
# External
bytes = "1.3"
chrono = { version = "=0.4.22", features = ["serde"] }
chrono = { version = "0.4.22", features = ["serde"] }
log = "0.4.14"
once_cell = "1.9.0"
@@ -22,5 +22,5 @@ subprocess_common = { path = "../../subprocess_common" }
anyhow = "1.0.75"
log = "0.4.14"
tempdir = "0.3.7"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
@@ -31,4 +31,4 @@ twitch_oauth2 = "0.6.0-rc.2"
# Serialization
serde = "1.0.125"
serde_derive = "1.0.125"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
+1 -1
View File
@@ -23,7 +23,7 @@ server_environment = { path = "../server_environment" }
dotenv = "0.15.0"
hostname = "0.3.1"
log = "0.4.14"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -1
View File
@@ -22,4 +22,4 @@ anyhow = "1.0.75"
# In-memory caching
lru_time_cache = "0.11.11"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
+1 -1
View File
@@ -23,7 +23,7 @@ r2d2_redis = "0.14.0"
serde = "1.0.125"
serde_derive = "1.0.125"
serde_json = "1.0.108"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
# None yet
+26
View File
@@ -0,0 +1,26 @@
[package]
name = "collections"
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
publish = false
[lib]
# NB: Public "collections" crate is not yet taken (!!), so we're fine to use this internally for now.
name = "collections"
path = "src/lib.rs"
[dependencies]
# Internal
errors = { path = "../errors" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
# External
# KEEP THIS TO A MINIMUM OR NIL.
rand = "0.8.5"
[dev-dependencies]
# None yet
+22
View File
@@ -0,0 +1,22 @@
//! collections
//!
//! The purpose of this library is to provide "extra" data structures or utilities related to
//! data structures. There should be minimal dependency introduction here.
//!
// Never allow these
#![forbid(private_in_public)]
#![forbid(unused_must_use)] // NB: It's unsafe to not close/check some things
// Okay to toggle
#![forbid(unreachable_patterns)]
#![forbid(unused_imports)]
#![forbid(unused_mut)]
#![forbid(unused_variables)]
// Always allow
#![allow(dead_code)]
#![allow(non_snake_case)]
pub mod multiple_random_from_vec;
pub mod random_from_vec;
@@ -12,7 +12,7 @@ pub fn multiple_random_from_vec<T>(vec: &Vec<T>, amount: usize) -> Vec<&T> {
#[cfg(test)]
mod tests {
use crate::collections::multiple_random_from_vec::multiple_random_from_vec;
use crate::multiple_random_from_vec::multiple_random_from_vec;
#[test]
fn pulls_item_from_vec() {
@@ -7,7 +7,7 @@ pub fn random_from_vec<T>(vec: &Vec<T>) -> Option<&T> {
#[cfg(test)]
mod tests {
use crate::collections::random_from_vec::random_from_vec;
use crate::random_from_vec::random_from_vec;
#[test]
fn pulls_item_from_vec() {
+1 -1
View File
@@ -14,7 +14,7 @@ path = "src/lib.rs"
[dependencies]
# Internal
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
# External
# (None yet)
+1 -1
View File
@@ -21,7 +21,7 @@ errors = { path = "../errors" }
hmac = "0.10.0" # jwt signing
jwt = "0.13.0"
sha2 = "0.9.5" # hmac signing
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+2 -2
View File
@@ -15,8 +15,8 @@ name = "crockford"
path = "src/lib.rs"
[dependencies]
rand = "0.8.3"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
rand = "0.8.5"
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+2 -2
View File
@@ -13,9 +13,9 @@ name = "datetimes"
path = "src/lib.rs"
[dependencies]
chrono = { version = "=0.4.22", features = ["serde"] }
chrono = { version = "0.4.22", features = ["serde"] }
once_cell = "1.18.0"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# (none)
+1 -1
View File
@@ -21,4 +21,4 @@ easyenv = { path = "../../../lib/easyenv" }
# External
anyhow = "1.0.75"
url = "2.4.1"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
@@ -17,14 +17,14 @@ path = "src/lib.rs"
# External
anyhow = "1.0.75"
once_cell = "1.18.0"
rand = "0.8.3"
rand = "0.8.5"
uuid = { version = "0.8.2", features = ["v4"] }
log = "0.4.14"
# Serialization
serde = { version = "1.0.125", features = ["derive"] }
toml = "0.5.8"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
@@ -1,2 +0,0 @@
pub mod multiple_random_from_vec;
pub mod random_from_vec;
@@ -1,15 +0,0 @@
use std::path::PathBuf;
use anyhow::bail;
use crate::anyhow_result::AnyhowResult;
pub fn check_directory_exists(path: &PathBuf) -> AnyhowResult<()> {
if !path.exists() {
bail!("Path doesn't exist: {:?}", path);
}
if !path.is_dir() {
bail!("Path isn't a directory: {:?}", path);
}
Ok(())
}
@@ -1,5 +0,0 @@
pub mod check_directory_exists;
pub mod check_file_exists;
pub mod safe_delete_possible_temp_file;
pub mod safe_delete_temp_directory;
pub mod safe_delete_temp_file;
@@ -1,7 +1,5 @@
pub mod anyhow_result;
pub mod collections;
pub mod files;
pub mod filesystem;
pub mod i18n;
pub mod numerics;
pub mod thread;
@@ -1,3 +1,2 @@
pub mod random_crockford_token;
pub mod random_prefix_crockford_token;
pub mod random_uuid;
@@ -1,100 +0,0 @@
use anyhow::anyhow;
use rand::Rng;
use crate::anyhow_result::AnyhowResult;
// Crockford characters
const CROCKFORD_UPPERCASE_CHARSET: &[u8] = b"0123456789ABCDEFGHJKMNPQRSTVWXYZ";
const CROCKFORD_LOWERCASE_CHARSET: &[u8] = b"0123456789abcdefghjkmnpqrstvwxyz";
// Random part can't be any less than this.
const MIN_ENTROPY_LENGTH : usize = 8;
#[deprecated(note = "see internal 'crockford' and 'token' crates")]
pub fn random_prefix_crockford_token(prefix: &str, length: usize, uppercase: bool) -> AnyhowResult<String> {
let mut prefix = prefix.trim().to_string();
if prefix.is_empty() {
return Err(anyhow!("prefix not set; use other crockford functions"));
}
if !prefix.ends_with(":") {
prefix = format!("{}:", prefix);
}
let entropy_length : usize = length.saturating_sub(prefix.len());
if entropy_length < MIN_ENTROPY_LENGTH {
return Err(anyhow!("not enough entropy in token"));
}
let mut rng = rand::thread_rng();
let charset = if uppercase { CROCKFORD_UPPERCASE_CHARSET } else { CROCKFORD_LOWERCASE_CHARSET };
let entropy_part: String = (0..entropy_length)
.map(|_| {
let idx = rng.gen_range(0..charset.len());
charset[idx] as char
})
.collect();
let token = format!("{}{}", prefix, entropy_part);
Ok(token)
}
#[cfg(test)]
mod tests {
use crate::token::random_prefix_crockford_token::random_prefix_crockford_token;
#[test]
fn no_prefix_error() {
assert!(random_prefix_crockford_token("", 0, false).is_err());
assert!(random_prefix_crockford_token("", 10, false).is_err());
assert!(random_prefix_crockford_token("", 32, false).is_err());
assert!(random_prefix_crockford_token("", 0, true).is_err());
assert!(random_prefix_crockford_token("", 10, true).is_err());
assert!(random_prefix_crockford_token("", 32, true).is_err());
}
#[test]
fn not_enough_entropy_error() {
assert!(random_prefix_crockford_token("foo", 0, false).is_err());
assert!(random_prefix_crockford_token("foo", 5, false).is_err());
assert!(random_prefix_crockford_token("foo", 11, false).is_err());
assert!(random_prefix_crockford_token("foo:", 11, false).is_err());
assert!(random_prefix_crockford_token("foo", 0, true).is_err());
assert!(random_prefix_crockford_token("foo", 5, true).is_err());
assert!(random_prefix_crockford_token("foo", 11, true).is_err());
assert!(random_prefix_crockford_token("foo:", 11, true).is_err());
}
#[test]
fn starts_with() {
assert!(random_prefix_crockford_token("w", 10, false).unwrap().starts_with("w:"));
assert!(random_prefix_crockford_token("w", 10, false).unwrap().starts_with("w:"));
assert!(random_prefix_crockford_token("prefix", 16, false).unwrap().starts_with("prefix:"));
assert!(random_prefix_crockford_token("prefix:", 16, false).unwrap().starts_with("prefix:"));
assert!(random_prefix_crockford_token("w", 10, true).unwrap().starts_with("w:"));
assert!(random_prefix_crockford_token("w", 10, true).unwrap().starts_with("w:"));
assert!(random_prefix_crockford_token("prefix", 16, true).unwrap().starts_with("prefix:"));
assert!(random_prefix_crockford_token("prefix:", 16, true).unwrap().starts_with("prefix:"));
}
#[test]
fn length() {
assert_eq!(random_prefix_crockford_token("w", 10, false).unwrap().len(), 10);
assert_eq!(random_prefix_crockford_token("w:", 10, false).unwrap().len(), 10);
assert_eq!(random_prefix_crockford_token("prefix", 16, false).unwrap().len(), 16);
assert_eq!(random_prefix_crockford_token("prefix:", 16, false).unwrap().len(), 16);
assert_eq!(random_prefix_crockford_token("asdf:", 32, false).unwrap().len(), 32);
assert_eq!(random_prefix_crockford_token("asdf", 32, false).unwrap().len(), 32);
assert_eq!(random_prefix_crockford_token("w", 10, true).unwrap().len(), 10);
assert_eq!(random_prefix_crockford_token("w:", 10, true).unwrap().len(), 10);
assert_eq!(random_prefix_crockford_token("prefix", 16, true).unwrap().len(), 16);
assert_eq!(random_prefix_crockford_token("prefix:", 16, true).unwrap().len(), 16);
assert_eq!(random_prefix_crockford_token("asdf:", 32, true).unwrap().len(), 32);
assert_eq!(random_prefix_crockford_token("asdf", 32, true).unwrap().len(), 32);
}
}
@@ -21,7 +21,7 @@ reusable_types = { path = "../../../_types/reusable_types" }
# External
anyhow = "1.0.75"
base64 = "0.21.0"
chrono = { version = "=0.4.22", features = ["serde"] }
chrono = { version = "0.4.22", features = ["serde"] }
log = "0.4.14"
once_cell = "1.18.0"
regex = "1.5.4"
@@ -39,7 +39,7 @@ language-tags = "0.3.2" # Parsing single tags richly
serde = "1.0.125"
serde_derive = "1.0.125"
serde_json = "1.0.108"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
actix-rt = "2.9.0"
+2 -2
View File
@@ -18,9 +18,9 @@ storyteller_root = { path = "../storyteller_root" }
# External
dotenv = "0.15.0"
env_logger = "0.10.0"
env_logger = "0.10.1"
log = "0.4.14"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+2 -2
View File
@@ -23,10 +23,10 @@ elasticsearch = "8.5.0-alpha.1"
log = "0.4.14"
# Serialization
chrono = { version = "=0.4.22", features = ["serde"] }
chrono = { version = "0.4.22", features = ["serde"] }
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.108"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
@@ -27,7 +27,7 @@ pub async fn search_tts_models(
let mut response_json = search_response.json::<Value>().await?;
let mut hits = response_json.get_mut("hits")
let hits = response_json.get_mut("hits")
.map(|hits| hits.take());
let hits = hits.map(|mut hits| {
+2 -2
View File
@@ -11,5 +11,5 @@ path = "src/lib.rs"
[dependencies]
errors = { path = "../errors" }
lettre = "0.11.0"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
lettre = "0.11.2"
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
+1 -1
View File
@@ -18,7 +18,7 @@ path = "src/lib.rs"
# Consider the dependencies here wisely.
# Ideally we have almost nothing as a dependency of this crate.
anyhow = "1.0.75"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -1
View File
@@ -20,7 +20,7 @@ errors = { path = "../../errors" }
# External
zip = "0.6.6"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
# None yet
+2 -1
View File
@@ -16,7 +16,8 @@ path = "src/lib.rs"
[dependencies]
# Internal
errors = { path = "../../errors" }
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
log = "0.4.20"
# External
# KEEP THIS TO A MINIMUM OR NIL.
@@ -0,0 +1,15 @@
use std::path::Path;
use errors::{AnyhowResult, bail};
pub fn check_directory_exists<P: AsRef<Path>>(path: P) -> AnyhowResult<()> {
let check_path = path.as_ref();
if !check_path.exists() {
bail!("Path doesn't exist: {:?}", check_path);
}
if !check_path.is_dir() {
bail!("Path isn't a directory: {:?}", check_path);
}
Ok(())
}
@@ -1,8 +1,7 @@
use std::path::PathBuf;
use anyhow::bail;
use crate::anyhow_result::AnyhowResult;
use errors::AnyhowResult;
use errors::bail;
pub fn check_file_exists(path: &PathBuf) -> AnyhowResult<()> {
if !path.exists() {
@@ -7,6 +7,7 @@ use errors::{anyhow, AnyhowResult};
pub fn file_size<P: AsRef<Path>>(filename: P) -> AnyhowResult<u64> {
let metadata = std::fs::metadata(filename.as_ref())?;
// TODO(bt,2023-11-29): Return io::Result and errors here.
if !metadata.is_file() {
Err(anyhow!("path {:?} is not a file", filename.as_ref()))
} else if metadata.is_symlink() {
@@ -0,0 +1,16 @@
// Nearly a third of `ErrorKind` is nightly rust, so we're going to have to match on
// unix error codes until the rest of the ErrorKind enum variants are stable.
// The error codes are maintained in sys/unix/mod.rs - decode_error_kind(i32)
const E_FILESYSTEM_QUOTA_EXCEEDED : i32 = 122; // pub const EDQUOT: ::c_int = 122;
const E_STORAGE_FULL : i32 = 28; // pub const ENOSPC: ::c_int = 28;
/// Reports if an io::Error was caused by the filesystem being full.
pub fn is_filesystem_full_error(err: &std::io::Error) -> bool {
match err.raw_os_error() {
Some(E_FILESYSTEM_QUOTA_EXCEEDED) => true,
Some(E_STORAGE_FULL) => true,
_ => false,
}
}
+6
View File
@@ -18,11 +18,17 @@
#![allow(dead_code)]
#![allow(non_snake_case)]
pub mod check_file_exists;
pub mod create_dir_all_if_missing;
pub mod directory_exists;
pub mod file_exists;
pub mod file_read_bytes;
pub mod file_size;
pub mod filename_concat;
pub mod is_filesystem_full_error;
pub mod path_to_string;
pub mod rename_across_devices;
pub mod check_directory_exists;
pub mod safe_delete_temp_file;
pub mod safe_delete_possible_temp_file;
pub mod safe_delete_temp_directory;
@@ -1,30 +1,80 @@
use std::error::Error;
use std::fmt;
use std::path::Path;
use log::error;
use crate::is_filesystem_full_error::is_filesystem_full_error;
#[derive(Debug)]
pub enum RenameError {
StorageFull,
IoError(std::io::Error),
}
impl Error for RenameError {}
impl fmt::Display for RenameError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RenameError::StorageFull => write!(f, "RenameError: storage is full"),
RenameError::IoError(err) => write!(f, "{:?}", err),
}
}
}
impl From<std::io::Error> for RenameError {
fn from(error: std::io::Error) -> Self {
RenameError::IoError(error)
}
}
/// Rename a file.
/// Ordinary rename will fail in Linux if it is across physical devices.
/// This function will perform a copy followed by delete in that case.
pub fn rename_across_devices<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> std::io::Result<()> {
/// In both cases, this function will overwrite the destination if it already exists.
pub fn rename_across_devices<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> Result<(), RenameError> {
let result = std::fs::rename(&from, &to);
let err = match result.as_ref() {
let err = match result {
Ok(_) => return Ok(()), // Rename succeeded.
Err(err) => err,
};
// Nearly a third of `ErrorKind` is nightly rust, so we're going to have to match on
// unix error codes until the rest of the ErrorKind enum variants are stable.
// The error codes are maintained in sys/unix/mod.rs - decode_error_kind(i32)
const E_CROSSES_DEVICES : i32 = 18; // pub const EXDEV: ::c_int = 18;
if is_filesystem_full_error(&err) {
error!("Filesystem is full during rename.");
return Err(RenameError::StorageFull);
}
match err.raw_os_error() {
Some(18) => {
// NO-OP: pass-through
// NB: We can clean this up in the future when `err.kind() == ErrorKind::CrossDevices`
// stabilizes. For now we can assume code "18" means we're trying to rename across devices.
Some(E_CROSSES_DEVICES) => {
// NB: Fall through.
}
_ => {
// Something else happened. Return original error.
return result;
return Err(RenameError::IoError(err));
}
}
let _num_bytes = std::fs::copy(&from, &to)?;
// NB: In production we've seen std::fs::copy silently succeed, yet copy zero bytes. The reason
// is more than likely that the filesystem is full. We'll check the number of copied bytes to
// confirm. Moreover, the Rust docs say wrt std::fs::copy, "On success, the total number of bytes
// copied is returned and it is equal to the length of the to file as reported by metadata."
let original_file_size = std::fs::metadata(from.as_ref())?.len();
let num_bytes_copied = std::fs::copy(&from, &to)?;
if num_bytes_copied != original_file_size {
error!("Filesystem is full during copy. Not all bytes copied.");
return Err(RenameError::StorageFull);
}
// An emulated "rename" would delete the source file.
std::fs::remove_file(&from)?;
Ok(())
@@ -1,6 +1,6 @@
use std::path::Path;
use crate::filesystem::safe_delete_temp_file::safe_delete_temp_file;
use crate::safe_delete_temp_file::safe_delete_temp_file;
pub fn safe_delete_possible_temp_file<P: AsRef<Path>>(maybe_file_path: Option<P>) {
if let Some(file_path) = maybe_file_path {
+1 -1
View File
@@ -22,7 +22,7 @@ bcrypt = "0.8" # password hashes
data-encoding = "2.3.2"
md-5 = "0.9.1" # DO NOT USE FOR SERIOUS CRYPTO (we use this for gravatar)
ring = "0.17.0-alpha.10"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -1
View File
@@ -21,7 +21,7 @@ errors = { path = "../../errors" }
# External
image = "0.24.1"
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
testing = { path = "../../testing" }
+1 -1
View File
@@ -26,7 +26,7 @@ log = "0.4.14"
# Opus is the browser's default (only) recording codec: https://blog.addpipe.com/audio-constraints-getusermedia/
symphonia = { git = "https://github.com/pdeljanov/Symphonia.git", rev = "e1a70095c4409478c1ded499fb8dd4afa540fb90", features = ["aac", "alac", "flac", "isomp4", "mkv", "mp3", "ogg", "opus", "vorbis", "wav"] }
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -1
View File
@@ -16,7 +16,7 @@ path = "src/lib.rs"
[dependencies]
# External
infer = "0.11" # Mimetype detection
my-workspace-hack = { version = "0.1", path = "../../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
[dev-dependencies]
# None yet
+1 -1
View File
@@ -19,7 +19,7 @@ path = "src/lib.rs"
# External
uuid = { version = "0.8.2", features = ["v4"] }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+2 -2
View File
@@ -24,7 +24,7 @@ redis_common = { path = "../redis_common" }
# External
anyhow = "1.0.75"
chrono = { version = "=0.4.22", features = ["serde"] }
chrono = { version = "0.4.22", features = ["serde"] }
log = "0.4.14"
r2d2_redis = "0.14.0"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
+2 -2
View File
@@ -15,9 +15,9 @@ path = "src/lib.rs"
[dependencies]
dotenv = "0.15.0"
env_logger = "0.10.0"
env_logger = "0.10.1"
log = "0.4.20"
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
[dev-dependencies]
# None yet
+2 -6
View File
@@ -25,7 +25,7 @@ tokens = { path = "../../_types/tokens" }
# External
anyhow = "1.0.75"
chrono = { version = "=0.4.22", features = ["serde"] }
chrono = { version = "0.4.22", features = ["serde"] }
dotenv = "0.15.0"
log = "0.4.14"
@@ -39,14 +39,10 @@ serde_derive = "1.0.125"
serde_json = "1.0.108"
toml = "0.5.8"
serial_test = "2.0.0"
# MySql Database
# "offline" supports typesafe builds without a live database
# "rustls" doesn't appear to work with IP addresses, per:
# https://github.com/launchbadge/sqlx/issues/1095#issuecomment-798050828
tokio = { version = "1.6.0", features = ["full"] }
rand = "0.8"
sqlx = { version = "0.7.2", features = [ "mysql", "runtime-tokio", "tls-rustls", "chrono" ] }
my-workspace-hack = { version = "0.1", path = "../../../my-workspace-hack" }
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
@@ -167,7 +167,7 @@ FROM email_sender_jobs"#.to_string();
LIMIT ?
"#);
let mut query = sqlx::query_as::<_, AvailableEmailSenderJobRawInternal>(&query)
let query = sqlx::query_as::<_, AvailableEmailSenderJobRawInternal>(&query)
.bind(args.is_debug_worker)
.bind(args.num_records);
@@ -336,7 +336,7 @@ FROM generic_inference_jobs"#.to_string();
LIMIT ?
"#);
let mut query = sqlx::query_as::<_, AvailableInferenceJobRawInternal>(&query)
let query = sqlx::query_as::<_, AvailableInferenceJobRawInternal>(&query)
.bind(args.is_debug_worker)
.bind(args.num_records);
@@ -20,7 +20,7 @@ pub async fn mark_generic_inference_job_failure(
// statuses: "attempt_failed", "complete_failure", "dead"
let mut next_status = "attempt_failed";
let mut maybe_public_failure_reason = maybe_public_failure_reason.map(|reason| {
let maybe_public_failure_reason = maybe_public_failure_reason.map(|reason| {
let mut reason = reason.trim().to_string();
reason.truncate(512); // Max length of column is 512
reason
@@ -14,7 +14,7 @@ use tokens::tokens::users::UserToken;
use crate::helpers::boolean_converters::i8_to_bool;
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct GenericInferenceJobStatus {
pub job_token: InferenceJobToken,
@@ -40,7 +40,7 @@ pub struct GenericInferenceJobStatus {
/// Details about the user's original inference request
/// (We may want to present it in the "pending" UI.)
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct RequestDetails {
pub inference_category: InferenceCategory,
pub maybe_model_type: Option<String>, // TODO: Strongly type
@@ -52,7 +52,7 @@ pub struct RequestDetails {
}
/// Details about the generated result
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct ResultDetails {
pub entity_type: String,
pub entity_token: String,
@@ -71,7 +71,7 @@ pub struct ResultDetails {
/// NB: DO NOT EXPOSE TO FRONTEND.
/// This is used to gate access to job termination
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct UserDetails {
pub maybe_creator_user_token: Option<UserToken>,
pub maybe_creator_anonymous_visitor_token: Option<AnonymousVisitorTrackingToken>,
@@ -168,6 +168,11 @@ WHERE jobs.token = ?
}
};
Ok(Some(raw_record_to_public_result(record)))
}
/// Map the internal record type (since we query over several result tables)
fn raw_record_to_public_result(record: RawGenericInferenceJobStatus) -> GenericInferenceJobStatus {
let maybe_model_title = match record.inference_category {
InferenceCategory::LipsyncAnimation => Some("lipsync animation"),
InferenceCategory::TextToSpeech => record.maybe_tts_model_title.as_deref(),
@@ -213,7 +218,7 @@ WHERE jobs.token = ?
})
});
Ok(Some(GenericInferenceJobStatus {
GenericInferenceJobStatus {
job_token: record.job_token,
status: record.status,
attempt_count: record.attempt_count,
@@ -237,9 +242,10 @@ WHERE jobs.token = ?
is_keepalive_required: i8_to_bool(record.is_keepalive_required),
created_at: record.created_at,
updated_at: record.updated_at,
}))
}
}
#[derive(Debug, Default)]
struct RawGenericInferenceJobStatus {
pub job_token: InferenceJobToken,
@@ -281,3 +287,60 @@ struct RawGenericInferenceJobStatus {
pub maybe_successfully_completed_at: Option<DateTime<Utc>>,
}
#[cfg(test)]
mod tests {
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use crate::queries::generic_inference::web::get_inference_job_status::{raw_record_to_public_result, RawGenericInferenceJobStatus};
#[test]
fn text_to_speech_as_media_file() {
// NB(bt,2023-12-06): After tts migration to media files, these are the results the job system will return
let record = RawGenericInferenceJobStatus {
inference_category: InferenceCategory::TextToSpeech,
maybe_result_entity_type: Some("media_file".to_string()), // NB: Media file record
maybe_result_entity_token: Some("m_00af018cy75pxytpb8wbdx9jqgtp0p".to_string()),
maybe_media_file_public_bucket_directory_hash: Some("3vb91yq71z5zne56saazn4qntt52yter".to_string()), // NB: Media file
maybe_media_file_public_bucket_prefix: Some("fakeyou_".to_string()),
maybe_media_file_public_bucket_extension: Some(".wav".to_string()),
maybe_tts_public_bucket_path: None, // NB: Not a tts_result!
..Default::default()
};
let record = raw_record_to_public_result(record);
assert!(record.maybe_result_details.is_some());
let result_details = record.maybe_result_details.expect("should have result details");
assert_eq!(&result_details.entity_type, "media_file");
assert_eq!(&result_details.entity_token, "m_00af018cy75pxytpb8wbdx9jqgtp0p");
assert_eq!(&result_details.public_bucket_location_or_hash, "3vb91yq71z5zne56saazn4qntt52yter");
assert_eq!(result_details.public_bucket_location_is_hash, true);
}
#[test]
fn text_to_speech_as_tts_result() {
// NB(bt,2023-12-06): Prior to tts migration to media files, these are the results the job system will return
let record = RawGenericInferenceJobStatus {
inference_category: InferenceCategory::TextToSpeech,
maybe_result_entity_type: Some("text_to_speech".to_string()), // NB: TTS record
maybe_result_entity_token: Some("TR:wefhbk4j3yc8d6zwembedbdw4ad4s".to_string()),
maybe_tts_public_bucket_path: Some("/tts_inference_output/c/5/8/vocodes_c58aeaef-84df-4478-9e7f-c64280a852e8.wav".to_string()), // NB: tts_result!
maybe_media_file_public_bucket_directory_hash: None, // NB: Not a media file!
maybe_media_file_public_bucket_prefix: None,
maybe_media_file_public_bucket_extension: None,
..Default::default()
};
let record = raw_record_to_public_result(record);
assert!(record.maybe_result_details.is_some());
let result_details = record.maybe_result_details.expect("should have result details");
assert_eq!(&result_details.entity_type, "text_to_speech");
assert_eq!(&result_details.entity_token, "TR:wefhbk4j3yc8d6zwembedbdw4ad4s");
assert_eq!(&result_details.public_bucket_location_or_hash, "/tts_inference_output/c/5/8/vocodes_c58aeaef-84df-4478-9e7f-c64280a852e8.wav");
assert_eq!(result_details.public_bucket_location_is_hash, false);
}
}
@@ -24,6 +24,8 @@ pub struct InsertGenericInferenceArgs<'a> {
pub maybe_raw_inference_text: Option<&'a str>,
pub maybe_max_duration_seconds: Option<i32>,
pub maybe_inference_args: Option<GenericInferenceArgs>,
pub maybe_creator_user_token: Option<&'a UserToken>,
@@ -54,6 +56,11 @@ pub async fn insert_generic_inference_job(args: InsertGenericInferenceArgs<'_>)
routing_tag
});
// This only applies to certain types of inference.
// "0" is the default value, typically 12 seconds for TTS.
// "-1" means "unlimited"
let max_duration_seconds = args.maybe_max_duration_seconds.unwrap_or(0);
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
@@ -80,6 +87,7 @@ SET
priority_level = ?,
is_keepalive_required = ?,
max_duration_seconds = ?,
is_debug_request = ?,
maybe_routing_tag = ?,
@@ -109,6 +117,7 @@ SET
args.priority_level,
args.requires_keepalive,
max_duration_seconds,
args.is_debug_request,
maybe_routing_tag,

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