Compare commits

..
Author SHA1 Message Date
Brandon Thomas c1bb4ee486 enqueue animation endpoint + more plumbing 2023-07-28 01:45:39 -04:00
Brandon Thomas a249b2b774 upload images (untested) 2023-07-28 01:10:29 -04:00
1102 changed files with 10069 additions and 32732 deletions
-5
View File
@@ -75,8 +75,3 @@ TTS_HIFIGAN_SUPERRES_VOCODER_MODEL_FILENAME=hifigan_superres_twilight_33000.pt
# Development key. Permissible to check in.
NEWRELIC_API_KEY=c402be1c4c4216ec83d0cfc0851520cfFFFFNRAL
STORYTELLER_ROOT = "/home/tensor/code/storyteller" # your path here!
STORYTELLER_FRONTEND = "storyteller-frontend"
STORYTELLER_ML = "storyteller-ml"
STORYTELLER_RUST = "storyteller-rust"
+2 -3
View File
@@ -1,6 +1,5 @@
# Ignore certain code for Github language statistics
# https://github.com/github/linguist/blob/master/docs/overrides.md
old_code/trumpet-trumped.com/dictionary/cmudict-0.7b linguist-vendored
old_code/voder-vocodes-1.0/frontends/admin/node_modules/** linguist-vendored
test_data/html_scraping/** linguist-vendored
windows/sqlite/** linguist-vendored
old_code/voder-vocodes-1.0/frontends/admin/node_modules linguist-vendored
windows/sqlite linguist-vendored
-11
View File
@@ -1,11 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "cargo" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
-7
View File
@@ -3,8 +3,6 @@
<words>
<w>arpabet</w>
<w>backfill</w>
<w>canonicalized</w>
<w>canonicalizing</w>
<w>cashapp</w>
<w>cheermote</w>
<w>cidrs</w>
@@ -12,10 +10,7 @@
<w>culted</w>
<w>dalle</w>
<w>demuxer</w>
<w>dereferencing</w>
<w>downloaders</w>
<w>downvote</w>
<w>encodec</w>
<w>fakeyou</w>
<w>ffprobe</w>
<w>greenlight</w>
@@ -26,8 +21,6 @@
<w>hparams</w>
<w>huggingface</w>
<w>lipsync</w>
<w>mochi</w>
<w>nestedness</w>
<w>pathbuf</w>
<w>replayable</w>
<w>retryably</w>
Generated
+1892 -552
View File
File diff suppressed because it is too large Load Diff
+4 -14
View File
@@ -11,32 +11,28 @@ members = [
# CLI tools for operations, etc.
"crates/cli/database_backup",
"crates/cli/database_cleanup",
"crates/cli/dev_database_seed",
"crates/cli/dev_upload_media_file",
"crates/cli/kubectl_pod_cleanup",
"crates/cli/scrape_test",
# 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/concurrency",
"crates/lib/cookies",
"crates/lib/crockford",
"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/easyenv", # NB: Vendored version of https://github.com/echelon/easyenv.rs that we'll improve.
"crates/lib/envvar",
"crates/lib/errors",
"crates/lib/files/archives",
"crates/lib/files/filesys",
"crates/lib/files/hashing",
"crates/lib/files/images",
"crates/lib/files/media",
"crates/lib/files/mimetypes",
"crates/lib/idempotency",
@@ -44,19 +40,16 @@ members = [
"crates/lib/mysql_queries",
"crates/lib/redis_common",
"crates/lib/server_environment",
"crates/lib/sqlite_queries",
"crates/lib/sqlx_mysql_helpers",
"crates/lib/storyteller_root",
"crates/lib/subprocess_common",
"crates/lib/testing",
"crates/lib/tts_common",
"crates/lib/url_config",
"crates/lib/user_input_common",
"crates/lib/web_scrapers",
#"crates/lib/api_clients/fakeyou_client",
#"crates/lib/sqlite_queries",
# Programs: Desktop apps
#"crates/programs/aichatbot-sidecar",
"crates/programs/aichatbot-sidecar",
# Services: API servers, jobs, workers, etc.
"crates/service/job/analytics_job",
@@ -75,7 +68,4 @@ members = [
"crates/service/plugins/billing",
"crates/service/plugins/inference_workloads",
"crates/service/plugins/users",
# Vendored code
"crates/vendor/newrelic-telemetry-sdk-rust",
]
-61
View File
@@ -1,61 +0,0 @@
# Persist clippy check configurations:
# https://github.com/ericseppanen/cargo-cranky
# Clippy doesn't allow this (yet):
# https://github.com/rust-lang/rust-clippy/issues/6625
deny = [
# Rust
"unsafe_code", # We may remove this if needed
# Clippy - "serious" lints
"clippy::borrow_interior_mutable_const", # Seems dangerous to allow this. Eg. `const F = Lazy::new()`;
# Clippy - bad math
#"clippy::cast_possible_truncation", # Seems dangerous, eg f64 to u64.
#"clippy::cast_possible_wrap",
# Clippy - pointer safety / readability / correctness
"clippy::as_ptr_cast_mut",
"clippy::borrow_as_ptr",
"clippy::borrow_deref_ref",
# Clippy - performance
"clippy::cmp_owned",
"clippy::useless_vec",
"clippy::format_in_format_args",
#"clippy::redundant_clone",
#"clippy::unnecessary_to_owned",
#"clippy::vec_init_then_push",
# Clippy - "ergonomic" / "usage" lints
"clippy::option_option", # Lint: Don't ever Option<Option<T>>! Enums instead.
"clippy::zero_sized_map_values", # Lint: use a HashSet instead of HashMap<T, ()>.
# Clippy - "aesthetic" / "style" lints
"clippy::clone_double_ref", # Lint: feels safer/hygienic to disallow this, but I'm not strongly opposed.
"clippy::double_comparisons", # Lint: readability
"clippy::empty_structs_with_brackets", # Lint: {} feels less aesthetic than ;
"clippy::implicit_clone", # Lint: Recommendation here seems more idiomatic.
"clippy::needless_return", # Lint: not the worst offender, but let's try to keep unnecessary returns out.
"clippy::redundant_field_names", # Lint: Duplicate names is a burden when reading: you wonder why they're dupes.
"clippy::redundant_static_lifetimes", # Lint: feels more modern to elide static lifetimes
# Rust
"unused_imports", # These are easy to automatically cull
# Possible:
# "clippy::ptr_arg",
# "clippy::too_many_lines" (note: this is configurable)
]
warn = [
]
allow = [
# Rust
"deprecated", # Other systems can handle deprecated code instead of the linter
"missing_docs", # Not everything needs documentation. Too much documentation is bad. Literate code.
# Clippy
"clippy::if_same_then_else", # There are cases this is clearer! Branches may have notes / considerations.
"clippy::single_char_pattern", # This is like punishing trailing commas. Chars are dumb.
]
+1 -4
View File
@@ -43,7 +43,4 @@ Our Rust monorepo, which serves both our API surface area and our downloadable c
.' /"' | "' '_ One Rust Monorepo at a time
/_|.-'\ ,". '.'`__'-( \
/ ,"'"\,' `/ `-.|"
```
- [documentation](./_develop/docs)
- [tools, misc](./_develop)
```
-52
View File
@@ -1,52 +0,0 @@
README
======
This directory contains a collection of (hopefully organized and up to date) documentation on
running the various backend pieces, development setup, production maintenance, etc. Check out
all the markdown documents in this directory tree for information organized by topic.
Development / Setup
-------------------
- [Most of the general documents for cross-cutting setup of FakeYou.com live here.](./local_development)
- Some per-application documents (such as for `aichatbot-sidecar`) live as READMEs under that particular
application's code directory, eg. `/crates/{appCategory}/{appName}/README.md` (These are irrelevant
for most folks.)
Web API Overview
----------------
### FakeYou.com
* [FakeYou.com](https://fakeyou.com) is powered by the following applications:
* HTTP APIs:
* `storyteller-web` - HTTP API + database monolith for FakeYou
* Asynchronous Jobs:
* `download-job` - Handle async download of ML models (RVC, SVC, etc.)
* `inference-job` - Run async ML model inference (RVC, SVC, SadTalker, etc.)
This will handle most model inference going forward.
* `tts-download-job` - (*deprecated*) Async download of Tacotron2 models only
* `tts-inference-job` - (*deprecated*) Async TTS inference of Tacotron2 models only
* `w2l-download-job` - (*deprecated*) Async download of videos and images
* `w2l-inference-job` - (*deprecated*) Async W2L inference
### PowerStream
* [PowerStream](https://power.stream) (deprecated) is powered by the following applications:
* HTTP APIs:
* `storyteller-web` - HTTP + database monolith for FakeYou ***and*** PowerStream.
* Twitch API integration:
* `twitch-pubsub-subscriber` - Dynamically subscribes to Twitch PubSub for "active" users
* Websocket events:
* `websocket-gateway` - Websocket for users' browsers to pull down enriched Twitch events.
TODO
----
Notes / TODOs:
* Examples for good Actix+Sqlx Tests:
https://stackoverflow.com/questions/65370752/how-do-i-create-an-actix-web-server-that-accepts-both-sqlx-database-pools-and-tr
* Actix/sqlx runtime compat:
https://github.com/launchbadge/sqlx/issues/1117#issuecomment-801237734
+38
View File
@@ -0,0 +1,38 @@
AI Chatbot Sidecar
==================
This is the first app that doesn't run as a part of our SoA API architecture. (Though it is written such that we
could port it.) This app is responsible for generating all the content that goes into our streaming AI-powered TV
programs.
### Windows Installation
The application uses sqlite, which is tricky to install on Windows.
1. Put together an sqlite build directory containing the sources and dll file. One is checked in under this monorepo
in `./windows/sqlite` at the time of this writing, though that may change in the future.
2. Add environment variables for the sqlite build directory (see https://github.com/diesel-rs/diesel/issues/487)
* PATH (append the sqlite build directory to the end)
* SQLITE3_LIB_DIR (a new environment variable; set it to the sqllite build path)
3. Build the `sqlite3.lib` file with the following:
```
lib /def:sqlite3.def /out:sqlite3.lib /MACHINE:amd64
```
This must be done in "Developer Command Prompt for VS 2022" (or similar), not `cmd` or `PowerShell`.
4. Run the diesel_cli tool build
```
cargo install diesel_cli --no-default-features --features sqlite
```
If it still complains about the `sqlite3.lib` file not being found, be sure to double check that `echo %PATH%` shows
the updated PATH from the steps above.
-43
View File
@@ -1,43 +0,0 @@
Migrations guide
================
## Diesel Migrations
To run pending migrations, execute the following:
```bash
diesel migration run
```
To revert the last 3 migrations:
```bash
diesel migration revert -n 3
```
To reset the entire database (drop, migrate), run:
```bash
diesel database reset
```
## Server Query Codegen
We use SQLx instead of Diesel in the production server. It's typesafe
SQL instead of an ORM like Diesel.
SQLx connects to a database to derive type information, but obviously
cannot do this for builds in CI. In order to cache the types, we build
and check in a cache file (necessary for builds):
```bash
SQLX_OFFLINE=true cargo sqlx prepare
```
Now that we have multiple binaries, it's required to include all the queries in the main
binary so we can generate the cached queries as a single target. That's then executed
with:
```bash
SQLX_OFFLINE=true cargo sqlx prepare -- --bin storyteller-web
```
@@ -1,8 +1,6 @@
database schema
================
(This is woefully incomplete and unmaintained.)
Twitch Model
------------
@@ -1,216 +0,0 @@
FakeYou Development Setup (bare metal)
======================================
Set your Environment .env File with the following paths, copy this in
The root path and the folders associated with the path.
This will change the base paths for development.
STORYTELLER_ROOT = "/home/tensor/code/storyteller" # change this
STORYTELLER_FRONTEND = "storyteller-frontend"
STORYTELLER_ML = "storyteller-ml"
STORYTELLER_RUST = "storyteller-rust"
This document describes how to run the FakeYou infrastructure on your development
machine's bare metal (no containers).
Setup instructions and development were tested and known to work on the following
platforms:
- Mac OS (Apple M2 silicon)
- Ubuntu 22.04
The applications (binary targets) you might be interested in running include, but
are not limited to:
- `storyteller-web`, the HTTP API server
- `download-job`, which downloads models from the web and stores them in GCS
- `inference-job`, which downloads models from GCS and runs inference with them
Setup Instructions
------------------
### (1) Install Rust
Install Rust [using this guide](https://www.rust-lang.org/learn/get-started). If it asks,
you'll want "stable" Rust, not "nightly" Rust. If it doesn't ask, it defaults to "stable".
### (2) Install the necessary libraries
Mac: (Lost the list, but it should match Linux. Install Homebrew.)
Ubuntu 22.04:
```bash
sudo apt install jq \
libmysqlclient-dev \
libsqlite3-dev \
pkgconf
```
(Note: jq is for combining mysql codegen outputs; pkgconf is if using openssl instead of rustls.)
### (3) Install MySQL server
Mac:
```bash
brew install mysql
```
If `mysql -uroot` fails, reboot the machine:
```bash
sudo reboot now
```
Ubuntu 22.04:
```bash
sudo apt install mysql-server
```
### (4) Install a `storyteller` user and table in MySQL
Connect to mysql:
```bash
# If the following command asks for a password, the password is typically "root"
sudo mysql -u root -p
```
Once in MySQL, run the following:
```mysql
use mysql;
CREATE DATABASE storyteller;
CREATE USER 'storyteller'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON storyteller.* TO 'storyteller'@'localhost';
```
Then verify access with `./dev_mysql_connect.sh`
### (5) Install Diesel CLI (for MySQL migrations):
```bash
cargo install diesel_cli \
--no-default-features \
--features mysql,sqlite
```
As of this writing, Mac [has some issues with Diesel CLI](https://github.com/diesel-rs/diesel/issues/2605)
and requires a few extra dependencies to be installed:
```bash
brew install libpq
```
### (6) Run the pending database migrations:
```bash
diesel migration run
```
You might get a scary message about `"Encountered unknown type for Mysql: enum"` -- you can ignore this
error (see below).
### (7) (optional) Install the SQLx CLI (if doing database development)
```bash
# NB(bt,2023-10-04): "--no-default-features" not working
# cargo install sqlx-cli --no-default-features --features rustls,mysql,sqlite
cargo install sqlx-cli --features rustls,mysql,sqlite
```
We'll be using diesel to manage the migrations, but sqlx within the app to actually perform queries.
Diesel is an immature ORM, which isn't a good tech bet, so we use sqlx as at-compile-time
typesafe SQL.
### (8) Install hosts file:
(This should be the same on Linux and Mac, but might differ for Windows.)
If you're developing against the frontend, it'll target development domains (eg. `dev.fakeyou.com`) instead
of `127.0.0.1` or `localhost`. You can make your machine route domains to localhost by editing your hosts
file (located at `/etc/hosts`) to include the following configuration lines:
```
127.0.0.1 dev.fakeyou.com
127.0.0.1 api.dev.fakeyou.com
127.0.0.1 devproxy.fakeyou.com
127.0.0.1 dev.storyteller.ai
127.0.0.1 api.dev.storyteller.ai
127.0.0.1 devproxy.storyteller.ai
```
### (9a) Install Redis
```
sudo apt install redis
```
### (9b) Run one or more applications:
DO NOT CHECK THESE TWO FILES INTO THE REPO
Ask Brandon for the .env-secrets and .storteller-web.development-secrets.env and place it in the root of the folder.
To start the HTTP API server,
```bash
cargo run --bin storyteller-web
```
Note that this compiles and runs the "development" binary. It's faster and easier to debug than the
optimized "production" build. To build a fully optimized production release,
run `cargo build --release --bin storyteller-web` . Note that this will take much longer.
DO NOT CHECK THESE TWO FILES INTO THE REPO
Ask Brandon for the .download-job.development-secrets.env and place it in
crates/service/job/download_job/config
Ask Brandon for the .inference-job.development-secrets.env and place it in
crates/service/job/inference_job/config
To download some ML models, run:
```bash
cargo run --bin download-job
cargo run --bin tts-download-job
```
If you want to run both the HTTP API and the jobs, you'll need to run both processes in different
terminals or tmux sessions.
Note also that the configurations pointing to the ML monorepo must be set up for each application.
Additionally, some development secrets may be needed (ask the team to share).
To execute ML inference, run:
```bash
cargo run --bin inference-job
cargo run --bin tts-inference-job
```
Again, note that the configurations pointing to the ML monorepo must be set up for each application.
Additionally, some development secrets may be needed (ask the team to share).
Solutions to Common Setup Problems
-----------------------------------
### [Fix] Sqlx Error when Performing Schema Migrations
You might get this error message during migration,
```
Encountered unknown type for Mysql: enum
thread 'main' panicked at 'internal error: entered unreachable code: Mysql only supports a closed set of types.
If you ever see this error message please open an issue at https://github.com/diesel-rs/diesel
containing a dump of your schema definition.', diesel_cli/src/print_schema.rs:310:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
I haven't found the cause (it doesn't happen on newer installs), but the migrations appear to work regardless
of this error message. You can essentially ignore it.
### [Fix] Can't connect to local MySQL after install on Ubuntu
- If MySql in local dev can't be connected to, [reset the accounts](https://linuxconfig.org/how-to-reset-root-mysql-mariadb-password-on-ubuntu-20-04-focal-fossa-linux).
@@ -1,56 +0,0 @@
Local Development nginx proxy
=============================
It isn't necessary to use nginx for development, but it can be nice. Nginx allows for a more
sophisticated testing setup that makes cookie and CORS issues less of a pain.
You can use nginx to serve (locally-signed) SSL, redirect traffic to different ports, or run
multiple copies of the app side by side.
### Hosts file
Set the following configs in your `/etc/hosts` file (as you would probably do even without nginx),
```
127.0.0.1 dev.fakeyou.com
127.0.0.1 api.dev.fakeyou.com
127.0.0.1 devproxy.fakeyou.com
127.0.0.1 dev.storyteller.ai
127.0.0.1 api.dev.storyteller.ai
127.0.0.1 devproxy.storyteller.ai
# Deprecated development hostnames :
127.0.0.1 jungle.horse
127.0.0.1 api.jungle.horse
```
### Nginx installation and administration
Configure Nginx per the checked in Nginx configs (and instructions) in
the directory `/_develop/localdev/nginx-http-config`.
This should be straightforward, but if it isn't, contribute docs here.
### [Fix] Python 3.6 on Apple M1 Mac
Python3.6 isn't supported on Apple silicon, and it's not in homebrew. It can be installed with
[nix using Rosetta](https://stackoverflow.com/a/65980989):
Download: https://nixos.org/download.html#nix-quick-install
```
nix run nixpkgs.python36 -c python
```
Install venv:
```
nix run nixpkgs.python36 -c python -m venv python
```
Install other packages on Mac that aren't used in venv:
```
python3 -m pip install --user requests gdown youtube_dl
```
@@ -1,7 +1,5 @@
# Local Kubernetes environment for standing up the APIs and their dependencies
(These are Paul's notes.)
- Install minikube, kubectl, docker, and musl from your OS package manager
- `rustup target add x86_64-unknown-linux-musl`
- `cargo build --release --bin storyteller-web --target=x86_64-unknown-linux-musl`
+248
View File
@@ -0,0 +1,248 @@
dev setup
=========
[Back to main README](../../README.md)
## Debugging and Fixing CUDA/PyTorch
See this spreadsheet for previous battles with version incompatibility:
https://docs.google.com/spreadsheets/d/1BEdLmwOzo3r83-iJn9sj6co1VT92t3lIeJ-lNH25bdQ/edit#gid=0
Ubuntu might upgrade the driver by accident, and it might need reinstallation. Who knows.
This stuff is a nightmare.
## Database Setup
### Mac Install
```
brew install mysql
# If mysql -uroot fails, reboot the machine:
sudo reboot now
```
### Linux Install
Install the following libraries, and see the notes further below about MySQL on Ubuntu 20.04.
```
jq # for combining mysql codegen outputs
libmysqlclient-dev
mysql-server
libsqlite3-dev
pkgconf # if using openssl instead of rustls
```
### Migrations
To manage the database and perform migrations, install the Rust tools diesel and sqlx.
We'll be using diesel to manage the migrations, but sqlx within the app to actually perform queries.
Diesel is an ORM, which is dumb, so we use sqlx as at-compile-time typesafe SQL.
The CLI is necessary to perform codegen:
```
sudo apt-get install libmysqlclient-dev
cargo install sqlx-cli --no-default-features --features rustls,mysql,sqlite
```
Diesel now supports configuring the migration directory via an environment variable,
so we can install the currently published version:
```
cargo install diesel_cli \
--no-default-features \
--features mysql,sqlite
```
If the modern version fails, try installing a cherry-picked version with a
TOML-based migration directory configuration:
```
cargo install diesel_cli \
--git https://github.com/diesel-rs/diesel.git \
--rev a213fe232a122f35a812b0ce0269708a1845a4c9 \
--no-default-features \
--features mysql
```
#### Sqlx Error on Linux when Performing Schema Migrations
You might get this error message during migration,
```
Encountered unknown type for Mysql: enum
thread 'main' panicked at 'internal error: entered unreachable code: Mysql only supports a closed set of types.
If you ever see this error message please open an issue at https://github.com/diesel-rs/diesel containing a dump of your schema definition.', diesel_cli/src/print_schema.rs:310:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
I haven't found the cause (it doesn't happen on Mac), but the migrations appear to work regardless of the error message.
#### Linux database notes
If MySql in local dev can't be connected to, reset the accounts:
https://linuxconfig.org/how-to-reset-root-mysql-mariadb-password-on-ubuntu-20-04-focal-fossa-linux
#### MySql on Ubuntu 22.04
Should work largely out of the box. We'll need a dev account:
```
# Connect to mysql:
# sudo mysql -u root -p (password is "root")
use mysql;
CREATE USER 'storyteller'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON storyteller.* TO 'storyteller'@'localhost';
```
Then verify with `./dev_mysql_connect.sh`
#### Fixing dev MySql on Ubuntu 20.04
For some reason, the MySql default install on 20.04 gave me a bunch of trouble.
In retrospect, I _think_ this is because 'root@localhost' requires sudo to access, but if this
gives any trouble in the future, here's how I got around it (two full hours of distraction!)
```
sudo apt-get install mysql-server
# But for some reason the default password doesn't work and diesel/sqlx can't connect?
# Kill everything
sudo apt purge mysql-server mysql-client mysql-common
sudo apt autoremove
sudo mv -iv /var/lib/mysql /var/tmp/mysql-backup
sudo rm -rf /var/lib/mysql*
sudo /usr/bin/mysql_secure_installation
# still no work...
sudo systemctl stop mysql.service
# ugh, it wasn't chowned or created (both states observed in different installs)…
sudo mkdir -p /var/run/mysqld
sudo chown mysql:mysql /var/run/mysqld
sudo mysqld_safe --skip-grant-tables --skip-networking &
mysql -u root
flush privileges;
USE mysql;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
sudo killall -u mysql
sudo systemctl restart mysql.service
# now it works
sudo mysql -u root -p
# but now I have to use "sudo" !?!?
use mysql;
CREATE USER 'storyteller'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON storyteller.* TO 'storyteller'@'localhost';
```
### Install Diesel (migrations only)
We use Diesel to manage migrations, but we don't use it in server code.
Actual server code uses SQLx. To install the CLI tool, run the following:
```
cargo install diesel_cli
```
Mac [has issues](https://github.com/diesel-rs/diesel/issues/2605) and requires a few dependencies:
```
brew install libpq
```
### Database migrations
To reset the entire database (drop, migrate), run:
```
diesel database reset
```
To migrate at the current step and beyond:
```
diesel migration run
```
To undo migrations at the current step:
```
diesel migration redo
```
### Server Query Codegen
We use SQLx instead of Diesel in the production server. It's typesafe
SQL instead of an ORM like Diesel.
SQLx connects to a database to derive type information, but obviously
cannot do this for builds in CI. In order to cache the types, we build
and check in a cache file (necessary for builds):
```
SQLX_OFFLINE=true cargo sqlx prepare
```
Now that we have multiple binaries, it's required to include all the queries in the main
binary so we can generate the cached queries as a single target. That's then executed
with:
```
SQLX_OFFLINE=true cargo sqlx prepare -- --bin storyteller-web
```
### Setting Up a Local Nginx Proxy
Set up a local nginx to proxy to the frontend and backend so cookie issues aren't annoying
Configure Nginx per the checked in Nginx configs (and instructions) in `localdev/nginx-http-config`.
```
And in /etc/hosts,
```
127.0.0.1 jungle.horse
127.0.0.1 api.jungle.horse
```
### Python 3.6 on Apple M1 Mac
Python3.6 isn't supported on Apple silicon, and it's not in homebrew. It can be installed with
[nix using Rosetta](https://stackoverflow.com/a/65980989):
Download: https://nixos.org/download.html#nix-quick-install
```
nix run nixpkgs.python36 -c python
```
Install venv:
```
nix run nixpkgs.python36 -c python -m venv python
```
Install other packages on Mac that aren't used in venv:
```
python3 -m pip install --user requests gdown youtube_dl
```
+77
View File
@@ -0,0 +1,77 @@
old readme
==========
Contents of the main README.md, which will always be woefully out of date. Docs will migrate into this folder on a
per-subject basis. App-specific docs will live under each app.
Application overview
--------------------
* [FakeYou.com](https://fakeyou.com) is powered by:
* HTTP APIs:
* `storyteller-web` - HTTP + database monolith for FakeYou
* Asynchronous Jobs:
* `tts-download-job` - Async download of models
* `tts-inference-job` - Async TTS inference
* `w2l-download-job` - Async download of videos and images
* `w2l-inference-job` - Async W2L inference
* [StorytellerStream](https://storyteller.stream) is powered by:
* HTTP APIs:
* `storyteller-web` - HTTP + database monolith for FakeYou
* Websocket events:
* `websocket-gateway` - Websocket to pull down Twitch events.
* Twitch API integration:
* `twitch-pubsub-subscriber` - Dynamically subscribes to Twitch PubSub for "active" users
Schema and API notes
--------------------
* [Redis Schema Notes README](_docs/redis_schema.md)
Local development
-----------------
[Local development setup README](_docs/local_development_setup.md)
Production and Deployment
-------------------------
[Production builds and deployment README](_docs/production_builds_and_deployment.md)
Development notes
-----------------
[Development notes README](_docs/development_notes.md)
Dump a MySQL report
-------------------
```
mysql -u storyteller \
-pPasswordHere \
-h IP_HERE \
-P 3306 \
-D storyteller \
-B \
-e "select * from voice_clone_requests;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > voice_clone_report.csv
```
TODO
----
* Revise this README to be more useful.
Notes / TODOs:
* Examples for good Actix+Sqlx Tests:
https://stackoverflow.com/questions/65370752/how-do-i-create-an-actix-web-server-that-accepts-both-sqlx-database-pools-and-tr
* Actix/sqlx runtime compat:
https://github.com/launchbadge/sqlx/issues/1117#issuecomment-801237734
* Redis caching of more endpoints
* Jobs for analytics queries (#uses per model, etc)
* Jobs for ingesting Discord, Twitter, Reddit RPAN chat, Twitch chat (not PubSub), etc.
@@ -1,17 +0,0 @@
Production Database
===================
Secrets can be subbed in for `.env` and the standard diesel migration tooling will work.
Dump a MySQL report
-------------------
```bash
mysql -u storyteller \
-pPasswordHere \
-h IP_HERE \
-P 3306 \
-D storyteller \
-B \
-e "select * from voice_clone_requests;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > voice_clone_report.csv
```
-9
View File
@@ -7,12 +7,3 @@ update generic_inference_jobs set status = 'dead' where maybe_routing_tag IS NOT
-- Get pending jobs
select count(*) from generic_inference_jobs where status = 'pending';
update generic_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed');
update generic_inference_jobs
set status = 'dead'
where status IN ('pending', 'started', 'attempt_failed')
and maybe_model_type IN ('sad_talker', 'so_vits_svc');
+3 -213
View File
@@ -85,227 +85,17 @@ where token IN (
'vcm_jxd74xhcszry',
'vcm_tvk0g6dwg3yv',
'vcm_vrsdv4ahterx',
'vcm_e2debszbm8vt',
'vcm_rh98fw9a9an1',
'vcm_2bvd1gmysaxf',
'vcm_2cqq1j33y2hr',
'vcm_ysj7kwb96kcp',
'vcm_ef0eaneyr72p',
'vcm_t59d7vdxtqs4',
'vcm_90hrepevshtg',
'vcm_4st9ex13vnbh',
'vcm_30fne697qhab',
'vcm_qy7evy03p6tg',
'vcm_775eze19tv0n',
'vcm_4bzkfvaexbv3',
'vcm_08v2tdga8v93',
'vcm_whxeyxzw12q6',
'vcm_0rj5b6npxfkh',
'vcm_hv22emyfkex4',
'vcm_a1fmtgthezs0',
'vcm_z9fpz1p5bpr2',
'vcm_2y8ck2dbppkq',
'vcm_0c9h3mzc4kre',
'vcm_m0z3tt4gytm9'
'vcm_e2debszbm8vt'
);
-- Remove duplicate models (2)
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'duplicate model'
where token IN (
'vcm_v790w43dv3ce',
'vcm_xmzm7eextc3n',
'vcm_r3b91dr0eta5',
'vcm_p1rpmfmckd5c',
'vcm_cpajdgenjfw7',
'vcm_qchjs52fsr9y',
'vcm_pkkjy8c6cpt3',
'vcm_f8ra6j8d6wgv',
'vcm_mhsz9bjn19tw',
'vcm_btd5zab2jdqv',
'vcm_q5evptaaqne3',
'vcm_wqtqs4gj2zmj',
'vcm_14rv35fct2ay',
'vcm_418j0h41qy8a',
'vcm_3m5m6bpm0rt2',
'vcm_gdw4krmaxpza',
'vcm_b3xhdb8zymvf',
'vcm_aak9m6nvj3am',
'vcm_mcw5kn21bbjh',
'vcm_fydr6ts21mtf',
'vcm_zpw560jzyqpw',
'vcm_w24wcctnxbxf',
'vcm_ya5tpzdcvvcz',
'vcm_1ctmgrjtn1j7',
'vcm_rk8fycc0reb2',
'vcm_e2c8942vky34',
'vcm_wevg8cf3hcw8',
'vcm_6hzbyg453xb9',
'vcm_xqfffshe2g0q',
'vcm_32j1zmcvn61n'
);
-- Remove duplicate models (3)
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'duplicate model'
where token IN (
'vcm_46sbq0r9hfjk',
'vcm_k8nseqy8jyte',
'vcm_gs8qam6npe46',
'vcm_djh15g49cxm8',
'vcm_d7zygjnp35my',
'vcm_334yqeq11rpm',
'vcm_6m3b6121318k',
'vcm_a419w7gw6jrt',
'vcm_wtyszwjwq0ts',
'vcm_0q9t2azhqvf1',
'vcm_fx2k40ffzjqg',
'vcm_wvjqmzd8y4mt',
'vcm_b2635v3p50je',
'vcm_zfyr07z2d0rb',
'vcm_yn2sn5j2jwed',
'vcm_z596ja3yvyy9',
'vcm_a1p854bn1sjs',
'vcm_fv24vmr93805',
'vcm_0y7vsc2e9s3r',
'vcm_5aqzq0d246rm',
'vcm_trvge62x7je9',
'vcm_sghga68kwggk',
'vcm_raxcc33pj608',
'vcm_a66b3va0sj64',
'vcm_bd1rjawqypw6',
'vcm_evzff14n721p',
'vcm_jnrr4ht9f42f'
);
-- Remove duplicate models (4)
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'duplicate model'
where token IN (
'vcm_ds2pz63sagan',
'vcm_wkczgvq2fjqq',
'vcm_z8137w1rddse',
'vcm_gknzxybf4erw',
'vcm_z0m1qtmawccn',
'vcm_yek6pmgvbb1s',
'vcm_qqhnjwsjrvnx',
'vcm_8fetm7qz94cp',
'vcm_kz1zm1d269j0',
'vcm_rfnkc8g5gbbv',
'vcm_4ncqxetfe7dm',
'vcm_qkpfem2a153n',
'vcm_z5jkd9r4cawf',
'vcm_vgh6ja6zzj0p',
'vcm_bd473tdrrzhk',
'vcm_2k7tmx3ndd3y',
'vcm_weyxz516dd2m',
'vcm_1j4kpjvgsj6k',
'vcm_211g17ea44fw',
'vcm_7zkbj6be0yr5',
'vcm_nnaaxeqy4xj6',
'vcm_wp7sgtz6mhc4',
'vcm_h5w7fzhxcpxm',
'vcm_7d5rxpqkjy07',
'vcm_9vhjvrptygfz',
'vcm_4qbbawahnkvb',
'vcm_am870m8162at',
'vcm_cftdb5227qt5',
'vcm_m7vv1mcxfxvm',
'vcm_qn8vsvvh1rqc',
'vcm_erhvqjvk1dsk',
'vcm_4zs8tdrw971e',
'vcm_4zs8tdrw971e',
'vcm_z8htjaejr1wx',
'vcm_99wdsazefjwr',
'vcm_k1at1sbepvqv',
'vcm_xcp34f5d7ygs',
'vcm_8v8srq9sx7cq',
'vcm_f2yf7bxmk8h5',
'vcm_gvtrjte4as1s',
'vcm_2s0y50avy43b',
'vcm_r638ygfxkpmq',
'vcm_1ttm6pxcpqna',
'vcm_0ytfkxh6pm4f',
'vcm_zderdrfmgq6c',
'vcm_jvdpr6mtddb8',
'vcm_9tvcv961g09x',
'vcm_aynpmxbhpy7n',
'vcm_2gzsjb5bdsdq',
'vcm_a0vep64tz56n',
'vcm_zt4hgc9pyv11',
'vcm_szfxm0crd8y8',
'vcm_3q89kba3cy5z',
'vcm_ywpwnhk4pv4x',
'vcm_4he8jjmengb3',
'vcm_jpdfswn0empy',
'vcm_2nztkt3rgm1q',
'vcm_q5gyxf5a11zf',
'vcm_sa7k9ycne147',
'vcm_p6gxtj9qefsg',
'vcm_j2fvzdyachtw',
'vcm_ecbv0rhc6br3',
'vcm_jrgwspz2wt7p',
'vcm_f5b4j3rt180n',
'vcm_pzajxdfcjfpa',
'vcm_rq4f2cbbm6j1',
'vcm_rdmfpbnab47w',
'vcm_03dtk4xtggm6',
'vcm_zx7mdkh9s9qb',
'vcm_e0megdtf71x6'
);
-- Remove older models replaced by new versions
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'replaced with new version'
where token IN (
'vcm_gdg3najz6j3g'
);
-- Remove takedown request models
-- Remove duplicate models
update voice_conversion_models
set
mod_deleted_at = NOW(),
maybe_mod_comments = 'takedown request'
where token IN (
'vcm_2af74np3jh6q',
'vcm_8kk7355dc184',
'vcm_nsh89pcx4569',
'vcm_q7ewn3yym4gy',
'vcm_cwngb21xsf66',
'vcm_jmzjrky179cm',
'vcm_hj6a1nt1yvh9',
'vcm_6wwx1e3cd48s',
'vcm_pc76gc1xh7jg',
'vcm_gb0p1wmtk9wp',
'vcm_pbs955dvaeq6',
'vcm_x2wyzr6h6539',
'vcm_py7qwz310qff',
'vcm_k01bqvh0dseq',
'vcm_5m4dsn2fwa0q',
'vcm_hn9m98g1am3z',
'vcm_f9168tyyn6ex',
'vcm_03y9w4h99r1h',
'vcm_yr9f1s0xc7pc',
'vcm_45767r26a9bb',
'vcm_rq3cvp3x3hnh',
'vcm_ng1nz8d67z4v',
'vcm_f5arabzrk4en',
'vcm_d379600cr8yx',
'vcm_p7m9jw1krrkr',
'vcm_x7v3m9mcvten',
'vcm_6r057m7594bv',
'vcm_wkm9e42d3spm',
'vcm_cvz78weydh57',
'vcm_7g5q89m75n1p',
'vcm_fg3175bxy7kj'
'vcm_8kk7355dc184'
);
@@ -2,14 +2,6 @@
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- See how many jobs of each time were created in the last period
select
distinct maybe_model_type as model_type,
count(*) as created
from generic_inference_jobs
where created_at > (CURDATE() - INTERVAL 60 MINUTE)
group by maybe_model_type;
-- See how long recent jobs are taking
select
id,
@@ -23,19 +15,6 @@ and success_execution_millis IS NOT NULL
order by id desc
limit 50;
-- See who is uploading SadTalker jobs
select
maybe_creator_user_token,
users.username as maybe_creator_username,
creator_ip_address,
count(*) as attempts
from generic_inference_jobs
left outer join users
on users.token = generic_inference_jobs.maybe_creator_user_token
where maybe_model_type = 'sad_talker'
and status IN ('pending', 'started', 'complete_failure', 'attempt_failed')
group by maybe_creator_user_token, maybe_creator_username, creator_ip_address
order by attempts desc;
-- 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
@@ -70,8 +49,7 @@ from (
m.token = jobs.maybe_input_source_token
where
jobs.status != 'pending'
AND jobs.created_at > NOW() - INTERVAL 20 MINUTE
AND jobs.maybe_model_type IN ('so_vits_svc')
AND jobs.created_at > NOW() - INTERVAL 20 MINUTE
order by id desc
limit 200
) as t
@@ -120,99 +98,3 @@ order by jobs.id
desc
limit 100;
-- Generic inference jobs + legacy TTS (this is a production endpoint)
-- UPDATED QUERY: Queues as named rows
SELECT
maybe_model_type as queue_type,
count(*) as pending_job_count,
NOW() as present_time
FROM (
SELECT
token,
maybe_model_type
FROM generic_inference_jobs
WHERE status IN ("pending", "attempt_failed")
UNION
SELECT
token,
maybe_model_type
FROM generic_inference_jobs
WHERE status IN ("started")
AND created_at > (CURDATE() - INTERVAL 15 MINUTE)
) as generic_inner
GROUP BY queue_type
UNION
SELECT
"legacy_tts" as queue_type,
count(*) as pending_job_count,
NOW() as present_time
FROM
(
SELECT token
FROM tts_inference_jobs
WHERE status IN ("pending", "attempt_failed")
UNION
SELECT token
FROM tts_inference_jobs
WHERE status IN ("started")
AND created_at > (CURDATE() - INTERVAL 15 MINUTE)
) as legacy_inner
GROUP BY queue_type;
-- Generic inference jobs + legacy TTS (this was a production endpoint)
-- OLD QUERY: Queues as columns
SELECT
(
SELECT
COUNT(distinct token) as generic_job_count
FROM
(
SELECT token
FROM generic_inference_jobs
WHERE status = "started"
AND created_at > (CURDATE() - INTERVAL 5 MINUTE)
UNION
SELECT token
FROM generic_inference_jobs
WHERE status IN ("pending", "attempt_failed")
) as g
) as generic_job_count,
(
SELECT
COUNT(distinct token) as legacy_tts_job_count
FROM
(
SELECT token
FROM tts_inference_jobs
WHERE status = "started"
AND created_at > (CURDATE() - INTERVAL 5 MINUTE)
UNION
SELECT token
FROM tts_inference_jobs
WHERE status IN ("pending", "attempt_failed")
) as t
) as legacy_tts_job_count,
NOW() as present_time;
-- Histogram of inference
select
date(created_at) as created_date,
count(*) as job_count
from generic_inference_jobs
group by created_date
-- Histogram of inference (within range)
select
date(created_at) as created_date,
count(*) as job_count
from generic_inference_jobs
where created_at > (CURDATE() - INTERVAL 5 DAY)
group by created_date
-- Histogram of inference (within range)
select
date(created_at) as created_date,
count(*) as job_count
from generic_inference_jobs
where date(created_at) >= "2023-01-01"
group by created_date
-17
View File
@@ -21,23 +21,6 @@ group by creator_ip_address
order by attempts desc
limit 50;
-- Top (IP addresses, usernames) making requests
select distinct j.creator_ip_address, u.username, count(*) as attempts
from tts_inference_jobs AS j
left outer join users AS u
on u.token = j.maybe_creator_user_token
where j.status = 'pending'
group by j.creator_ip_address, u.username
order by attempts desc
limit 50;
-- Find a job by an IP
select *
from tts_inference_jobs
where status = 'pending'
and creator_ip_address = '191.102.120.182'
limit 1;
-- Top voices in requests
select distinct model_token, count(*) as attempts
from tts_inference_jobs
-15
View File
@@ -307,21 +307,6 @@ from (
order by m.created_at desc
limit 100;
-- Histogram of model contributions
select
date(created_at) as created_date,
count(*) as model_count
from tts_models
group by created_date
-- Histogram of model contributions (within range)
select
date(created_at) as created_date,
count(*) as model_count
from tts_models
where created_at > (CURDATE() - INTERVAL 5 DAY)
group by created_date
--
-- Models deleted recently (voice actor take down)
--
+1 -24
View File
@@ -31,29 +31,6 @@ from (
) as sample
where sample.is_generated_on_prem IS TRUE;
-- Histogram of days of content per day
select
date(created_at) as created_date,
sum(duration_millis) / 1000 / 60 / 60 / 24 as days
from tts_results
group by created_date
-- Histogram of days of content per day (range)
select
date(created_at) as created_date,
sum(duration_millis) / 1000 / 60 / 60 / 24 as days
from tts_results
where date(created_at) >= "2023-01-01"
group by created_date
-- Histogram of days of content per day (range)
-- Maybe non-tablescan?
select
date(created_at) as created_date,
sum(duration_millis) / 1000 / 60 / 60 / 24 as days
from tts_results
where created_at > (CURDATE() - INTERVAL 30 DAY)
group by created_date
-- Find TTS results for a single model
select count(*) from tts_results
@@ -119,7 +96,7 @@ WHERE
--- Search for 101soundboards.com using us
SELECT
r.maybe_creator_user_token, r.creator_ip_address, r.raw_inference_text
r.maybe_creator_user_token, r.creator_ip_address
FROM
tts_results as r
LEFT OUTER JOIN
+1 -2
View File
@@ -14,8 +14,7 @@ ON u.token = j.maybe_creator_user_token
SELECT
t.maybe_creator_user_token as user_token,
u.username,
count(*) as usage_count,
u.created_at
count(*) as usage_count
FROM tts_results as t
JOIN users as u
ON u.token = t.maybe_creator_user_token
@@ -9,11 +9,3 @@ select count(*) from users;
select count(*)
from users
where created_at > ( CURDATE() - INTERVAL 365 DAY )
-- Histogram of user signups
select
date(created_at) as created_date,
count(*) as registered
from users
where date(created_at) >= "2023-01-01"
group by created_date
@@ -37,37 +37,6 @@ where
and vc.mod_deleted_at IS NULL
order by vc.title asc;
-- Inventory duplicate non-deleted models
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.original_download_url IN (
select original_download_url from (
select original_download_url,
count(*) as duplicate_count
from voice_conversion_models
where user_deleted_at IS NULL
and mod_deleted_at IS NULL
group by original_download_url
order by original_download_url desc
) as duplicates
where duplicate_count > 1
)
and vc.user_deleted_at IS NULL
and vc.mod_deleted_at IS NULL
order by
vc.original_download_url asc,
id asc;
-- order by vc.original_download_url ASC;
--
@@ -76,7 +45,6 @@ order by
--
select
m.token,
m.model_type,
m.title,
u.username,
r.use_count,
@@ -95,76 +63,3 @@ from (
on u.token = m.creator_user_token
order by r.use_count desc
limit 100;
--
-- Top 100 voice conversion models by use count (NON DELETED)
-- (jobs table, not results table)
--
select
m.token,
m.model_type,
m.title,
u.username,
r.use_count,
m.created_at
from (
select maybe_model_token, count(*) as use_count
from generic_inference_jobs
where maybe_model_token IS NOT NULL
group by maybe_model_token
) as r
join voice_conversion_models as m
on m.token = r.maybe_model_token
join users as u
on u.token = m.creator_user_token
where m.user_deleted_at IS NULL
and m.mod_deleted_at IS NULL
order by r.use_count desc
limit 100;
--
-- Top 100 voice conversion models by use count (NON DELETED, LAST 7 DAYS)
-- (jobs table, not results table)
--
select
m.token,
m.model_type,
m.title,
u.username,
r.use_count,
m.created_at
from (
select maybe_model_token, count(*) as use_count
from generic_inference_jobs
where maybe_model_token IS NOT NULL
and created_at > ( CURDATE() - INTERVAL 7 day)
group by maybe_model_token
) as r
join voice_conversion_models as m
on m.token = r.maybe_model_token
join users as u
on u.token = m.creator_user_token
where m.user_deleted_at IS NULL
and m.mod_deleted_at IS NULL
order by r.use_count desc
limit 100;
-- Histogram of model contributions
select
date(created_at) as created_date,
count(*) as model_count
from voice_conversion_models
group by created_date
-- Histogram of model contributions (within range)
select
date(created_at) as created_date,
count(*) as model_count
from voice_conversion_models
where created_at > (CURDATE() - INTERVAL 5 DAY)
group by created_date
@@ -1,11 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Histogram of days of content per day
select
date(created_at) as created_date,
sum(duration_millis) / 1000 / 60 / 60 / 24 as days
from voice_conversion_results
group by created_date
-23
View File
@@ -5,26 +5,3 @@
-- Pending job count
select count(*) from w2l_inference_jobs where status='pending';
-- Histogram of inference
select
date(created_at) as created_date,
count(*) as job_count
from w2l_inference_jobs
group by created_date
-- Histogram of inference (within range)
select
date(created_at) as created_date,
count(*) as job_count
from w2l_inference_jobs
where date(created_at) >= "2023-01-01"
group by created_date
-- Histogram of inference (within range)
select
date(created_at) as created_date,
count(*) as job_count
from w2l_inference_jobs
where created_at > (CURDATE() - INTERVAL 5 DAY)
group by created_date
-42
View File
@@ -1,42 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Histogram of results
select
date(created_at) as created_date,
count(*) as result_count
from w2l_results
group by created_date
-- Histogram of results and durations
select
date(created_at) as created_date,
sum(duration_millis) / 1000 / 60 / 60 as hours,
avg(duration_millis) / 60 as average_seconds,
count(*) as video_count
from w2l_results
group by created_date
-- Histogram of results (within range)
select
date(created_at) as created_date,
count(*) as result_count
from w2l_results
where created_at > (CURDATE() - INTERVAL 5 DAY)
group by created_date
-- Created by date (within range)
select
date(created_at) as created_date,
count(*) as use_count
from w2l_results
where date(created_at) > "2023-07-31"
group by created_date
select
date(created_at) as created_date,
count(*) as created_count
from tts_inference_jobs
where created_at > (CURDATE() - INTERVAL 90 DAY)
group by created_date
-19
View File
@@ -1,19 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Histogram of template contributions
select
date(created_at) as created_date,
count(*) as template_count
from w2l_templates
group by created_date
-- Histogram of template contributions (within range)
select
date(created_at) as created_date,
count(*) as template_count
from w2l_templates
where created_at > (CURDATE() - INTERVAL 5 DAY)
group by created_date
@@ -2,20 +2,6 @@
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Per-user password resets.
-- Password resets are valid until any of the following are true:
--
-- 1) database NOW() > password_rests.expires_at
-- 2) password_rests.is_redeemed == TRUE
-- 3) users.password_version > password_resets.current_password_version
--
-- When creating a new password reset, send the user an email with the `secret_key` in the URL.
-- The user will have to supply their username and/or email address, plus the secret key to
-- redeem the password reset.
--
-- Also when creating the password hash, be sure to set `expires_at` to be "NOW() + 3 hours", or
-- some other small, reasonable time frame.
--
CREATE TABLE password_resets (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
@@ -36,7 +22,7 @@ CREATE TABLE password_resets (
-- reset is no longer valid.
current_password_version INT NOT NULL DEFAULT 0,
-- Whether the password reset has been consumed.
-- Username is a lookup key; display_name allows the user to add custom case.
is_redeemed BOOLEAN NOT NULL DEFAULT false,
-- For abuse tracking.
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table media_files;
@@ -1,159 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- This table contains both user uploads and inference or processing results.
CREATE TABLE media_files (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
token VARCHAR(32) NOT NULL,
-- We don't need an idempotency token!
-- Store upload idempotency tokens in a separate table.
-- uuid_idempotency_token VARCHAR(36) NOT NULL,
-- ========== FOREIGN KEY TO ORIGIN ==========
-- Where the file came from:
-- * 'inference' for inference output
-- * 'processed' for processed file
-- * 'upload' for direct user upload
origin_category VARCHAR(16) NOT NULL,
-- For inference that can be tied back to a model, the type of model.
-- * 'sad_talker', which doesn't have a value for maybe_origin_model_token (!!!)
-- * (more tome come)
maybe_origin_model_type VARCHAR(32) DEFAULT NULL,
-- For inference that can be tied back to a model, the token of the model.
-- For zero shot models, this may be set as the token for the vector.
maybe_origin_model_token VARCHAR(32) DEFAULT NULL,
-- The original filename of the media (if uploaded by a user)
maybe_origin_filename VARCHAR(255) DEFAULT NULL,
-- ========== METADATA ==========
-- We can store text transcripts, etc. in other tables and refer back via foreign key.
-- Titles and even descriptions can go in another table(s): media_file_annotations, media_file_tags, media_file_descriptions, ...
-- (Not everything would have a text transcript.)
-- ========== MEDIA DETAILS ==========
-- Type of media:
-- * 'audio' for wav, mp3, etc.
-- * 'image' for a variety of video types.
-- * 'video' for a variety of video types.
media_type VARCHAR(16) NOT NULL,
-- The file's mime type.
maybe_mime_type VARCHAR(32) DEFAULT NULL,
-- The file size.
file_size_bytes INT(10) NOT NULL DEFAULT 0,
-- The duration in millis, if audio or video.
maybe_duration_millis INT(10) DEFAULT NULL,
-- Audio encoder details
-- Only present if the file was audio or a video that had audio.
maybe_audio_encoding VARCHAR(32) DEFAULT NULL,
-- Video encoder details
-- Only present if the file was a video.
maybe_video_encoding VARCHAR(32) DEFAULT NULL,
-- For videos, the original frame width.
maybe_frame_width INT(5) DEFAULT NULL,
-- For videos, the original frame height.
maybe_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,
-- The directory this media is uploaded to will be exclusive for this file.
-- Only this given record will live in this bucket, but the directory may include
-- other transcodings or truncations.
public_bucket_directory_full_path VARCHAR(255) 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.
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),
KEY index_origin_category (origin_category),
KEY index_maybe_origin_model_type (maybe_origin_model_type),
KEY fk_maybe_origin_model_token (maybe_origin_model_token),
KEY fk_maybe_origin_model_type_and_token (maybe_origin_model_type, maybe_origin_model_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;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table generic_synthetic_ids;
@@ -1,31 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- It gets unwieldy to show results without a numeric sequence.
-- We create a synthetic sequence for each user to make revisiting results easier.
-- This should be a reusable table for handling this for many different types of results.
CREATE TABLE generic_synthetic_ids (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" (PUBLIC)
user_token VARCHAR(32) NOT NULL,
-- The type of synthetic id to increment.
-- eg "media_file", "lipsync_animation", etc.
id_category VARCHAR(32) NOT NULL,
-- The next result id.
-- After we use an id, we increment this counter.
next_id BIGINT(20) NOT NULL DEFAULT 0,
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 (user_token, id_category),
KEY fk_user_token (user_token)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -1,9 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Revert the rename
ALTER TABLE media_files RENAME COLUMN maybe_creator_file_synthetic_id TO maybe_creator_synthetic_id ;
ALTER TABLE media_files
DROP COLUMN maybe_creator_category_synthetic_id;
@@ -1,11 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- We'll have one ordering by files
ALTER TABLE media_files RENAME COLUMN maybe_creator_synthetic_id TO maybe_creator_file_synthetic_id;
-- And another ordering by category
ALTER TABLE media_files
ADD COLUMN maybe_creator_category_synthetic_id BIGINT(20) DEFAULT NULL
AFTER maybe_creator_file_synthetic_id;
@@ -1,7 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files
ADD COLUMN public_bucket_directory_full_path VARCHAR(255) NOT NULL
AFTER public_bucket_directory_hash;
@@ -1,7 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Kill the column
ALTER TABLE media_files
DROP COLUMN public_bucket_directory_full_path;
@@ -1,7 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files DROP COLUMN generated_by_cluster;
ALTER TABLE media_files DROP COLUMN generated_by_worker;
ALTER TABLE media_files DROP COLUMN is_generated_on_prem;
@@ -1,15 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files
ADD COLUMN is_generated_on_prem BOOLEAN NOT NULL DEFAULT FALSE
AFTER maybe_mod_user_token;
ALTER TABLE media_files
ADD COLUMN generated_by_worker VARCHAR(255) DEFAULT NULL
AFTER is_generated_on_prem;
ALTER TABLE media_files
ADD COLUMN generated_by_cluster VARCHAR(255) DEFAULT NULL
AFTER generated_by_worker;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table zs_voices;
@@ -1,154 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- This table contains both zero shot TTS voices (speaker embeddings) and zero shot V2V voices (speaker embeddings).
-- These are the zero shot voices that are usable by our users.
CREATE TABLE zs_voices (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" for joins, API, etc. (PUBLIC)
token VARCHAR(32) NOT NULL,
-- NB: No idempotency token.
-- Store it in another table to prevent duplicate record creation from rapid user inputs.
-- ========== ZERO SHOT FOREIGN KEYS AND STATE==========
-- The zero shot dataset that was used to create this voice.
-- The dataset will only be accessible to the original author of the voice.
-- The original author can create multiple voices from the same dataset.
dataset_token VARCHAR(32) NOT NULL,
-- When datasets are edited, we bump their version.
-- This tells us which version of the dataset created this voice (not that we should preserve
-- record of which samples are in which version.)
-- We can surface this to the users as well.
dataset_version INT NOT NULL DEFAULT 0,
-- ========== MODEL DETAILS ==========
-- The class or category of model/algorithm this voice is intended for.
-- * 'tts' for zero shot TTS
-- * 'vc' for zero shot voice conversion
-- * 'pitch' for pitch correction models (hypothetical)
-- * (Since this isn't an enum, the list of values can be expanded.)
model_category VARCHAR(16) NOT NULL,
-- The model used for the voice:
-- * 'vall-e-x' for Vall-E-X
-- * 'ns2vc' for NaturalSpeech2 voice conversion (hypothetical)
-- * (Since this isn't an enum, the list of values can be expanded.)
model_type VARCHAR(16) NOT NULL,
-- The version of the model.
-- If we deploy new model weights for the model, we may need to regenerate
-- all of the corresponding speaker embeddings. This lets us know which voices
-- are the old version.
-- In some cases, we may need to preserve, hide, or roll back to older versions.
model_version INTEGER UNSIGNED NOT NULL DEFAULT 0,
-- What kind of features these are: spectrogram, encodec, etc.
-- Technically we shouldn't need this, as the 2-tuple (model_type, model_version) implicitly knows
-- what its features should be, but this is probably useful for our own analysis and may be easier
-- to deal with.
--
-- Example values:
-- * 'spectrogram'
-- * 'encodec'
-- * (Since this isn't an enum, the list of values can be expanded.)
encoding_type VARCHAR(16) NOT NULL,
-- ========== VOICE DETAILS ==========
-- The "title" of the voice. This can be the name and additional information as supplied by the user.
title VARCHAR(255) NOT NULL,
-- The full IETF BCP47 language tag (eg. en, en-US, es-419, ja-JP, pt, etc.)
-- The wide varchar space is because these language tags can become cumbersome, eg "hy-Latn-IT-arevela"
ietf_language_tag VARCHAR(64) NOT NULL DEFAULT 'en',
-- The IETF BCP47 language tag's primary language subtag (eg. "es-419" becomes "es" and "en-US" becomes "en")
ietf_primary_language_subtag VARCHAR(12) NOT NULL DEFAULT 'en',
-- TODO: misc speaker metadata
-- We'll want rich metadata for search
-- series_name VARCHAR(255) DEFAULT NULL,
-- speaker_name VARCHAR(255) DEFAULT NULL,
-- speaker_gender VARCHAR(255) DEFAULT NULL,
-- speaker_age VARCHAR(255) DEFAULT NULL,
-- speaker_voice_style VARCHAR(255) DEFAULT NULL,
-- ========== STORAGE DETAILS ==========
-- The hash for the bucket directory that contains the original upload
-- eg. /speaker_vectors/{bucket_hash}/{voice_model_version}.bin
bucket_hash VARCHAR(32) NOT 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.
-- Fine details of moderator actions are kept in a separate `audit_logs` table.
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,
-- ========== VECTOR CLOCK ==========
-- Incremented with every update.
version INT NOT NULL DEFAULT 0,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
-- TODO: These are not correct. Fix these before landing / running migrations.
KEY index_model_category (model_category),
KEY index_model_type (model_type),
KEY index_model_type_and_version (model_type, model_version),
KEY index_encoding_type (encoding_type),
KEY index_ietf_primary_language_subtag (ietf_primary_language_subtag),
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;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table zs_voice_datasets;
@@ -1,106 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- This table describes a zero shot voice in the process of being created (or later reused / edited / enhanced)
-- These are not usable voices until their vector embeddings have been created, and this table does not serve
-- the production voice list.
--
-- Multiple voices can be created from a single "dataset" as the data set is mutable over time. Users can add or
-- remove new samples to the data set at any time.
CREATE TABLE zs_voice_datasets (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" for joins, API, etc. (PUBLIC)
token VARCHAR(32) NOT NULL,
-- NB: No idempotency token.
-- Store it in another table to prevent duplicate record creation from rapid user inputs.
-- ========== VOICE DETAILS ==========
-- The "title" of the voice. This can be the name and additional information as supplied by the user.
-- When the voice embeddings are created, this will be copied to the produced "voice" (embeddings) record.
title VARCHAR(255) NOT NULL,
-- The full IETF BCP47 language tag (eg. en, en-US, es-419, ja-JP, pt, etc.)
-- The wide varchar space is because these language tags can become cumbersome, eg "hy-Latn-IT-arevela"
ietf_language_tag VARCHAR(64) NOT NULL DEFAULT 'en',
-- The IETF BCP47 language tag's primary language subtag (eg. "es-419" becomes "es" and "en-US" becomes "en")
ietf_primary_language_subtag VARCHAR(12) NOT NULL DEFAULT 'en',
-- TODO: misc speaker metadata
-- We'll want rich metadata for search
-- When the voice embeddings are created, this will be copied to the produced "voice" (embeddings) record.
-- We don't want a hard link between the dataset and the produced voice as the voice is static once
-- created (with the exception of regenerating embeddings), but the dataset my drift as the user experiments,
-- adds/removes samples, etc.
-- series_name VARCHAR(255) DEFAULT NULL,
-- speaker_name VARCHAR(255) DEFAULT NULL,
-- speaker_gender VARCHAR(255) DEFAULT NULL,
-- speaker_age VARCHAR(255) DEFAULT NULL,
-- speaker_voice_style VARCHAR(255) 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.
-- Fine details of moderator actions are kept in a separate `audit_logs` table.
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,
-- ========== VECTOR CLOCK ==========
-- Incremented with every update.
version INT NOT NULL DEFAULT 0,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
KEY index_ietf_primary_language_subtag (ietf_primary_language_subtag),
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;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table zs_voice_dataset_samples;
@@ -1,84 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- These are the individual files in each dataset.
-- Files can be added and removed from a dataset at any time.
CREATE TABLE zs_voice_dataset_samples (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- Effective "primary key" for joins, API, etc. (PUBLIC)
token VARCHAR(32) NOT NULL,
-- NB: No idempotency token.
-- Store it in another table to prevent duplicate record creation from rapid user inputs.
-- ========== ZERO SHOT FOREIGN KEYS AND STATE==========
-- The zero shot dataset that was used to create this voice.
-- The dataset will only be accessible to the original author of the voice.
-- The original author can create multiple voices from the same dataset.
dataset_token VARCHAR(32) NOT NULL,
-- Foreign key to the uploaded media file.
-- There was an option of handling uploads and file management separately, but by electing to store the dataset
-- samples in the "media_files" table, they can be reused by our other code, queries, machinery, etc.
-- Note that this requires that the "media_files" record must be an audio (not video) file (which our code will
-- enforce), and that it is given a category of "voice_zero_shot" so it isn't co-mingled with other uploads/outputs
media_file_token VARCHAR(32) NOT NULL,
-- Some data sets require raw transcripts for the audio.
-- If required, they'll live here.
maybe_raw_transcription TEXT DEFAULT NULL,
-- A way to order the data set samples
-- We don't necessarily need to reimplement file reordering.
-- order_id INT 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,
-- ========== MODERATION DETAILS ==========
-- The last moderator that made changes last.
-- Fine details of moderator actions are kept in a separate `audit_logs` table.
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,
-- ========== VECTOR CLOCK ==========
-- Incremented with every update.
version INT NOT NULL DEFAULT 0,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
KEY fk_dataset_token (dataset_token),
KEY fk_media_file_token (media_file_token),
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;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table zs_voice_included_samples;
@@ -1,26 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- In order to rebuild any "zs_voice", we need to know which dataset samples were included.
-- Since users can change the dataset at any time after a voice was originally created, these
-- records are generated to retain a record of which samples fed into a given voice.
-- These records will probably not be used for any product features, just as a means to study
-- poor-performing voices, perform migrations, etc.
CREATE TABLE zs_voice_included_samples (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- First member of composite effective "primary key"
-- The "zs_voice" that was created.
voice_token VARCHAR(32) NOT NULL,
-- Second member of composite effective "primary key"
-- The "zs_voice_dataset_sample" that was used.
dataset_sample_token VARCHAR(32) NOT NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (voice_token, dataset_sample_token)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files DROP COLUMN maybe_public_bucket_extension;
@@ -1,7 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files
ADD COLUMN maybe_public_bucket_extension VARCHAR(16) DEFAULT NULL
AFTER public_bucket_directory_hash;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files DROP COLUMN maybe_public_bucket_prefix;
@@ -1,7 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files
ADD COLUMN maybe_public_bucket_prefix VARCHAR(16) DEFAULT NULL
AFTER public_bucket_directory_hash;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files DROP COLUMN origin_product_category;
@@ -1,10 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files
ADD COLUMN origin_product_category VARCHAR(16) NOT NULL DEFAULT "unknown"
AFTER origin_category;
ALTER TABLE media_files
ADD INDEX index_origin_product_category (origin_product_category);
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs DROP COLUMN frontend_failure_category;
@@ -1,7 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN frontend_failure_category VARCHAR(32) DEFAULT NULL
AFTER internal_debugging_failure_reason;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE zs_voice_dataset_samples DROP COLUMN uuid_idempotency_token;

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