mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-23 01:59:31 -04:00
Compare commits
582
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff22319c77 | ||
|
|
16f2d5557b | ||
|
|
e5cdb84c52 | ||
|
|
8079be9f7e | ||
|
|
2821240cc0 | ||
|
|
ae0522419a | ||
|
|
46bb4274ca | ||
|
|
f2b6dc4349 | ||
|
|
a395c04265 | ||
|
|
d3a4613cc9 | ||
|
|
bdca25cf4f | ||
|
|
06a053b6d9 | ||
|
|
4104ef0129 | ||
|
|
0f076cbacd | ||
|
|
817b2c01df | ||
|
|
c06c47f02e | ||
|
|
23b0dafd6b | ||
|
|
91e83c8b90 | ||
|
|
4a32ced9cd | ||
|
|
75014a673a | ||
|
|
52afa5462d | ||
|
|
a826d54311 | ||
|
|
4f38e4b20a | ||
|
|
6880efd2f0 | ||
|
|
e372a4b5ec | ||
|
|
f978f1b055 | ||
|
|
ee69e72661 | ||
|
|
6295fd9569 | ||
|
|
53d9d55036 | ||
|
|
7e236f1e81 | ||
|
|
6b7370ee64 | ||
|
|
406d2eb7af | ||
|
|
1cfb3663e9 | ||
|
|
aa24f781fb | ||
|
|
3a2dad2027 | ||
|
|
814c04cdac | ||
|
|
c45a6da8a5 | ||
|
|
a5b2028588 | ||
|
|
4a743bace1 | ||
|
|
5ef5d6832b | ||
|
|
0ebb1e398b | ||
|
|
4be572c36b | ||
|
|
97bea31b1d | ||
|
|
f3dd785331 | ||
|
|
0d99c2fc08 | ||
|
|
edba26a2db | ||
|
|
89a9448c9a | ||
|
|
d557c78123 | ||
|
|
9ac7f33008 | ||
|
|
716e7923ff | ||
|
|
ad389491a2 | ||
|
|
85b5e427b9 | ||
|
|
74d7b543f2 | ||
|
|
2078bac70f | ||
|
|
2e0110b0d9 | ||
|
|
80a32eedf3 | ||
|
|
539c5ae796 | ||
|
|
6440d519f9 | ||
|
|
690f4f1064 | ||
|
|
a1e4ca35cd | ||
|
|
d93c0a5a8d | ||
|
|
9cc5ce9a04 | ||
|
|
202b6c4a97 | ||
|
|
71abf1caa2 | ||
|
|
de01d0fde7 | ||
|
|
bb5ef2a3fe | ||
|
|
a8ab9c1265 | ||
|
|
2412e15868 | ||
|
|
4b45924455 | ||
|
|
72ce767337 | ||
|
|
76c562bf2e | ||
|
|
6ac8759aba | ||
|
|
3503a4527c | ||
|
|
03160b73d4 | ||
|
|
601b786b06 | ||
|
|
05503512d8 | ||
|
|
7db6f074b6 | ||
|
|
e7ad3a34de | ||
|
|
5ccd512a2a | ||
|
|
c40333e2a2 | ||
|
|
edcfc9ff9b | ||
|
|
862be58f1a | ||
|
|
8b08f2ba1d | ||
|
|
fe3f8dec6c | ||
|
|
8ae5d34074 | ||
|
|
89f8837706 | ||
|
|
03ed0b4c7b | ||
|
|
f1d8161481 | ||
|
|
2d20430f55 | ||
|
|
e2b98491cb | ||
|
|
910caa1000 | ||
|
|
0e39999097 | ||
|
|
77779bc231 | ||
|
|
898c22b9cc | ||
|
|
96b80b35a5 | ||
|
|
d182f800f7 | ||
|
|
60af92ea39 | ||
|
|
da8c164b40 | ||
|
|
d304f40984 | ||
|
|
8f0d347c38 | ||
|
|
73db1b1a49 | ||
|
|
97b7120ff8 | ||
|
|
961c5cf43d | ||
|
|
4c2c54bd74 | ||
|
|
c158097b42 | ||
|
|
1c9366da4b | ||
|
|
f648f7b714 | ||
|
|
c3db6ce24a | ||
|
|
1910b6497c | ||
|
|
ac90b89230 | ||
|
|
70e6ba5aec | ||
|
|
5af6a68de7 | ||
|
|
19532388a3 | ||
|
|
27adc9f73e | ||
|
|
6d082f2b9e | ||
|
|
2c86a4189c | ||
|
|
bf5b2b385e | ||
|
|
b7c73930b4 | ||
|
|
f9d61a1482 | ||
|
|
4799d3ceac | ||
|
|
696fd2bd8d | ||
|
|
1cfb3bb715 | ||
|
|
ccb36f7f6e | ||
|
|
83a16f83e3 | ||
|
|
8f9554be9f | ||
|
|
d987397586 | ||
|
|
41e03feb85 | ||
|
|
5c8cab0d90 | ||
|
|
8f40db9a3e | ||
|
|
b0a7c953be | ||
|
|
a08bc3fa64 | ||
|
|
5d111f0a68 | ||
|
|
51a5571d84 | ||
|
|
95f2ec3e40 | ||
|
|
b511420c03 | ||
|
|
aeab9da077 | ||
|
|
46452415fd | ||
|
|
cecbc8e730 | ||
|
|
1ba73c817c | ||
|
|
8395739500 | ||
|
|
c537f09c8f | ||
|
|
1e7de6bf36 | ||
|
|
ab6e3ceb5a | ||
|
|
896938b762 | ||
|
|
486960905d | ||
|
|
2a54d3aac9 | ||
|
|
10ac9fee82 | ||
|
|
cab4840a61 | ||
|
|
68a3c123eb | ||
|
|
582ce9aa93 | ||
|
|
eaeb864c1c | ||
|
|
77d4bc3b75 | ||
|
|
b6be95144c | ||
|
|
5ca4dd3600 | ||
|
|
294c3107b5 | ||
|
|
2de7ce146f | ||
|
|
f7ddd24325 | ||
|
|
1b1ed15f21 | ||
|
|
dc93602306 | ||
|
|
2898f40ad1 | ||
|
|
ced51c7f58 | ||
|
|
b208847ec8 | ||
|
|
744656cfd9 | ||
|
|
a735d3e972 | ||
|
|
90aa091398 | ||
|
|
f8e7ae3ced | ||
|
|
a1b8a22225 | ||
|
|
0a0105410d | ||
|
|
69a79b76ea | ||
|
|
809387958c | ||
|
|
44f7824910 | ||
|
|
1e05dcb7e2 | ||
|
|
72bdea7d10 | ||
|
|
c3981e8554 | ||
|
|
6b937b7cd0 | ||
|
|
5be10ae87a | ||
|
|
12f7e30047 | ||
|
|
a5e0c2ab01 | ||
|
|
0764711439 | ||
|
|
969be4726c | ||
|
|
8244bac6e1 | ||
|
|
1d173a74d5 | ||
|
|
3786a64eb1 | ||
|
|
cc6cf0d6c0 | ||
|
|
144df6ffc0 | ||
|
|
85e0ce4b4a | ||
|
|
107d11f0f9 | ||
|
|
7efb65ae08 | ||
|
|
ba3ff9768a | ||
|
|
b8e37d2e77 | ||
|
|
5a1e61b692 | ||
|
|
19b57b9c1d | ||
|
|
6c33c31289 | ||
|
|
b1bbfe21ec | ||
|
|
5878224f7e | ||
|
|
5497b7c0aa | ||
|
|
bc58b50408 | ||
|
|
ce17a3e1bf | ||
|
|
b8fe3a0e7d | ||
|
|
d41cec6c90 | ||
|
|
6a86f43a92 | ||
|
|
65a7a46914 | ||
|
|
31eafed60d | ||
|
|
6abbbaae01 | ||
|
|
82efbf4d1f | ||
|
|
b1cefa66d5 | ||
|
|
7f5f578abd | ||
|
|
0c574c31d6 | ||
|
|
393bc084d4 | ||
|
|
035faa0561 | ||
|
|
84e2bcd2c3 | ||
|
|
bc69ecbda5 | ||
|
|
5f35323a5f | ||
|
|
30c9f779bd | ||
|
|
4f7d03a505 | ||
|
|
5a031b1b80 | ||
|
|
d1b6facd95 | ||
|
|
79984058c0 | ||
|
|
adc52cd01e | ||
|
|
aad257a1b2 | ||
|
|
b8d5a1fad1 | ||
|
|
f757b94eaf | ||
|
|
8ff2408cbf | ||
|
|
01fa2f8d67 | ||
|
|
25b7024655 | ||
|
|
f7b8423623 | ||
|
|
0f99360c20 | ||
|
|
fe606c1610 | ||
|
|
201481f969 | ||
|
|
665cd83739 | ||
|
|
eefe48f8ca | ||
|
|
a1c5ef6eb2 | ||
|
|
2f4fe2dabc | ||
|
|
d63a505b8b | ||
|
|
fb1bf9940e | ||
|
|
d4de388bb6 | ||
|
|
a0a5c68086 | ||
|
|
ddb106a9af | ||
|
|
7c229ba59b | ||
|
|
d1978298f0 | ||
|
|
1dcf06b571 | ||
|
|
8af2368f32 | ||
|
|
79fba33aae | ||
|
|
bff0f9181d | ||
|
|
bd8f2570e2 | ||
|
|
74c289b338 | ||
|
|
63bb0e7253 | ||
|
|
4140d07924 | ||
|
|
aa03abd3b5 | ||
|
|
fb8142fb49 | ||
|
|
362f41cbf3 | ||
|
|
a79d3bcf9a | ||
|
|
41e7780fa0 | ||
|
|
329e7defc5 | ||
|
|
6ce0437aa2 | ||
|
|
34bb2c5266 | ||
|
|
2b50d2bce5 | ||
|
|
c9f55fbb7c | ||
|
|
2da4971ec7 | ||
|
|
2cd6a98259 | ||
|
|
7ba765b89c | ||
|
|
02d7495e54 | ||
|
|
088535cb5a | ||
|
|
4ef9ad35a7 | ||
|
|
f80f2c8962 | ||
|
|
98fb5758e5 | ||
|
|
06f219a8af | ||
|
|
439527a504 | ||
|
|
61e1cc62b6 | ||
|
|
633dfb5682 | ||
|
|
8df0273ca8 | ||
|
|
41630e1fc5 | ||
|
|
40bc0cf883 | ||
|
|
7fdb5cfe9c | ||
|
|
a0da010dab | ||
|
|
74ff632f4d | ||
|
|
e6d1f0db11 | ||
|
|
d190173f4d | ||
|
|
22e8a14170 | ||
|
|
b6fce130b5 | ||
|
|
1bb0dda330 | ||
|
|
bcbb36a9ed | ||
|
|
dbfd80531d | ||
|
|
4152b346c1 | ||
|
|
3b37cf9e89 | ||
|
|
c49bbd299a | ||
|
|
993fe647b4 | ||
|
|
d46778569c | ||
|
|
2ea0e1450c | ||
|
|
b31bafd639 | ||
|
|
9246ab83cf | ||
|
|
93b06bd8b5 | ||
|
|
271bce9815 | ||
|
|
f0bebc6135 | ||
|
|
98ce37d9a4 | ||
|
|
b0bc019db2 | ||
|
|
f3c34d9a7b | ||
|
|
98c8bbda57 | ||
|
|
18b20d6c4d | ||
|
|
11fd4881ea | ||
|
|
7ab39d0b5c | ||
|
|
77e16d4bd8 | ||
|
|
58c7695a2a | ||
|
|
140c93fc76 | ||
|
|
2b58e3c32d | ||
|
|
142adf10ee | ||
|
|
d1698ead1d | ||
|
|
2909e2dbb4 | ||
|
|
9015efdf9e | ||
|
|
2a5634503f | ||
|
|
623b82dd0e | ||
|
|
9fbafd7fcd | ||
|
|
cc573fe242 | ||
|
|
c4225ce571 | ||
|
|
2f6747b98a | ||
|
|
bc5090af54 | ||
|
|
8062833e8d | ||
|
|
e5a852acd6 | ||
|
|
84ccda1960 | ||
|
|
893a861d22 | ||
|
|
13b014e7fc | ||
|
|
c8598bc9e3 | ||
|
|
ecf84c4b15 | ||
|
|
c4ea221c50 | ||
|
|
8de1722466 | ||
|
|
a716b8963f | ||
|
|
7f70de0148 | ||
|
|
bc033c2202 | ||
|
|
756c357462 | ||
|
|
4b8c454c84 | ||
|
|
d2b3386fea | ||
|
|
f458f29109 | ||
|
|
aa3faca551 | ||
|
|
2512810e81 | ||
|
|
db629a6a0d | ||
|
|
30202e6e5a | ||
|
|
9a263a01a1 | ||
|
|
85ae704ab5 | ||
|
|
b128cdb3f5 | ||
|
|
8755e7a533 | ||
|
|
9f873c33e7 | ||
|
|
81302d0e1d | ||
|
|
9e589c2b72 | ||
|
|
7a33c0721a | ||
|
|
e1793d71b5 | ||
|
|
5b20710f96 | ||
|
|
77e1319b81 | ||
|
|
8061880a83 | ||
|
|
651ed42b64 | ||
|
|
e870d6f4de | ||
|
|
16a2e765ca | ||
|
|
ee7626602a | ||
|
|
533cd5e051 | ||
|
|
7f51ccd01b | ||
|
|
f2bfcfeb75 | ||
|
|
603a678378 | ||
|
|
1ba3215881 | ||
|
|
c4c5b89118 | ||
|
|
9aaee506ed | ||
|
|
ff12990b01 | ||
|
|
45b7af9bd2 | ||
|
|
a34aedc375 | ||
|
|
cb1e092ccd | ||
|
|
07d13a4ab5 | ||
|
|
43c890b27c | ||
|
|
a1510d45b2 | ||
|
|
32c7354798 | ||
|
|
31bb03d9d3 | ||
|
|
66bb76e60f | ||
|
|
68f2e46540 | ||
|
|
d08d3cd543 | ||
|
|
e7fc93de86 | ||
|
|
deb3671be6 | ||
|
|
8591f74ff2 | ||
|
|
26587e51e3 | ||
|
|
2fad965446 | ||
|
|
c2f4c2c057 | ||
|
|
51350e6e5c | ||
|
|
5f598dc516 | ||
|
|
7bcde1e490 | ||
|
|
13d00f6edf | ||
|
|
91695cde00 | ||
|
|
91ac868369 | ||
|
|
60af0ea36d | ||
|
|
46280c7877 | ||
|
|
08c2736ea4 | ||
|
|
02bf8808d0 | ||
|
|
1de10d1b9f | ||
|
|
b649bb17c5 | ||
|
|
587ea70d33 | ||
|
|
ffd7793a8d | ||
|
|
6e13777e84 | ||
|
|
b7fd9aa8d1 | ||
|
|
26e91bd990 | ||
|
|
61d0cbd385 | ||
|
|
28d7a26d97 | ||
|
|
4196a6499b | ||
|
|
2cf07c1346 | ||
|
|
f56ea64dce | ||
|
|
5cfb3f50d7 | ||
|
|
5e0851eb09 | ||
|
|
0d3ffd3f3b | ||
|
|
1b60427ab0 | ||
|
|
75ede876d5 | ||
|
|
086980318c | ||
|
|
c4ca48f399 | ||
|
|
ad88800b4e | ||
|
|
64e3864140 | ||
|
|
81757870ab | ||
|
|
2769a0b3f9 | ||
|
|
89e721e3bc | ||
|
|
353aa4211b | ||
|
|
422e36b405 | ||
|
|
110c7f828f | ||
|
|
b9e2c87025 | ||
|
|
b1d5244620 | ||
|
|
7bcb576436 | ||
|
|
2e561acbb4 | ||
|
|
c1860a0584 | ||
|
|
70140c0e7d | ||
|
|
cc56deb27c | ||
|
|
a15324adee | ||
|
|
fa108a5303 | ||
|
|
7193ddf18b | ||
|
|
21e74c5367 | ||
|
|
11304d77cb | ||
|
|
ba52695f35 | ||
|
|
d28fb07d6d | ||
|
|
740b419989 | ||
|
|
8f2640c5eb | ||
|
|
6e7c708374 | ||
|
|
7b0066bea5 | ||
|
|
3d3dec1e23 | ||
|
|
1ac61b7748 | ||
|
|
24c9cc2d08 | ||
|
|
2392062276 | ||
|
|
94c74eb9e0 | ||
|
|
7f5ccac55c | ||
|
|
62c4f2cbe0 | ||
|
|
507f97bef5 | ||
|
|
a628e986e5 | ||
|
|
2fdd3b38ea | ||
|
|
a3234b3cb4 | ||
|
|
dbf3d541e2 | ||
|
|
f690c73ebf | ||
|
|
567f3143d4 | ||
|
|
2416056f6f | ||
|
|
e390a7d1ac | ||
|
|
00ab91b05c | ||
|
|
b403ed7c9e | ||
|
|
049b0cf375 | ||
|
|
0e6657e9b7 | ||
|
|
acdea58a81 | ||
|
|
9711a60494 | ||
|
|
8edbb3efda | ||
|
|
87b319b99a | ||
|
|
ed6f19c2ab | ||
|
|
31fc96c356 | ||
|
|
4b6eab5a1d | ||
|
|
6af1234095 | ||
|
|
8132a0bcb0 | ||
|
|
c679aa3430 | ||
|
|
33485670dd | ||
|
|
9008e7c044 | ||
|
|
2d2a0b68ff | ||
|
|
a211d45f26 | ||
|
|
d20d8a4c1c | ||
|
|
9aec48d237 | ||
|
|
e4835258cb | ||
|
|
f34fd6fc4c | ||
|
|
413d1b7c1c | ||
|
|
fb99af8a23 | ||
|
|
23b0dab44f | ||
|
|
8ee5eca076 | ||
|
|
9a1df0cd8c | ||
|
|
5377cca3b1 | ||
|
|
badcb4b058 | ||
|
|
28a4f5ca8d | ||
|
|
3efe1afa48 | ||
|
|
d4a7c06f72 | ||
|
|
6b4d0b3ad1 | ||
|
|
23f6e74fd8 | ||
|
|
778d7eba7e | ||
|
|
e5db702289 | ||
|
|
4eb400867a | ||
|
|
4584e9dbcf | ||
|
|
2ca477fd8c | ||
|
|
13487a9046 | ||
|
|
aff94446ac | ||
|
|
15c9c1256b | ||
|
|
009d0eab87 | ||
|
|
0d9a882f3f | ||
|
|
4c878e332e | ||
|
|
d22242ab69 | ||
|
|
5ee51ed8e2 | ||
|
|
560448f1ad | ||
|
|
1b40495ef3 | ||
|
|
e8d376a3eb | ||
|
|
8e6c02d1b1 | ||
|
|
4e4dbf0688 | ||
|
|
1ca54927d7 | ||
|
|
ddd29ada80 | ||
|
|
5ef27bb86f | ||
|
|
c03bdba0a6 | ||
|
|
14432e9808 | ||
|
|
1204ac5399 | ||
|
|
468d2d1d75 | ||
|
|
aac2af635b | ||
|
|
90c96b5f50 | ||
|
|
207e63a5aa | ||
|
|
399ed6cb2e | ||
|
|
d51d6720e6 | ||
|
|
8f807a7719 | ||
|
|
c8ba2d1863 | ||
|
|
2f3cbd4523 | ||
|
|
cf7cd9945d | ||
|
|
6a2a99741e | ||
|
|
dc115a7aa1 | ||
|
|
6ea1bf3226 | ||
|
|
334fc3022e | ||
|
|
3fb26771de | ||
|
|
ba448ccc50 | ||
|
|
fd3081e440 | ||
|
|
66981c4d2c | ||
|
|
c6a1fc18d6 | ||
|
|
afb77393c0 | ||
|
|
a2e71d8944 | ||
|
|
ca63e00905 | ||
|
|
faf689dc09 | ||
|
|
aec31779b8 | ||
|
|
452a3473b3 | ||
|
|
00322c6ed4 | ||
|
|
6dd02d48c4 | ||
|
|
2eaf7c499e | ||
|
|
3b82e7a389 | ||
|
|
c825f17672 | ||
|
|
6bbf4453da | ||
|
|
dda247b5ea | ||
|
|
f0435804ec | ||
|
|
176feda73b | ||
|
|
f81d40b5bb | ||
|
|
c07f100986 | ||
|
|
9feded54bd | ||
|
|
4acec068aa | ||
|
|
e1d4c0f5f3 | ||
|
|
f066658c3c | ||
|
|
17021f04b9 | ||
|
|
0e5b4599bb | ||
|
|
02e7d1f4fa | ||
|
|
360a389e3d | ||
|
|
999d73db81 | ||
|
|
ec1f5edd5c | ||
|
|
2bc00dd6ca | ||
|
|
6e6253bf86 | ||
|
|
97e6fdc51b | ||
|
|
3cb9afa074 | ||
|
|
34d08bce61 | ||
|
|
3b3603d7cf | ||
|
|
ab0180a591 | ||
|
|
40e92a1b24 | ||
|
|
bf9bc013df | ||
|
|
4a58f49d3d | ||
|
|
da7270e058 | ||
|
|
420a2c8b40 | ||
|
|
d1e261e633 | ||
|
|
bfe4b8d090 | ||
|
|
269145a395 | ||
|
|
22122046ce | ||
|
|
4284aeced6 | ||
|
|
d047fa50a9 | ||
|
|
273b5f3c4e | ||
|
|
3477cc395b | ||
|
|
59f2c4a55d | ||
|
|
84c616b6f6 | ||
|
|
57e3dd05c7 | ||
|
|
2b52488bfa | ||
|
|
3d2f28431f | ||
|
|
f1c8364b72 | ||
|
|
bb8ba60829 | ||
|
|
50d6537a73 | ||
|
|
e68b6dc72d | ||
|
|
1da020abd4 |
@@ -1,9 +1,11 @@
|
||||
*secret*sh
|
||||
*~
|
||||
.dockerignore
|
||||
.env
|
||||
.env-secrets
|
||||
.git
|
||||
.idea/
|
||||
Dockerfile
|
||||
__pycache__/
|
||||
_ignored_schema.rs
|
||||
models/Wav2Lip/python/
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
SERVER_ENVIRONMENT=development
|
||||
|
||||
DATABASE_URL=mysql://storyteller:password@localhost/storyteller
|
||||
#DATABASE_URL=mysql://root:root@localhost/storyteller
|
||||
#DATABASE_URL=mysql://root@localhost/storyteller
|
||||
|
||||
# Diesel-cli reads this for the migration directory to use.
|
||||
# We've renamed it so the migrations are sorted near the top of the project directory tree
|
||||
# (since they kind of serve as documentation)
|
||||
MIGRATION_DIRECTORY=_sql/migrations/
|
||||
|
||||
# SQLX normally requires a live database to reflect upon at build time.
|
||||
# This setting turns that on and requires a `sql-data.json` cache file instead.
|
||||
# See https://github.com/launchbadge/sqlx/tree/master/sqlx-cli#readme
|
||||
@@ -64,3 +71,14 @@ 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
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# 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
|
||||
@@ -0,0 +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
|
||||
windows/sqlite linguist-vendored
|
||||
@@ -0,0 +1,52 @@
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
env:
|
||||
MYSQL_URL: mysql://root:root@localhost/storyteller
|
||||
DATABASE_URL: mysql://root:root@localhost/storyteller
|
||||
REDIS_0_URL: redis://redisd@localhost/0
|
||||
REDIS_1_URL: redis://redisd@localhost/1
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
jobs:
|
||||
setup_build_test:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}
|
||||
- name: Setup mysql
|
||||
run: |
|
||||
sudo systemctl start mysql
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install mysql-client libmysqlclient-dev
|
||||
mysql -e "create user 'storyteller'@'localhost' IDENTIFIED BY 'password';" -uroot -proot
|
||||
mysql -e "create database storyteller; grant all on storyteller.* to 'storyteller'@'localhost';" -uroot -proot
|
||||
- name: Setup Redis
|
||||
run: |
|
||||
sudo apt-get -y install redis-server
|
||||
sudo service redis-server start
|
||||
- name: Setup Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup show
|
||||
rustup install 1.66
|
||||
rustup default 1.66
|
||||
rustup show
|
||||
cargo install sqlx-cli --features openssl-vendored
|
||||
cargo install diesel_cli
|
||||
- name: Run database migrations
|
||||
run: |
|
||||
# nothing to see here ;)
|
||||
set +e +o pipefail
|
||||
diesel migration run
|
||||
set -e -o pipefail
|
||||
- name: Build
|
||||
run: cargo build --release
|
||||
- name: Test
|
||||
run: cargo test --release
|
||||
@@ -15,53 +15,98 @@ env:
|
||||
jobs:
|
||||
# Push image to GitHub Packages.
|
||||
# See also https://docs.docker.com/docker-hub/builds/
|
||||
push:
|
||||
runs-on: ubuntu-latest
|
||||
# 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@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
# - 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.repository_owner }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ github.actor }} # username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build image
|
||||
- name: Calculate short SHA
|
||||
id: vars
|
||||
# echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
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}
|
||||
echo "sha_short=$(echo ${{ github.sha }} | cut -c1-12)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Push image to GitHub Container Registry
|
||||
- name: Emit short SHA
|
||||
run: |
|
||||
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
|
||||
echo "Full SHA: ${{ github.sha }}"
|
||||
echo "Short SHA: ${{ steps.vars.outputs.sha_short }}"
|
||||
|
||||
# Change all uppercase to lowercase
|
||||
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
|
||||
#- uses: actions/cache@v2
|
||||
# name: Cache Docker layers
|
||||
# with:
|
||||
# path: /tmp/.buildx-cache
|
||||
# key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-buildx-
|
||||
|
||||
# Strip git ref prefix from version
|
||||
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
|
||||
# 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
|
||||
# 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 }}"
|
||||
|
||||
# Strip "v" prefix from tag name
|
||||
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
||||
# - 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}
|
||||
|
||||
# Use Docker `latest` tag convention
|
||||
[ "$VERSION" == "$default-branch" ] && VERSION=latest
|
||||
# - name: Push image to GitHub Container Registry
|
||||
# run: |
|
||||
# IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
|
||||
|
||||
echo IMAGE_ID=$IMAGE_ID
|
||||
echo VERSION=$VERSION
|
||||
# # Change all uppercase to lowercase
|
||||
# IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
|
||||
|
||||
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
|
||||
docker push $IMAGE_ID:$VERSION
|
||||
# # Strip git ref prefix from version
|
||||
# VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
|
||||
|
||||
SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-12)
|
||||
# # Strip "v" prefix from tag name
|
||||
# [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
||||
|
||||
docker tag $IMAGE_NAME $IMAGE_ID:$SHORT_SHA
|
||||
docker push $IMAGE_ID:$SHORT_SHA
|
||||
# # 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
|
||||
|
||||
+40
-11
@@ -1,22 +1,51 @@
|
||||
*.swo
|
||||
*.swp
|
||||
# Secrets are BAD!
|
||||
*secret*sh
|
||||
*~
|
||||
.env
|
||||
.env-aichatbot-secrets
|
||||
.env-secrets
|
||||
.idea/
|
||||
__pycache__/
|
||||
_ignored_schema.rs
|
||||
db.secrets
|
||||
db_secrets.toml
|
||||
models/Wav2Lip/python/
|
||||
models/tacotron2/python/
|
||||
production_database_secret_connect.sh
|
||||
production_database_secret_query.sh
|
||||
production_database_voice_clone_report_download.sh
|
||||
secrets.toml
|
||||
secrets.yaml
|
||||
target/
|
||||
tools/.secrets
|
||||
tools/db_secrets.toml
|
||||
_develop/tools/.secrets
|
||||
_develop/tools/db_secrets.toml
|
||||
twitch_secrets.toml
|
||||
|
||||
# Rust build directory
|
||||
target/
|
||||
crates/lib/database_queries/target/
|
||||
crates/lib/sqlite_queries/target/
|
||||
|
||||
# Vim noise
|
||||
*.swo
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# IntelliJ/CLion noise
|
||||
.idea/
|
||||
|
||||
# Python noise
|
||||
__pycache__/
|
||||
|
||||
# We use diesel for DB migrations only. We don't care about its codgen.
|
||||
_ignored_schema.rs
|
||||
|
||||
# AI Chat Sidecar has its own schema managed by diesel, but we don't care for diesel codegen.
|
||||
crates/programs/aichatbot-sidecar/_ignored_schema.rs
|
||||
|
||||
# AI Chat sidecar's SQlite database shouldn't be checked in
|
||||
crates/programs/aichatbot-sidecar/database.db
|
||||
|
||||
# Runtime data for the AI chatbot
|
||||
runtime_data/
|
||||
|
||||
# Old Python virtual environments
|
||||
models/Wav2Lip/python/
|
||||
models/tacotron2/python/
|
||||
|
||||
# Stuff I want to keep around, but not commit
|
||||
scraps/
|
||||
|
||||
|
||||
Generated
+21
-4
@@ -1,18 +1,35 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<!--
|
||||
Despite spellcheck dictionaries being created per-user, IntelliJ loads all of them, per:
|
||||
https://stackoverflow.com/a/28151692
|
||||
-->
|
||||
<dictionary name="bt">
|
||||
<words>
|
||||
<w>arpabet</w>
|
||||
<w>backfill</w>
|
||||
<w>cashapp</w>
|
||||
<w>cheermote</w>
|
||||
<w>crockford</w>
|
||||
<w>culted</w>
|
||||
<w>dalle</w>
|
||||
<w>downvote</w>
|
||||
<w>fakeyou</w>
|
||||
<w>ffprobe</w>
|
||||
<w>greenlight</w>
|
||||
<w>greenlighting</w>
|
||||
<w>greenlit</w>
|
||||
<w>hanashi</w>
|
||||
<w>hifigan</w>
|
||||
<w>replayable</w>
|
||||
<w>retryably</w>
|
||||
<w>scrollback</w>
|
||||
<w>softvc</w>
|
||||
<w>symphonia</w>
|
||||
<w>tacotron</w>
|
||||
<w>techcrunch</w>
|
||||
<w>transcoded</w>
|
||||
<w>transcodings</w>
|
||||
<w>upserting</w>
|
||||
<w>vocoded</w>
|
||||
<w>vocoder</w>
|
||||
<w>vocoders</w>
|
||||
<w>vocodes</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
Generated
+4014
-666
File diff suppressed because it is too large
Load Diff
+56
-18
@@ -1,29 +1,67 @@
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
# Types: common strongly-typed tokens, ids, payloads, etc.
|
||||
# Also common cloud buckets and other "strongly typed" configs.
|
||||
"crates/_types/buckets",
|
||||
"crates/_types/enums",
|
||||
"crates/_types/reusable_types", # TODO(bt, 2022-12-21): Deprecate
|
||||
"crates/_types/tokens",
|
||||
|
||||
# CLI tools for operations, etc.
|
||||
"crates/cli/database_backup",
|
||||
"crates/cli/database_cleanup",
|
||||
"crates/cli/scrape_test",
|
||||
|
||||
# Shared libraries
|
||||
"crates/lib/config",
|
||||
"crates/lib/container_common",
|
||||
"crates/lib/database_queries",
|
||||
"crates/lib/google_drive_common",
|
||||
"crates/lib/actix_helpers",
|
||||
"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/errors",
|
||||
"crates/lib/files",
|
||||
"crates/lib/hashing",
|
||||
"crates/lib/http_server_common",
|
||||
"crates/lib/idempotency",
|
||||
"crates/lib/jobs_common",
|
||||
"crates/lib/memory_caching",
|
||||
"crates/lib/media",
|
||||
"crates/lib/redis_common",
|
||||
"crates/lib/reusable_types",
|
||||
"crates/lib/storage_buckets_common",
|
||||
"crates/lib/sqlite_queries",
|
||||
"crates/lib/sqlx_mysql_helpers",
|
||||
"crates/lib/subprocess_common",
|
||||
"crates/lib/tts_common",
|
||||
"crates/lib/twitch_common",
|
||||
"crates/lib/url_config",
|
||||
"crates/lib/user_input_common",
|
||||
"crates/lib/web_scrapers",
|
||||
|
||||
# Application
|
||||
"crates/service/generic_download_job",
|
||||
"crates/service/storyteller_web",
|
||||
"crates/service/tts_download_job",
|
||||
"crates/service/tts_inference_job",
|
||||
"crates/service/twitch_pubsub_subscriber",
|
||||
"crates/service/w2l_download_job",
|
||||
"crates/service/w2l_inference_job",
|
||||
"crates/service/websocket_gateway",
|
||||
# Programs: Desktop apps
|
||||
"crates/programs/aichatbot-sidecar",
|
||||
|
||||
# Services: API servers, jobs, workers, etc.
|
||||
"crates/service/job/analytics_job",
|
||||
"crates/service/job/download_job",
|
||||
"crates/service/job/inference_job",
|
||||
"crates/service/job/tts_download_job",
|
||||
"crates/service/job/tts_inference_job",
|
||||
"crates/service/job/w2l_download_job",
|
||||
"crates/service/job/w2l_inference_job",
|
||||
"crates/service/other/twitch_pubsub_subscriber",
|
||||
"crates/service/web/dummy_service",
|
||||
"crates/service/web/image_generation_service",
|
||||
"crates/service/web/storyteller_web",
|
||||
"crates/service/web/websocket_gateway",
|
||||
|
||||
# Service Plugins: complete subsystems that can be plugged into services (users, billing, etc.)
|
||||
"crates/service/plugins/billing",
|
||||
"crates/service/plugins/inference_workloads",
|
||||
"crates/service/plugins/users",
|
||||
]
|
||||
|
||||
|
||||
+152
-111
@@ -1,70 +1,104 @@
|
||||
# ==================== Python Build Base ====================
|
||||
|
||||
FROM ghcr.io/storytold/docker-base-images-nvidia-cuda-experimental:080f96bc7087 as pybuild-base
|
||||
|
||||
# The downloader needs youtube-dl as a python library
|
||||
# NB: No longer maintained: https://news.ycombinator.com/item?id=28319624
|
||||
#RUN pip3 install --upgrade youtube-dl
|
||||
|
||||
# Used by the downloader script.
|
||||
# And it looks like youtube-dl is dead...
|
||||
# Per the README, it looks like pip will always pull the latest version.
|
||||
# https://github.com/yt-dlp/yt-dlp#update
|
||||
RUN python3 -m pip install --upgrade yt-dlp
|
||||
|
||||
# ==================== Python Build Step 2: Wav2Lip Requirements ====================
|
||||
|
||||
FROM pybuild-base as pybuild-requirements
|
||||
|
||||
WORKDIR /
|
||||
|
||||
COPY models/Wav2Lip ./models/Wav2Lip
|
||||
WORKDIR models/Wav2Lip
|
||||
|
||||
# NB: We need Python3.6
|
||||
RUN python3.6 -m venv python
|
||||
#RUN virtualenv -p /usr/bin/python3.6 ... wait
|
||||
RUN . python/bin/activate \
|
||||
&& pip install --upgrade pip \
|
||||
&& pip install -r requirements.txt \
|
||||
&& deactivate
|
||||
|
||||
WORKDIR /
|
||||
|
||||
COPY models/tts ./models/tts
|
||||
WORKDIR models/tts
|
||||
|
||||
# NB: Not sure if we need Python3.6 for Tacotron2, but Python3.8 gave me trouble.
|
||||
# NB: Setuptools fix: https://github.com/tensorflow/tensorflow/issues/34302#issuecomment-554450289
|
||||
RUN python3.6 -m venv python
|
||||
RUN . python/bin/activate \
|
||||
&& pip install --upgrade pip setuptools \
|
||||
&& pip install -r requirements-tacotron-python36.txt \
|
||||
&& deactivate
|
||||
|
||||
# ==================== Rust Build Base ====================
|
||||
# ================================================================
|
||||
# =============== (1) set up core rust build image ===============
|
||||
# ================================================================
|
||||
|
||||
# Custom base image
|
||||
# Make sure to add this repository so it has read acces to the base image:
|
||||
# https://github.com/orgs/storytold/packages/container/docker-base-images-rust-ssl/settings/actions_access
|
||||
FROM ghcr.io/storytold/docker-base-images-rust-ssl:latest as rust-build
|
||||
# FROM ghcr.io/storytold/docker-base-images-rust-ssl:d94ce4350c3b as rust-build
|
||||
FROM ubuntu:jammy as rust-base
|
||||
|
||||
# NB: This can be "stable" or another version.
|
||||
ARG RUST_TOOLCHAIN="1.66.0"
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
COPY Cargo.lock .
|
||||
# NB: cmake is required for freetype-sys-0.13.1, which in turn has only been added for egui.
|
||||
# NB: fontconfig is required by servo-fontconfig-sys, which is in the dependency chain for egui.
|
||||
# NB: libfontconfig-dev is required by servo-fontconfig-sys, which is in the dependency chain for egui.
|
||||
# NB: pkg-config and libssl are for container TLS; we may switch to rustls in the future.
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
fontconfig \
|
||||
libfontconfig1-dev \
|
||||
libssl-dev \
|
||||
pkg-config
|
||||
|
||||
# NB: Fix for fontconfig (servo-fontconfig-sys): https://github.com/alacritty/alacritty/issues/4423#issuecomment-727277235
|
||||
# TODO(bt, 2023-02-23): This has not been verified to work yet.
|
||||
RUN export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig
|
||||
|
||||
# Install Rust
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
||||
| sh -s -- --default-toolchain $RUST_TOOLCHAIN -y
|
||||
|
||||
# Install correct Rust version
|
||||
#RUN $HOME/.cargo/bin/rustup install $RUST_VERSION
|
||||
#RUN $HOME/.cargo/bin/rustup default $RUST_VERSION
|
||||
|
||||
# Report Rust version for build debugging
|
||||
RUN $HOME/.cargo/bin/rustup show
|
||||
RUN $HOME/.cargo/bin/rustc --version
|
||||
RUN $HOME/.cargo/bin/cargo --version
|
||||
|
||||
# Cargo Chef does Rust build caching: https://github.com/LukeMathWalker/cargo-chef
|
||||
# TODO(bt,2023-03-08): builds are failing with "no space left on device"; disabling build caching
|
||||
#RUN $HOME/.cargo/bin/cargo install cargo-chef --locked
|
||||
|
||||
# ======================================================================
|
||||
# =============== (2) use cargo-chef to "plan" the build ===============
|
||||
# ======================================================================
|
||||
|
||||
FROM rust-base AS planner
|
||||
|
||||
# NB: Copying in everything does not appear to impact cached builds if irrelevant files are changed (at least at this step)
|
||||
# TODO(bt,2023-03-08): builds are failing with "no space left on device"; disabling build caching
|
||||
#COPY . .
|
||||
# TODO(bt,2023-03-08): builds are failing with "no space left on device"; disabling build caching
|
||||
#RUN $HOME/.cargo/bin/cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
# ======================================================================================================
|
||||
# =============== (3) "cook" the libraries (cacheable), then run the app build and tests ===============
|
||||
# ======================================================================================================
|
||||
|
||||
FROM rust-base AS builder
|
||||
|
||||
# TODO(bt,2023-03-08): builds are failing with "no space left on device"; disabling build caching
|
||||
#COPY --from=planner /tmp/recipe.json recipe.json
|
||||
|
||||
# NB: This step builds and caches the dependencies as its own layer.
|
||||
# TODO(bt,2023-03-08): builds are failing with "no space left on device"; disabling build caching
|
||||
#RUN $HOME/.cargo/bin/cargo chef cook --release --recipe-path recipe.json
|
||||
|
||||
# NB: Now we build and test our code.
|
||||
COPY Cargo.lock .
|
||||
COPY Cargo.toml .
|
||||
COPY sqlx-data.json .
|
||||
COPY crates/ ./crates
|
||||
COPY db/ ./db
|
||||
COPY test_data/ ./test_data
|
||||
COPY container_includes/ ./container_includes
|
||||
|
||||
RUN $HOME/.cargo/bin/cargo fetch
|
||||
|
||||
ARG GIT_SHA
|
||||
RUN echo -n ${GIT_SHA} > GIT_SHA
|
||||
# Print a report on disk space
|
||||
#RUN echo "Disk usage at root (before tests):"
|
||||
#RUN du -hsc / | sort -hr
|
||||
RUN echo "Disk usage at current directory (before tests):"
|
||||
RUN pwd
|
||||
RUN du -hsc * | sort -hr
|
||||
|
||||
# Run all of the tests
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo test
|
||||
#RUN SQLX_OFFLINE=true \
|
||||
# LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
# $HOME/.cargo/bin/cargo test
|
||||
|
||||
# Print a report on disk space
|
||||
#RUN echo "Disk usage at root (after tests):"
|
||||
#RUN du -hsc / | sort -hr
|
||||
RUN echo "Disk usage at current directory (after tests):"
|
||||
RUN pwd
|
||||
RUN du -hsc * | sort -hr
|
||||
|
||||
# Build all the binaries.
|
||||
RUN SQLX_OFFLINE=true \
|
||||
@@ -73,6 +107,30 @@ RUN SQLX_OFFLINE=true \
|
||||
--release \
|
||||
--bin storyteller-web
|
||||
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo build \
|
||||
--release \
|
||||
--bin dummy-service
|
||||
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo build \
|
||||
--release \
|
||||
--bin analytics-job
|
||||
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo build \
|
||||
--release \
|
||||
--bin download-job
|
||||
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo build \
|
||||
--release \
|
||||
--bin inference-job
|
||||
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo build \
|
||||
@@ -85,12 +143,6 @@ RUN SQLX_OFFLINE=true \
|
||||
--release \
|
||||
--bin w2l-download-job
|
||||
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo build \
|
||||
--release \
|
||||
--bin generic-download-job
|
||||
|
||||
RUN SQLX_OFFLINE=true \
|
||||
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
|
||||
$HOME/.cargo/bin/cargo build \
|
||||
@@ -115,72 +167,61 @@ RUN SQLX_OFFLINE=true \
|
||||
--release \
|
||||
--bin twitch-pubsub-subscriber
|
||||
|
||||
# Print a report on disk space
|
||||
RUN echo "Disk usage at current directory (after all builds):"
|
||||
RUN pwd
|
||||
RUN du -hsc * | sort -hr
|
||||
|
||||
# =============================================================
|
||||
# =============== (4) construct the final image ===============
|
||||
# =============================================================
|
||||
|
||||
# Final image
|
||||
# FROM ubuntu:xenial
|
||||
FROM pybuild-requirements as final
|
||||
FROM ubuntu:jammy as final
|
||||
|
||||
# See: https://github.com/opencontainers/image-spec/blob/master/annotations.md
|
||||
LABEL org.opencontainers.image.title='Storyteller Rust'
|
||||
LABEL org.opencontainers.image.authors='bt@brand.io, echelon@gmail.com'
|
||||
LABEL org.opencontainers.image.description='All of the binaries from the Rust monorepo'
|
||||
LABEL org.opencontainers.image.documentation='https://github.com/storytold/storyteller-web'
|
||||
LABEL org.opencontainers.image.source='https://github.com/storytold/storyteller-web'
|
||||
LABEL org.opencontainers.image.url='https://github.com/storytold/storyteller-web'
|
||||
|
||||
WORKDIR /
|
||||
|
||||
COPY scripts/ ./scripts
|
||||
|
||||
# See: https://github.com/opencontainers/image-spec/blob/master/annotations.md
|
||||
LABEL org.opencontainers.image.authors='bt@brand.io, echelon@gmail.com'
|
||||
LABEL org.opencontainers.image.url='https://github.com/storytold/storyteller-web'
|
||||
LABEL org.opencontainers.image.documentation='https://github.com/storytold/storyteller-web'
|
||||
LABEL org.opencontainers.image.source='https://github.com/storytold/storyteller-web'
|
||||
|
||||
# NB(echelon,2022-05-31): NVIDIA revoked some of their keys.
|
||||
# A better long term fix is to remove these dependencies outright and not have ML deps in this repo.
|
||||
# https://developer.nvidia.com/blog/updating-the-cuda-linux-gpg-repository-key/
|
||||
# https://forums.developer.nvidia.com/t/invalid-public-key-for-cuda-apt-repository/212901/11
|
||||
RUN apt-key del 7fa2af80
|
||||
|
||||
# NB: Fix for 'E: Conflicting values set for option Signed-By regarding source'
|
||||
# NB: We need to remove all sources
|
||||
RUN rm $(find /etc/apt | grep cuda)
|
||||
|
||||
#RUN wget https://developer.download.nvidia.com/compute/cuda/repos/$distro/$arch/cuda-keyring_1.0-1_all.deb
|
||||
RUN wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.0-1_all.deb
|
||||
RUN dpkg -i cuda-keyring_1.0-1_all.deb
|
||||
|
||||
# NB: Comment this out for non-debug images
|
||||
# TODO: Figure out how this is done elsewhere with just the static binaries
|
||||
# Others: `mysql-client`
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
curl \
|
||||
python3-pip \
|
||||
python3 \
|
||||
wget
|
||||
|
||||
RUN python3 --version
|
||||
|
||||
# TODO: Use venv to do this instead.
|
||||
RUN pip3 install gdown
|
||||
# Give the container its version so it can report over HTTP.
|
||||
ARG GIT_SHA
|
||||
RUN echo -n ${GIT_SHA} > GIT_SHA
|
||||
|
||||
# Copy all the binaries.
|
||||
COPY --from=rust-build /tmp/target/release/storyteller-web /
|
||||
COPY --from=rust-build /tmp/target/release/tts-download-job /
|
||||
COPY --from=rust-build /tmp/target/release/tts-inference-job /
|
||||
COPY --from=rust-build /tmp/target/release/w2l-download-job /
|
||||
COPY --from=rust-build /tmp/target/release/w2l-inference-job /
|
||||
COPY --from=rust-build /tmp/target/release/websocket-gateway /
|
||||
COPY --from=rust-build /tmp/target/release/twitch-pubsub-subscriber /
|
||||
COPY --from=rust-build /tmp/target/release/generic-download-job /
|
||||
COPY --from=rust-build /tmp/GIT_SHA /
|
||||
COPY --from=builder /tmp/target/release/storyteller-web /
|
||||
COPY --from=builder /tmp/target/release/dummy-service /
|
||||
COPY --from=builder /tmp/target/release/analytics-job /
|
||||
COPY --from=builder /tmp/target/release/download-job /
|
||||
COPY --from=builder /tmp/target/release/inference-job /
|
||||
COPY --from=builder /tmp/target/release/tts-download-job /
|
||||
COPY --from=builder /tmp/target/release/tts-inference-job /
|
||||
COPY --from=builder /tmp/target/release/w2l-download-job /
|
||||
COPY --from=builder /tmp/target/release/w2l-inference-job /
|
||||
COPY --from=builder /tmp/target/release/websocket-gateway /
|
||||
COPY --from=builder /tmp/target/release/twitch-pubsub-subscriber /
|
||||
|
||||
# SSL certs are required for crypto
|
||||
COPY --from=rust-build /etc/ssl /etc/ssl
|
||||
COPY --from=builder /etc/ssl /etc/ssl
|
||||
|
||||
# Required dynamically linked libraries
|
||||
COPY --from=rust-build /lib/x86_64-linux-gnu/libssl.* /lib/x86_64-linux-gnu/
|
||||
COPY --from=rust-build /lib/x86_64-linux-gnu/libcrypto.* /lib/x86_64-linux-gnu/
|
||||
COPY --from=builder /usr/lib/x86_64-linux-gnu/libssl.* /lib/x86_64-linux-gnu/
|
||||
COPY --from=builder /usr/lib/x86_64-linux-gnu/libcrypto.* /lib/x86_64-linux-gnu/
|
||||
|
||||
# Container includes
|
||||
COPY container_includes/ /container_includes
|
||||
|
||||
# Make sure all the links resolve
|
||||
RUN ldd storyteller-web
|
||||
|
||||
# Without a .env file, Rust crashes "mysteriously" (ugh)
|
||||
RUN touch .env
|
||||
RUN touch .env-download-job
|
||||
RUN touch .env-secrets
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
@@ -1,77 +1,46 @@
|
||||
storyteller-rust
|
||||
================
|
||||
|
||||
Our Rust monorepo, which services our
|
||||
API surface area.
|
||||
|
||||
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
|
||||
-------------------
|
||||
Our Rust monorepo, which serves both our API surface area and our downloadable client applications.
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
."-,.__
|
||||
`. `. ,
|
||||
.--' .._,'"-' `.
|
||||
. .' `'
|
||||
`. / ,'
|
||||
` '--. ,-"'
|
||||
`"` | \
|
||||
-. \, |
|
||||
`--Y.' ___.
|
||||
\ L._, \
|
||||
_., `. < <\ _
|
||||
,' ' `, `. | \ ( `
|
||||
../, `. ` | .\`. \ \_
|
||||
,' ,.. . _.,' ||\l ) '".
|
||||
, ,' \ ,'.-.`-._,' | . _._`.
|
||||
,' / \ \ `' ' `--/ | \ / / ..\
|
||||
.' / \ . |\__ - _ ,'` ` / / `.`.
|
||||
| ' .. `-...-" | `-' / / . `.
|
||||
| / |L__ | | / / `. `.
|
||||
, / . . | | / / ` `
|
||||
/ / ,. ,`._ `-_ | | _ ,-' / ` \
|
||||
/ . \"`_/. `-_ \_,. ,' +-' `-' _, ..,-. \`.
|
||||
. ' .-f ,' ` '. \__.---' _ .' ' \ \
|
||||
' / `.' l .' / \.. ,_|/ `. ,'` L`
|
||||
|' _.-""` `. \ _,' ` \ `.___`.'"`-. , | | | \
|
||||
|| ,' `. `. ' _,...._ ` | `/ ' | ' .|
|
||||
|| ,' `. ;.,.---' ,' `. `.. `-' .-' /_ .' ;_ ||
|
||||
|| ' V / / ` | ` ,' ,' '. ! `. ||
|
||||
||/ _,-------7 ' . | `-' l / `||
|
||||
. | ,' .- ,' || | .-. `. .' ||
|
||||
`' ,' `".' | | `. '. -.' `'
|
||||
/ ,' | |,' \-.._,.'/'
|
||||
. / . . \ .''
|
||||
.`. | `. / :_,'.'
|
||||
\ `...\ _ ,'-. .' /_.-' S T O R Y T E L L E R
|
||||
`-.__ `, `' . _.>----''. _ __ / Turning memes into dreams
|
||||
.' /"' | "' '_ One Rust Monorepo at a time
|
||||
/_|.-'\ ,". '.'`__'-( \
|
||||
/ ,"'"\,' `/ `-.|"
|
||||
```
|
||||
@@ -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.
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Local Kubernetes environment for standing up the APIs and their dependencies
|
||||
|
||||
- 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`
|
||||
- `minikube start --extra-config=apiserver.service-node-port-range=1-65535`
|
||||
- `eval $(minikube docker-env)`
|
||||
- `minikube mount /path/to/storyteller-rust/:/storyteller-rust &> /dev/null &`
|
||||
- `docker build -t storyteller-web -f localdev/Dockerfile .`
|
||||
- `kubectl apply -f localdev/kubernetes.yml`
|
||||
- Get the ip address of minikube with `minikube ip`, this is where all the services will be running on their
|
||||
regular ports (12345 for the api, 6379 for redis, 3306 for mysql)
|
||||
- That's it, we just spun up mysql, applied database migrations, spun up redis, and spun up our api
|
||||
|
||||
# Development tips
|
||||
- Rebuild and "deploy" (locally) with `cargo build --release --bin storyteller-web --target=x86_64-unknown-linux-musl && kubectl rollout restart storyteller-web`
|
||||
- View logs from the api with `kubectl logs storyteller-web<TAB>`
|
||||
- Delete everything minikube (if you start running out of disk space or what-have-you) with `minikube delete`
|
||||
- See pod status with `kubectl get pods`
|
||||
- If there are errors you can get more info with `kubectl describe pods`
|
||||
@@ -1,9 +1,9 @@
|
||||
dev setup
|
||||
=========
|
||||
|
||||
[Back to main README](../README.md)
|
||||
[Back to main README](../../README.md)
|
||||
|
||||
### Debugging and Fixing CUDA/PyTorch
|
||||
## 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
|
||||
@@ -11,27 +11,53 @@ https://docs.google.com/spreadsheets/d/1BEdLmwOzo3r83-iJn9sj6co1VT92t3lIeJ-lNH25
|
||||
Ubuntu might upgrade the driver by accident, and it might need reinstallation. Who knows.
|
||||
This stuff is a nightmare.
|
||||
|
||||
### Database Setup
|
||||
## 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
|
||||
imagemagick
|
||||
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 mysql [2022-01-16: is this needed?]
|
||||
cargo install sqlx-cli --no-default-features --features rustls,mysql,sqlite
|
||||
```
|
||||
|
||||
To install a more modern version of Diesel (unreleased) that
|
||||
supports the "migrations_dir" toml config option:
|
||||
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 \
|
||||
@@ -60,6 +86,21 @@ 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.
|
||||
@@ -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.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
FROM rust:latest
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
mariadb-client \
|
||||
imagemagick \
|
||||
libmariadb-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
RUN cargo install diesel_cli --features mysql && \
|
||||
cargo install sqlx-cli --features mysql
|
||||
|
||||
WORKDIR /storyteller-rust
|
||||
|
||||
ARG GIT_SHA
|
||||
|
||||
RUN echo -n ${GIT_SHA} > /GIT_SHA
|
||||
|
||||
CMD ["/storyteller-rust/localdev/startup.sh"]
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mysql
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
containers:
|
||||
- name: mysql
|
||||
image: mysql:8.0.30
|
||||
env:
|
||||
- name: MYSQL_USER
|
||||
value: storyteller
|
||||
- name: MYSQL_PASSWORD
|
||||
value: password
|
||||
- name: MYSQL_DATABASE
|
||||
value: storyteller
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
value: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
|
||||
---
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7.0.4
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
|
||||
---
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: storyteller-web
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: storyteller-web
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: storyteller-web
|
||||
spec:
|
||||
containers:
|
||||
- name: storyteller-web
|
||||
image: storyteller-web:latest
|
||||
imagePullPolicy: Never
|
||||
env:
|
||||
- name: MYSQL_URL
|
||||
value: mysql://storyteller:password@mysql.default/storyteller
|
||||
- name: REDIS_0_URL
|
||||
value: redis://redisd@redis.default/0
|
||||
- name: REDIS_1_URL
|
||||
value: redis://redisd@redis.default/1
|
||||
- name: ACCESS_KEY
|
||||
value: garbage
|
||||
- name: SECRET_KEY
|
||||
value: garbage
|
||||
- name: REGION_NAME
|
||||
value: garbage
|
||||
- name: W2L_PRIVATE_DOWNLOAD_BUCKET_NAME
|
||||
value: garbage
|
||||
- name: W2L_PUBLIC_DOWNLOAD_BUCKET_NAME
|
||||
value: garbage
|
||||
- name: AUDIO_UPLOADS_BUCKET_ROOT
|
||||
value: garbage
|
||||
- name: TWITCH_USERNAME
|
||||
value: garbage
|
||||
- name: TWITCH_STREAM_KEY
|
||||
value: garbage
|
||||
- name: TWITCH_APP_CLIENT_ID
|
||||
value: garbage
|
||||
- name: TWITCH_APP_CLIENT_SECRET
|
||||
value: garbage
|
||||
ports:
|
||||
- containerPort: 12345
|
||||
volumeMounts:
|
||||
- mountPath: /storyteller-rust
|
||||
name: storyteller-rust-folder
|
||||
volumes:
|
||||
- name: storyteller-rust-folder
|
||||
hostPath:
|
||||
path: /storyteller-rust
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- name: mysql
|
||||
port: 3306
|
||||
nodePort: 3306
|
||||
selector:
|
||||
app: mysql
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- name: redis
|
||||
port: 6379
|
||||
nodePort: 6379
|
||||
selector:
|
||||
app: redis
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: storyteller-web
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- name: storyteller-web
|
||||
port: 12345
|
||||
nodePort: 12345
|
||||
selector:
|
||||
app: storyteller-web
|
||||
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
# Nginx configs for "jungle.horse" and "api.jungle.horse" (http)
|
||||
#
|
||||
# On Ubuntu Linux, this config is located at the following location:
|
||||
#
|
||||
# - /etc/nginx/sites-enabled/{name-of-site}
|
||||
#
|
||||
# Move this file there, and then restart with,
|
||||
#
|
||||
# sudo service nginx restart
|
||||
#
|
||||
# On Mac, this is located at the following locations:
|
||||
#
|
||||
# - /opt/homebrew/etc/nginx/servers/{name-of-site} (for nginx installed with homebrew)
|
||||
# - /usr/local/etc/nginx/sites-enabled/{name-of-site} (for default nginx install)
|
||||
#
|
||||
#
|
||||
# On Mac, verify configs and restart with,
|
||||
#
|
||||
# sudo nginx -t
|
||||
# sudo nginx -s reload
|
||||
#
|
||||
# ================
|
||||
# SSL Instructions
|
||||
# ================
|
||||
#
|
||||
# You can launch Chrome in a way it disregards self-signed certs and CORS:
|
||||
#
|
||||
# chromium --disable-web-security --ignore-certificate-errors --user-data-dir=~/chromeTemp
|
||||
#
|
||||
# To create self-signed certs on Ubuntu Linux,
|
||||
#
|
||||
# sudo apt-get install openssl
|
||||
#
|
||||
# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/localhost.key -out /etc/ssl/certs/localhost.crt
|
||||
#
|
||||
# ^ most fields can be blank, but the "Common Name" should be `*.jungle.horse`
|
||||
#
|
||||
# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/devfakeyou.key -out /etc/ssl/certs/devfakeyou.crt
|
||||
# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/devstoryteller.key -out /etc/ssl/certs/devstoryteller.crt
|
||||
#
|
||||
# ^ most fields can be blank, but the "Common Name" should be `*.dev.fakeyou.com` and `*.dev.storyteller.io` respectively.
|
||||
#
|
||||
# For more: https://www.cloudsavvyit.com/1306/how-to-create-and-use-self-signed-ssl-on-nginx/
|
||||
#
|
||||
# To create self-signed certs on Mac,
|
||||
#
|
||||
# openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt
|
||||
#
|
||||
# ^ most fields can be blank, but the "Common Name" should be `*.jungle.horse`
|
||||
#
|
||||
# On Mac, load the self signed cert into the keychain with the following command:
|
||||
#
|
||||
# sudo security add-trusted-cert \
|
||||
# -d -r trustRoot \
|
||||
# -k /Library/Keychains/System.keychain /etc/ssl/certs/localhost.crt
|
||||
#
|
||||
# Self signed certs might be considered insecure by the browser. In Firefox,
|
||||
# set about:config `security.tls.insecure_fallback_hosts` to include a list of
|
||||
# permitted domains. You may also need to configure other settings.
|
||||
#
|
||||
#
|
||||
|
||||
# ========================================================
|
||||
# FAKEYOU
|
||||
# ========================================================
|
||||
|
||||
# FakeYou javascript frontend over plain HTTP (launched by Yarn)
|
||||
server {
|
||||
listen 80;
|
||||
server_name dev.fakeyou.com;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:7000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# FakeYou API backend over plain HTTP (Rust app)
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.dev.fakeyou.com;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:12345;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# FakeYou javascript frontend over SSL (launched by Yarn)
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
ssl_certificate /etc/ssl/certs/devfakeyou.crt;
|
||||
ssl_certificate_key /etc/ssl/private/devfakeyou.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
server_name dev.fakeyou.com;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:7000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# FakeYou API backend over SSL (Rust app)
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
ssl_certificate /etc/ssl/certs/devfakeyou.crt;
|
||||
ssl_certificate_key /etc/ssl/private/devfakeyou.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
server_name api.dev.fakeyou.com;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:12345;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# ========================================================
|
||||
# STORYTELLER
|
||||
# ========================================================
|
||||
|
||||
# Storyteller javascript frontend over plain HTTP (launched by Yarn)
|
||||
server {
|
||||
listen 80;
|
||||
server_name dev.storyteller.io;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:7000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# Storyteller API backend over plain HTTP
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.dev.storyteller.io;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:12345;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# Storyteller javascript frontend over SSL (launched by Yarn)
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
ssl_certificate /etc/ssl/certs/devstoryteller.crt;
|
||||
ssl_certificate_key /etc/ssl/private/devstoryteller.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
server_name dev.storyteller.io;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:7000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# Storyteller API backend over SSL
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
ssl_certificate /etc/ssl/certs/devstoryteller.crt;
|
||||
ssl_certificate_key /etc/ssl/private/devstoryteller.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
server_name api.dev.storyteller.io;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:12345;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
|
||||
# ========================================================
|
||||
# OLD PRODUCTS THAT NEED UPDATING
|
||||
# ========================================================
|
||||
|
||||
# ## TODO(2022-02-13): This is new and untested
|
||||
# # WebSocket API backend over plain HTTP
|
||||
# server {
|
||||
# listen 80;
|
||||
# server_name ws.jungle.horse;
|
||||
# location / {
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_pass http://127.0.0.1:54321;
|
||||
# proxy_redirect off;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Websocket API backend over SSL
|
||||
# server {
|
||||
# listen 443 ssl;
|
||||
# listen [::]:443 ssl;
|
||||
# ssl_certificate /etc/ssl/certs/localhost.crt;
|
||||
# ssl_certificate_key /etc/ssl/private/localhost.key;
|
||||
# ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
# server_name ws.jungle.horse;
|
||||
# location / {
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_pass http://127.0.0.1:54321;
|
||||
# proxy_redirect off;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Javascript frontend over plain HTTP
|
||||
# server {
|
||||
# listen 80;
|
||||
# server_name jungle.horse;
|
||||
# location / {
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_pass http://127.0.0.1:7000;
|
||||
# proxy_redirect off;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # TODO(2022-02-13): This is new and untested
|
||||
# # Javascript frontend (OBS Layer) over plain HTTP
|
||||
# server {
|
||||
# listen 80;
|
||||
# server_name obs.jungle.horse;
|
||||
# location / {
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_pass http://127.0.0.1:7007;
|
||||
# proxy_redirect off;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Javascript frontend over SSL
|
||||
# server {
|
||||
# listen 443 ssl;
|
||||
# listen [::]:443 ssl;
|
||||
# ssl_certificate /etc/ssl/certs/localhost.crt;
|
||||
# ssl_certificate_key /etc/ssl/private/localhost.key;
|
||||
# ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
# server_name jungle.horse;
|
||||
# location / {
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_pass http://127.0.0.1:7000;
|
||||
# proxy_redirect off;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Javascript frontend over SSL (OBS Layer)
|
||||
# server {
|
||||
# listen 443 ssl;
|
||||
# listen [::]:443 ssl;
|
||||
# ssl_certificate /etc/ssl/certs/localhost.crt;
|
||||
# ssl_certificate_key /etc/ssl/private/localhost.key;
|
||||
# ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||
# server_name obs.jungle.horse;
|
||||
# location / {
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_pass http://127.0.0.1:7007;
|
||||
# proxy_redirect off;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set +e +o pipefail
|
||||
diesel migration run --database-url="${MYSQL_URL}"
|
||||
set -e -o pipefail
|
||||
./target/x86_64-unknown-linux-musl/release/storyteller-web
|
||||
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo 'Installing APT packages...'
|
||||
|
||||
# OpenSSL requirements: libssl-dev, pkg-config
|
||||
# Database requirements: mysql-server, libmysqlclient-dev
|
||||
# Other tools: jq (db codegen)
|
||||
sudo apt-get install -y \
|
||||
jq \
|
||||
libmysqlclient-dev \
|
||||
libssl-dev \
|
||||
mysql-server \
|
||||
pkg-config \
|
||||
--no-install-recommends
|
||||
|
||||
echo 'Installing Cargo packages...'
|
||||
|
||||
# Install Diesel CLI for migrations
|
||||
cargo install diesel_cli \
|
||||
--no-default-features \
|
||||
--features mysql
|
||||
|
||||
# Install SQLx for codegen
|
||||
cargo install sqlx-cli \
|
||||
--no-default-features \
|
||||
--features rustls,mysql
|
||||
|
||||
echo 'Installing Database user...'
|
||||
|
||||
# Create DB account (using default system mysql password)
|
||||
sudo mysql \
|
||||
-u "root" \
|
||||
-p"password" \
|
||||
-e "use mysql; CREATE DATABASE IF NOT EXISTS storyteller; CREATE USER IF NOT EXISTS 'storyteller'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON storyteller.* TO 'storyteller'@'localhost';"
|
||||
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE users (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Visible "primary key"
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Username is a lookup key; display_name allows the user to add custom case.
|
||||
username VARCHAR(20) NOT NULL,
|
||||
display_name VARCHAR(20) NOT NULL,
|
||||
|
||||
email_address VARCHAR(255) NOT NULL,
|
||||
email_confirmed BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- The role assigned to the user confers permissions.
|
||||
user_role_slug VARCHAR(16) NOT NULL,
|
||||
|
||||
-- ========== CREDENTIALS ==========
|
||||
|
||||
-- Bcrypt password hash. Granted, there are newer methods:
|
||||
-- https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
||||
-- Passwords may be a max of 64 characters per BCrypt.
|
||||
password_hash BINARY(60) NOT NULL,
|
||||
|
||||
-- Incremented with every update to the password.
|
||||
password_version INT NOT NULL DEFAULT 0,
|
||||
|
||||
-- ========== ABUSE TRACKING ==========
|
||||
|
||||
-- For abuse tracking.
|
||||
-- Wide enough for IPv4/6
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
ip_address_last_login VARCHAR(40) NOT NULL,
|
||||
ip_address_last_update VARCHAR(40) NOT NULL,
|
||||
|
||||
-- ========== DISPLAY / PROFILE ==========
|
||||
|
||||
-- Gravatar image hashes are precomputed.
|
||||
email_gravatar_hash CHAR(32) NOT NULL,
|
||||
|
||||
-- The profile of the user in markdown (user editable).
|
||||
profile_markdown TEXT NOT NULL,
|
||||
|
||||
-- Generated HTML (not user-editable).
|
||||
profile_rendered_html TEXT NOT NULL,
|
||||
|
||||
-- An uploaded avatar. Public hash in our bucket.
|
||||
-- avatar_public_bucket_hash CHAR(32) DEFAULT NULL,
|
||||
|
||||
-- ========== SOCIAL MEDIA ==========
|
||||
|
||||
-- Social media usernames
|
||||
-- These are not confirmed. We'll need to build an OAuth system to handle that.
|
||||
discord_username VARCHAR(36) DEFAULT NULL,
|
||||
twitter_username VARCHAR(36) DEFAULT NULL,
|
||||
twitch_username VARCHAR(36) DEFAULT NULL,
|
||||
patreon_username VARCHAR(36) DEFAULT NULL,
|
||||
github_username VARCHAR(36) DEFAULT NULL,
|
||||
cashapp_username VARCHAR(36) DEFAULT NULL,
|
||||
website_url VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- ========== USER PREFERENCES ==========
|
||||
|
||||
-- If the user doesn't want to use gravatar and doesn't have an uploaded avatar.
|
||||
disable_gravatar BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- (THIS MIGHT NOT BE USED)
|
||||
-- NB: DO NOT SORT!
|
||||
-- THIS MUST MATCH THE RESPECTIVE JOBS TABLE.
|
||||
-- Visibility preference used at TTS inference time (which can be changed on the result itself).
|
||||
-- Moderators will still see them.
|
||||
preferred_tts_result_visibility ENUM(
|
||||
'public',
|
||||
'hidden',
|
||||
'private'
|
||||
) NOT NULL DEFAULT 'public',
|
||||
|
||||
-- (THIS MIGHT NOT BE USED)
|
||||
-- NB: DO NOT SORT!
|
||||
-- THIS MUST MATCH THE RESPECTIVE JOBS TABLE.
|
||||
-- Visibility preference used at TTS inference time (which can be changed on the result itself).
|
||||
-- Moderators will still see them.
|
||||
preferred_w2l_result_visibility ENUM(
|
||||
'public',
|
||||
'hidden',
|
||||
'private'
|
||||
) NOT NULL DEFAULT 'public',
|
||||
|
||||
-- Auto play preferences
|
||||
-- Tri-state because we want to potentially change the default behavior.
|
||||
auto_play_audio_preference BOOLEAN DEFAULT NULL,
|
||||
auto_play_video_preference BOOLEAN DEFAULT NULL,
|
||||
|
||||
-- Favorite TTS voice to use by default
|
||||
-- maybe_preferred_tts_model_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- Favorite W2L model to use by default
|
||||
-- maybe_preferred_w2l_template_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- Settings
|
||||
-- DO NOT REORDER.
|
||||
-- dark_mode_preference ENUM(
|
||||
-- 'light-mode',
|
||||
-- 'dark-mode',
|
||||
-- 'use-clock'
|
||||
-- ) NOT NULL DEFAULT 'light-mode',
|
||||
|
||||
-- ========== STATS ==========
|
||||
|
||||
-- For tracking stats.
|
||||
-- The "cached" values are updated by a background job.
|
||||
-- cached_tts_rendered_counter INT(10) NOT NULL DEFAULT 0,
|
||||
-- cached_w2l_rendered_counter INT(10) NOT NULL DEFAULT 0,
|
||||
|
||||
-- ========== MODERATION DETAILS ==========
|
||||
|
||||
-- Different than deleted.
|
||||
-- Users still show up, but can't do anything.
|
||||
is_banned BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- If a moderator has comments.
|
||||
maybe_mod_comments VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- The last moderator that made changes.
|
||||
maybe_mod_user_token VARCHAR(32) 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 the user is deleted, we set this.
|
||||
-- This is different than banned. These users won't show up at all.
|
||||
user_deleted_at TIMESTAMP NULL,
|
||||
mod_deleted_at TIMESTAMP NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
UNIQUE KEY (username),
|
||||
UNIQUE KEY (email_address),
|
||||
KEY fk_user_role_slug (user_role_slug)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
CREATE TABLE user_roles (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Effective "primary key"
|
||||
slug CHAR(16) NOT NULL,
|
||||
|
||||
name VARCHAR(255) NOT NULL,
|
||||
|
||||
-- Usage
|
||||
can_use_tts BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_use_w2l BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_tts_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_w2l_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_account BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Contribution
|
||||
can_upload_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_upload_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Moderation
|
||||
can_approve_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- Edit includes "lock_from_use" and "lock_from_modification"
|
||||
can_edit_other_users_profiles BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_edit_other_users_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_edit_other_users_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_tts_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_w2l_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_ban_users BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_users BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Incremented with every update.
|
||||
version INT 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 (slug)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
CREATE TABLE user_sessions (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Session entropy
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Foreign key to user
|
||||
user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Track each session's creation IP.
|
||||
-- Wide enough for IPv4/6
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
-- Session termination time.
|
||||
-- This must be set by the server code, or the session is invalid
|
||||
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- deletion = session termination
|
||||
-- Typically these are destroyed by users, but if in the future we allow mods to
|
||||
-- delete them, it doesn't really matter who did the deletion: sessions are not
|
||||
-- designed to be recoverable.
|
||||
deleted_at TIMESTAMP NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
KEY fk_user_token (user_token),
|
||||
KEY index_ip_address_creation (ip_address_creation)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -1,110 +0,0 @@
|
||||
-- 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
|
||||
on_success_downloaded_entity_type VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- ========== UPLOAD DETAILS ==========
|
||||
|
||||
-- A "well defined" type of upload
|
||||
-- The first upload type will be "hifigan_model"
|
||||
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,
|
||||
|
||||
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,
|
||||
|
||||
-- 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;
|
||||
@@ -1,128 +0,0 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE vocoder_models (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Effective "primary key" (PUBLIC)
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The architecture of the vocoder.
|
||||
-- Currently supported values: 'hifigan'
|
||||
vocoder_type VARCHAR(32) NOT NULL,
|
||||
|
||||
-- ========== MUTABLE METADATA ==========
|
||||
|
||||
-- The "name" of the vocoder, which might be complicated.
|
||||
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,
|
||||
|
||||
-- ========== MUTABLE MOD-ONLY METADATA ==========
|
||||
|
||||
-- Whether the vocoder is recommended for use
|
||||
is_staff_recommended 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
|
||||
creator_ip_address_creation VARCHAR(40) NOT NULL,
|
||||
creator_ip_address_last_update 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',
|
||||
|
||||
-- ========== 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" of the bucket path, not including the hostname
|
||||
private_bucket_object_name VARCHAR(255) NOT NULL,
|
||||
|
||||
-- ========== MODERATION DETAILS ==========
|
||||
|
||||
-- Mods have locked the ability for non-authors (ie. people who didn't upload this)
|
||||
-- to assign the vocoder for use with their TTS models.
|
||||
-- TTS models that already incorporate the vocoder will not be affected.
|
||||
-- The vocoder will remain visible.
|
||||
-- This is independent of other visibility controls (is_mod_disabled_from_author_use,
|
||||
-- deleted_at, and creator_set_visibility)
|
||||
is_mod_disabled_from_public_use BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Mods have locked the ability for the author (ie. the person that uploaded this)
|
||||
-- to assign the vocoder for use with their TTS models.
|
||||
-- TTS models that already incorporate the vocoder will not be affected.
|
||||
-- The vocoder will remain visible.
|
||||
-- This is independent of other visibility controls (is_mod_disabled_from_public_use,
|
||||
-- deleted_at, and creator_set_visibility)
|
||||
is_mod_disabled_from_author_use BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Extremely popular models may be locked from deletion or modification by users.
|
||||
-- If true, only moderators can edit or delete the vocoder.
|
||||
is_mod_author_editing_locked BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- If a moderator has comments.
|
||||
maybe_mod_comments VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- The last moderator that made changes.
|
||||
maybe_mod_user_token VARCHAR(32) 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 fk_creator_user_token (creator_user_token),
|
||||
KEY fk_maybe_mod_user_token (maybe_mod_user_token),
|
||||
KEY index_creator_ip_address_creation (creator_ip_address_creation),
|
||||
KEY index_creator_ip_address_last_update (creator_ip_address_last_update),
|
||||
KEY index_creator_set_visibility (creator_set_visibility),
|
||||
KEY index_private_bucket_hash (private_bucket_hash),
|
||||
KEY index_is_mod_disabled_from_public_use (is_mod_disabled_from_public_use),
|
||||
KEY index_is_mod_disabled_from_author_use (is_mod_disabled_from_author_use),
|
||||
KEY index_is_mod_author_editing_locked (is_mod_author_editing_locked)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -1,124 +0,0 @@
|
||||
-- NB: This is a manually squashed view of all the CREATE and ALTER statements,
|
||||
-- with comments attached to the fields for centralized documentation.
|
||||
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE tts_inference_jobs (
|
||||
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,
|
||||
|
||||
-- ========== SUCCESS CASE ==========
|
||||
|
||||
-- If the job completes successfully, this is the result token.
|
||||
-- This is only populated on a successful result.
|
||||
on_success_result_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- ========== INFERENCE DETAILS ==========
|
||||
|
||||
-- The model to use.
|
||||
-- This also determines which architecture we're using.
|
||||
model_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- If set, use a different pretrained vocoder.
|
||||
maybe_override_pretrained_vocoder VARCHAR(64) DEFAULT NULL,
|
||||
|
||||
-- The raw, unprocessed user input.
|
||||
raw_inference_text TEXT NOT NULL,
|
||||
|
||||
-- ========== CREATOR DETAILS ==========
|
||||
|
||||
-- Foreign key to user
|
||||
-- If no user is 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',
|
||||
|
||||
-- ========== SOURCE METADATA ==========
|
||||
|
||||
is_from_api BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_for_twitch BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- If true, the request gets routed to a special "debug" worker.
|
||||
is_debug_request BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- ========== 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',
|
||||
|
||||
-- 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 TINYINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
|
||||
-- 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,
|
||||
|
||||
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,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
UNIQUE KEY (uuid_idempotency_token),
|
||||
KEY fk_on_success_result_token (on_success_result_token),
|
||||
KEY fk_model_token (model_token),
|
||||
KEY fk_maybe_creator_user_token (maybe_creator_user_token),
|
||||
KEY index_status (status),
|
||||
KEY index_creator_ip_address (creator_ip_address),
|
||||
KEY index_is_debug_request (is_debug_request)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -1,217 +0,0 @@
|
||||
-- NB: This is a manually squashed view of all the CREATE and ALTER statements,
|
||||
-- with comments attached to the fields for centralized documentation.
|
||||
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE tts_models (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Effective "primary key" (PUBLIC)
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- NB: DO NOT CHANGE ORDER; APPEND ONLY!
|
||||
-- THIS MUST MATCH THE RESPECTIVE JOBS TABLE.
|
||||
tts_model_type ENUM(
|
||||
'not-set',
|
||||
'tacotron2',
|
||||
'glowtts',
|
||||
'glowtts-vocodes',
|
||||
'talknet'
|
||||
) NOT NULL DEFAULT 'not-set',
|
||||
|
||||
-- The name of the type of pipeline to use, eg "legacy_fakeyou", "legacy_vocodes", "english_v1", etc.
|
||||
-- New pipelines may be added at any point in the future and the source of truth for them will mostly
|
||||
-- live in the `storyteller-ml` repository.
|
||||
-- Older models and brand new models will have this field set to null, and we'll infer which value to
|
||||
-- lazily backfill based on the creation date and language setting.
|
||||
text_pipeline_type VARCHAR(64) DEFAULT NULL,
|
||||
|
||||
-- For models distributed as archives/bundles (eg. TalkNet), we can pack
|
||||
-- in a vocoder. Note that this vocoder does not have to be used.
|
||||
has_self_contained_vocoder BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- For models distributed as archives/bundles (eg. TalkNet), we can pack
|
||||
-- in a duration model.
|
||||
has_self_contained_duration_model BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- For models distributed as archives/bundles (eg. TalkNet), we can pack
|
||||
-- in a pitch model.
|
||||
has_self_contained_pitch_model BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- NB(2022-07-05): THIS IS NOW MEANINGLESS AND SUPERSEDED BY `TEXT_PIPELINE_TYPE`.
|
||||
-- NB: DO NOT CHANGE ORDER; APPEND ONLY!
|
||||
-- How text should be handled.
|
||||
text_preprocessing_algorithm ENUM(
|
||||
'basic',
|
||||
'arpabet'
|
||||
) NOT NULL DEFAULT 'basic',
|
||||
|
||||
-- If set, use a different pretrained vocoder.
|
||||
-- If not set, use the website default. (Currently HifiGan-SS)
|
||||
maybe_default_pretrained_vocoder VARCHAR(64) DEFAULT NULL,
|
||||
|
||||
-- If set, we'll use a custom vocoder (from table vocoder_models) instead of a default vocoder.
|
||||
-- If not set, we'll use `maybe_default_pretrained_vocoder` (or the website default).
|
||||
maybe_custom_vocoder_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- Optional Pointer to a newer version of the voice
|
||||
-- If there's a newer version, we can disable this one.
|
||||
-- maybe_updated_model_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- We can set as a combination of ['username' + 'voice-name']
|
||||
-- There can be public aliases for voices, eg. a voice's default model.
|
||||
-- A user can change this.
|
||||
-- As such, these should not be foreign keys.
|
||||
-- updatable_slug VARCHAR(64) NOT NULL,
|
||||
|
||||
-- Can be linked to a well-known voice
|
||||
-- maybe_subject_token VARCHAR(32) DEFAULT NULL,
|
||||
-- maybe_actor_subject_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- ========== UNSTRUCTURED METADATA ==========
|
||||
|
||||
-- The full IETF BCP47 language tag (eg. en, en-US, es-419, ja-JP, pt, etc.)
|
||||
ietf_language_tag VARCHAR(64) NOT NULL DEFAULT 'en',
|
||||
|
||||
-- The IETF BCP47 language tag's primary language subtag (eg. "es-419" becomes "es")
|
||||
ietf_primary_language_subtag VARCHAR(12) NOT NULL DEFAULT 'en',
|
||||
|
||||
-- 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,
|
||||
|
||||
-- eg. Bill Clinton, Batman, or Goku.
|
||||
voice_name VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- Optional; eg. Sean Schemmel
|
||||
actor_name VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- Optional; eg. if the voice is "happy" or a singer "a-capella", etc.
|
||||
characteristic VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- Optional; eg. if you train the model more than once.
|
||||
version_string VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- Whether the voice features on the front of FakeYou or Storyteller Twitch TTS
|
||||
is_front_page_featured BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_twitch_featured BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- A suggested bot command prefix, eg. 'sonic' that could be interpreted as '/sonic'
|
||||
-- by a TTS system. These are unique strings that can only be applied to one model at
|
||||
-- a time at most. Only moderators can set this, and it's only for the best voices.
|
||||
maybe_suggested_unique_bot_command VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- ========== 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
|
||||
creator_ip_address_creation VARCHAR(40) NOT NULL,
|
||||
creator_ip_address_last_update 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',
|
||||
|
||||
-- ========== 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,
|
||||
|
||||
-- Whether the file is a zip archive (rather than a model file).
|
||||
private_bucket_object_is_archive BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- ========== 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 have to approve of tts 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,
|
||||
|
||||
-- In this case, a moderator disables it from being used for inference.
|
||||
-- This also disables it for the creator.
|
||||
-- Unlike deletion, it remains "visible" to those that have access.
|
||||
is_locked_from_use BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- If a moderator has comments.
|
||||
maybe_mod_comments VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- The last moderator that made changes.
|
||||
maybe_mod_user_token VARCHAR(32) 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 fk_creator_user_token (creator_user_token),
|
||||
KEY fk_maybe_mod_user_token (maybe_mod_user_token),
|
||||
KEY fk_maybe_custom_vocoder_token (maybe_custom_vocoder_token),
|
||||
KEY index_creator_ip_address_creation (creator_ip_address_creation),
|
||||
KEY index_creator_ip_address_last_update (creator_ip_address_last_update),
|
||||
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),
|
||||
KEY index_is_locked_from_use (is_locked_from_use)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -0,0 +1,43 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Select TTS models within a category
|
||||
-- (NOTE CATEGORIES ARE *SOFT DELETED* AND THIS MAY MIS-ATTRIBUTE)
|
||||
select
|
||||
tts.token,
|
||||
tts.ietf_language_tag,
|
||||
tts.title
|
||||
from tts_category_assignments as cat
|
||||
join tts_models as tts
|
||||
on tts.token = cat.model_token
|
||||
where
|
||||
cat.category_token = 'CAT:n06k9gfgq20';
|
||||
|
||||
-- Select TTS models within a category
|
||||
select
|
||||
tts.token,
|
||||
tts.ietf_language_tag,
|
||||
tts.title
|
||||
from tts_category_assignments as cat
|
||||
join tts_models as tts
|
||||
on tts.token = cat.model_token
|
||||
where
|
||||
cat.category_token = 'CAT:jtdwpy6ptrn'
|
||||
AND cat.deleted_at IS NULL;
|
||||
|
||||
|
||||
-- Select TTS models within a category
|
||||
-- Exclude given languages.
|
||||
select
|
||||
tts.token,
|
||||
tts.ietf_language_tag,
|
||||
tts.title
|
||||
from tts_category_assignments as cat
|
||||
join tts_models as tts
|
||||
on tts.token = cat.model_token
|
||||
where
|
||||
cat.category_token = 'CAT:jtdwpy6ptrn'
|
||||
AND tts.ietf_language_tag NOT IN ('es', 'es-419', 'es-ES', 'es-MX')
|
||||
AND cat.deleted_at IS NULL;
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- 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
|
||||
where status = 'pending';
|
||||
|
||||
-- Total pending API jobs
|
||||
select count(*)
|
||||
from tts_inference_jobs
|
||||
where status = 'pending'
|
||||
and is_from_api = true;
|
||||
|
||||
-- Top IP addresses making requests
|
||||
select distinct creator_ip_address, count(*) as attempts
|
||||
from tts_inference_jobs
|
||||
where status = 'pending'
|
||||
group by creator_ip_address
|
||||
order by attempts desc
|
||||
limit 50;
|
||||
|
||||
-- Top voices in requests
|
||||
select distinct model_token, count(*) as attempts
|
||||
from tts_inference_jobs
|
||||
where status = 'pending'
|
||||
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,
|
||||
maybe_creator_user_token,
|
||||
raw_inference_text
|
||||
from tts_inference_jobs
|
||||
where status = 'pending';
|
||||
|
||||
-- Sample the pending inference text (truncated)
|
||||
select creator_ip_address,
|
||||
model_token,
|
||||
maybe_creator_user_token,
|
||||
TRIM(REPLACE(SUBSTRING(raw_inference_text, 1, 50), '\n', ''))
|
||||
from tts_inference_jobs
|
||||
where status = 'pending'
|
||||
limit 100;
|
||||
|
||||
-- Sample long pending texts
|
||||
select creator_ip_address,
|
||||
model_token,
|
||||
maybe_creator_user_token,
|
||||
raw_inference_text
|
||||
from tts_inference_jobs
|
||||
where status = 'pending'
|
||||
and length(raw_inference_text) > 100
|
||||
limit 100;
|
||||
|
||||
-- Delete old TTS inference jobs (1)
|
||||
DELETE FROM tts_inference_jobs
|
||||
WHERE status IN ('dead', 'complete_success', 'complete_failure')
|
||||
LIMIT 100000;
|
||||
|
||||
-- Delete old TTS inference jobs (2)
|
||||
-- Roughly 20 seconds to delete 100k, 4 minutes for 1M.
|
||||
DELETE FROM tts_inference_jobs
|
||||
WHERE created_at < ( CURDATE() - INTERVAL 1 DAY )
|
||||
LIMIT 100000;
|
||||
@@ -0,0 +1,302 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
--
|
||||
-- Top 100 models all time by use count
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.text_pipeline_type,
|
||||
m.ietf_language_tag,
|
||||
m.title,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.mod_deleted_at,
|
||||
m.created_at
|
||||
from (
|
||||
select model_token, count(*) as use_count
|
||||
from tts_results
|
||||
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
|
||||
order by r.use_count desc
|
||||
limit 100;
|
||||
|
||||
--
|
||||
-- Same, but simpler...
|
||||
--
|
||||
select m.token, m.title, r.use_count from (
|
||||
select model_token, count(*) as use_count from tts_results
|
||||
group by model_token
|
||||
order by use_count desc limit 100
|
||||
) as r
|
||||
join tts_models as m
|
||||
on m.token = r.model_token;
|
||||
|
||||
--
|
||||
-- Top 100 models by use count, last 5 days
|
||||
-- Limited due to tmux scrollback.
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.text_pipeline_type,
|
||||
m.ietf_language_tag,
|
||||
m.title,
|
||||
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 12 HOUR )
|
||||
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
|
||||
order by r.use_count desc
|
||||
limit 25;
|
||||
|
||||
--
|
||||
-- Top 20 ***NEW*** models to share in #announcements
|
||||
-- Can be scoped by creator.
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.text_pipeline_type,
|
||||
m.ietf_language_tag,
|
||||
m.title,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.mod_deleted_at,
|
||||
m.created_at
|
||||
from (
|
||||
select model_token, count(*) as use_count
|
||||
from tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 5 DAY )
|
||||
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.created_at > ( CURDATE() - INTERVAL 31 DAY )
|
||||
AND u.username IN ( 'vegito1089', 'justinjohn0306')
|
||||
order by r.use_count desc
|
||||
limit 100;
|
||||
|
||||
--
|
||||
-- Top 100 models by use count, last 5 days, not spanish, etc.
|
||||
-- Limited due to tmux scrollback.
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.text_pipeline_type,
|
||||
m.ietf_language_tag,
|
||||
m.title,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.mod_deleted_at,
|
||||
m.created_at
|
||||
from (
|
||||
select model_token, count(*) as use_count
|
||||
from tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 5 DAY )
|
||||
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 NOT IN ('es', 'es-419', 'es-ES', 'es-MX', 'pt-BR')
|
||||
order by r.use_count desc
|
||||
limit 100;
|
||||
|
||||
--
|
||||
-- Top 100 models by use count, last 5 days, in specific language.
|
||||
-- Limited due to tmux scrollback.
|
||||
--
|
||||
-- English: ('en', 'en-US', 'en-AU', 'en-CA', 'en-GB')
|
||||
-- Spanish: ('es', 'es-419', 'es-AR', 'es-CL', 'es-CO', 'es-ES', 'es-MX', 'es-PE', 'es-US')
|
||||
-- Italian: ('it', 'it-CH', 'it-IT')
|
||||
-- Portuguese: ('pt', 'pt-BR')
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.title,
|
||||
m.text_pipeline_type,
|
||||
m.ietf_language_tag,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.mod_deleted_at,
|
||||
m.created_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
|
||||
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;
|
||||
|
||||
--
|
||||
-- Most popular voices by use count over 5-day window, single language, single user.
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.title,
|
||||
m.ietf_language_tag,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.mod_deleted_at,
|
||||
m.created_at
|
||||
from (
|
||||
select model_token, count(*) as use_count
|
||||
from tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 5 DAY )
|
||||
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 NOT IN ('es', 'es-419', 'es-ES', 'es-MX', 'pt-BR')
|
||||
AND u.username = 'vegito1089'
|
||||
order by r.use_count desc
|
||||
limit 100;
|
||||
|
||||
--
|
||||
-- Most popular deleted models
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.title,
|
||||
m.ietf_language_tag,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.mod_deleted_at,
|
||||
m.created_at
|
||||
from (
|
||||
select model_token, count(*) as use_count
|
||||
from tts_results
|
||||
where model_token IN (
|
||||
select token
|
||||
from tts_models
|
||||
where
|
||||
user_deleted_at IS NOT NULL
|
||||
OR mod_deleted_at IS NOT NULL
|
||||
)
|
||||
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
|
||||
order by r.use_count desc
|
||||
limit 100;
|
||||
|
||||
--
|
||||
-- Most popular deleted models (only by users, not mods)
|
||||
-- Mod-deleted models were probably on purpose
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.title,
|
||||
m.ietf_language_tag,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.created_at
|
||||
from (
|
||||
select model_token, count(*) as use_count
|
||||
from tts_results
|
||||
where model_token IN (
|
||||
select token
|
||||
from tts_models
|
||||
where
|
||||
user_deleted_at IS NOT NULL
|
||||
)
|
||||
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
|
||||
order by r.use_count desc
|
||||
limit 100;
|
||||
|
||||
|
||||
--
|
||||
-- Models uploaded recently (to check if they use the right text_pipeline_type,
|
||||
-- vocoder -todo-, etc.)
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.title,
|
||||
m.text_pipeline_type,
|
||||
m.ietf_language_tag,
|
||||
u.username,
|
||||
r.use_count,
|
||||
m.user_deleted_at,
|
||||
m.mod_deleted_at,
|
||||
m.created_at
|
||||
from (
|
||||
select model_token, count(*) as use_count
|
||||
from tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 5 DAY )
|
||||
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
|
||||
order by m.created_at desc
|
||||
limit 100;
|
||||
|
||||
--
|
||||
-- Models deleted recently (voice actor take down)
|
||||
--
|
||||
select
|
||||
m.token,
|
||||
m.title,
|
||||
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 tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 30 DAY )
|
||||
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.mod_deleted_at > ( CURDATE() - INTERVAL 14 DAY )
|
||||
or m.user_deleted_at > ( CURDATE() - INTERVAL 14 DAY )
|
||||
order by r.use_count desc
|
||||
limit 500;
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
--
|
||||
-- Usage count in the past 24 hours
|
||||
--
|
||||
select count(*) as use_count
|
||||
from tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 1 DAY )
|
||||
|
||||
--
|
||||
-- Usage count in the past week
|
||||
--
|
||||
select count(*) as use_count
|
||||
from tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 7 DAY )
|
||||
|
||||
-- On-prem worker mix
|
||||
select count(*) as use_count
|
||||
from tts_results
|
||||
where created_at > ( CURDATE() - INTERVAL 1 MINUTE )
|
||||
and is_generated_on_prem IS TRUE
|
||||
|
||||
-- Calculate a percentage of on-prem worker capacity
|
||||
select count(*) as on_prem_count
|
||||
from (
|
||||
select is_generated_on_prem
|
||||
from tts_results
|
||||
order by id desc limit 1000
|
||||
) as sample
|
||||
where sample.is_generated_on_prem IS TRUE;
|
||||
|
||||
|
||||
-- Find TTS results for a single model
|
||||
select count(*) from tts_results
|
||||
where model_token = 'TM:ztt5s1be5tq6';
|
||||
|
||||
-- Find TTS results for a single model that are not deleted
|
||||
select count(*) from tts_results
|
||||
where model_token = 'TM:ztt5s1be5tq6'
|
||||
and mod_deleted_at is NULL;
|
||||
|
||||
-- Sample results for a single model
|
||||
select
|
||||
TRIM(REPLACE(SUBSTRING(raw_inference_text, 1, 50), '\n', ''))
|
||||
from tts_results
|
||||
where model_token='TM:yt4gfbkngsjj'
|
||||
order by id desc
|
||||
limit 150;
|
||||
|
||||
-- Search for results by eminem
|
||||
select
|
||||
token,
|
||||
created_at,
|
||||
raw_inference_text
|
||||
from tts_results
|
||||
where
|
||||
model_token IN ('TM:27fj0gsh11pd', 'TM:8h9bfjgabeer', 'TM:pdf9c1anbdjq')
|
||||
AND raw_inference_text LIKE "%rave%"
|
||||
AND raw_inference_text LIKE "%sound%"
|
||||
AND created_at > ( CURDATE() - INTERVAL 5 MONTH )
|
||||
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,
|
||||
maybe_creator_user_token,
|
||||
created_at
|
||||
FROM
|
||||
tts_results
|
||||
WHERE
|
||||
model_token = 'TM:ztt5s1be5tq6'
|
||||
AND raw_inference_text LIKE '%fakeyou%'
|
||||
|
||||
---
|
||||
-- WTF WHY IS THIS SLOW???
|
||||
SELECT
|
||||
res.id,
|
||||
model.title,
|
||||
res.raw_inference_text,
|
||||
res.maybe_creator_user_token
|
||||
FROM
|
||||
tts_results AS res
|
||||
JOIN
|
||||
tts_models as model
|
||||
ON
|
||||
res.model_token = model.token
|
||||
ORDER BY res.id
|
||||
LIMIT 10;
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- TODO: Do an analysis of voice binned by # of paying customers that use it.
|
||||
|
||||
-- The most popular models amongst paying subscribers.
|
||||
-- This should give us insight as to which models subscribers pay us for.
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT
|
||||
t.token,
|
||||
t.title,
|
||||
count(*) as use_count,
|
||||
t.text_pipeline_type,
|
||||
t.ietf_language_tag,
|
||||
t.created_at,
|
||||
t.user_deleted_at,
|
||||
t.mod_deleted_at
|
||||
FROM
|
||||
tts_inference_jobs as j
|
||||
JOIN
|
||||
tts_models as t
|
||||
ON
|
||||
t.token = j.model_token
|
||||
WHERE j.maybe_creator_user_token IN
|
||||
(
|
||||
select distinct user_token
|
||||
from user_subscriptions
|
||||
)
|
||||
AND
|
||||
j.created_at > ( CURDATE() - INTERVAL 1 DAY )
|
||||
GROUP BY t.token
|
||||
ORDER BY use_count DESC
|
||||
) as x
|
||||
WHERE
|
||||
x.use_count > 10;
|
||||
|
||||
|
||||
-- The first voice a paying customer uses
|
||||
-- TODO: List *all* of the voices a paying customer uses before they subscribe, not just the first.
|
||||
-- select first row of partially aggregate query: https://stackoverflow.com/a/73157541
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT
|
||||
t.token,
|
||||
t.title,
|
||||
count(*) as use_count,
|
||||
t.text_pipeline_type,
|
||||
t.ietf_language_tag,
|
||||
t.created_at,
|
||||
t.user_deleted_at,
|
||||
t.mod_deleted_at
|
||||
FROM tts_models AS t
|
||||
JOIN
|
||||
(
|
||||
SELECT
|
||||
model_token
|
||||
FROM (
|
||||
SELECT
|
||||
model_token,
|
||||
maybe_creator_user_token,
|
||||
row_number() over(partition by maybe_creator_user_token order by id asc) as rownum
|
||||
FROM
|
||||
tts_inference_jobs
|
||||
WHERE maybe_creator_user_token IN
|
||||
(
|
||||
select distinct user_token
|
||||
from user_subscriptions
|
||||
where created_at > (CURDATE() - INTERVAL 2 DAY)
|
||||
)
|
||||
) AS x
|
||||
WHERE rownum = 1
|
||||
ORDER BY model_token desc
|
||||
) AS y
|
||||
ON t.token = y.model_token
|
||||
GROUP BY t.token
|
||||
) AS z
|
||||
ORDER BY use_count desc
|
||||
|
||||
-- The last voice a paying customer uses
|
||||
-- select first row of partially aggregate query: https://stackoverflow.com/a/73157541
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT
|
||||
t.token,
|
||||
t.title,
|
||||
count(*) as use_count,
|
||||
t.text_pipeline_type,
|
||||
t.ietf_language_tag,
|
||||
t.created_at,
|
||||
t.user_deleted_at,
|
||||
t.mod_deleted_at
|
||||
FROM tts_models AS t
|
||||
JOIN
|
||||
(
|
||||
SELECT
|
||||
model_token
|
||||
FROM (
|
||||
SELECT
|
||||
model_token,
|
||||
maybe_creator_user_token,
|
||||
row_number() over(partition by maybe_creator_user_token order by id desc) as rownum
|
||||
FROM
|
||||
tts_inference_jobs
|
||||
WHERE maybe_creator_user_token IN
|
||||
(
|
||||
select distinct user_token
|
||||
from user_subscriptions
|
||||
)
|
||||
) AS x
|
||||
WHERE rownum = 1
|
||||
ORDER BY model_token desc
|
||||
) AS y
|
||||
ON t.token = y.model_token
|
||||
GROUP BY t.token
|
||||
) AS z
|
||||
ORDER BY use_count desc
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
|
||||
-- Number of paid users (inaccurate)
|
||||
select count(*) from users where maybe_stripe_customer_id IS NOT NULL;
|
||||
|
||||
-- Number of paid users (inaccurate)
|
||||
select count(*) from user_subscriptions;
|
||||
|
||||
-- Number of paid users
|
||||
-- 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");
|
||||
|
||||
-- ==================== TEXT TO SPEECH====================
|
||||
|
||||
-- All paid subscribers generating results in the last week
|
||||
select u.username, count(*) as use_count
|
||||
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
|
||||
where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired")
|
||||
)
|
||||
AND j.created_at > NOW() - interval 7 day
|
||||
GROUP BY u.username
|
||||
ORDER BY use_count desc
|
||||
|
||||
-- Paid subscribers generating results in the last month (with # threshold)
|
||||
select username, use_count
|
||||
FROM (
|
||||
select u.username, count(*) as use_count
|
||||
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
|
||||
where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired")
|
||||
)
|
||||
AND j.created_at > NOW() - interval 31 day
|
||||
GROUP BY u.username
|
||||
ORDER BY use_count desc
|
||||
) as t
|
||||
WHERE use_count > 10
|
||||
|
||||
-- Paid users generating results in the last month
|
||||
select u.username, count(*) as use_count
|
||||
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
|
||||
where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired")
|
||||
)
|
||||
AND j.created_at > NOW() - interval 1 day
|
||||
GROUP BY u.username
|
||||
ORDER BY use_count desc
|
||||
|
||||
-- ==================== WAV2LIP ====================
|
||||
|
||||
select u.username, count(*) as use_count
|
||||
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
|
||||
where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired")
|
||||
)
|
||||
AND j.created_at > NOW() - interval 31 day
|
||||
GROUP BY u.username
|
||||
ORDER BY use_count desc
|
||||
|
||||
select username, use_count
|
||||
FROM (
|
||||
select u.username, count(*) as use_count
|
||||
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
|
||||
where maybe_stripe_subscription_status NOT IN ("canceled", "incomplete", "incomplete_expired")
|
||||
)
|
||||
AND j.created_at > NOW() - interval 31 day
|
||||
GROUP BY u.username
|
||||
ORDER BY use_count desc
|
||||
) as t
|
||||
WHERE use_count >=5;
|
||||
|
||||
-- ==================== TTS MODELS ====================
|
||||
|
||||
select u.username, count(*) as use_count
|
||||
from users as u
|
||||
join tts_model_upload_jobs as j
|
||||
on u.token = j.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")
|
||||
)
|
||||
AND j.created_at > NOW() - interval 1 day
|
||||
GROUP BY u.username
|
||||
ORDER BY use_count desc
|
||||
|
||||
-- ==================== W2L TEMPLATES ====================
|
||||
|
||||
select u.username, count(*) as use_count
|
||||
from users as u
|
||||
join w2l_template_upload_jobs as j
|
||||
on u.token = j.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")
|
||||
)
|
||||
AND j.created_at > NOW() - interval 1 day
|
||||
GROUP BY u.username
|
||||
ORDER BY use_count desc
|
||||
@@ -0,0 +1,30 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- NB: These are for use in Stripe Sigma, not MySQL
|
||||
-- NB: You must use single quotes instead of double quotes when comparing string values.
|
||||
|
||||
-- Histogram of customers by country
|
||||
select address_country, count(*)
|
||||
from customers
|
||||
group by address_country
|
||||
|
||||
select customer_id, subscriptions.status
|
||||
from subscriptions
|
||||
|
||||
|
||||
select distinct customer_id
|
||||
from subscriptions
|
||||
where subscriptions.status = 'active'
|
||||
or subscriptions.status = 'past_due'
|
||||
|
||||
select address_country, count(*) as country_count
|
||||
from customers
|
||||
where id IN (
|
||||
select distinct customer_id
|
||||
from subscriptions
|
||||
where subscriptions.status = 'active'
|
||||
or subscriptions.status = 'past_due'
|
||||
)
|
||||
group by address_country
|
||||
@@ -0,0 +1,44 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Top TTS 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 tts_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;
|
||||
|
||||
|
||||
|
||||
-- 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
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Pending job count
|
||||
select count(*) from w2l_inference_jobs where status='pending';
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Get a count of pending jobs
|
||||
select count(*) from w2l_template_upload_jobs where status='pending';
|
||||
|
||||
-- See pending download URLs:
|
||||
select download_url from w2l_template_upload_jobs where status IN ('pending', 'started', 'attempt_failed');
|
||||
|
||||
-- See old jobs that might be stuck as "started"
|
||||
select count(*)
|
||||
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%';
|
||||
@@ -0,0 +1,238 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- NB: See the "squashed" copy of this for better documentation
|
||||
-- and the current state of the table.
|
||||
|
||||
CREATE TABLE users (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Visible "primary key"
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Username is a lookup key; display_name allows the user to add custom case.
|
||||
username VARCHAR(20) NOT NULL,
|
||||
display_name VARCHAR(20) NOT NULL,
|
||||
|
||||
email_address VARCHAR(255) NOT NULL,
|
||||
email_confirmed BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- The role assigned to the user confers permissions.
|
||||
user_role_slug VARCHAR(16) NOT NULL,
|
||||
|
||||
-- ========== CREDENTIALS ==========
|
||||
|
||||
-- Bcrypt password hash. Granted, there are newer methods:
|
||||
-- https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
||||
-- Passwords may be a max of 64 characters per BCrypt.
|
||||
password_hash BINARY(60) NOT NULL,
|
||||
|
||||
-- Incremented with every update to the password.
|
||||
password_version INT NOT NULL DEFAULT 0,
|
||||
|
||||
-- ========== ABUSE TRACKING ==========
|
||||
|
||||
-- For abuse tracking.
|
||||
-- Wide enough for IPv4/6
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
ip_address_last_login VARCHAR(40) NOT NULL,
|
||||
ip_address_last_update VARCHAR(40) NOT NULL,
|
||||
|
||||
-- ========== DISPLAY / PROFILE ==========
|
||||
|
||||
-- Gravatar image hashes are precomputed.
|
||||
email_gravatar_hash CHAR(32) NOT NULL,
|
||||
|
||||
-- The profile of the user in markdown (user editable).
|
||||
profile_markdown TEXT NOT NULL,
|
||||
|
||||
-- Generated HTML (not user-editable).
|
||||
profile_rendered_html TEXT NOT NULL,
|
||||
|
||||
-- An uploaded avatar. Public hash in our bucket.
|
||||
-- avatar_public_bucket_hash CHAR(32) DEFAULT NULL,
|
||||
|
||||
-- ========== SOCIAL MEDIA ==========
|
||||
|
||||
-- Social media usernames
|
||||
-- These are not confirmed. We'll need to build an OAuth system to handle that.
|
||||
discord_username VARCHAR(36) DEFAULT NULL,
|
||||
twitter_username VARCHAR(36) DEFAULT NULL,
|
||||
twitch_username VARCHAR(36) DEFAULT NULL,
|
||||
patreon_username VARCHAR(36) DEFAULT NULL,
|
||||
github_username VARCHAR(36) DEFAULT NULL,
|
||||
cashapp_username VARCHAR(36) DEFAULT NULL,
|
||||
website_url VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- ========== USER PREFERENCES ==========
|
||||
|
||||
-- If the user doesn't want to use gravatar and doesn't have an uploaded avatar.
|
||||
disable_gravatar BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- (THIS MIGHT NOT BE USED)
|
||||
-- NB: DO NOT SORT!
|
||||
-- THIS MUST MATCH THE RESPECTIVE JOBS TABLE.
|
||||
-- Visibility preference used at TTS inference time (which can be changed on the result itself).
|
||||
-- Moderators will still see them.
|
||||
preferred_tts_result_visibility ENUM(
|
||||
'public',
|
||||
'hidden',
|
||||
'private'
|
||||
) NOT NULL DEFAULT 'public',
|
||||
|
||||
-- (THIS MIGHT NOT BE USED)
|
||||
-- NB: DO NOT SORT!
|
||||
-- THIS MUST MATCH THE RESPECTIVE JOBS TABLE.
|
||||
-- Visibility preference used at TTS inference time (which can be changed on the result itself).
|
||||
-- Moderators will still see them.
|
||||
preferred_w2l_result_visibility ENUM(
|
||||
'public',
|
||||
'hidden',
|
||||
'private'
|
||||
) NOT NULL DEFAULT 'public',
|
||||
|
||||
-- Auto play preferences
|
||||
-- Tri-state because we want to potentially change the default behavior.
|
||||
auto_play_audio_preference BOOLEAN DEFAULT NULL,
|
||||
auto_play_video_preference BOOLEAN DEFAULT NULL,
|
||||
|
||||
-- Favorite TTS voice to use by default
|
||||
-- maybe_preferred_tts_model_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- Favorite W2L model to use by default
|
||||
-- maybe_preferred_w2l_template_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- Settings
|
||||
-- DO NOT REORDER.
|
||||
-- dark_mode_preference ENUM(
|
||||
-- 'light-mode',
|
||||
-- 'dark-mode',
|
||||
-- 'use-clock'
|
||||
-- ) NOT NULL DEFAULT 'light-mode',
|
||||
|
||||
-- ========== STATS ==========
|
||||
|
||||
-- For tracking stats.
|
||||
-- The "cached" values are updated by a background job.
|
||||
-- cached_tts_rendered_counter INT(10) NOT NULL DEFAULT 0,
|
||||
-- cached_w2l_rendered_counter INT(10) NOT NULL DEFAULT 0,
|
||||
|
||||
-- ========== MODERATION DETAILS ==========
|
||||
|
||||
-- Different than deleted.
|
||||
-- Users still show up, but can't do anything.
|
||||
is_banned BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- If a moderator has comments.
|
||||
maybe_mod_comments VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- The last moderator that made changes.
|
||||
maybe_mod_user_token VARCHAR(32) 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 the user is deleted, we set this.
|
||||
-- This is different than banned. These users won't show up at all.
|
||||
user_deleted_at TIMESTAMP NULL,
|
||||
mod_deleted_at TIMESTAMP NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
UNIQUE KEY (username),
|
||||
UNIQUE KEY (email_address),
|
||||
KEY fk_user_role_slug (user_role_slug)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
CREATE TABLE user_roles (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Effective "primary key"
|
||||
slug CHAR(16) NOT NULL,
|
||||
|
||||
name VARCHAR(255) NOT NULL,
|
||||
|
||||
-- Usage
|
||||
can_use_tts BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_use_w2l BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_tts_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_w2l_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_account BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Contribution
|
||||
can_upload_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_upload_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_own_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Moderation
|
||||
can_approve_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- Edit includes "lock_from_use" and "lock_from_modification"
|
||||
can_edit_other_users_profiles BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_edit_other_users_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_edit_other_users_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_tts_models BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_tts_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_w2l_templates BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_other_users_w2l_results BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_ban_users BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
can_delete_users BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- Incremented with every update.
|
||||
version INT 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 (slug)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
CREATE TABLE user_sessions (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Session entropy
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Foreign key to user
|
||||
user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Track each session's creation IP.
|
||||
-- Wide enough for IPv4/6
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
-- Session termination time.
|
||||
-- This must be set by the server code, or the session is invalid
|
||||
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- deletion = session termination
|
||||
-- Typically these are destroyed by users, but if in the future we allow mods to
|
||||
-- delete them, it doesn't really matter who did the deletion: sessions are not
|
||||
-- designed to be recoverable.
|
||||
deleted_at TIMESTAMP NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
KEY fk_user_token (user_token),
|
||||
KEY index_ip_address_creation (ip_address_creation)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user