Compare commits

...
Author SHA1 Message Date
Paul Sajna 6430f63702 update workspace 2023-06-21 01:20:38 -07:00
Paul Sajna 9752f39736 headless bevy 2023-06-21 01:17:41 -07:00
Paul Sajna a11779e3aa roko bevy testing 2023-06-19 11:31:32 -07:00
Brandon Thomas 523c02326b more logging 2023-05-28 22:34:48 -07:00
Brandon Thomas 37eef276a0 more logger methods 2023-05-28 21:20:30 -07:00
Brandon Thomas f5cbedb230 fix logger 2023-05-28 21:01:14 -07:00
Brandon Thomas 6994a9c2ce documentation 2023-05-28 19:07:45 -07:00
Brandon Thomas 213742ff29 override python logger in dockerfile 2023-05-28 19:05:51 -07:00
Brandon Thomas df4f1e6a6c fix log levels 2023-05-28 19:04:09 -07:00
Brandon Thomas 64fa281bc1 parameter for flushing logs 2023-05-28 18:52:01 -07:00
Brandon Thomas bd386aa70b don't need the logger.py in isolation 2023-05-28 18:16:35 -07:00
Brandon Thomas 28875c9272 Add patches to upstream logger 2023-05-28 18:16:11 -07:00
Brandon Thomas a79bfc7a24 add version of logger we're using in production - we'll patch instead 2023-05-28 17:42:32 -07:00
Brandon Thomas ecca8ff17c we'll need to replace python logging in our container for performance 2023-05-28 17:33:04 -07:00
Brandon Thomas a3cabf6779 fix import 2023-05-28 00:53:59 -07:00
Brandon Thomas dd35a7cca9 ignore sensitive env vars 2023-05-28 00:52:05 -07:00
Brandon Thomas f876cac4cf job pause file 2023-05-27 23:23:42 -07:00
Brandon Thomas d2b840cb13 analytics queries 2023-05-27 00:32:09 -07:00
Brandon Thomas 85bac00194 password_reset table 2023-05-23 02:12:58 -07:00
Brandon Thomas 367a516f89 fix option typo 2023-05-23 01:41:01 -07:00
Brandon Thomas 5fe85072a2 pack more in docker container, "hacky fix" flag for so-vits-svc 2023-05-23 00:16:11 -07:00
Brandon Thomas 5867d2356c install vim 2023-05-22 22:21:53 -07:00
Brandon Thomas 275333c1ed netstat in docker image 2023-05-22 17:44:41 -07:00
Brandon Thomas 5ec2cde68f report errors better 2023-05-22 11:15:19 -07:00
Brandon Thomas daf5a63f86 cleanup temp dir 2023-05-22 02:44:34 -07:00
Brandon Thomas 2fe3d5dc99 add less to container 2023-05-22 02:38:20 -07:00
Brandon Thomas 44df952bd1 fix inference job path for VC uploaded audio 2023-05-22 01:51:12 -07:00
Brandon Thomas 5bf98f70d9 rework where temp storage lives: download vs workspace 2023-05-22 00:52:49 -07:00
Brandon Thomas af685b37cf fix keepalive redis in job 2023-05-21 22:11:19 -07:00
Brandon Thomas 0f7ff50cf6 better error logging 2023-05-21 20:01:08 -07:00
Brandon Thomas 1ae8d8d615 Fail jobs with elapsed keepalive 2023-05-21 18:16:44 -07:00
Brandon Thomas 63c0124267 test execution safety 2023-05-21 17:52:53 -07:00
Brandon Thomas 17e8c1942e codegen db 2023-05-21 17:49:58 -07:00
Brandon Thomas cf24a07bba Set keepalive key 2023-05-21 17:48:29 -07:00
Brandon Thomas 9ece30722f Enqueue inferene with keepalive flag 2023-05-21 17:21:17 -07:00
Brandon Thomas 9ab977d016 Add job table keepalive column 2023-05-21 17:04:02 -07:00
Brandon Thomas ebd3f52717 tmux to gpu container 2023-05-19 04:22:53 -07:00
Brandon Thomas 35a75e144a unban IP 2023-05-19 04:08:29 -07:00
Brandon Thomas 4b145a7419 Patch for firefox opus audio uploads failing 2023-05-19 04:06:36 -07:00
Brandon Thomas eb539e9142 query was wrong 2023-05-19 02:08:51 -07:00
Brandon Thomas 37604cdd7b config 2023-05-19 02:48:22 -04:00
Brandon Thomas f724031aa3 config 2023-05-19 02:44:14 -04:00
Brandon Thomas b8b10f6fc1 f0-method and frequency transpose for job 2023-05-18 12:17:08 -07:00
Brandon Thomas bd4bcab2c2 args for pitch/f0 method in http handler 2023-05-18 00:14:42 -07:00
Brandon Thomas caa3e3ae53 clear filesystem when full 2023-05-16 01:13:54 -07:00
Brandon Thomas 7cd8099ab5 variable length tts inference text 2023-05-15 00:47:57 -07:00
Brandon Thomas 6ec39b9c68 loyalty for VC contributors 2023-05-14 21:00:27 -07:00
Brandon Thomas c8b4b7daa0 analytics queries 2023-05-13 09:27:57 -07:00
Brandon Thomas a294549d02 queries 2023-05-09 12:55:07 -04:00
Brandon Thomas 33ff75274f add ripgrep 2023-05-04 06:17:12 -07:00
Brandon Thomas 945e5226c5 add a few tools to the container 2023-05-04 03:47:54 -07:00
Brandon Thomas 85a52cd26e config comments 2023-05-04 03:09:23 -04:00
Brandon Thomas 32ee4209da this configuration works 2023-05-04 03:07:38 -04:00
Brandon Thomas f94cdac47d local dev confi 2023-05-03 23:18:53 -04:00
Brandon Thomas a2ea870ac7 update nvidia driver ??? 2023-05-02 23:01:29 -07:00
Brandon Thomas a2c48d7469 kill subprocess if timeout elapses 2023-05-02 22:19:03 -07:00
Brandon Thomas fe3dd7d66b add routing tags to inference jobs 2023-05-02 21:31:39 -07:00
Brandon Thomas 88fae4ba89 timeout argument 2023-05-02 06:12:49 -07:00
Brandon Thomas 6505e67bf2 analytics 2023-05-02 04:37:21 -07:00
Brandon Thomas 3453fe0e3b add minor logging 2023-05-02 01:18:25 -07:00
Brandon Thomas 8b36d870d1 fix inference job, add env perameter for threshold 2023-05-01 06:52:34 -07:00
Brandon Thomas 9555ac51fe Skip jobs that aren't on filesystem 2023-05-01 06:42:41 -07:00
Brandon Thomas f00b4011b5 record inferecne duration stats to db 2023-05-01 04:17:36 -07:00
Brandon Thomas d1d208d714 add more timing stats to the jobs tables 2023-05-01 03:59:05 -07:00
Brandon Thomas a5ce9a3cc4 analytics 2023-04-30 08:16:27 -07:00
Brandon Thomas 6ad2468e59 analytics queries 2023-04-30 08:09:07 -07:00
Brandon Thomas c59695343f extend media/symphonia to work with webm+opus 2023-04-30 05:03:40 -07:00
Brandon Thomas 52a83609b6 test case for failing web browser uploads 2023-04-30 00:31:03 -07:00
Brandon Thomas f710b68a3e Fix broken tests, add testing script 2023-04-29 23:56:48 -07:00
Brandon Thomas 3d63e34ca1 analytics queries 2023-04-29 23:36:02 -07:00
Brandon Thomas 4a1f1441bf split analytics and operational queries 2023-04-29 06:08:34 -07:00
Brandon Thomas ee90f03436 add extra inference job stats 2023-04-29 05:11:57 -07:00
Brandon Thomas 1858aea619 new job queue stats endpoint 2023-04-29 04:58:51 -07:00
Brandon Thomas 592ba627be documentation 2023-04-29 03:53:31 -07:00
Brandon Thomas f754c6e41f add execution time to job queries 2023-04-29 03:10:31 -07:00
Brandon Thomas 54af3d301c Add execution millis columns to jobs tables 2023-04-29 02:41:49 -07:00
Brandon Thomas 22eeacf355 stricter compiler flags 2023-04-29 02:30:41 -07:00
Brandon Thomas 630aa497f3 note 2023-04-29 02:28:32 -07:00
Brandon Thomas 6e9c05c596 bootstrap / env config improved, on-prem, etc. 2023-04-29 02:26:13 -07:00
Brandon Thomas 3f781ad98f clean up worker hostname / cluster name in jobs 2023-04-29 02:16:17 -07:00
Brandon Thomas 5d038fdf8f codegen db 2023-04-29 01:50:14 -07:00
Brandon Thomas a09acf7c53 add extra metadata to inference and download jobs 2023-04-29 01:49:25 -07:00
Brandon Thomas 3ba64618c3 add tracking columns to generic_inference_job too 2023-04-29 00:17:44 -07:00
Brandon Thomas 73e583c7ed Add extra metadata tracking to generic download jobs table 2023-04-29 00:08:54 -07:00
Brandon Thomas 1d7a54f640 python for docker image 2023-04-28 16:09:38 -07:00
Brandon Thomas 552fae54a7 fix 2023-04-28 16:02:04 -07:00
Brandon Thomas 4d2ae85fd9 send hubert path for docker 2023-04-28 16:01:18 -07:00
Brandon Thomas 76775dec60 hubert path config 2023-04-28 15:54:53 -07:00
Brandon Thomas 22bc8d54a0 organize settings 2023-04-28 18:46:18 -04:00
Brandon Thomas 878bff867a fix dev env vars 2023-04-28 02:01:11 -04:00
Brandon Thomas 05d5bfc1a7 rename 2023-04-27 23:00:16 -07:00
Brandon Thomas 3acdd0b5e2 rebase fix 2023-04-28 01:47:40 -04:00
Brandon Thomas 1a7a74ee8a so-vits-svc auto_predict_f0 default to false, add option 2023-04-27 22:45:28 -07:00
Brandon Thomas 820f4ebc32 fix firefox/opus again 2023-04-27 15:54:13 -07:00
Brandon Thomas 423fb369db add audio/opus 2023-04-27 08:15:46 -07:00
Brandon Thomas 2a58079289 copy all env vars to child process 2023-04-27 07:19:46 -07:00
Brandon Thomas b2df674178 report mimetype errors 2023-04-27 02:00:31 -07:00
Brandon Thomas 1fd33e76b4 update base image 2023-04-27 01:02:23 -07:00
Brandon Thomas 824683b974 fixup dockerfile 2023-04-27 00:50:45 -07:00
Brandon Thomas 4bed11d21d change name again 2023-04-27 00:12:48 -07:00
Brandon Thomas 13bdcbdda6 fix names of actions 2023-04-27 00:11:40 -07:00
Brandon Thomas f49c724303 GPU + CPU dockerfiles 2023-04-27 00:09:31 -07:00
Brandon Thomas a9502c183b flexible config path for inference job 2023-04-26 10:17:49 -07:00
Brandon Thomas b469a237ce temporarily add nvidia/sound packages to rust monorepo images 2023-04-26 09:14:17 -07:00
Brandon Thomas 0df93c48c3 configs for download job 2023-04-26 07:48:31 -07:00
Brandon Thomas 070c192633 set config and test wav upfront and at runtime 2023-04-26 07:43:59 -07:00
Brandon Thomas 75a68c7e0f install python 2023-04-26 05:45:28 -07:00
Brandon Thomas b2db079cf5 env vars for docker 2023-04-26 04:46:40 -07:00
Brandon Thomas 6658281a1c try more env vars for caching 2023-04-26 04:38:27 -07:00
Brandon Thomas 8cb04f1dcb huggingface+nltk caches 2023-04-26 04:25:43 -07:00
Brandon Thomas 58f6ee68df more flexible command specification 2023-04-26 04:11:06 -07:00
Brandon Thomas d0cef7bec9 hack 2023-04-26 03:30:38 -07:00
Brandon Thomas 8eed406fbd inference-job hack (see if we can run without 'svc' command) 2023-04-26 01:31:02 -07:00
Brandon Thomas 44586c4cee copy the correct env var files 2023-04-25 20:56:18 -07:00
Brandon Thomas 02f5aacb8e more robust configuration of download-job 2023-04-25 20:55:18 -07:00
Brandon Thomas 001ff86ed3 robust configuration for download-job 2023-04-25 20:51:51 -07:00
Brandon Thomas 94b406eca2 much more robust app initialization 2023-04-25 20:44:59 -07:00
Brandon Thomas f8bdea1b3b build error fix 2023-04-25 17:20:21 -07:00
Brandon Thomas 8a37a7240c more DDoS IPs 2023-04-25 17:16:29 -07:00
Brandon Thomas a4c1abfe9c codegen 2023-04-25 06:07:01 -07:00
Brandon Thomas 6bb7a18676 report model title 2023-04-25 04:13:28 -07:00
Brandon Thomas a8173226ea report bucket hash in results 2023-04-25 03:00:31 -07:00
Brandon Thomas 692c3f64b6 two different firehose notifications 2023-04-25 01:33:47 -07:00
Brandon Thomas 4842b9bbc1 local dev config changes 2023-04-25 04:28:00 -04:00
Brandon Thomas a507f8bc38 nope, didn't work 2023-04-25 01:27:28 -07:00
Brandon Thomas 24f2c07199 try to fix duration bug 2023-04-25 01:25:13 -07:00
Brandon Thomas e871dde078 add upload source 2023-04-25 01:09:24 -07:00
Brandon Thomas 47ff379018 timeout 2023-04-24 02:53:59 -07:00
Brandon Thomas cdb0f37889 downgrode symphonia off-master branch to support opus for browsers 2023-04-24 02:32:13 -07:00
Brandon Thomas 6d7c3c6e5f maybe build with correct codecs? 2023-04-24 01:46:52 -07:00
Brandon Thomas 7b72d51bd3 debug logging 2023-04-24 01:11:37 -07:00
Brandon Thomas 11a9e1249c remove inference args (for now) 2023-04-23 23:29:09 -07:00
Brandon Thomas f3a6ddb70a premium priority levels 2023-04-23 23:05:24 -07:00
Brandon Thomas d2aa07228b simplify upload endpoint 2023-04-23 22:30:13 -07:00
Brandon Thomas a2c3668beb upload audio endpoint 2023-04-23 22:25:46 -07:00
Brandon Thomas 15d66a4530 propagate media input token to inference result 2023-04-23 20:48:09 -07:00
Brandon Thomas 75523811e4 ops query 2023-04-23 13:59:01 -07:00
Brandon Thomas 4672102da4 code changes stemming from schema changes 2023-04-23 05:03:37 -07:00
Brandon Thomas ca59189dd9 simplify media_uploads schema 2023-04-23 04:31:00 -07:00
Brandon Thomas 3564c1b459 more schema mods 2023-04-23 04:13:50 -07:00
Brandon Thomas 78263e3c49 media token type 2023-04-23 03:58:16 -07:00
Brandon Thomas e36fb66e05 migrate voice_conversion_results 2023-04-23 03:24:05 -07:00
Brandon Thomas 1540d87018 cleanup 2023-04-23 02:12:46 -07:00
Brandon Thomas 61f0869359 calculate result metadata 2023-04-23 02:02:49 -07:00
Brandon Thomas d23c7abfeb remove deprecated crate -> move hashing + mimetype functions out 2023-04-23 01:31:58 -07:00
Brandon Thomas 2d59891dee organize "file"-related/adjacent crates together 2023-04-23 00:27:09 -07:00
Brandon Thomas 2f86bc75ac crate to handle just mimetype ops 2023-04-23 00:08:59 -07:00
Brandon Thomas 8c5fb0bee2 badge granter for voice conversion models 2023-04-22 06:22:06 -07:00
Brandon Thomas b9f0d7749d fix transaction 2023-04-22 05:36:22 -07:00
Brandon Thomas b2caa3758a fix synthetic id 2023-04-22 05:22:06 -07:00
Brandon Thomas de656d4d74 fix 2023-04-22 04:47:09 -07:00
Brandon Thomas c803232a52 creator synthetic id 2023-04-22 04:44:40 -07:00
Brandon Thomas cd9b0080dd fix result upload directory 2023-04-22 04:04:15 -07:00
Brandon Thomas 6885eb5fc9 temporarily don't get file metadata 2023-04-22 03:55:25 -07:00
Brandon Thomas 100ad0da35 use public bucket client 2023-04-22 03:48:52 -07:00
Brandon Thomas 7010d56bc3 error handling json hydration 2023-04-22 03:44:10 -07:00
Brandon Thomas b34371eef0 try to only parse payload if not empty string 2023-04-22 03:42:29 -07:00
Brandon Thomas e6542438b5 create model storage directory 2023-04-22 03:29:26 -07:00
Brandon Thomas 287e3e5f0c inference for local dev 2023-04-22 02:17:58 -07:00
Brandon Thomas 8fcb908af9 code compiles 2023-04-22 02:14:44 -07:00
Brandon Thomas 56e84f434f forgot schema migrations 2023-04-22 02:05:44 -07:00
Brandon Thomas 925f2d78ae more sane schema for voice conversion results (bucket storage) 2023-04-22 02:04:44 -07:00
Brandon Thomas 90219594bb insert result record 2023-04-22 01:43:24 -07:00
Brandon Thomas 08e8560499 voice conversion result upload (WIP) 2023-04-21 23:27:20 -07:00
Brandon Thomas 9e38b9a2fc progress on so-vits-svc inference 2023-04-21 23:12:24 -07:00
Brandon Thomas e9a6320eab so-vits-svc inference (wip) 2023-04-21 21:51:37 -07:00
Brandon Thomas da05885d7d don't upload duplicates 2023-04-21 05:54:10 -07:00
Brandon Thomas ba9f716ff8 encode fewer bytes in inference jobs 2023-04-21 02:24:23 -07:00
Brandon Thomas 2633c5f0ef clean up tokens in vc inference 2023-04-21 02:05:14 -07:00
Brandon Thomas da805b4f1d clean upload hashing, better error messages 2023-04-21 00:22:58 -07:00
Brandon Thomas 9eb75c7eba list media uploads by session 2023-04-20 01:40:36 -07:00
Brandon Thomas 75607b3c12 tests, aspath 2023-04-20 00:27:37 -07:00
Brandon Thomas ce69b1b055 filesys crate cleanup 2023-04-20 00:18:29 -07:00
Brandon Thomas 9ee7fdbac5 move endpoint 2023-04-19 01:18:07 -07:00
Brandon Thomas 67e3ecebc1 Voice conversion model list endpoint 2023-04-19 00:43:27 -07:00
Brandon Thomas 52db0b7796 python3.6 2023-04-18 15:46:08 -07:00
Brandon Thomas 15fa5a2bee update image 2023-04-18 15:44:58 -07:00
Brandon Thomas 32babc99f0 update image 2023-04-18 12:47:58 -07:00
Brandon Thomas bdac796e51 update tt2 legacy inference to support docker, etc, unfront config 2023-04-18 12:37:30 -07:00
Brandon Thomas 18c50af218 Add "Deepfake CNN" level 2023-04-16 02:54:57 -07:00
Brandon Thomas 62cbde94bc anderson cooper voice config 2023-04-15 23:43:54 -07:00
Brandon Thomas b2f9b44e96 uncommitted changes 2023-04-15 23:36:26 -07:00
Brandon Thomas 6a48a5372c fix arg 2023-04-13 16:58:26 -07:00
Brandon Thomas 1b0368664a update image 2023-04-13 19:53:37 -04:00
Brandon Thomas 6a83524fd9 switch from 'onnx' to 'infer' for checking model integrity 2023-04-13 16:48:14 -07:00
Brandon Thomas 233247f3c0 config path 2023-04-13 15:59:16 -07:00
Brandon Thomas 60045a01d0 fix command 2023-04-13 13:33:57 -07:00
Brandon Thomas dc5dfd9831 update docker image 2023-04-13 13:24:07 -07:00
Brandon Thomas 7b36fc0b98 Update model check command (so-vits-svc), upgrade easyenv 2023-04-13 12:52:18 -07:00
Brandon Thomas 92e1d10809 wip so-vits-svc 2023-04-12 02:53:57 -07:00
Brandon Thomas 4a486cedd2 add so-vits-svc download type 2023-04-10 01:39:54 -07:00
Brandon Thomas 004cde84a7 move enum 2023-04-09 23:03:15 -07:00
Brandon Thomas 61b74500d8 codegen, a few enums 2023-04-09 22:55:21 -07:00
Brandon Thomas 8285826ed0 move where config lives 2023-04-09 20:16:13 -07:00
Brandon Thomas 03d0110ee6 ml docker image 2023-04-09 23:02:57 -04:00
Brandon Thomas 34517fbaff fix build errors 2023-04-09 19:18:07 -07:00
Brandon Thomas 839f7885fb try another path 2023-04-09 02:58:23 -07:00
Brandon Thomas cee3ffb217 fix docker env vars 2023-04-09 02:29:22 -07:00
Brandon Thomas 90198252b8 nltk env var 2023-04-09 02:24:41 -07:00
Brandon Thomas 165130321f try setting cache dir with docker now 2023-04-09 02:10:34 -07:00
Brandon Thomas 061c2c7b07 try to move cache dir again 2023-04-09 01:46:37 -07:00
Brandon Thomas 413960b6cf actually pass env to popen 2023-04-09 01:37:33 -07:00
Brandon Thomas cc4b7deaa9 huggingface cache dir 2023-04-09 01:27:50 -07:00
Brandon Thomas 8229a3cfb3 record entity token/type after job completes 2023-04-08 22:59:16 -07:00
Brandon Thomas b461c7e8e7 make field optional 2023-04-08 21:03:07 -07:00
Brandon Thomas c58f23c117 fixup inference-job 2023-04-08 20:52:51 -07:00
Brandon Thomas 048cc26b6b fixup storyteller-web 2023-04-08 20:50:22 -07:00
Brandon Thomas 9b5508d8c0 fixup mysql queries 2023-04-08 20:41:10 -07:00
Brandon Thomas a81428913d migrate generic_inference_jobs to include better indices/foreign keys 2023-04-08 19:54:58 -07:00
Brandon Thomas 756c8e09ae inference status endpoints 2023-04-08 18:49:59 -07:00
Brandon Thomas 5b97360724 update upload routes 2023-04-08 01:09:22 -07:00
Brandon Thomas 79ad78bdde header to route TT2 requests to new worker 2023-04-06 22:00:44 -07:00
Brandon Thomas 311299105b updated docker image 2023-04-07 00:48:24 -04:00
Brandon Thomas 9dad3a153c ml repo update 2023-04-06 22:50:21 -04:00
Brandon Thomas 93157b50c8 vits inference command roughly done, need to test 2023-04-06 18:58:07 -07:00
Brandon Thomas 47fbc1704d analytics 2023-04-06 16:48:31 -07:00
Brandon Thomas efba106d3c analytics query 2023-04-06 16:26:06 -07:00
Brandon Thomas e340eee250 progress on VITS (WIP) 2023-04-06 16:02:01 -07:00
Brandon Thomas 73be1bbf05 git rid of dated enum, start work on VITS inference 2023-04-06 14:35:29 -07:00
Brandon Thomas 81306d1a56 (untested) route VITS tts to generic job type 2023-04-05 01:48:50 -07:00
Brandon Thomas 8e341f7a83 strongly typed tts model type 2023-04-05 01:21:31 -07:00
Brandon Thomas 1978e5e653 db index on tts_models.tts_model_type 2023-04-05 00:53:52 -07:00
Brandon Thomas 8eaaad9b55 fix path error 2023-04-04 15:01:04 -07:00
Brandon Thomas 082c284add debugging 2023-04-04 14:47:15 -07:00
Brandon Thomas a83e5ff224 logging 2023-04-04 14:25:50 -07:00
Brandon Thomas abaaaf2fdb dev 2023-04-04 14:12:33 -07:00
Brandon Thomas 3409689566 fix path handling, introduce another (smaller scope) filesystem crate 2023-04-04 13:59:21 -07:00
Brandon Thomas 84c0e42964 fmt 2023-04-04 12:53:09 -07:00
Brandon Thomas b848c2b549 update docker image for appropriate cuda version 2023-04-04 15:50:06 -04:00
Brandon Thomas 85abbd8587 set python intepreter, fix path 2023-04-04 03:14:40 -07:00
Brandon Thomas b844191db7 downloader image 2023-04-04 06:08:19 -04:00
Brandon Thomas 0267a4799d fix a few errors with paths and quoting 2023-04-04 03:07:54 -07:00
Brandon Thomas c50060b161 no vits download venv 2023-04-04 02:57:39 -07:00
Brandon Thomas a508a843bd root dir 2023-04-04 02:56:25 -07:00
Brandon Thomas d0bad0c8fb docker image for testing 2023-04-04 05:50:48 -04:00
Brandon Thomas d2c99a7bad configure download-job for VITS (wip) 2023-04-04 00:24:28 -07:00
Brandon Thomas 681d923ae0 Add 'vits' enum to tts model tables 2023-04-04 00:11:48 -07:00
Brandon Thomas 9e563a0640 VITS download WIP (nearly done) 2023-04-03 23:41:18 -07:00
Brandon Thomas db30096cb9 rename module in inference-job 2023-04-03 21:43:42 -07:00
Brandon Thomas 76f9f5a850 Refactor download job, begin to work on VITS downloading 2023-04-03 21:37:07 -07:00
Brandon Thomas 3a0eafee11 report back on how to handle the upload 2023-04-02 21:34:38 -07:00
Brandon Thomas 9fbecd5568 enqueue vits uploads (in theory) 2023-04-02 21:21:16 -07:00
Brandon Thomas b3dedfc5a8 WIP VITS uploads 2023-04-02 21:05:05 -07:00
Brandon Thomas 8ded313e7b configure storyteller-web with more db (why so slow in dev?!) 2023-04-02 20:23:12 -07:00
Brandon Thomas e305928b45 flexible docker image sha 2023-04-02 20:01:45 -07:00
Brandon Thomas db48ee0fd8 mac frontend cors 2023-04-01 05:40:25 -04:00
Brandon Thomas 5beedcb5e3 add one color 2023-03-25 23:12:14 -04:00
Brandon Thomas e43feeb700 add random avatar/color to several endpoints 2023-03-25 19:54:12 -04:00
Brandon Thomas 38dc835ff4 add to event feed 2023-03-25 19:33:59 -04:00
Brandon Thomas 62b19b2b0e functions to generate random avatar + color 2023-03-25 19:04:37 -04:00
Brandon Thomas b7b92f4419 reduce user tokens to a single list 2023-03-23 02:49:33 -04:00
Brandon Thomas 7ee7ff3875 split ipv4/ipv6 files 2023-03-23 02:44:28 -04:00
Brandon Thomas 29237d3ead user tokens 2023-03-23 02:42:05 -04:00
Brandon Thomas 5afbfc0ec4 change troll sequences 2023-03-23 02:32:05 -04:00
Brandon Thomas 6e5a2d1789 more accounts 2023-03-23 02:13:07 -04:00
Brandon Thomas 13281ea3b1 more accounts 2023-03-23 02:10:36 -04:00
Brandon Thomas 98f80a68de documentation on removed ipv6 bans (in cloudflare, not our code) 2023-03-23 01:55:34 -04:00
Brandon Thomas 075fcfb81e unblock ipv6 2023-03-23 01:42:27 -04:00
Brandon Thomas a8c45cfac2 more accounts 2023-03-23 01:40:56 -04:00
Brandon Thomas f0a4f0a4f7 more ips / accounts 2023-03-23 01:09:24 -04:00
Brandon Thomas 3b78853d7c new user tokens and ip addresses 2023-03-23 01:03:58 -04:00
Brandon Thomas 98b6bb34a7 lighten up on the troll text 2023-03-23 01:02:18 -04:00
Brandon Thomas 4d759719f6 more IPs and user tokens 2023-03-23 00:52:41 -04:00
Brandon Thomas ac28ff8a39 start blocking 101soundboards IPs too 2023-03-23 00:50:03 -04:00
Brandon Thomas 43a33a00ee gitignore 2023-03-23 00:43:27 -04:00
Brandon Thomas 8bbc490b61 ignore vim temp files 2023-03-23 00:43:01 -04:00
Brandon Thomas 168a476b72 user token + ip address troll bans 2023-03-23 00:28:00 -04:00
Brandon Thomas 2cebfbb3fc more 101soundboards user tokens 2023-03-23 00:12:44 -04:00
Brandon Thomas d57e070c8c dedup 2023-03-22 23:58:06 -04:00
Brandon Thomas bde6b4d562 more user tokens 2023-03-22 23:56:12 -04:00
Brandon Thomas 9cde097d38 more stupid accounts 2023-03-22 23:53:13 -04:00
Brandon Thomas 1d7d1ba194 more 101soundboards user tokens 2023-03-22 23:50:36 -04:00
Brandon Thomas 632cf5a710 more 101soundboards user tokens 2023-03-22 23:40:19 -04:00
Brandon Thomas c2e287f6f4 more damned accounts 2023-03-22 22:55:26 -04:00
Brandon Thomas 844799e30e more 101soundboards accounts 2023-03-22 22:49:38 -04:00
Brandon Thomas c1bd8ed611 actually fix builds 2023-03-22 19:57:04 -04:00
Brandon Thomas 1466bca4d7 fix build 2023-03-22 18:32:36 -04:00
Brandon Thomas 12fdf24028 temp disable build 2023-03-22 18:28:24 -04:00
Brandon Thomas cefb770340 codegen db 2023-03-22 16:49:24 -04:00
Brandon Thomas e971ea98dc fix troll bans 2023-03-22 16:47:10 -04:00
Brandon Thomas 9ab8b366e9 ban 101 soundboards 2023-03-22 16:24:23 -04:00
Brandon Thomas 96563fa345 add a means to ban user tokens (or disable the service in weird ways) 2023-03-22 16:05:09 -04:00
Brandon Thomas 67ab94664c working locally 2023-03-22 15:34:02 -04:00
Brandon Thomas 99f1226115 I have to run this under Docker locally since it's ancient 2023-03-21 05:35:08 -04:00
Brandon Thomas 9c45a17b8d new inference subprocess command 2023-03-21 05:18:07 -04:00
Brandon Thomas 2cf5a6f942 TTS inference almost working on generic-inference-job 2023-03-21 02:01:13 -04:00
Brandon Thomas 071928d7bf port more TT2 logic 2023-03-21 00:49:21 -04:00
Brandon Thomas b8442b54ee cleanup 2023-03-21 00:18:39 -04:00
Brandon Thomas 530d891ce9 about to bolt on TT2 2023-03-21 00:11:42 -04:00
Brandon Thomas 972f119468 query tts model 2023-03-20 23:57:44 -04:00
Brandon Thomas 9004432620 generic inference jobs can be listed (hacky fix) 2023-03-20 23:42:23 -04:00
Brandon Thomas 81a3bc270b fix generic job list query 2023-03-20 23:11:38 -04:00
Brandon Thomas 84fe5a5762 enqueue generic inference jobs for tt2 2023-03-20 22:28:59 -04:00
Brandon Thomas a02934ca4e Add routing column to inference jobs (wip) 2023-03-20 21:58:08 -04:00
Brandon Thomas 4ddcd43e33 remove a lot of garbage from inference-job 2023-03-20 20:04:49 -04:00
Brandon Thomas 37be0174af put inference job back into "working"(?) order 2023-03-20 19:29:06 -04:00
Brandon Thomas f2e314d168 make sure this gets put in the image 2023-03-20 19:23:54 -04:00
Brandon Thomas 3bd216f00d rename crate, fix path handling, move some env vars 2023-03-20 19:21:58 -04:00
Brandon Thomas dc5885114d env internal crate - search multiple directories for env files 2023-03-20 18:59:43 -04:00
Brandon Thomas 47873497b8 comment APIs needed disambiguation 2023-03-18 18:18:45 -04:00
Brandon Thomas 554766bd2a Don't load IP ban sets that are empty 2023-03-18 13:25:14 -04:00
Brandon Thomas 86382bf219 rename files for better sorting 2023-03-18 13:13:54 -04:00
Brandon Thomas 59b1e28a14 unban IP 2023-03-18 13:12:52 -04:00
Brandon Thomas 3f88a741c9 private model logging + fix(?) 2023-03-18 13:06:19 -04:00
Brandon Thomas 2efcba5da6 fix broken path 2023-03-18 13:00:19 -04:00
Brandon Thomas b4718a2f13 block broken python script IP 104.251.211.22 2023-03-18 12:59:19 -04:00
Brandon Thomas efbb0000f3 fix list comment route 2023-03-18 07:02:50 -04:00
Brandon Thomas 0280e6b706 let's not do this table just yet 2023-03-18 05:37:14 -04:00
Brandon Thomas 79d568ee14 codegen db 2023-03-18 04:51:35 -04:00
Brandon Thomas 85630390a0 route bindings, list endpoint 2023-03-18 04:33:53 -04:00
Brandon Thomas 215b727bc1 create comment, delete comment handlers (not tested) 2023-03-18 03:54:30 -04:00
Brandon Thomas e29c0b4c68 edit comment query 2023-03-18 02:13:46 -04:00
Brandon Thomas c81e6af507 fix codegen script 2023-03-18 01:35:40 -04:00
Brandon Thomas 98d30917e5 rename crate 'database_queries' -> 'mysql_queries' because sqlite 2023-03-18 01:19:15 -04:00
Brandon Thomas e62e409857 refactor package directory structure 2023-03-18 01:11:10 -04:00
Brandon Thomas 417137a9a8 deprecate some crates 2023-03-18 01:07:01 -04:00
Brandon Thomas 0da1994f0c 101soundboards user tokens 2023-03-18 00:45:33 -04:00
Brandon Thomas 36d016c3c7 todo 2023-03-17 09:34:58 -04:00
Brandon Thomas b22e978e54 cleanup tts authorization logic 2023-03-17 08:52:04 -04:00
Brandon Thomas c387f47c97 (untested) disallow use of private models unless owner 2023-03-17 08:34:15 -04:00
Brandon Thomas 1a09676327 codegen db 2023-03-17 07:57:50 -04:00
Brandon Thomas e516f85e5f filter out models that are private/hidden 2023-03-17 07:54:57 -04:00
Brandon Thomas e16b86d36e analytics query for non-public tts models 2023-03-17 06:50:06 -04:00
Brandon Thomas 003a86cd31 delete comments 2023-03-17 06:42:04 -04:00
Brandon Thomas ebf48e20be list comments endpoint 2023-03-16 12:21:28 -04:00
Brandon Thomas df2444ddc0 insert comment 2023-03-16 11:09:26 -04:00
Brandon Thomas 6b6a2ceeba codegen 2023-03-16 10:42:46 -04:00
Brandon Thomas 80da0d9649 Add tts result audio path to result endpoint 2023-03-16 10:31:28 -04:00
Brandon Thomas b8fd0486c7 Untested query for inserting audit log items 2023-03-16 10:25:47 -04:00
Brandon Thomas 12ffb2ded1 new token types: comments, audit logs 2023-03-16 09:36:13 -04:00
Brandon Thomas f810256b9c new table enums 2023-03-16 09:28:49 -04:00
Brandon Thomas 461030b681 new tables (WIP) for comments + voice survey 2023-03-16 09:03:56 -04:00
Brandon Thomas a33ff3f060 20 trending english voices 2023-03-16 09:02:43 -04:00
Brandon Thomas 98736324dc 25 trending english voices 2023-03-16 09:01:57 -04:00
Brandon Thomas 89a6f36f1a gitignore for windows 2023-03-13 20:33:31 -04:00
Brandon Thomas ac5bcbdd16 aichatbot: handler for current level 2023-03-13 18:27:25 -04:00
Brandon Thomas 7566c0d71c use strum and default for more maintainable options 2023-03-13 18:20:58 -04:00
Brandon Thomas 0ca007b6e7 add level option for AiChatbotSidecar 2023-03-13 18:09:28 -04:00
Brandon Thomas cbe07e2b3e move test function out of aichatbot-sidecar 2023-03-13 17:50:04 -04:00
Brandon Thomas 495c01c38c Merge pull request #40 from storytold/bt-cache-session
cache sessions + purge cache on billing, edit profile, etc.
2023-03-12 05:19:28 -04:00
797 changed files with 31321 additions and 7360 deletions
+8 -15
View File
@@ -14,10 +14,14 @@ MIGRATION_DIRECTORY=_sql/migrations/
# See https://github.com/launchbadge/sqlx/tree/master/sqlx-cli#readme
#SQLX_OFFLINE=true
# We can't serve HTTPS locally without self-signed certificate nonsense.
COOKIE_SECURE=false
COOKIE_DOMAIN=.jungle.horse
WEBSITE_HOMEPAGE_REDIRECT=http://jungle.horse
# NB(bt, 2023-03-20):
# These are used in storyteller-web, image-generation-service, and websocket-gateway.
# I'm moving them to env configs that live under storyteller-web/.env.
# This will break the other services for now.
# # We can't serve HTTPS locally without self-signed certificate nonsense.
# COOKIE_SECURE=false
# COOKIE_DOMAIN=.jungle.horse
# WEBSITE_HOMEPAGE_REDIRECT=http://jungle.horse
# Bucket config (non-secret)
REGION_NAME=us-east1
@@ -71,14 +75,3 @@ TTS_HIFIGAN_SUPERRES_VOCODER_MODEL_FILENAME=hifigan_superres_twilight_33000.pt
# Development key. Permissible to check in.
NEWRELIC_API_KEY=c402be1c4c4216ec83d0cfc0851520cfFFFFNRAL
# Stripe configs
# All secrets are development and okay to check in
STRIPE_CHECKOUT_SUCCESS_URL_PATH=/checkout_success
STRIPE_CHECKOUT_CANCEL_URL_PATH=/checkout_cancel
STRIPE_PORTAL_RETURN_URL_PATH=/portal_success
STRIPE_PORTAL_DEFAULT_CONFIG_ID=bpc_1LyPPREU5se17MekYiViZF12
# STRIPE_PORTAL_DEFAULT_CONFIG_ID=bpc_1M4jc3EU5se17MekmgdS4dDJ # Production (not a secret)
STRIPE_PUBLISHABLE_KEY=pk_test_51KZvWXEU5se17Mekx6e0gw32ovDF78k2eeaGctLIs8oQVxN6DerEp1BDqh6gLMYKli4VsTZoVGHoxq5RmwKMlxtP00r59UEEad
STRIPE_SECRET_KEY=sk_test_51KZvWXEU5se17Mek11ZdnWr4frnyw7tWOPuvl3pRzL290zvkT6KqcbGUl3fcvc3hA8oH6lWXz2kGWXXUlNcCuDxB003uVT9JX0
STRIPE_SECRET_WEBHOOK_SIGNING_KEY=whsec_40b60bd75768052532b63dbeefa7a1b163e182c3e657fb27fa906ef49a2cd59f
-25
View File
@@ -1,25 +0,0 @@
# Environmental configurations specific to `download-job`.
# These are defaulted for dev and are easy to overwrite in production with K8s environment variables.
# !! DOES *NOT* CONTAIN SECRETS !!
WEB_DOWNLOADER_COMMAND=./download_internet_file.py
WEB_DOWNLOADER_MAYBE_VENV_SCRIPT=./python/bin/activate
WEB_DOWNLOADER_MAYBE_DOCKER_IMAGE=d73f28ce3ff6
SOFTVC_MODEL_CHECK_ROOT_DIRECTORY=/
SOFTVC_MODEL_CHECK_MAYBE_VENV_COMMAND="source python/bin/activate"
SOFTVC_MODEL_CHECK_MAYBE_DOCKER_IMAGE=a79106991ce3
TACOTRON_MODEL_CHECK_ROOT_DIRECTORY=/models/tts
TACOTRON_MODEL_CHECK_MAYBE_VENV_COMMAND="source python/bin/activate"
TACOTRON_MODEL_CHECK_COMMAND=./vocodes_model_check_tacotron.py
TACOTRON_MODEL_CHECK_MAYBE_DOCKER_IMAGE=5642d0fd7fc1
HIFIGAN_SOFTVC_MODEL_CHECK_ROOT_DIRECTORY=/
HIFIGAN_SOFTVC_MODEL_CHECK_MAYBE_VENV_COMMAND="source python/bin/activate"
HIFIGAN_SOFTVC_MODEL_CHECK_MAYBE_DOCKER_IMAGE=a79106991ce3
HIFIGAN_MODEL_CHECK_ROOT_DIRECTORY=/models/tts
HIFIGAN_MODEL_CHECK_MAYBE_VENV_COMMAND="source python/bin/activate"
HIFIGAN_MODEL_CHECK_COMMAND=./vocodes_model_check_hifigan.py
HIFIGAN_MODEL_CHECK_MAYBE_DOCKER_IMAGE=5642d0fd7fc1
@@ -2,7 +2,7 @@
# https://github.com/actions/starter-workflows/ci/docker-publish.yml
# If using base images, don't forget to add READ access, eg. from a package settings page like:
# https://github.com/orgs/storytold/packages/container/docker-base-images-rust-ssl/settings/actions_access
name: Publish Docker Container to GHCR
name: "[CPU] Build GHCR Docker artifact"
on:
push:
branches:
@@ -64,6 +64,7 @@ jobs:
username: ${{ github.actor }} # username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
image_name: storytold/storyteller-rust
dockerfile: service_cpu.Dockerfile
# NB: The `git_push_tag: true` option does not work as expected, so we put the sha in `image_tag`:
# https://github.com/whoan/docker-build-with-cache-action/issues/72
image_tag: latest,${{ github.sha }},${{ steps.vars.outputs.sha_short }}
+113
View File
@@ -0,0 +1,113 @@
# Adapted from
# https://github.com/actions/starter-workflows/ci/docker-publish.yml
# If using base images, don't forget to add READ access, eg. from a package settings page like:
# https://github.com/orgs/storytold/packages/container/docker-base-images-rust-ssl/settings/actions_access
name: "[GPU] Build GHCR Docker artifact"
on:
push:
branches:
# NB: Default-branch doesn't work, despite Github's documentation.
#- $default-branch
- master
env:
IMAGE_NAME: storyteller-rust-gpu
jobs:
# Push image to GitHub Packages.
# See also https://docs.docker.com/docker-hub/builds/
# See also https://depot.dev/blog/docker-layer-caching-in-github-actions
# See also https://evilmartians.com/chronicles/build-images-on-github-actions-with-docker-layer-caching
build-docker-image:
name: "Build Docker Image"
runs-on: ubuntu-22.04 # runs-on: ubuntu-latest
if: github.event_name == 'push'
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v3
# - uses: docker/setup-buildx-action@v1
# name: Set up Docker Buildx
- uses: docker/login-action@v1
name: Login to GitHub Container Registry
with:
registry: ghcr.io
username: ${{ github.actor }} # username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Calculate short SHA
id: vars
# echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
run: |
echo "sha_short=$(echo ${{ github.sha }} | cut -c1-12)" >> $GITHUB_OUTPUT
- name: Emit short SHA
run: |
echo "Full SHA: ${{ github.sha }}"
echo "Short SHA: ${{ steps.vars.outputs.sha_short }}"
#- uses: actions/cache@v2
# name: Cache Docker layers
# with:
# path: /tmp/.buildx-cache
# key: ${{ runner.os }}-buildx-${{ github.sha }}
# restore-keys: |
# ${{ runner.os }}-buildx-
# Docs for this action are at https://github.com/marketplace/actions/build-docker-images-using-cache
- uses: whoan/docker-build-with-cache-action@v6
with:
registry: ghcr.io
username: ${{ github.actor }} # username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
image_name: storytold/storyteller-rust-gpu
dockerfile: service_gpu.Dockerfile
# NB: The `git_push_tag: true` option does not work as expected, so we put the sha in `image_tag`:
# https://github.com/whoan/docker-build-with-cache-action/issues/72
image_tag: latest,${{ github.sha }},${{ steps.vars.outputs.sha_short }}
# NB: Inject the Git SHA into the container so the servers can emit their own version:
build_extra_args: "--build-arg=GIT_SHA=${{ github.sha }}"
# - name: Build image
# run: |
# SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-12)
# docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}" --build-arg GIT_SHA=${SHORT_SHA}
# - name: Push image to GitHub Container Registry
# run: |
# IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# # Change all uppercase to lowercase
# IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
# # Strip git ref prefix from version
# VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# # Strip "v" prefix from tag name
# [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# # Use Docker `latest` tag convention
# [ "$VERSION" == "$default-branch" ] && VERSION=latest
# echo IMAGE_ID=$IMAGE_ID
# echo VERSION=$VERSION
# docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
# docker push $IMAGE_ID:$VERSION
# SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-12)
# docker tag $IMAGE_NAME $IMAGE_ID:$SHORT_SHA
# docker push $IMAGE_ID:$SHORT_SHA
- name: Cleanup / Debug
# This job will run even on failures to help with debugging.
if: always()
run: |
echo "Report at final github action step:"
echo "Disk usage:"
pwd
du -hsc * | sort -hr
+8
View File
@@ -13,6 +13,10 @@ secrets.yaml
_develop/tools/.secrets
_develop/tools/db_secrets.toml
twitch_secrets.toml
crates/service/web/storyteller_web/config/storyteller-web.development-secrets.env
# New env secrets (per-app)
*-secrets.env
# Rust build directory
target/
@@ -49,3 +53,7 @@ models/tacotron2/python/
# Stuff I want to keep around, but not commit
scraps/
# Windows build files
# These should be built by the platform
windows/sqlite/sqlite3.exp
windows/sqlite/sqlite3.lib
+7
View File
@@ -8,6 +8,7 @@
<w>crockford</w>
<w>culted</w>
<w>dalle</w>
<w>demuxer</w>
<w>downvote</w>
<w>fakeyou</w>
<w>ffprobe</w>
@@ -16,16 +17,22 @@
<w>greenlit</w>
<w>hanashi</w>
<w>hifigan</w>
<w>hparams</w>
<w>huggingface</w>
<w>pathbuf</w>
<w>replayable</w>
<w>retryably</w>
<w>scrollback</w>
<w>softvc</w>
<w>sql's</w>
<w>symphonia</w>
<w>tacotron</w>
<w>techcrunch</w>
<w>transcoded</w>
<w>transcodings</w>
<w>unpermitted</w>
<w>upserting</w>
<w>vits</w>
<w>vocoded</w>
<w>vocoder</w>
<w>vocoders</w>
Generated
+2653 -239
View File
File diff suppressed because it is too large Load Diff
+17 -11
View File
@@ -1,4 +1,5 @@
[workspace]
resolver="2"
members = [
# Types: common strongly-typed tokens, ids, payloads, etc.
@@ -15,26 +16,30 @@ members = [
# Shared libraries
"crates/lib/actix_helpers",
"crates/lib/api_clients/cloud_storage",
"crates/lib/api_clients/fakeyou_client",
"crates/lib/api_clients/google_drive_common",
"crates/lib/api_clients/twitch_common",
"crates/lib/bootstrap",
"crates/lib/caching/memory_caching",
"crates/lib/caching/redis_caching",
"crates/lib/clients/cloud_storage",
"crates/lib/clients/fakeyou_client",
"crates/lib/clients/google_drive_common",
"crates/lib/clients/twitch_common",
"crates/lib/concurrency",
"crates/lib/config", # TODO(bt, 2023-02-13): Deprecate or repurpose
"crates/lib/container_common", # TODO(bt, 2023-02-13): Pull apart and rehome pieces
"crates/lib/crockford",
"crates/lib/database_queries", # TODO(bt2, 2023-02-13): Rename "mysql_queries", though this will not live beyond a single DB
"crates/lib/datetimes",
"crates/lib/deprecated/config", # TODO(bt, 2023-02-13): Deprecate or repurpose
"crates/lib/deprecated/container_common", # TODO(bt, 2023-02-13): Pull apart and rehome pieces
"crates/lib/deprecated/http_server_common", # TODO(bt, 2023-03-20): Move useful pieces to actix_helpers
"crates/lib/envvar",
"crates/lib/errors",
"crates/lib/files",
"crates/lib/hashing",
"crates/lib/http_server_common",
"crates/lib/files/filesys",
"crates/lib/files/hashing",
"crates/lib/files/media",
"crates/lib/files/mimetypes",
"crates/lib/idempotency",
"crates/lib/jobs_common",
"crates/lib/media",
"crates/lib/mysql_queries",
"crates/lib/redis_common",
"crates/lib/server_environment",
"crates/lib/sqlite_queries",
"crates/lib/sqlx_mysql_helpers",
"crates/lib/subprocess_common",
@@ -45,6 +50,7 @@ members = [
# Programs: Desktop apps
"crates/programs/aichatbot-sidecar",
"crates/programs/bevy-experiments",
# Services: API servers, jobs, workers, etc.
"crates/service/job/analytics_job",
+6
View File
@@ -0,0 +1,6 @@
# Secrets
db_secrets.toml
# Python Virtual Env
python/
+100
View File
@@ -0,0 +1,100 @@
#!/usr/bin/env python
# FIXME: Needs packages 'toml' and 'mysql-connector-python'. Put in requirements.txt.
import time
import toml
import mysql.connector
DB_SECRETS_FILE = 'db_secrets.toml'
# TODO: Share db-related setup when more scripts are added.
def read_database_secrets(secrets_file = DB_SECRETS_FILE):
secrets = None
with open(secrets_file, "r") as f:
secrets = toml.load(f)
required_keys = ['database', 'hostname', 'port', 'password', 'username']
for key in required_keys:
if key not in secrets:
raise Exception(f"Required key '#{key}' not present")
return secrets
def connect_to_mysql():
secrets = read_database_secrets()
connection = mysql.connector.connect(
host = secrets['hostname'],
port = secrets['port'],
user = secrets['username'],
password = secrets['password'],
database = secrets['database'],
)
return connection
connection = connect_to_mysql()
cursor = connection.cursor()
SAFE_ID = 76000000 # Reasonably completed on 2022-06-24
LIMIT = 100000
#def get_record_count():
# query = f"SELECT COUNT(*) FROM tts_inference_jobs"
# cursor.execute(query)
# result = cursor.fetchall()
# print(result)
# return result[0]
#
##total_count = get_record_count()
#total_count = 75082057
total_count = 21925602
def get_user_tokens(cursor):
query = f"""
SELECT
r.maybe_creator_user_token, r.creator_ip_address
FROM
tts_results as r
LEFT OUTER JOIN
users as u
ON
r.maybe_creator_user_token = u.token
WHERE
r.raw_inference_text LIKE '%spidermant%'
AND r.created_at > ( CURDATE() - INTERVAL 1 HOUR )
"""
cursor.execute(query)
results = cursor.fetchall()
user_tokens = [row[0] for row in results]
user_tokens = [token for token in user_tokens if token is not None]
user_tokens = set(user_tokens)
ip_addresses = [row[1] for row in results]
ip_addresses = [ip for ip in ip_addresses if ip is not None]
ip_addresses = set(ip_addresses)
return (user_tokens, ip_addresses)
(user_tokens, ip_addresses) = get_user_tokens(cursor)
print(user_tokens)
print(len(user_tokens))
print(len(ip_addresses))
with open('101_user_tokens.txt', 'w') as f:
for user_token in user_tokens:
f.write(user_token)
f.write("\n")
with open('101_ip_addresses.txt', 'w') as f:
for ip in ip_addresses:
f.write(ip)
f.write("\n")
+3
View File
@@ -0,0 +1,3 @@
mysql-connector-python==8.0.32
protobuf==3.20.3
toml==0.10.2
+9
View File
@@ -0,0 +1,9 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Kill routed jobs
update generic_inference_jobs set status = 'dead' where maybe_routing_tag IS NOT NULL limit 100;
-- Get pending jobs
select count(*) from generic_inference_jobs where status = 'pending';
+24
View File
@@ -0,0 +1,24 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Kill pending jobs
update tts_inference_jobs set status = 'dead' where status = 'pending';
-- Kill all low priority pending, waiting, and in-progress jobs
update tts_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed')
and priority_level IN (0, 1);
-- Kill all pending jobs
update tts_inference_jobs
set status = 'dead'
where status = 'pending';
-- Kill all waiting and in-progress jobs
update tts_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed');
+11
View File
@@ -0,0 +1,11 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Delete TTS results for a single model
-- Do this in short batches so a lock isn't held for prohibitively long.
update tts_results
set mod_deleted_at = NOW()
where model_token = 'TM:ztt5s1be5tq6'
and mod_deleted_at IS NULL
limit 5000;
+35
View File
@@ -0,0 +1,35 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Upgrade top TTS model uploaders to a loyalty plan
update users
set maybe_loyalty_program_key = 'fakeyou_contributor'
where token IN (
select creator_user_token from
(
select count(*) as upload_count,
creator_user_token
from tts_models
group by creator_user_token
having upload_count >= 10
order by upload_count desc
) as t
);
-- Upgrade top VC model uploaders to a loyalty plan
update users
set maybe_loyalty_program_key = 'fakeyou_contributor'
where token IN (
select creator_user_token from
(
select count(*) as upload_count,
creator_user_token
from voice_conversion_models
group by creator_user_token
having upload_count >= 10
order by upload_count desc
) as t
);
+55
View File
@@ -0,0 +1,55 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Remove temporary test models
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'temporary test model'
where token IN (
'vcm_jt9mdz9xjjcb',
'vcm_4xzkzdhs4kk5',
'vcm_502wkt2pca3y'
);
-- Remove broken models
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'broken model'
where token IN (
'vcm_982y9g6v3jrg',
'vcm_16rpyehf7f0a',
'vcm_8vjtz3dbnw17',
'vcm_tc9mwr60cjth',
'vcm_bshsyp01w9vg',
'vcm_31whj8apmqj7',
'vcm_84qa0an44p8p',
'vcm_9xx4v5qz5fbg',
'vcm_7zp2b2hs2at2',
'vcm_zhvk0mnnb7zp',
'vcm_1vc4scq9qp6m',
'vcm_sr1b54mwy0ym',
'vcm_qx96y8aasydk'
);
-- Remove duplicate models
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'duplicate model'
where token IN (
'vcm_6w21em1bs7q3',
'vcm_sbhvyj7926w4',
'vcm_anv469g89adz',
'vcm_xsx5yx585c7x',
'vcm_dpahzjjpkf18',
'vcm_y09dqe6zgwyk',
'vcm_xrp96dwgppv2'
);
+19
View File
@@ -0,0 +1,19 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Kill pending jobs
update w2l_inference_jobs set status='dead' where status IN ('pending', 'started', 'attempt_failed');
-- Unstick old jobs that might be stuck as "started"
update w2l_template_upload_jobs
set status='dead'
where status='started'
and created_at < ( CURDATE() - INTERVAL 1 DAY );
-- Kill pending jobs with tiktok URLs:
-- These need to be blocked in the server and job directly.
update w2l_template_upload_jobs
set status='dead'
where status='pending'
and download_url LIKE '%tiktok%';
@@ -0,0 +1,80 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- See how long recent jobs are taking
select
id,
maybe_input_source_token,
assigned_worker,
assigned_cluster,
success_execution_millis / 1000 / 60 as minutes
from generic_inference_jobs
where status != 'pending'
and success_execution_millis IS NOT NULL
order by id desc
limit 50;
-- Detailed report on most recent jobs, ordered by worst performing.
-- TODO: Determine if the problem is in downloading models. Make sure the job timer doesn't include
-- sections where models / files get downloaded.
select *
from (
select
jobs.created_at,
jobs.first_started_at,
jobs.id,
jobs.status,
jobs.attempt_count as attempts,
trim(replace(replace(jobs.internal_debugging_failure_reason, "\n", ""), "\r", ""))
as i_failure_reason,
-- u.username,
jobs.assigned_worker,
jobs.assigned_cluster,
jobs.maybe_input_source_token,
jobs.maybe_model_token,
m.media_source,
m.maybe_original_mime_type as mime_type,
TRUNCATE(jobs.success_execution_millis / 1000 / 60, 2) as execution_mins,
TRUNCATE(jobs.success_inference_execution_millis / 1000 / 60, 2) as inference_mins,
TRUNCATE((jobs.success_execution_millis - jobs.success_inference_execution_millis) / 1000 / 60, 2) as extra_mins,
TRUNCATE(m.original_duration_millis / 1000 / 60, 2) as input_mins,
jobs.success_execution_millis / m.original_duration_millis as ratio
from generic_inference_jobs AS jobs
left join users AS u on
u.token = jobs.maybe_creator_user_token
left join media_uploads AS m on
m.token = jobs.maybe_input_source_token
where
jobs.status != 'pending'
AND jobs.created_at > NOW() - INTERVAL 20 MINUTE
order by id desc
limit 5000
) as t
order by execution_mins desc;
order by assigned_worker desc, first_started_at asc;
order by first_started_at asc;
order by assigned_worker desc, execution_mins desc;
-- Get pending so-vits-svc jobs
select count(*)
from generic_inference_jobs
where maybe_model_type = 'so_vits_svc'
and status='pending';
-- Get jobs that have routing tags
select
id,
maybe_input_source_token,
maybe_creator_user_token,
maybe_routing_tag,
status
from generic_inference_jobs
where maybe_routing_tag IS NOT NULL
limit 10;
@@ -0,0 +1,50 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
select
mu.id,
mu.token,
u.username,
mu.media_source,
maybe_original_filename as filename,
original_file_size_bytes as size_bytes,
original_duration_millis as duration_millis,
maybe_original_mime_type as mime_type
from media_uploads as mu
left join users AS u
on u.token = mu.maybe_creator_user_token
order by id desc limit 10;
-- Analyze all media
select
mu.id,
mu.token,
u.username,
mu.media_source,
maybe_original_filename as filename,
original_file_size_bytes as size_bytes,
original_duration_millis as duration_millis,
maybe_original_mime_type as mime_type
from media_uploads as mu
left join users AS u
on u.token = mu.maybe_creator_user_token
order by id desc
limit 40;
-- Analyze broken media (no duration)
select
mu.id,
mu.token,
u.username,
mu.media_source,
maybe_original_filename as filename,
original_file_size_bytes as size_bytes,
original_duration_millis as duration_millis,
maybe_original_mime_type as mime_type
from media_uploads as mu
left join users AS u
on u.token = mu.maybe_creator_user_token
where mu.original_duration_millis = 0
order by id desc
limit 40;
-14
View File
@@ -2,9 +2,6 @@
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Kill pending jobs
update tts_inference_jobs set status = 'dead' where status = 'pending';
-- Total pending jobs
select count(*)
from tts_inference_jobs
@@ -32,17 +29,6 @@ group by model_token
order by attempts desc
limit 50;
-- Kill pending jobs
update tts_inference_jobs
set status = 'dead'
where status = 'pending';
-- Kill all waiting and in-progress jobs
update tts_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed');
-- Sample the pending inference text
select creator_ip_address,
model_token,
+81 -18
View File
@@ -12,9 +12,9 @@ select
m.title,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at,
m.created_at
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -63,7 +63,41 @@ from (
join users as u
on u.token = m.creator_user_token
order by r.use_count desc
limit 25;
limit 100;
--
-- Top models binned by IP address.
-- Should give us a look at demand independent of model quality / repeated use.
--
select
m.token,
m.title,
m.user_ratings_positive_count / m.user_ratings_total_count as rating,
m.text_pipeline_type,
m.ietf_language_tag,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from (
select model_token, creator_ip_address
from tts_results
where created_at > (CURDATE() - INTERVAL 12 HOUR)
group by model_token, creator_ip_address
) as x
group by model_token
) as r
join tts_models as m
on m.token = r.model_token
join users as u
on u.token = m.creator_user_token
where m.ietf_language_tag IN ('en', 'en-US', 'en-AU', 'en-CA', 'en-GB')
order by r.use_count desc
limit 100;
--
-- Top 20 ***NEW*** models to share in #announcements
@@ -73,12 +107,13 @@ select
m.token,
m.text_pipeline_type,
m.ietf_language_tag,
m.creator_set_visibility,
m.title,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at,
m.created_at
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -90,7 +125,7 @@ from (
join users as u
on u.token = m.creator_user_token
where m.created_at > ( CURDATE() - INTERVAL 31 DAY )
AND u.username IN ( 'vegito1089', 'justinjohn0306')
-- AND u.username IN ( 'vegito1089', 'justinjohn0306')
order by r.use_count desc
limit 100;
@@ -105,9 +140,9 @@ select
m.title,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at,
m.created_at
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -138,9 +173,9 @@ select
m.ietf_language_tag,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at,
m.created_at
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -164,9 +199,9 @@ select
m.ietf_language_tag,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at,
m.created_at
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -192,9 +227,9 @@ select
m.ietf_language_tag,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at,
m.created_at
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -224,8 +259,8 @@ select
m.ietf_language_tag,
u.username,
r.use_count,
m.user_deleted_at,
m.created_at
m.created_at,
m.user_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -256,9 +291,9 @@ select
m.ietf_language_tag,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at,
m.created_at
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
@@ -300,3 +335,31 @@ where m.mod_deleted_at > ( CURDATE() - INTERVAL 14 DAY )
order by r.use_count desc
limit 500;
--
-- Non-public models
--
select
m.token,
m.title,
m.text_pipeline_type,
m.ietf_language_tag,
m.creator_set_visibility,
u.username,
r.use_count,
m.created_at,
m.user_deleted_at,
m.mod_deleted_at
from (
select model_token, count(*) as use_count
from tts_results
where created_at > ( CURDATE() - INTERVAL 30 DAY )
group by model_token
) as r
left outer join tts_models as m
on m.token = r.model_token
join users as u
on u.token = m.creator_user_token
where m.creator_set_visibility != 'public'
order by r.use_count desc
limit 500;
+33 -8
View File
@@ -64,14 +64,6 @@ ORDER BY created_at DESC
-- Delete TTS results for a single model
-- Do this in short batches so a lock isn't held for prohibitively long.
update tts_results
set mod_deleted_at = NOW()
where model_token = 'TM:ztt5s1be5tq6'
and mod_deleted_at IS NULL
limit 5000;
--- Search for particular text by a particular model
SELECT
raw_inference_text,
@@ -83,6 +75,39 @@ WHERE
model_token = 'TM:ztt5s1be5tq6'
AND raw_inference_text LIKE '%fakeyou%'
--- Search for 101soundboards.com using us
SELECT
r.raw_inference_text,
r.maybe_creator_user_token,
u.username,
u.ip_address_creation,
r.creator_ip_address,
r.created_at
FROM
tts_results as r
LEFT OUTER JOIN
users as u
ON
r.maybe_creator_user_token = u.token
WHERE
r.raw_inference_text LIKE '%bananas%'
AND r.created_at > ( CURDATE() - INTERVAL 1 HOUR )
--- Search for 101soundboards.com using us
SELECT
r.maybe_creator_user_token, r.creator_ip_address
FROM
tts_results as r
LEFT OUTER JOIN
users as u
ON
r.maybe_creator_user_token = u.token
WHERE
r.raw_inference_text LIKE '%pickle%'
AND r.created_at > ( CURDATE() - INTERVAL 1 HOUR )
---
-- WTF WHY IS THIS SLOW???
SELECT
+47 -1
View File
@@ -13,6 +13,52 @@ select count(*) from user_subscriptions;
-- NB: "active" status users are current, treating "past_due" as active too (for now)
select count(*) from user_subscriptions where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired");
-- ==================== TTS + VC + W2L ====================
-- Make sure the time intervals are the same!
SELECT
username,
count(*) as total_use_count
FROM (
SELECT
u.username as username,
j.token as token
FROM users AS u
JOIN tts_inference_jobs AS j
ON u.token = j.maybe_creator_user_token
WHERE u.token IN (
SELECT DISTINCT user_token
FROM user_subscriptions
)
AND j.created_at > NOW() - INTERVAL 31 DAY
UNION
SELECT
u.username as username,
j.token as token
FROM users AS u
JOIN generic_inference_jobs AS j
ON u.token = j.maybe_creator_user_token
WHERE u.token IN (
SELECT DISTINCT user_token
FROM user_subscriptions
)
AND j.created_at > NOW() - INTERVAL 31 DAY
UNION
SELECT
u.username as username,
j.token as token
FROM users AS u
JOIN w2l_inference_jobs AS j
ON u.token = j.maybe_creator_user_token
WHERE u.token IN (
SELECT DISTINCT user_token
FROM user_subscriptions
)
AND j.created_at > NOW() - INTERVAL 31 DAY
) as t
GROUP BY username
ORDER BY total_use_count desc
-- ==================== TEXT TO SPEECH====================
-- All paid subscribers generating results in the last week
@@ -23,7 +69,7 @@ on u.token = j.maybe_creator_user_token
WHERE u.token IN (
select distinct user_token
from user_subscriptions
where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired")
-- where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired")
)
AND j.created_at > NOW() - interval 7 day
GROUP BY u.username
+21 -15
View File
@@ -25,20 +25,26 @@ on u.token = m.creator_user_token
where m.upload_count >= 5;
-- Upgrade top TTS model uploaders to a loyalty plan
update users
set maybe_loyalty_program_key = 'fakeyou_contributor'
where token IN (
select creator_user_token from
(
select count(*) as upload_count,
creator_user_token
from tts_models
group by creator_user_token
having upload_count >= 10
order by upload_count desc
) as t
);
-- Top VC model uploaders
select
u.id,
u.token,
u.username,
u.created_at,
u.maybe_stripe_customer_id,
u.maybe_loyalty_program_key,
m.upload_count
from users as u
join
(
select
count(*) as upload_count,
creator_user_token
from voice_conversion_models
group by creator_user_token
order by upload_count desc
) as m
on u.token = m.creator_user_token
where m.upload_count >= 5;
@@ -0,0 +1,37 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Inventory all
select
vc.id,
vc.token,
vc.model_type,
vc.title,
u.username,
vc.original_download_url,
vc.created_at,
vc.updated_at,
vc.user_deleted_at,
vc.mod_deleted_at,
vc.maybe_mod_comments
from voice_conversion_models as vc
left join users AS u on
u.token = vc.creator_user_token;
-- Inventory non-deleted
select
vc.id,
vc.token,
vc.model_type,
vc.title,
u.username,
vc.original_download_url,
vc.created_at,
vc.updated_at
from voice_conversion_models as vc
left join users AS u on
u.token = vc.creator_user_token
where
vc.user_deleted_at IS NULL
and vc.mod_deleted_at IS NULL;
@@ -14,15 +14,3 @@ from w2l_template_upload_jobs
where status='started'
and created_at < ( CURDATE() - INTERVAL 1 DAY );
-- Unstick old jobs that might be stuck as "started"
update w2l_template_upload_jobs
set status='dead'
where status='started'
and created_at < ( CURDATE() - INTERVAL 1 DAY );
-- Kill pending jobs with tiktok URLs:
-- These need to be blocked in the server and job directly.
update w2l_template_upload_jobs
set status='dead'
where status='pending'
and download_url LIKE '%tiktok%';
@@ -88,7 +88,7 @@ CREATE TABLE generic_inference_jobs (
is_from_api_user BOOLEAN NOT NULL DEFAULT FALSE,
is_for_twitch BOOLEAN NOT NULL DEFAULT FALSE,
-- If true, the request gets routed to a special "debug" worker.
-- NB: The meaning of this column has changed. See the "squashed" schema for docs/details.
is_debug_request BOOLEAN NOT NULL DEFAULT FALSE,
-- ========== JOB SYSTEM DETAILS ==========
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP TABLE comments;
@@ -0,0 +1,69 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Comments that can be attached to just about anything.
-- This is a polymorphic table and can apply to a wide variety of entities.
CREATE TABLE comments (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
token VARCHAR(32) NOT NULL,
-- Idempotency token from client
-- This is so the frontend client doesn't submit duplicate items.
uuid_idempotency_token VARCHAR(36) NOT NULL,
-- User making the comment
user_token VARCHAR(32) NOT NULL,
-- The type of entity the comment applies to
entity_type VARCHAR(32) NOT NULL,
-- The token of the entity the comment applies to
entity_token VARCHAR(32) NOT NULL,
-- The comment in markdown
comment_markdown TEXT NOT NULL,
-- Generated HTML (not user-editable).
comment_rendered_html TEXT NOT NULL,
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
editor_ip_address VARCHAR(40) NOT NULL,
-- ========== VECTOR CLOCK ==========
-- Incremented with every update.
version INT NOT NULL DEFAULT 0,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- Technically, this conveys *user* edits, not things that update the record itself.
edited_at TIMESTAMP NULL,
-- If this is removed by a mod.
-- It completely disappears from the system.
user_deleted_at TIMESTAMP NULL,
mod_deleted_at TIMESTAMP NULL,
-- The owner of the thing the comment is attached to can delete the comment too.
object_owner_deleted_at TIMESTAMP NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
UNIQUE KEY (uuid_idempotency_token),
KEY index_entity_type_entity_token (entity_type, entity_token),
KEY index_user_token (user_token),
KEY index_created_at (created_at),
KEY index_user_deleted_at (user_deleted_at),
KEY index_mod_deleted_at (mod_deleted_at),
KEY index_object_owner_deleted_at (object_owner_deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs DROP COLUMN maybe_routing_tag;
@@ -0,0 +1,10 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN maybe_routing_tag VARCHAR(32) DEFAULT NULL
AFTER is_debug_request;
ALTER TABLE generic_inference_jobs
ADD INDEX index_maybe_routing_tag (maybe_routing_tag);
@@ -0,0 +1,23 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- REVERT ADDING 'vits' MODEL TYPE
ALTER TABLE tts_models
MODIFY COLUMN tts_model_type ENUM(
'not-set',
'tacotron2',
'glowtts',
'glowtts-vocodes',
'talknet'
) NOT NULL DEFAULT 'not-set';
ALTER TABLE tts_model_upload_jobs
MODIFY COLUMN tts_model_type ENUM(
'not-set',
'tacotron2',
'glowtts',
'glowtts-vocodes',
'talknet'
) NOT NULL DEFAULT 'not-set';
@@ -0,0 +1,28 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Add 'vits' to the tts_model_type.
ALTER TABLE tts_models
MODIFY COLUMN tts_model_type ENUM(
'not-set',
'tacotron2',
'glowtts',
'glowtts-vocodes',
'talknet',
'vits'
) NOT NULL DEFAULT 'not-set';
-- Technically we won't be using the model upload jobs table anymore,
-- but add 'vits' for consistency.
ALTER TABLE tts_model_upload_jobs
MODIFY COLUMN tts_model_type ENUM(
'not-set',
'tacotron2',
'glowtts',
'glowtts-vocodes',
'talknet',
'vits'
) NOT NULL DEFAULT 'not-set';
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP INDEX `index_tts_model_type` ON `tts_models`;
@@ -0,0 +1,6 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE tts_models ADD INDEX index_tts_model_type (tts_model_type);
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs RENAME COLUMN inference_category TO inference_type;
ALTER TABLE generic_inference_jobs RENAME INDEX index_inference_category TO index_inference_type;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs RENAME COLUMN inference_type TO inference_category;
ALTER TABLE generic_inference_jobs RENAME INDEX index_inference_type TO index_inference_category;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs MODIFY maybe_model_token VARCHAR(32) DEFAULT NULL AFTER maybe_raw_inference_text;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs MODIFY maybe_model_token VARCHAR(32) DEFAULT NULL AFTER inference_category;
@@ -0,0 +1,8 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP INDEX index_maybe_model_type_and_maybe_model_token ON generic_inference_jobs;
DROP INDEX index_maybe_model_type ON generic_inference_jobs;
ALTER TABLE generic_inference_jobs DROP COLUMN maybe_model_type;
@@ -0,0 +1,10 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN maybe_model_type VARCHAR(32) DEFAULT NULL
AFTER inference_category;
CREATE INDEX index_maybe_model_type_and_maybe_model_token ON generic_inference_jobs (maybe_model_type, maybe_model_token);
CREATE INDEX index_maybe_model_type ON generic_inference_jobs (maybe_model_type);
@@ -0,0 +1,26 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE voice_conversion_results DROP COLUMN public_bucket_hash;
ALTER TABLE voice_conversion_results DROP COLUMN bucket_has_wav;
ALTER TABLE voice_conversion_results DROP COLUMN bucket_has_mp3;
ALTER TABLE voice_conversion_results DROP COLUMN bucket_has_mp4;
ALTER TABLE voice_conversion_results DROP COLUMN bucket_has_webm;
ALTER TABLE voice_conversion_results DROP COLUMN bucket_has_spectrogram;
ALTER TABLE voice_conversion_results
ADD COLUMN public_bucket_directory_full_path VARCHAR(255) NOT NULL
AFTER maybe_creator_synthetic_id;
ALTER TABLE voice_conversion_results
ADD COLUMN public_bucket_wav_audio_object_name VARCHAR(255) NOT NULL
AFTER public_bucket_directory_full_path;
ALTER TABLE voice_conversion_results
ADD COLUMN public_bucket_spectrogram_object_name VARCHAR(255) NOT NULL
AFTER public_bucket_wav_audio_object_name;
ALTER TABLE voice_conversion_results
ADD COLUMN public_bucket_video_object_name VARCHAR(255) NOT NULL
AFTER public_bucket_spectrogram_object_name;
@@ -0,0 +1,39 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- These columns are no longer useful.
-- It's better to store booleans for each type of file we store and calculate the paths.
ALTER TABLE voice_conversion_results DROP COLUMN public_bucket_directory_full_path;
ALTER TABLE voice_conversion_results DROP COLUMN public_bucket_wav_audio_object_name;
ALTER TABLE voice_conversion_results DROP COLUMN public_bucket_spectrogram_object_name;
ALTER TABLE voice_conversion_results DROP COLUMN public_bucket_video_object_name;
-- The hash will contain the key information for where files live
ALTER TABLE voice_conversion_results
ADD COLUMN public_bucket_hash VARCHAR(64) NOT NULL
AFTER maybe_creator_synthetic_id;
-- The boolean flags will tell what we store.
ALTER TABLE voice_conversion_results
ADD COLUMN bucket_has_wav BOOLEAN NOT NULL DEFAULT FALSE
AFTER public_bucket_hash;
ALTER TABLE voice_conversion_results
ADD COLUMN bucket_has_mp3 BOOLEAN NOT NULL DEFAULT FALSE
AFTER bucket_has_wav;
ALTER TABLE voice_conversion_results
ADD COLUMN bucket_has_mp4 BOOLEAN NOT NULL DEFAULT FALSE
AFTER bucket_has_mp3;
ALTER TABLE voice_conversion_results
ADD COLUMN bucket_has_webm BOOLEAN NOT NULL DEFAULT FALSE
AFTER bucket_has_mp4;
ALTER TABLE voice_conversion_results
ADD COLUMN bucket_has_spectrogram BOOLEAN NOT NULL DEFAULT FALSE
AFTER bucket_has_webm;
@@ -0,0 +1,15 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP INDEX `fk_media_token_and_media_token_type` ON `voice_conversion_results`;
ALTER TABLE voice_conversion_results DROP COLUMN media_token_type;
ALTER TABLE voice_conversion_results DROP COLUMN generated_by_cluster;
ALTER TABLE voice_conversion_results
ADD COLUMN maybe_vocoder_token VARCHAR(64) DEFAULT NULL
AFTER model_token;
CREATE INDEX `fk_maybe_vocoder_token`
ON `voice_conversion_results` (`maybe_vocoder_token`);
@@ -0,0 +1,20 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- There isn't a vocoder, and even if so, it doesn't need to be referenced here.
DROP INDEX `fk_maybe_vocoder_token` ON `voice_conversion_results`;
ALTER TABLE voice_conversion_results DROP COLUMN maybe_vocoder_token;
ALTER TABLE voice_conversion_results
ADD COLUMN media_token_type VARCHAR(32) NOT NULL
AFTER media_token;
ALTER TABLE voice_conversion_results
ADD COLUMN generated_by_cluster VARCHAR(255) NOT NULL
AFTER generated_by_worker;
CREATE INDEX `fk_media_token_and_media_token_type`
ON `voice_conversion_results` (`media_token`, `media_token_type`);
@@ -0,0 +1,9 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP INDEX `fk_maybe_input_source_token` ON `generic_inference_jobs`;
DROP INDEX `fk_maybe_input_source_token_and_type` ON `generic_inference_jobs`;
ALTER TABLE generic_inference_jobs DROP COLUMN maybe_input_source_token;
ALTER TABLE generic_inference_jobs DROP COLUMN maybe_input_source_token_type;
@@ -0,0 +1,17 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN maybe_input_source_token VARCHAR(32) DEFAULT NULL
AFTER maybe_model_token;
ALTER TABLE generic_inference_jobs
ADD COLUMN maybe_input_source_token_type VARCHAR(32) DEFAULT NULL
AFTER maybe_input_source_token;
CREATE INDEX `fk_maybe_input_source_token`
ON `generic_inference_jobs` (`maybe_input_source_token`);
CREATE INDEX `fk_maybe_input_source_token_and_type`
ON `generic_inference_jobs` (`maybe_input_source_token`, `maybe_input_source_token_type`);
@@ -0,0 +1,10 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_uploads
ADD COLUMN public_bucket_directory_full_path VARCHAR(255) NOT NULL
AFTER public_bucket_directory_hash;
ALTER TABLE media_uploads
RENAME COLUMN maybe_extra_file_modification_info TO extra_file_modification_info ;
@@ -0,0 +1,8 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_uploads DROP COLUMN public_bucket_directory_full_path;
ALTER TABLE media_uploads
RENAME COLUMN extra_file_modification_info TO maybe_extra_file_modification_info;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_uploads DROP COLUMN media_source;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_uploads
ADD COLUMN media_source VARCHAR(16) NOT NULL
AFTER media_type;
@@ -0,0 +1,8 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_download_jobs DROP COLUMN first_started_at;
ALTER TABLE generic_download_jobs DROP COLUMN assigned_cluster;
ALTER TABLE generic_download_jobs DROP COLUMN assigned_worker;
ALTER TABLE generic_download_jobs DROP COLUMN successfully_completed_at;
@@ -0,0 +1,19 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_download_jobs
ADD COLUMN assigned_worker VARCHAR(128) DEFAULT NULL
AFTER failure_reason;
ALTER TABLE generic_download_jobs
ADD COLUMN assigned_cluster VARCHAR(128) DEFAULT NULL
AFTER assigned_worker;
ALTER TABLE generic_download_jobs
ADD COLUMN first_started_at TIMESTAMP NULL
AFTER retry_at;
ALTER TABLE generic_download_jobs
ADD COLUMN successfully_completed_at TIMESTAMP NULL
AFTER first_started_at;
@@ -0,0 +1,8 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs DROP COLUMN first_started_at;
ALTER TABLE generic_inference_jobs DROP COLUMN assigned_cluster;
ALTER TABLE generic_inference_jobs DROP COLUMN assigned_worker;
ALTER TABLE generic_inference_jobs DROP COLUMN successfully_completed_at;
@@ -0,0 +1,19 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN assigned_worker VARCHAR(128) DEFAULT NULL
AFTER last_assigned_worker;
ALTER TABLE generic_inference_jobs
ADD COLUMN assigned_cluster VARCHAR(128) DEFAULT NULL
AFTER assigned_worker;
ALTER TABLE generic_inference_jobs
ADD COLUMN first_started_at TIMESTAMP NULL
AFTER retry_at;
ALTER TABLE generic_inference_jobs
ADD COLUMN successfully_completed_at TIMESTAMP NULL
AFTER first_started_at;
@@ -0,0 +1,6 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_download_jobs DROP COLUMN success_execution_millis;
ALTER TABLE generic_inference_jobs DROP COLUMN success_execution_millis;
@@ -0,0 +1,11 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_download_jobs
ADD COLUMN success_execution_millis INT(10) UNSIGNED DEFAULT NULL
AFTER failure_reason;
ALTER TABLE generic_inference_jobs
ADD COLUMN success_execution_millis INT(10) UNSIGNED DEFAULT NULL
AFTER internal_debugging_failure_reason;
@@ -0,0 +1,6 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_download_jobs DROP COLUMN success_inference_execution_millis;
ALTER TABLE generic_inference_jobs DROP COLUMN success_inference_execution_millis;
@@ -0,0 +1,11 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_download_jobs
ADD COLUMN success_inference_execution_millis INT(10) UNSIGNED DEFAULT NULL
AFTER success_execution_millis;
ALTER TABLE generic_inference_jobs
ADD COLUMN success_inference_execution_millis INT(10) UNSIGNED DEFAULT NULL
AFTER success_execution_millis;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs DROP COLUMN is_keepalive_required;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN is_keepalive_required BOOLEAN NOT NULL DEFAULT FALSE
AFTER priority_level;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table password_resets;
@@ -0,0 +1,51 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE password_resets (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Password hash "primary key"
-- (ie. for the future when we have a support dashboard)
token VARCHAR(32) NOT NULL,
-- Foreign key to user
user_token VARCHAR(32) NOT NULL,
-- Secret "key" for the password reset
-- This will be shared via URL or user text input.
secret_key VARCHAR(32) NOT NULL,
-- Copied from the user record at the time of password reset issuance.
-- If the user's password version is greater than this value, then this
-- reset is no longer valid.
current_password_version INT NOT NULL DEFAULT 0,
-- Username is a lookup key; display_name allows the user to add custom case.
is_redeemed BOOLEAN NOT NULL DEFAULT false,
-- For abuse tracking.
-- Wide enough for IPv4/6
ip_address_creation VARCHAR(40) NOT NULL,
ip_address_redemption VARCHAR(40) NOT NULL,
-- Incremented with every update.
version INT NOT NULL DEFAULT 0,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- When the password reset expires
expires_at TIMESTAMP NOT NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
KEY fk_user_token (user_token),
KEY index_secret_key (secret_key),
KEY index_expires_at (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,137 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE generic_download_jobs (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
-- This is so the in-progress results can be looked up by the UI.
token VARCHAR(32) NOT NULL,
-- Idempotency token
-- This is so the frontend client doesn't submit duplicate jobs.
uuid_idempotency_token VARCHAR(36) NOT NULL,
-- ========== SUCCESS CASE ==========
-- If the job completes successfully, this is the result token.
-- This is only populated on a successful result.
on_success_downloaded_entity_token VARCHAR(32) DEFAULT NULL,
-- The type of the object will vary based on the type of the upload,
-- and we may include heuristics that auto-detect types in the future
-- Example types: 'hifigan', 'hifigan_rocket_vc' (codename for softvc), 'tacotron2', ...
on_success_downloaded_entity_type VARCHAR(32) DEFAULT NULL,
-- ========== UPLOAD DETAILS ==========
-- A "well defined" type of upload
-- Examples: "hifigan", "tacotron2", etc.
download_type VARCHAR(32) NOT NULL,
-- Assume the same URL can be uploaded more than once (in case of errors or
-- people sharing models)
download_url VARCHAR(512) NOT NULL,
-- The user-supplied title of the upload
-- This might have different meanings for different upload types
-- The "name" of the voice model, which might be complicated.
-- If maybe_subject_token (etc.) is set, then it's authoritative instead.
title VARCHAR(255) NOT NULL,
-- ========== CREATOR DETAILS AND PREFERENCES ==========
-- Foreign key to user
creator_user_token VARCHAR(32) NOT NULL,
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
-- The creator can set a desired visibility for their data.
-- This does not always apply to every upload type.
-- Additionally, some upload types may require moderator approval prior
-- to being publicly listed, and this field has no bearing on that.
-- NB: DO NOT CHANGE THE ORDER OF THE ENUM VALUES DURING SCHEMA MIGRATIONS.
creator_set_visibility ENUM(
'public',
'hidden',
'private'
) NOT NULL DEFAULT 'public',
-- ========== JOB SYSTEM DETAILS ==========
-- Jobs begin as "pending", then transition to other states.
--
-- * Pending = job is ready to go
-- * Started = job is running
-- * Complete_Success = job is done (success)
-- * Complete_Failure = job is done (failure)
-- * Attempt_Failed = job failed but may retry.
-- * Dead = job failed permanently.
--
-- Pending -> Started -> Complete_Success
-- |-> Complete_Failure
-- \-> Attempt_Failed -> Started -> { Complete, Failed, Dead }
status ENUM(
'pending',
'started',
'complete_success',
'complete_failure',
'attempt_failed',
'dead') NOT NULL DEFAULT 'pending',
-- We can track this against a "max_attempt_count"
attempt_count INT(3) NOT NULL DEFAULT 0,
-- If there is a failure, tell the user why.
failure_reason VARCHAR(512) DEFAULT NULL,
-- On success, we populate how long the job execution took in milliseconds.
-- We have this because 1) the job system timestamps are second-resolution,
-- and 2) the structure of the jobs executor may change, potentially changing
-- derived execution time analytics with it.
success_execution_millis INT(10) UNSIGNED DEFAULT NULL,
-- This is only the inference portion and does not include downloads, uploads,
-- or any subsequent processing.
success_inference_execution_millis INT(10) UNSIGNED DEFAULT NULL,
-- Worker hostname (linux hostname, k8s pod name)
-- Assigned when a worker picks up the job
-- Reassigned if the job fails and gets picked up again
assigned_worker VARCHAR(128) DEFAULT NULL,
-- Cluster name (k8s)
-- Assigned when a worker picks up the job
-- Reassigned if the job fails and gets picked up again
assigned_cluster VARCHAR(128) DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- Failed jobs will set a next attempt time.
-- Subsequent tries can increase the timeout.
-- Failures because of permissions require human intervention => [retry_at=null].
-- Failures because of invalid files are dead => [status=dead].
retry_at TIMESTAMP NULL,
-- Set when the job first starts executing
first_started_at TIMESTAMP NULL,
-- Set when the job is successfully completed
successfully_completed_at TIMESTAMP NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
UNIQUE KEY (uuid_idempotency_token),
KEY fk_on_download_type (download_type),
KEY fk_creator_user_token (creator_user_token),
KEY index_status (status),
KEY index_creator_ip_address (creator_ip_address)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,215 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE generic_inference_jobs (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
-- This is so the in-progress results can be looked up by the UI.
token VARCHAR(32) NOT NULL,
-- Idempotency token from client
-- This is so the frontend client doesn't submit duplicate jobs.
uuid_idempotency_token VARCHAR(36) NOT NULL,
-- ========== INFERENCE DETAILS ==========
-- Broad category of inference
-- Examples (may not be up to date):
-- * text_to_speech
-- * voice_conversion
inference_category VARCHAR(32) NOT NULL,
-- Potential part of the composite foreign key to the primary model being used, if any.
-- This will normally live in `maybe_inference_args`, but in this case, it's useful for
-- running easy database analytical queries.
maybe_model_type VARCHAR(32) DEFAULT NULL,
-- Potential part of the composite foreign key to the primary model being used, if any.
-- This will normally live in `maybe_inference_args`, but in this case, it's useful for
-- running easy database analytical queries.
maybe_model_token VARCHAR(32) DEFAULT NULL,
-- If the inference job takes some other kind of entity, this will be the token
-- Not all inference jobs have record-like input sources.
maybe_input_source_token VARCHAR(32) DEFAULT NULL,
-- If the inference job takes some other kind of entity, this will be the type of the
-- token. For now, this is just `media_upload`.
-- Not all inference jobs have record-like input sources.
maybe_input_source_token_type VARCHAR(32) DEFAULT NULL,
-- Polymorphic arguments payload that depends on the type of inference job.
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_inference_args TEXT DEFAULT NULL,
-- For text-based workloads, the raw, unprocessed user input.
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_raw_inference_text TEXT DEFAULT NULL,
-- ========== SUCCESS CASE ==========
-- The type of the object will vary based on the type of the upload,
-- and we may include heuristics that auto-detect types in the future
on_success_result_entity_type VARCHAR(32) DEFAULT NULL,
-- If the job completes successfully, this is the result token.
-- This is only populated on a successful result.
on_success_result_entity_token VARCHAR(32) DEFAULT NULL,
-- ========== CREATOR DETAILS AND PREFERENCES ==========
-- Foreign key to user
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
-- Based on a cookie sent by the frontend.
-- We'll save this even if the user is logged in.
maybe_creator_anonymous_visitor_token VARCHAR(32) DEFAULT NULL,
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
-- The creator can set a desired visibility for their data.
-- This does not always apply to every upload type.
-- Additionally, some upload types may require moderator approval prior
-- to being publicly listed, and this field has no bearing on that.
-- NB: DO NOT CHANGE THE ORDER OF THE ENUM VALUES DURING SCHEMA MIGRATIONS.
creator_set_visibility ENUM(
'public',
'hidden',
'private'
) NOT NULL DEFAULT 'public',
-- ========== PREMIUM FEATURES METADATA ==========
-- The maximum duration for generated audio or video in seconds.
-- Zero is implied to be the default value, which is typically 12 seconds.
-- A negative value implies "unlimited".
max_duration_seconds INTEGER NOT NULL DEFAULT 0,
-- ========== WORKLOAD SOURCE AND PRIORITY ==========
-- Priority *increases*, so a level of 2 will be higher than 1.
-- These are the level semantics currently:
-- - All jobs from anonymous FakeYou users have level 0.
-- - All jobs from logged in FakeYou users have level 1.
-- - All jobs from Twitch TTS (unpaid) have level 10 (ten).
-- - (There will be future levels for paid Twitch and social FakeYou rewards.)
priority_level SMALLINT UNSIGNED NOT NULL DEFAULT 0,
-- For non-premium workloads (or some other workloads), we may require that the
-- user remains on the website. This will help us kill jobs if the user leaves.
-- The state for this keepalive signal will be job-type dependent and may live
-- in Redis or some other system. Typically the frontend job status polling will
-- populate this keepalive signal (eg. in a Redis key with TTL).
is_keepalive_required BOOLEAN NOT NULL DEFAULT FALSE,
-- TODO: add is_for_storyteller_product
is_from_premium_user BOOLEAN NOT NULL DEFAULT FALSE,
is_from_api_user BOOLEAN NOT NULL DEFAULT FALSE,
is_for_twitch BOOLEAN NOT NULL DEFAULT FALSE,
-- ========== DEVELOPMENT AND DEBUGGING METADATA ==========
-- If true, the request gets a "debug" flag, which may do different
-- things depending on the type of work.
is_debug_request BOOLEAN NOT NULL DEFAULT FALSE,
-- If set, the request gets processed by a special "tagged" worker
-- that matches this tag. The ordinary workers will ignore this work.
maybe_routing_tag VARCHAR(32) DEFAULT NULL,
-- ========== JOB SYSTEM DETAILS ==========
-- Jobs begin as "pending", then transition to other states.
--
-- * Pending = job is ready to go
-- * Started = job is running
-- * Complete_Success = job is done (success)
-- * Complete_Failure = job is done (failure)
-- * Attempt_Failed = job failed but may retry.
-- * Dead = job failed permanently.
--
-- Pending -> Started -> Complete_Success
-- |-> Complete_Failure
-- \-> Attempt_Failed -> Started -> { Complete, Failed, Dead }
status ENUM(
'pending',
'started',
'complete_success',
'complete_failure',
'attempt_failed',
'dead') NOT NULL DEFAULT 'pending',
-- We can track this against a "max_attempt_count"
attempt_count SMALLINT UNSIGNED NOT NULL DEFAULT 0,
-- If there is a failure, tell the user why.
failure_reason VARCHAR(512) DEFAULT NULL,
-- Optional internal-only debugging information in the case of failure.
internal_debugging_failure_reason VARCHAR(512) DEFAULT NULL,
-- On success, we populate how long the job execution took in milliseconds.
-- We have this because 1) the job system timestamps are second-resolution,
-- and 2) the structure of the jobs executor may change, potentially changing
-- derived execution time analytics with it.
success_execution_millis INT(10) UNSIGNED DEFAULT NULL,
-- This is only the inference portion and does not include downloads, uploads,
-- or any subsequent processing.
success_inference_execution_millis INT(10) UNSIGNED DEFAULT NULL,
-- TODO: Remove once `assigned_worker` column is added
-- and existing queries for this column are removed.
-- The last worker (hostname or pod name) to touch the job, either in the case of success or failure.
last_assigned_worker VARCHAR(255) DEFAULT NULL,
-- Worker hostname (linux hostname, k8s pod name)
-- Assigned when a worker picks up the job
-- Reassigned if the job fails and gets picked up again
assigned_worker VARCHAR(128) DEFAULT NULL,
-- Cluster name (k8s)
-- Assigned when a worker picks up the job
-- Reassigned if the job fails and gets picked up again
assigned_cluster VARCHAR(128) DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- Failed jobs will set a next attempt time.
-- Subsequent tries can increase the timeout.
-- Failures because of permissions require human intervention => [retry_at=null].
-- Failures because of invalid files are dead => [status=dead].
retry_at TIMESTAMP NULL,
-- Set when the job first starts executing
first_started_at TIMESTAMP NULL,
-- Set when the job is successfully completed
successfully_completed_at TIMESTAMP NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
UNIQUE KEY (uuid_idempotency_token),
KEY index_inference_category (inference_category),
KEY index_maybe_model_type_and_maybe_model_token (maybe_model_type, maybe_model_token),
KEY index_maybe_model_type (maybe_model_type),
KEY fk_maybe_model_token (maybe_model_token),
KEY fk_maybe_input_source_token (maybe_input_source_token),
KEY fk_maybe_input_source_token_and_type (maybe_input_source_token, maybe_input_source_token_type),
KEY fk_on_success_result_entity_token (on_success_result_entity_token),
KEY fk_maybe_creator_user_token (maybe_creator_user_token),
KEY index_creator_ip_address (creator_ip_address),
KEY index_priority_level (priority_level),
KEY index_is_debug_request (is_debug_request),
KEY index_maybe_routing_tag (maybe_routing_tag),
KEY index_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+135
View File
@@ -0,0 +1,135 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE media_uploads (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
-- This is so the in-progress results can be looked up by the UI.
token VARCHAR(32) NOT NULL,
-- Idempotency token from client
-- This is so the frontend client doesn't submit duplicate jobs.
uuid_idempotency_token VARCHAR(36) NOT NULL,
-- ========== MEDIA DETAILS ==========
-- Type of media:
-- * 'audio' for wav, mp3, etc.
-- * 'image' for png, jpg, etc.
-- * 'video' for a variety of video types.
media_type VARCHAR(16) NOT NULL,
-- Where the media originated.
-- * 'file' for user file uploads
-- * 'device_api' for user device API sessions (eg. browser+microphone)
-- * 'unknown' for unknown source
media_source VARCHAR(16) NOT NULL,
-- The original filename of the media
maybe_original_filename VARCHAR(255) DEFAULT NULL,
-- The original (non-transcoded or truncated) file size
original_file_size_bytes INT(10) NOT NULL DEFAULT 0,
-- The original (non-transcoded or truncated) duration in millis.
original_duration_millis INT(10) NOT NULL DEFAULT 0,
-- The original file's mime type.
maybe_original_mime_type VARCHAR(32) DEFAULT NULL,
-- Audio encoder details
-- Only present if the file was audio or a video that had audio.
maybe_original_audio_encoding VARCHAR(32) DEFAULT NULL,
-- Video encoder details
-- Only present if the file was a video.
maybe_original_video_encoding VARCHAR(32) DEFAULT NULL,
-- For videos, the original frame width.
maybe_original_frame_width INT(5) DEFAULT NULL,
-- For videos, the original frame height.
maybe_original_frame_height INT(5) DEFAULT NULL,
-- Checksum of the original media
-- SHA1 hash [SHA2 = CHAR(64), SHA1 = CHAR(40), MD5 = CHAR(32)]
-- checksum_sha1 CHAR(40) NOT NULL,
-- Checksum of the original media
-- SHA2 hash [SHA2 = CHAR(64), SHA1 = CHAR(40), MD5 = CHAR(32)]
-- Note that SHA2 is a hash family (SHA-228, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256, ...)
-- and produces different lengths output depending on the choice of algorithm.
checksum_sha2 CHAR(64) NOT NULL,
-- ========== UPLOAD, TRANSCODING, AND TRUNCATION DETAILS ==========
-- The hash for the bucket directory that contains the original upload
-- as well as any transcodings, downsamplings, etc.
public_bucket_directory_hash VARCHAR(32) NOT NULL,
-- We'll likely transcode (and potentially truncate) most media given to us.
-- This will store a json-encoded struct that details the changes.
-- TEXT = 65,535 bytes (64 KiB), ~= 4 bytes per UTF-8 character, ~ 16383 characters.
maybe_extra_file_modification_info TEXT DEFAULT NULL,
-- ========== CREATOR DETAILS AND PREFERENCES ==========
-- Foreign key to user
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
-- Based on a cookie sent by the frontend.
-- We'll save this even if the user is logged in.
maybe_creator_anonymous_visitor_token VARCHAR(32) DEFAULT NULL,
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
-- The creator can set a desired visibility for their data.
-- This does not always apply to every upload type.
-- Additionally, some upload types may require moderator approval prior
-- to being publicly listed, and this field has no bearing on that.
-- NB: DO NOT CHANGE THE ORDER OF THE ENUM VALUES DURING SCHEMA MIGRATIONS.
creator_set_visibility ENUM(
'public',
'hidden',
'private'
) NOT NULL DEFAULT 'public',
-- The synthetic id associated with this result.
-- These ids are incremented on a per-user basis to help users
-- sequence their own work. They serve no other purpose.
maybe_creator_synthetic_id BIGINT(20) DEFAULT NULL,
-- ========== MODERATION DETAILS ==========
-- The last moderator that made changes last.
-- We should also build an audit table to supersede this.
maybe_mod_user_token VARCHAR(32) DEFAULT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- If this is removed by a mod or the creator.
user_deleted_at TIMESTAMP NULL,
mod_deleted_at TIMESTAMP NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
UNIQUE KEY (uuid_idempotency_token),
KEY index_media_type (media_type),
KEY index_checksum_sha2 (checksum_sha2),
KEY fk_maybe_creator_user_token (maybe_creator_user_token),
KEY fk_maybe_mod_user_token (maybe_mod_user_token),
KEY index_creator_ip_address (creator_ip_address),
KEY index_user_deleted_at (user_deleted_at),
KEY index_mod_deleted_at (mod_deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -63,6 +63,7 @@ CREATE TABLE tts_inference_jobs (
is_for_twitch BOOLEAN NOT NULL DEFAULT FALSE,
-- If true, the request gets routed to a special "debug" worker.
-- NB: This has a *DIFFERENT* meaning on the generic_inference_jobs table.
is_debug_request BOOLEAN NOT NULL DEFAULT FALSE,
-- ========== PREMIUM FEATURES METADATA ==========
@@ -37,7 +37,8 @@ CREATE TABLE tts_model_upload_jobs (
'tacotron2',
'glowtts',
'glowtts-vocodes',
'talknet'
'talknet',
'vits'
) NOT NULL DEFAULT 'not-set',
-- Can be linked to a well-known voice
@@ -19,7 +19,8 @@ CREATE TABLE tts_models (
'tacotron2',
'glowtts',
'glowtts-vocodes',
'talknet'
'talknet',
'vits'
) NOT NULL DEFAULT 'not-set',
-- The name of the type of pipeline to use, eg "legacy_fakeyou", "legacy_vocodes", "english_v1", etc.
@@ -225,6 +226,7 @@ CREATE TABLE tts_models (
KEY index_private_bucket_hash (private_bucket_hash),
KEY index_is_public_listing_approved (is_public_listing_approved),
KEY index_is_locked_from_user_modification (is_locked_from_user_modification),
KEY index_is_locked_from_use (is_locked_from_use)
KEY index_is_locked_from_use (is_locked_from_use),
KEY index_tts_model_type (tts_model_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,144 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE voice_conversion_models (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
token VARCHAR(32) NOT NULL,
-- ========== MODEL FUNCTIONALITY ==========
-- The type of voice conversion model
-- eg. 'rocket_vc' (codename for 'softvc'), 'diffsvc'
model_type VARCHAR(32) NOT NULL,
-- If set, we'll use the vocoder defined.
-- If not set, some global default will be used.
maybe_vocoder_token VARCHAR(32) DEFAULT NULL,
-- ========== MODEL DESCRIPTION ==========
-- The "name" of the voice model, which might be complicated.
-- If maybe_subject_token (etc.) is set, then it's authoritative instead.
title VARCHAR(255) NOT NULL,
-- The description of the model in markdown.
description_markdown TEXT NOT NULL,
-- Generated HTML (not user-editable).
description_rendered_html TEXT NOT NULL,
-- The full IETF BCP47 language tag (eg. en, en-US, es-419, ja-JP, pt, etc.)
-- (Not that it matters apart from categorization, since voice conversion is universal.)
ietf_language_tag VARCHAR(64) NOT NULL DEFAULT 'en',
-- The IETF BCP47 language tag's primary language subtag (eg. "es-419" becomes "es")
-- (Not that it matters apart from categorization, since voice conversion is universal.)
ietf_primary_language_subtag VARCHAR(12) NOT NULL DEFAULT 'en',
-- ========== MODEL PLACEMENT ==========
-- Whether the voice features on the front of FakeYou
is_front_page_featured BOOLEAN NOT NULL DEFAULT FALSE,
-- ========== IMMUTABLE PROVENANCE AND METADATA ==========
-- Where the file was originally downloaded (if it was downloaded)
original_download_url VARCHAR(512) DEFAULT NULL,
-- The filename that was used at upload time (if available)
original_filename VARCHAR(255) DEFAULT NULL,
-- File characteristics
file_size_bytes INT(10) NOT NULL DEFAULT 0,
-- ========== CREATOR DETAILS ==========
-- The person that created the template.
creator_user_token VARCHAR(32) NOT NULL,
-- For abuse tracking.
-- Wide enough for IPv4/6.
-- This will pick up moderator IP addresses, but a future audit logs table
-- will capture all edits.
ip_address_creation VARCHAR(40) NOT NULL,
ip_address_last_update VARCHAR(40) NOT NULL,
-- The last user to edit the model. This could be the creator or a moderator.
-- Check the future audit logs table for more info.
maybe_last_update_user_token VARCHAR(32) DEFAULT NULL,
-- (THIS MIGHT NOT BE USED)
-- NB: DO NOT SORT!
-- THIS MUST MATCH THE RESPECTIVE JOBS TABLE.
creator_set_visibility ENUM(
'public',
'hidden',
'private'
) NOT NULL DEFAULT 'public',
-- ========== BUCKET STORAGE ==========
-- The pytorch model
-- For now, this will be a hash of the file contents.
-- NB: NOT UNIQUE! We can allow duplicate uploads.
private_bucket_hash CHAR(64) NOT NULL,
-- The "full url" version of the path
private_bucket_object_name VARCHAR(255) NOT NULL,
-- ========== RATING AND RANKING ==========
-- Calculated average, on a scale of 0-100
-- Null with zero ratings.
-- calculated_average_score INT(3) DEFAULT NULL,
-- Other metrics
-- calculated_total_ratings_submitted_count INT(10) NOT NULL DEFAULT 0,
-- calculated_total_uses_count BIGINT(10) NOT NULL DEFAULT 0,
-- ========== MODERATION DETAILS ==========
-- Mods may have to approve of vc models for them to show up in a public index.
-- Models can be used by the author (or other parties that know the URL) before
-- they're approved, but unapproved models won't show up in public indices.
-- This is independent of other visibility controls (is_mod_disabled, deleted_at,
-- and creator_set_visibility)
is_public_listing_approved BOOLEAN DEFAULT NULL,
-- Extremely popular models may be locked from deletion or modification by users.
is_locked_from_user_modification BOOLEAN NOT NULL DEFAULT FALSE,
-- If a moderator has comments.
maybe_mod_comments VARCHAR(255) DEFAULT NULL,
-- ========== VECTOR CLOCK ==========
-- Incremented with every update.
version INT NOT NULL DEFAULT 0,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- If this is removed by a mod.
-- It completely disappears from the system.
user_deleted_at TIMESTAMP NULL,
mod_deleted_at TIMESTAMP NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
KEY index_model_type (model_type),
KEY fk_maybe_vocoder_token (maybe_vocoder_token),
KEY fk_creator_user_token (creator_user_token),
KEY index_creator_set_visibility (creator_set_visibility),
KEY index_private_bucket_hash (private_bucket_hash),
KEY index_is_public_listing_approved (is_public_listing_approved),
KEY index_is_locked_from_user_modification (is_locked_from_user_modification)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,121 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE voice_conversion_results (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
token VARCHAR(32) NOT NULL,
-- ========== INFERENCE DETAILS ==========
-- The TTS model that was used
model_token VARCHAR(32) NOT NULL,
-- Which media token was used as input (can be audio or video), potentially
-- from a wide number of tables (eg. media_uploads, tts_results, etc.)
media_token VARCHAR(32) NOT NULL,
-- For now we just support the `media_uploads` table, but we may grow to
-- support media inputs from other areas of the system (eg. tts, video, etc.)
media_token_type VARCHAR(32) NOT NULL,
-- ========== CREATOR DETAILS ==========
-- The person that created the result
-- If the user wasn't logged in, this is null
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
-- Based on a cookie sent by the frontend.
-- We'll save this even if the user is logged in.
maybe_creator_anonymous_visitor_token VARCHAR(32) DEFAULT NULL,
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
-- (THIS MIGHT NOT BE USED)
-- NB: DO NOT SORT!
-- THIS MUST MATCH THE RESPECTIVE JOBS TABLE.
creator_set_visibility ENUM(
'public',
'hidden',
'private'
) NOT NULL DEFAULT 'public',
-- The synthetic id associated with this result.
-- These ids are incremented on a per-user basis to help users
-- sequence their own work. They serve no other purpose.
maybe_creator_synthetic_id BIGINT(20) DEFAULT NULL,
-- ========== BUCKET STORAGE ==========
-- The hash lets us reconstitute the bucket directory
-- location (which stores potentially several files)
public_bucket_hash VARCHAR(64) NOT NULL,
-- Whether we're storing a wav result file.
bucket_has_wav BOOLEAN NOT NULL DEFAULT FALSE,
-- Whether we're storing a mp3 result file.
bucket_has_mp3 BOOLEAN NOT NULL DEFAULT FALSE,
-- Whether we're storing a mp4 result file.
bucket_has_mp4 BOOLEAN NOT NULL DEFAULT FALSE,
-- Whether we're storing a webm result file.
bucket_has_webm BOOLEAN NOT NULL DEFAULT FALSE,
-- Whether we're storing a spectrogram json file.
bucket_has_spectrogram BOOLEAN NOT NULL DEFAULT FALSE,
-- ========== METADATA ==========
file_size_bytes INT(10) NOT NULL DEFAULT 0,
duration_millis INT(10) NOT NULL DEFAULT 0,
-- ========== INFERENCE METADATA, DC, ROUTING, DEBUGGING ==========
-- If true, the request was routed to a special "debug" worker.
is_debug_request BOOLEAN NOT NULL DEFAULT FALSE,
-- Whether we generated this result from our own data center (vs. cloud).
is_generated_on_prem BOOLEAN NOT NULL DEFAULT FALSE,
-- Worker hostname (linux hostname, k8s pod name)
generated_by_worker VARCHAR(255) DEFAULT NULL,
-- Cluster name (k8s)
generated_by_cluster VARCHAR(255) DEFAULT NULL,
-- ========== MODERATION DETAILS ==========
-- The last user (possibly moderator) that made changes.
-- See the future audit logs table for better info and accounting.
maybe_last_update_user_token VARCHAR(32) DEFAULT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- If this is removed by a mod or the creator.
user_deleted_at TIMESTAMP NULL,
mod_deleted_at TIMESTAMP NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
KEY fk_model_token (model_token),
KEY fk_media_token (media_token),
KEY fk_media_token_and_media_token_type (media_token, media_token_type),
KEY fk_maybe_creator_user_token (maybe_creator_user_token),
KEY fk_maybe_creator_anonymous_visitor_token (maybe_creator_anonymous_visitor_token),
KEY index_creator_ip_address (creator_ip_address),
KEY index_user_deleted_at(user_deleted_at),
KEY index_mod_deleted_at(mod_deleted_at),
KEY index_created_at(created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP TABLE voice_survey_answers;
@@ -0,0 +1,53 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Voice survey answers
CREATE TABLE voice_survey_answers (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
token VARCHAR(32) NOT NULL,
-- Idempotency token from client
-- This is so the frontend client doesn't submit duplicate items.
uuid_idempotency_token VARCHAR(36) NOT NULL,
-- User making the comment
maybe_user_token VARCHAR(32) DEFAULT NULL,
-- The voice that is being requested
voice_name VARCHAR(128) NOT NULL,
-- If the person would pay for FakeYou premium
would_pay BOOLEAN NOT NULL DEFAULT FALSE,
-- How much the user would hypothetically pay per month
would_pay_amount DOUBLE DEFAULT NULL,
-- For abuse tracking.
-- Wide enough for IPv4/6
creator_ip_address VARCHAR(40) NOT NULL,
-- ========== VECTOR CLOCK ==========
-- Incremented with every update.
version INT NOT NULL DEFAULT 0,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
UNIQUE KEY (uuid_idempotency_token),
KEY index_maybe_user_token (maybe_user_token),
KEY index_voice_name (voice_name),
KEY index_would_pay (would_pay),
KEY index_would_pay_amount (would_pay_amount),
KEY index_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+1 -1
View File
@@ -17,7 +17,7 @@ SQLITE_DATABASE_PATH=./runtime_data/database.db
build_shared_mysql_database_library() {
# NB: For now, this is our monolithic DB that serves all of our microservices (gross)
# It's a single package so that queries can be shared (again, gross)
pushd crates/lib/database_queries
pushd crates/lib/mysql_queries
SQLX_OFFLINE=true cargo sqlx prepare --merged
popd
}
@@ -3,3 +3,6 @@
# Just an example
/exact/match/path
# Broken Python script
/tts/job/None
@@ -0,0 +1,6 @@
# This broken Python script has been around since at least the DDoS time
# But now it's actively spamming the logs at 100QPS on single nodes!
# It's from a single IP address, which we'll block:
# Unbanning for now as the code fix should resolve the issue.
# 104.251.211.22
@@ -0,0 +1,46 @@
# These IPv6 were blocked within Cloudflare. The blast radius seemed to be too big - it hit Paul and other users.
# From Cloudflare list I created called "top_attacker_ips":
# (These were created around March 9th - March 11th.)
# 2400:8500:1302:775::/64
# 2a01:4f8:c17:750::/64
# From Cloudflare list I created called "attacker_ips_v2":
# (These were created around March 9th.)
# 2001:448a:2061:2fc7::/64
# 2001:569:be9b:8c00::/64
# 2001:818:ea7c:5500::/64
# 2001:871:266:4f57::/64
# 2001:9e8:2478:9c00::/64
# 2001:bc8:47b0:1719::/64
# 2003:e0:712:9e80::/64
# 2401:4900:190a:9085::/64
# 2401:4900:60e2:41ca::/64
# 2405:201:580b:7020::/64
# 2405:201:a42e:c014::/64
# 2405:3800:811:bd79::/64
# 2409:4089:aa84:92f5::/64
# 2600:387:f:5831::/64
# 2800:200:e200:1307::/64
# 2800:200:e800:2e69::/64
# 2800:200:f140:33f::/64
# 2800:a4:1a10:6200::/64
# 2800:af0:103b:4871::/64
# 2800:e2:637f:fcc1::/64
# 2804:431:c7d9:8aa0::/64
# 2804:7efc:42a:3901::/64
# 2806:2a0:43c:82cb::/64
# 2806:2f0:72a0:fef9::/64
# 2a01:4f8:c17:750::/64
# 2a01:c23:8d83:9200::/64
# 2a01:cb06:2f9:da00::/64
# 2a02:2f08:1201:2c00::/64
# 2a02:2f08:6917:eb00::/64
# 2a02:2f0d:b819:cb00::/64
# 2a02:8084:61a3:db00::/64
# 2a03:b0c0:3:d0::/64
# 2a0c:5a80:4604:2100::/64
# From Cloudflare list I created called "attacker_ips":
# (These were created around March 9th.)
# (None)
@@ -0,0 +1,28 @@
# There's another ongoing DDoS, but it appears to be Python clients
# Top client appears to be using Python/3.10 aiohttp/3.8.3
# Second client appears to be using python-urllib3/1.26.12
# /tts/job/None is the top URL (191M)
# /tts/queue_length is the second most visited URL (36k)
# /tts/job/None (191M requests, lots of IPs)
104.251.211.22
47.253.48.57
81.56.107.8
13.234.107.200
104.247.114.86
66.214.82.240
# Unban on 2023-05-19:
# Vegito1089: I know you are super busy but is it possible to unblock this IP address?
# This one paying customer refuses refunds and says he really wants to keep using our website.
# His IP got blocked during the second DDOS attack
# Vegito1089: 38.25.15.183
# 38.25.15.183
# 2600:1700:4d40:4920:ac48:939e:b6c:9e7
# 2800:bf0:10b:f82:1516:7cdc:974a:17e8
# /tts/queue_length (14k requests, just one IP)
173.81.41.29
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
# It looks like 101soundboards has fewer IP addresses they can use (relative to user accounts).
# IPv4 addresses are the primary pool.
104.143.54.63
141.98.84.147
141.98.84.173
141.98.84.44
141.98.84.57
147.78.181.146
147.78.183.60
174.107.171.93
176.119.141.136
178.20.30.32
185.102.112.120
185.102.113.129
185.102.113.94
185.152.92.89
185.61.216.111
185.61.216.174
185.61.221.200
185.81.144.108
185.81.144.90
185.81.145.102
185.81.145.168
185.81.145.76
185.88.100.90
185.89.100.27
185.96.37.100
185.96.37.83
193.202.82.158
193.203.10.225
193.203.11.59
193.31.126.43
194.156.124.101
204.116.214.102
212.119.44.13
212.119.46.138
212.119.46.69
212.119.47.163
212.119.47.178
212.119.47.99
212.60.20.209
212.60.21.120
213.108.0.114
213.108.0.140
213.108.0.157
213.108.0.179
213.108.0.235
213.108.0.60
213.108.3.105
213.108.3.14
45.10.164.163
45.10.164.26
45.10.164.30
45.10.167.215
45.138.100.15
45.148.234.61
45.66.208.149
45.66.208.222
5.181.169.143
5.181.169.167
5.181.169.220
5.181.169.35
5.181.169.83
5.183.252.70
72.219.85.206
76.0.25.232
77.220.192.46
83.142.52.192
83.142.54.125
83.142.55.165
98.143.187.29
@@ -0,0 +1,9 @@
# It looks like 101soundboards has fewer IP addresses they can use (relative to user accounts).
# They have a few IPv6 addresses that are infrequently used.
# TODO: Support IPv6 addresses and CIDRs
# 2600:6c64:4c7f:f11f:4171:9854:beed:6dde
# 2601:205:c380:6810:5860:82ac:f25c:81de
# 2601:300:4400:3290:1864:2e36:fdab:dd9b
# 2601:648:8300:4cc0:a9c7:d8bc:9614:c76d
# 2603:9001:3f00:4e29:e4e9:56c0:ffc:f1d5
@@ -1,6 +1,7 @@
use crate::public::media_uploads::directory::MediaUploadDirectory;
use crate::public::public_path::PublicPath;
use crockford::crockford_entropy_lower;
use std::path::PathBuf;
const ORIGINAL_FILE_BASENAME : &'static str = "original_upload.bin";
@@ -37,6 +38,10 @@ impl MediaUploadOriginalFilePath {
&self.full_object_path
}
pub fn to_full_object_pathbuf(&self) -> PathBuf {
PathBuf::from(&self.full_object_path)
}
pub fn get_directory(&self) -> &MediaUploadDirectory {
&self.directory
}
@@ -53,6 +58,7 @@ impl MediaUploadOriginalFilePath {
#[cfg(test)]
mod tests {
use crate::public::media_uploads::original_file::MediaUploadOriginalFilePath;
use std::path::PathBuf;
#[test]
pub fn generate_new_entropy() {
@@ -67,6 +73,12 @@ mod tests {
assert_eq!(file.get_full_object_path_str(), "/media_upload/a/b/c/d/e/abcdefghijk/original_upload.bin");
}
#[test]
pub fn to_full_object_pathbuf() {
let file = MediaUploadOriginalFilePath::from_object_hash("abcdefghijk");
assert_eq!(file.to_full_object_pathbuf(), PathBuf::from("/media_upload/a/b/c/d/e/abcdefghijk/original_upload.bin"));
}
#[test]
pub fn get_full_object_path_str_short_name() {
let file = MediaUploadOriginalFilePath::from_object_hash("foo");
+2 -1
View File
@@ -1,2 +1,3 @@
pub mod media_uploads;
pub mod public_path;
pub mod public_path;
pub mod voice_conversion_results;
@@ -0,0 +1,63 @@
use crate::public::public_path::PublicPath;
use crate::util::hashed_directory_path_long_string::hashed_directory_path_long_string;
// TODO: Generate these from a macro.
// TODO: Use a central path registry for quick reference
const DIRECTORY: &'static str = "/voice_conversion";
/// Directory for voice conversion results.
/// Each result gets its own directory so that we can store the result
/// alongside metadata and re-processed derivatives.
#[derive(Clone)]
pub struct VoiceConversionResultDirectory {
object_hash: String,
directory: String,
}
impl PublicPath for VoiceConversionResultDirectory {}
impl VoiceConversionResultDirectory {
pub fn from_public_bucket_directory_hash(object_hash: &str) -> Self {
// TODO: Path construction could be cleaner.
let middle = hashed_directory_path_long_string(object_hash);
let directory = format!("{}/{}{}", DIRECTORY, middle, object_hash);
Self {
object_hash: object_hash.to_string(),
directory,
}
}
pub fn get_directory_path_str(&self) -> &str {
&self.directory
}
pub fn get_object_hash(&self) -> &str {
&self.object_hash
}
}
#[cfg(test)]
mod tests {
use crate::public::voice_conversion_results::directory::VoiceConversionResultDirectory;
#[test]
pub fn get_directory_path_str() {
let directory = VoiceConversionResultDirectory::from_public_bucket_directory_hash("abcdefghijk");
assert_eq!(directory.get_directory_path_str(), "/voice_conversion/a/b/c/d/e/abcdefghijk");
}
#[test]
pub fn get_directory_path_str_short_name() {
let directory = VoiceConversionResultDirectory::from_public_bucket_directory_hash("foo");
assert_eq!(directory.get_directory_path_str(), "/voice_conversion/f/o/foo");
}
#[test]
pub fn get_object_hash() {
let hash = "abcdefghijk";
let directory = VoiceConversionResultDirectory::from_public_bucket_directory_hash(hash);
assert_eq!(directory.get_object_hash(), hash);
}
}
@@ -0,0 +1,2 @@
pub mod directory;
pub mod original_file;
@@ -0,0 +1,105 @@
use crate::public::public_path::PublicPath;
use crate::public::voice_conversion_results::directory::VoiceConversionResultDirectory;
use crockford::crockford_entropy_lower;
use std::path::PathBuf;
const ORIGINAL_FILE_PREFIX : &'static str = "fakeyou_";
const ORIGINAL_FILE_SUFFIX : &'static str = ".wav";
// TODO: Generate these from a macro.
/// The original user upload file.
/// It may have derivative files (down samples, crops, etc.) that live alongside it.
#[derive(Clone)]
pub struct VoiceConversionResultOriginalFilePath {
directory: VoiceConversionResultDirectory,
basename: String,
full_object_path: String,
}
impl PublicPath for VoiceConversionResultOriginalFilePath {}
impl VoiceConversionResultOriginalFilePath {
pub fn generate_new() -> Self {
let entropy = crockford_entropy_lower(32);
Self::from_object_hash(&entropy)
}
pub fn from_object_hash(hash: &str) -> Self {
// TODO: Path construction could be cleaner.
let directory = VoiceConversionResultDirectory::from_public_bucket_directory_hash(hash);
let basename = format!("{}{}{}", ORIGINAL_FILE_PREFIX, hash, ORIGINAL_FILE_SUFFIX);
let full_object_path = format!("{}/{}{}{}", directory.get_directory_path_str(), ORIGINAL_FILE_PREFIX, hash, ORIGINAL_FILE_SUFFIX);
Self {
directory,
basename,
full_object_path,
}
}
pub fn get_full_object_path_str(&self) -> &str {
&self.full_object_path
}
pub fn to_full_object_pathbuf(&self) -> PathBuf {
PathBuf::from(&self.full_object_path)
}
pub fn get_directory(&self) -> &VoiceConversionResultDirectory {
&self.directory
}
pub fn get_object_hash(&self) -> &str {
&self.directory.get_object_hash()
}
pub fn get_basename(&self) -> &str {
&self.basename
}
}
#[cfg(test)]
mod tests {
use crate::public::voice_conversion_results::original_file::VoiceConversionResultOriginalFilePath;
use std::path::PathBuf;
#[test]
pub fn generate_new_entropy() {
let file = VoiceConversionResultOriginalFilePath::generate_new();
assert_eq!(file.get_object_hash().len(), 32);
assert_eq!(file.get_directory().get_object_hash().len(), 32);
}
#[test]
pub fn get_full_object_path_str() {
let file = VoiceConversionResultOriginalFilePath::from_object_hash("abcdefghijk");
assert_eq!(file.get_full_object_path_str(), "/voice_conversion/a/b/c/d/e/abcdefghijk/fakeyou_abcdefghijk.wav");
}
#[test]
pub fn to_full_object_pathbuf() {
let file = VoiceConversionResultOriginalFilePath::from_object_hash("abcdefghijk");
assert_eq!(file.to_full_object_pathbuf(), PathBuf::from("/voice_conversion/a/b/c/d/e/abcdefghijk/fakeyou_abcdefghijk.wav"));
}
#[test]
pub fn get_full_object_path_str_short_name() {
let file = VoiceConversionResultOriginalFilePath::from_object_hash("foo");
assert_eq!(file.get_full_object_path_str(), "/voice_conversion/f/o/foo/fakeyou_foo.wav");
}
#[test]
pub fn get_full_object_path_str_starts_with_directory() {
let file = VoiceConversionResultOriginalFilePath::from_object_hash("abcdefghijk");
let full_path = file.get_full_object_path_str();
assert!(full_path.starts_with(file.get_directory().get_directory_path_str()))
}
#[test]
pub fn get_object_hash() {
let hash = "abcdefghijk";
let file = VoiceConversionResultOriginalFilePath::from_object_hash(hash);
assert_eq!(file.get_object_hash(), hash);
}
}
@@ -0,0 +1,84 @@
use serde::Deserialize;
use serde::Serialize;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
/// Used in the `audit_logs` table in a `VARCHAR(32)` field named `entity_action`.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize)]
pub enum AuditLogEntityAction {
/// Create action
#[serde(rename = "create")]
Create,
/// Edit action
#[serde(rename = "edit")]
Edit,
/// Delete action
#[serde(rename = "delete")]
Delete,
}
// TODO(bt, 2023-01-17): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(AuditLogEntityAction);
impl_mysql_enum_coders!(AuditLogEntityAction);
/// NB: Legacy API for older code.
impl AuditLogEntityAction {
pub fn to_str(&self) -> &'static str {
match self {
Self::Create => "create",
Self::Edit => "edit",
Self::Delete => "delete",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"create" => Ok(Self::Create),
"edit" => Ok(Self::Edit),
"delete" => Ok(Self::Delete),
_ => Err(format!("invalid value: {:?}", value)),
}
}
}
#[cfg(test)]
mod tests {
use crate::by_table::audit_logs::audit_log_entity_action::AuditLogEntityAction;
use crate::test_helpers::assert_serialization;
mod serde {
use super::*;
#[test]
fn test_serialization() {
assert_serialization(AuditLogEntityAction::Create, "create");
assert_serialization(AuditLogEntityAction::Edit, "edit");
assert_serialization(AuditLogEntityAction::Delete, "delete");
}
}
mod impl_methods {
use super::*;
#[test]
fn test_to_str() {
assert_eq!(AuditLogEntityAction::Create.to_str(), "create");
assert_eq!(AuditLogEntityAction::Edit.to_str(), "edit");
assert_eq!(AuditLogEntityAction::Delete.to_str(), "delete");
}
#[test]
fn test_from_str() {
assert_eq!(AuditLogEntityAction::from_str("create").unwrap(), AuditLogEntityAction::Create);
assert_eq!(AuditLogEntityAction::from_str("edit").unwrap(), AuditLogEntityAction::Edit);
assert_eq!(AuditLogEntityAction::from_str("delete").unwrap(), AuditLogEntityAction::Delete);
assert!(AuditLogEntityAction::from_str("foo").is_err());
}
}
}
@@ -0,0 +1,102 @@
use serde::Deserialize;
use serde::Serialize;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
/// Used in the `audit_logs` table in a `VARCHAR(32)` field named `entity_type`.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize)]
pub enum AuditLogEntityType {
/// Comment system
#[serde(rename = "comment")]
Comment,
/// TTS model (architecture does not matter)
#[serde(rename = "tts_model")]
TtsModel,
/// TTS result (architecture does not matter)
#[serde(rename = "tts_result")]
TtsResult,
/// W2L template
#[serde(rename = "w2l_template")]
W2lTemplate,
/// W2L result
#[serde(rename = "w2l_result")]
W2lResult,
}
// TODO(bt, 2023-01-17): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(AuditLogEntityType);
impl_mysql_enum_coders!(AuditLogEntityType);
/// NB: Legacy API for older code.
impl AuditLogEntityType {
pub fn to_str(&self) -> &'static str {
match self {
Self::Comment => "comment",
Self::TtsModel => "tts_model",
Self::TtsResult => "tts_result",
Self::W2lTemplate => "w2l_template",
Self::W2lResult => "w2l_result",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"comment" => Ok(Self::Comment),
"tts_model" => Ok(Self::TtsModel),
"tts_result" => Ok(Self::TtsResult),
"w2l_template" => Ok(Self::W2lTemplate),
"w2l_result" => Ok(Self::W2lResult),
_ => Err(format!("invalid value: {:?}", value)),
}
}
}
#[cfg(test)]
mod tests {
use crate::by_table::audit_logs::audit_log_entity_type::AuditLogEntityType;
use crate::test_helpers::assert_serialization;
mod serde {
use super::*;
#[test]
fn test_serialization() {
assert_serialization(AuditLogEntityType::Comment, "comment");
assert_serialization(AuditLogEntityType::TtsModel, "tts_model");
assert_serialization(AuditLogEntityType::TtsResult, "tts_result");
assert_serialization(AuditLogEntityType::W2lTemplate, "w2l_template");
assert_serialization(AuditLogEntityType::W2lResult, "w2l_result");
}
}
mod impl_methods {
use super::*;
#[test]
fn test_to_str() {
assert_eq!(AuditLogEntityType::Comment.to_str(), "comment");
assert_eq!(AuditLogEntityType::TtsModel.to_str(), "tts_model");
assert_eq!(AuditLogEntityType::TtsResult.to_str(), "tts_result");
assert_eq!(AuditLogEntityType::W2lTemplate.to_str(), "w2l_template");
assert_eq!(AuditLogEntityType::W2lResult.to_str(), "w2l_result");
}
#[test]
fn test_from_str() {
assert_eq!(AuditLogEntityType::from_str("comment").unwrap(), AuditLogEntityType::Comment);
assert_eq!(AuditLogEntityType::from_str("tts_model").unwrap(), AuditLogEntityType::TtsModel);
assert_eq!(AuditLogEntityType::from_str("tts_result").unwrap(), AuditLogEntityType::TtsResult);
assert_eq!(AuditLogEntityType::from_str("w2l_template").unwrap(), AuditLogEntityType::W2lTemplate);
assert_eq!(AuditLogEntityType::from_str("w2l_result").unwrap(), AuditLogEntityType::W2lResult);
assert!(AuditLogEntityType::from_str("foo").is_err());
}
}
}
@@ -0,0 +1,2 @@
pub mod audit_log_entity_action;
pub mod audit_log_entity_type;
@@ -0,0 +1,102 @@
use serde::Deserialize;
use serde::Serialize;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
/// Used in the `comments` table in a `VARCHAR(32)` field named `entity_type`.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize)]
pub enum CommentEntityType {
/// User
#[serde(rename = "user")]
User,
/// TTS model (architecture does not matter)
#[serde(rename = "tts_model")]
TtsModel,
/// TTS result (architecture does not matter)
#[serde(rename = "tts_result")]
TtsResult,
/// W2L template
#[serde(rename = "w2l_template")]
W2lTemplate,
/// W2L result
#[serde(rename = "w2l_result")]
W2lResult,
}
// TODO(bt, 2023-01-17): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(CommentEntityType);
impl_mysql_enum_coders!(CommentEntityType);
/// NB: Legacy API for older code.
impl CommentEntityType {
pub fn to_str(&self) -> &'static str {
match self {
Self::User => "user",
Self::TtsModel => "tts_model",
Self::TtsResult => "tts_result",
Self::W2lTemplate => "w2l_template",
Self::W2lResult => "w2l_result",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"user" => Ok(Self::User),
"tts_model" => Ok(Self::TtsModel),
"tts_result" => Ok(Self::TtsResult),
"w2l_template" => Ok(Self::W2lTemplate),
"w2l_result" => Ok(Self::W2lResult),
_ => Err(format!("invalid value: {:?}", value)),
}
}
}
#[cfg(test)]
mod tests {
use crate::by_table::comments::comment_entity_type::CommentEntityType;
use crate::test_helpers::assert_serialization;
mod serde {
use super::*;
#[test]
fn test_serialization() {
assert_serialization(CommentEntityType::User, "user");
assert_serialization(CommentEntityType::TtsModel, "tts_model");
assert_serialization(CommentEntityType::TtsResult, "tts_result");
assert_serialization(CommentEntityType::W2lTemplate, "w2l_template");
assert_serialization(CommentEntityType::W2lResult, "w2l_result");
}
}
mod impl_methods {
use super::*;
#[test]
fn test_to_str() {
assert_eq!(CommentEntityType::User.to_str(), "user");
assert_eq!(CommentEntityType::TtsModel.to_str(), "tts_model");
assert_eq!(CommentEntityType::TtsResult.to_str(), "tts_result");
assert_eq!(CommentEntityType::W2lTemplate.to_str(), "w2l_template");
assert_eq!(CommentEntityType::W2lResult.to_str(), "w2l_result");
}
#[test]
fn test_from_str() {
assert_eq!(CommentEntityType::from_str("user").unwrap(), CommentEntityType::User);
assert_eq!(CommentEntityType::from_str("tts_model").unwrap(), CommentEntityType::TtsModel);
assert_eq!(CommentEntityType::from_str("tts_result").unwrap(), CommentEntityType::TtsResult);
assert_eq!(CommentEntityType::from_str("w2l_template").unwrap(), CommentEntityType::W2lTemplate);
assert_eq!(CommentEntityType::from_str("w2l_result").unwrap(), CommentEntityType::W2lResult);
assert!(CommentEntityType::from_str("foo").is_err());
}
}
}
@@ -0,0 +1 @@
pub mod comment_entity_type;
@@ -22,6 +22,12 @@ pub enum GenericDownloadType {
#[sqlx(rename = "hifigan_rocket_vc")]
HifiGanRocketVc,
/// NB: Note - this is hifigan for SoVitsSvc
/// Some work will need to be done to unify this with other hifigan types.
#[serde(rename = "hifigan_so_vits_svc")]
#[sqlx(rename = "hifigan_so_vits_svc")]
HifiGanSoVitsSvc,
//#[serde(rename = "melgan_vocodes")]
//#[sqlx(rename = "melgan_vocodes")]
//MelGanVocodes,
@@ -32,10 +38,20 @@ pub enum GenericDownloadType {
#[sqlx(rename = "rocket_vc")]
RocketVc,
/// so-vits-svc voice conversion models
#[serde(rename = "so_vits_svc")]
#[sqlx(rename = "so_vits_svc")]
SoVitsSvc,
/// Tacotron TTS models.
#[serde(rename = "tacotron2")]
#[sqlx(rename = "tacotron2")]
Tacotron2,
/// VITS TTS models.
#[serde(rename = "vits")]
#[sqlx(rename = "vits")]
Vits,
}
/// NB: Legacy API for older code.
@@ -44,8 +60,11 @@ impl GenericDownloadType {
match self {
Self::HifiGan => "hifigan",
Self::HifiGanRocketVc => "hifigan_rocket_vc",
Self::HifiGanSoVitsSvc => "hifigan_so_vits_svc",
Self::RocketVc => "rocket_vc",
Self::SoVitsSvc => "so_vits_svc",
Self::Tacotron2 => "tacotron2",
Self::Vits => "vits",
}
}
@@ -53,8 +72,11 @@ impl GenericDownloadType {
match value {
"hifigan" => Ok(Self::HifiGan),
"hifigan_rocket_vc" => Ok(Self::HifiGanRocketVc),
"hifigan_so_vits_svc" => Ok(Self::HifiGanSoVitsSvc),
"rocket_vc" => Ok(Self::RocketVc),
"so_vits_svc" => Ok(Self::SoVitsSvc),
"tacotron2" => Ok(Self::Tacotron2),
"vits" => Ok(Self::Vits),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -62,30 +84,39 @@ impl GenericDownloadType {
#[cfg(test)]
mod tests {
use crate::workers::generic_download_type::GenericDownloadType;
use crate::by_table::generic_download_jobs::generic_download_type::GenericDownloadType;
use crate::test_helpers::assert_serialization;
#[test]
fn test_serialization() {
assert_serialization(GenericDownloadType::HifiGan, "hifigan");
assert_serialization(GenericDownloadType::HifiGanRocketVc, "hifigan_rocket_vc");
assert_serialization(GenericDownloadType::HifiGanSoVitsSvc, "hifigan_so_vits_svc");
assert_serialization(GenericDownloadType::RocketVc, "rocket_vc");
assert_serialization(GenericDownloadType::SoVitsSvc, "so_vits_svc");
assert_serialization(GenericDownloadType::Tacotron2, "tacotron2");
assert_serialization(GenericDownloadType::Vits, "vits");
}
#[test]
fn to_str() {
assert_eq!(GenericDownloadType::HifiGan.to_str(), "hifigan");
assert_eq!(GenericDownloadType::HifiGanRocketVc.to_str(), "hifigan_rocket_vc");
assert_eq!(GenericDownloadType::HifiGanSoVitsSvc.to_str(), "hifigan_so_vits_svc");
assert_eq!(GenericDownloadType::RocketVc.to_str(), "rocket_vc");
assert_eq!(GenericDownloadType::SoVitsSvc.to_str(), "so_vits_svc");
assert_eq!(GenericDownloadType::Tacotron2.to_str(), "tacotron2");
assert_eq!(GenericDownloadType::Vits.to_str(), "vits");
}
#[test]
fn from_str() {
assert_eq!(GenericDownloadType::from_str("hifigan").unwrap(), GenericDownloadType::HifiGan);
assert_eq!(GenericDownloadType::from_str("hifigan_rocket_vc").unwrap(), GenericDownloadType::HifiGanRocketVc);
assert_eq!(GenericDownloadType::from_str("hifigan_so_vits_svc").unwrap(), GenericDownloadType::HifiGanSoVitsSvc);
assert_eq!(GenericDownloadType::from_str("rocket_vc").unwrap(), GenericDownloadType::RocketVc);
assert_eq!(GenericDownloadType::from_str("so_vits_svc").unwrap(), GenericDownloadType::SoVitsSvc);
assert_eq!(GenericDownloadType::from_str("tacotron2").unwrap(), GenericDownloadType::Tacotron2);
assert_eq!(GenericDownloadType::from_str("vits").unwrap(), GenericDownloadType::Vits);
}
}
@@ -0,0 +1 @@
pub mod generic_download_type;
@@ -0,0 +1,93 @@
use std::collections::BTreeSet;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
/// Used in the `generic_inference_jobs` table in `VARCHAR(32)` field `inference_category`.
///
/// Our "generic inference" pipeline supports a wide variety of ML models and other media.
/// Each "category" of inference is identified by the following enum variants.
/// These types are present in the HTTP API and database columns as serialized here.
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
pub enum InferenceCategory {
#[serde(rename = "text_to_speech")]
TextToSpeech,
#[serde(rename = "voice_conversion")]
VoiceConversion,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(InferenceCategory);
impl_mysql_enum_coders!(InferenceCategory);
/// NB: Legacy API for older code.
impl InferenceCategory {
pub fn to_str(&self) -> &'static str {
match self {
Self::TextToSpeech => "text_to_speech",
Self::VoiceConversion => "voice_conversion",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"text_to_speech" => Ok(Self::TextToSpeech),
"voice_conversion" => Ok(Self::VoiceConversion),
_ => Err(format!("invalid value: {:?}", value)),
}
}
pub fn all_variants() -> BTreeSet<Self> {
// NB: BTreeSet is sorted
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
Self::TextToSpeech,
Self::VoiceConversion,
])
}
}
#[cfg(test)]
mod tests {
use crate::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use crate::test_helpers::assert_serialization;
#[test]
fn test_serialization() {
assert_serialization(InferenceCategory::TextToSpeech, "text_to_speech");
assert_serialization(InferenceCategory::VoiceConversion, "voice_conversion");
}
#[test]
fn to_str() {
assert_eq!(InferenceCategory::TextToSpeech.to_str(), "text_to_speech");
assert_eq!(InferenceCategory::VoiceConversion.to_str(), "voice_conversion");
}
#[test]
fn from_str() {
assert_eq!(InferenceCategory::from_str("text_to_speech").unwrap(), InferenceCategory::TextToSpeech);
assert_eq!(InferenceCategory::from_str("voice_conversion").unwrap(), InferenceCategory::VoiceConversion);
}
#[test]
fn all_variants() {
// Static check
let mut variants = InferenceCategory::all_variants();
assert_eq!(variants.len(), 2);
assert_eq!(variants.pop_first(), Some(InferenceCategory::TextToSpeech));
assert_eq!(variants.pop_first(), Some(InferenceCategory::VoiceConversion));
assert_eq!(variants.pop_first(), None);
// Generated check
use strum::IntoEnumIterator;
assert_eq!(InferenceCategory::all_variants().len(), InferenceCategory::iter().len());
}
}
@@ -0,0 +1,79 @@
use std::collections::BTreeSet;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
/// Used in the `generic_inference_jobs` table in `VARCHAR(32)` field `maybe_input_source_token`.
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
pub enum InferenceInputSourceTokenType {
#[serde(rename = "media_upload")]
MediaUpload,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(InferenceInputSourceTokenType);
impl_mysql_enum_coders!(InferenceInputSourceTokenType);
/// NB: Legacy API for older code.
impl InferenceInputSourceTokenType {
pub fn to_str(&self) -> &'static str {
match self {
Self::MediaUpload => "media_upload",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"media_upload" => Ok(Self::MediaUpload),
_ => Err(format!("invalid value: {:?}", value)),
}
}
pub fn all_variants() -> BTreeSet<InferenceInputSourceTokenType> {
// NB: BTreeSet is sorted
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
InferenceInputSourceTokenType::MediaUpload,
])
}
}
#[cfg(test)]
mod tests {
use crate::by_table::generic_inference_jobs::inference_input_source_token_type::InferenceInputSourceTokenType;
use crate::test_helpers::assert_serialization;
#[test]
fn test_serialization() {
assert_serialization(InferenceInputSourceTokenType::MediaUpload, "media_upload");
}
#[test]
fn to_str() {
assert_eq!(InferenceInputSourceTokenType::MediaUpload.to_str(), "media_upload");
}
#[test]
fn from_str() {
assert_eq!(InferenceInputSourceTokenType::from_str("media_upload").unwrap(), InferenceInputSourceTokenType::MediaUpload);
}
#[test]
fn all_variants() {
// Static check
let mut variants = InferenceInputSourceTokenType::all_variants();
assert_eq!(variants.len(), 1);
assert_eq!(variants.pop_first(), Some(InferenceInputSourceTokenType::MediaUpload));
assert_eq!(variants.pop_first(), None);
// Generated check
use strum::IntoEnumIterator;
assert_eq!(InferenceInputSourceTokenType::all_variants().len(), InferenceInputSourceTokenType::iter().len());
}
}
@@ -0,0 +1,106 @@
use std::collections::BTreeSet;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
/// Used in the `generic_inference_jobs` table in `VARCHAR(32)` field `maybe_model_type`.
///
/// Our "generic inference" pipeline supports a wide variety of ML models and other media.
/// Each inference "model type" identified by the following enum variants, though some pipelines
/// may use multiple models or no model (and may report NULL).
///
/// These types are present in the HTTP API and database columns as serialized here.
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
pub enum InferenceModelType {
#[serde(rename = "so_vits_svc")]
SoVitsSvc,
// TODO: Does this need to be "legacy_tacotron2" ?
#[serde(rename = "tacotron2")]
Tacotron2,
#[serde(rename = "vits")]
Vits,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(InferenceModelType);
impl_mysql_enum_coders!(InferenceModelType);
/// NB: Legacy API for older code.
impl InferenceModelType {
pub fn to_str(&self) -> &'static str {
match self {
Self::SoVitsSvc => "so_vits_svc",
Self::Tacotron2 => "tacotron2",
Self::Vits => "vits",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"so_vits_svc" => Ok(Self::SoVitsSvc),
"tacotron2" => Ok(Self::Tacotron2),
"vits" => Ok(Self::Vits),
_ => Err(format!("invalid value: {:?}", value)),
}
}
pub fn all_variants() -> BTreeSet<InferenceModelType> {
// NB: BTreeSet is sorted
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
InferenceModelType::SoVitsSvc,
InferenceModelType::Tacotron2,
InferenceModelType::Vits,
])
}
}
#[cfg(test)]
mod tests {
use crate::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
use crate::test_helpers::assert_serialization;
#[test]
fn test_serialization() {
assert_serialization(InferenceModelType::SoVitsSvc, "so_vits_svc");
assert_serialization(InferenceModelType::Tacotron2, "tacotron2");
assert_serialization(InferenceModelType::Vits, "vits");
}
#[test]
fn to_str() {
assert_eq!(InferenceModelType::SoVitsSvc.to_str(), "so_vits_svc");
assert_eq!(InferenceModelType::Tacotron2.to_str(), "tacotron2");
assert_eq!(InferenceModelType::Vits.to_str(), "vits");
}
#[test]
fn from_str() {
assert_eq!(InferenceModelType::from_str("so_vits_svc").unwrap(), InferenceModelType::SoVitsSvc);
assert_eq!(InferenceModelType::from_str("tacotron2").unwrap(), InferenceModelType::Tacotron2);
assert_eq!(InferenceModelType::from_str("vits").unwrap(), InferenceModelType::Vits);
}
#[test]
fn all_variants() {
// Static check
let mut variants = InferenceModelType::all_variants();
assert_eq!(variants.len(), 3);
assert_eq!(variants.pop_first(), Some(InferenceModelType::SoVitsSvc));
assert_eq!(variants.pop_first(), Some(InferenceModelType::Tacotron2));
assert_eq!(variants.pop_first(), Some(InferenceModelType::Vits));
assert_eq!(variants.pop_first(), None);
// Generated check
use strum::IntoEnumIterator;
assert_eq!(InferenceModelType::all_variants().len(), InferenceModelType::iter().len());
}
}

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