createFunscript fixes
This commit is contained in:
parent
110565d536
commit
fad0d49776
@ -1,15 +0,0 @@
|
||||
# See https://caddyserver.com/docs/caddyfile for more details
|
||||
{
|
||||
admin 0.0.0.0:2020
|
||||
auto_https disable_certs
|
||||
http_port 8800
|
||||
https_port 4443
|
||||
}
|
||||
|
||||
:8082 {
|
||||
root * {$CADDY_ROOT_DIR}
|
||||
log {
|
||||
output file {$CADDY_LOG_DIR}/caddy.log
|
||||
}
|
||||
file_server
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
Hello World!
|
||||
</body>
|
||||
</html>
|
46
devbox.json
46
devbox.json
@ -1,46 +0,0 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
|
||||
"packages": [
|
||||
"nodejs@20",
|
||||
"ffmpeg@latest",
|
||||
"yt-dlp@latest",
|
||||
"lazydocker@latest",
|
||||
"chisel@latest",
|
||||
"entr@latest",
|
||||
"act@latest",
|
||||
"git-subrepo@latest",
|
||||
"opentofu@latest",
|
||||
"ggshield@latest",
|
||||
"python310@latest",
|
||||
"python310Packages.pip@latest",
|
||||
"caddy@latest"
|
||||
],
|
||||
"env": {
|
||||
"DEVBOX_COREPACK_ENABLED": "true",
|
||||
"ENV": "development",
|
||||
"KUBECONFIG": "$HOME/.kube/futureporn.yaml",
|
||||
"VENV_DIR": ".venv"
|
||||
},
|
||||
"shell": {
|
||||
"init_hook": [
|
||||
"echo Welcome to Futureporn devbox",
|
||||
". $VENV_DIR/bin/activate",
|
||||
"pip install -r requirements.txt"
|
||||
],
|
||||
"scripts": {
|
||||
"tunnel": "dotenvx run -f ./.env.development -- chisel client bright.fp.sbtp.xyz:9090 R:4000",
|
||||
"backup": "docker exec -t postgres_db pg_dumpall -c -U postgres > ./backups/dev_`date +%Y-%m-%d_%H_%M_%S`.sql",
|
||||
"act": "dotenvx run -f ./.env.testing -- act -W ./.gitea/workflows --secret-file .env.development",
|
||||
"act:builder": "dotenvx run -f ./.env.testing -- act --env-file .env.testing -W ./.gitea/workflows/builder.yaml --secret-file .env.testing --var-file .env.testing --insecure-secrets",
|
||||
"act:tests": "dotenvx run -f ./.env.testing -- act --env-file .env.testing -W ./.gitea/workflows/tests.yaml --secret-file .env.testing --var-file .env.testing --insecure-secrets",
|
||||
"bright:compile:watch": "cd ./apps/bright && find . -type f -name \"*.ex\" -o -name \"*.exs\" | entr -r mix compile --warnings-as-errors",
|
||||
"bright:compile:watch2": "cd ./apps/bright && pnpx chokidar-cli \"**/*\" -i \"deps/**\" -i \"_build/**\" -c \"mix compile --warnings-as-errors\"",
|
||||
"bright:dev": "cd ./apps/bright && dotenvx run -f ../../.env.development -e MIX_ENV=dev -- mix phx.server",
|
||||
"bright:test:unit:watch": "cd ./apps/bright && pnpx chokidar-cli '**/*' -i \"deps/**\" -i '_build/**' -c 'mix test --only=unit'",
|
||||
"bright:act": "cd ./apps/bright && act --env MIX_ENV=test -W ./.gitea/workflows/tests.yaml --secret-file .env.development",
|
||||
"test": "act -W ./.gitea/workflows/tests.yaml --secret-file .env.testing --var-file .env.testing && devbox run beep || devbox run boop",
|
||||
"beep": "ffplay -nodisp -loglevel quiet -autoexit ./apps/beep/beep2.wav",
|
||||
"boop": "ffplay -nodisp -loglevel quiet -autoexit ./apps/beep/beep1.wav"
|
||||
}
|
||||
}
|
||||
}
|
827
devbox.lock
827
devbox.lock
@ -1,827 +0,0 @@
|
||||
{
|
||||
"lockfile_version": "1",
|
||||
"packages": {
|
||||
"act@latest": {
|
||||
"last_modified": "2025-02-07T11:26:36Z",
|
||||
"resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#act",
|
||||
"source": "devbox-search",
|
||||
"version": "0.2.72",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/69mqjq6ysm38yppm5l0a68zaxfk3jsb5-act-0.2.72",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/69mqjq6ysm38yppm5l0a68zaxfk3jsb5-act-0.2.72"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/di3cp7yr4dq07byl8hm8xwnas7hn8xcn-act-0.2.72",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/di3cp7yr4dq07byl8hm8xwnas7hn8xcn-act-0.2.72"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/yblc9543pbzncgy0q4bfdj8h7nrs35am-act-0.2.72",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/yblc9543pbzncgy0q4bfdj8h7nrs35am-act-0.2.72"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/k7nqxipi81pzfdbh2a19np9q84qmgj3w-act-0.2.72",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/k7nqxipi81pzfdbh2a19np9q84qmgj3w-act-0.2.72"
|
||||
}
|
||||
}
|
||||
},
|
||||
"caddy@latest": {
|
||||
"last_modified": "2025-02-07T11:26:36Z",
|
||||
"plugin_version": "0.0.3",
|
||||
"resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#caddy",
|
||||
"source": "devbox-search",
|
||||
"version": "2.9.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/wsj8iixhs5iwjhfyy4l00va0dj301sjs-caddy-2.9.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/wsj8iixhs5iwjhfyy4l00va0dj301sjs-caddy-2.9.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/w6cg28ws2404fglmhbzddqjjkniqfiam-caddy-2.9.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/w6cg28ws2404fglmhbzddqjjkniqfiam-caddy-2.9.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/8q0lw048apajs1rg6vpfbp2p1m37f25a-caddy-2.9.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/8q0lw048apajs1rg6vpfbp2p1m37f25a-caddy-2.9.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/ax0979vnibikl5cr180lmxvb80m2zq50-caddy-2.9.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/ax0979vnibikl5cr180lmxvb80m2zq50-caddy-2.9.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chisel@latest": {
|
||||
"last_modified": "2024-12-23T21:10:33Z",
|
||||
"resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#chisel",
|
||||
"source": "devbox-search",
|
||||
"version": "1.10.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/2rls3b9lq2i3g53zpr09d6ph43mgfxwz-chisel-1.10.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/2rls3b9lq2i3g53zpr09d6ph43mgfxwz-chisel-1.10.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/7ff1z4mr0ia2ifdgggpqkbc2j795ccy4-chisel-1.10.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/7ff1z4mr0ia2ifdgggpqkbc2j795ccy4-chisel-1.10.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/2cb5sa449vpah2g4q4prvqfz1dcf1rdw-chisel-1.10.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/2cb5sa449vpah2g4q4prvqfz1dcf1rdw-chisel-1.10.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/pphc5mnhx6mb08ak6mb3rnh061427xbj-chisel-1.10.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/pphc5mnhx6mb08ak6mb3rnh061427xbj-chisel-1.10.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"entr@latest": {
|
||||
"last_modified": "2025-01-19T08:16:51Z",
|
||||
"resolved": "github:NixOS/nixpkgs/50165c4f7eb48ce82bd063e1fb8047a0f515f8ce#entr",
|
||||
"source": "devbox-search",
|
||||
"version": "5.6",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/2qbvxdg5asmjs0fjcf84mssrv5pw7apa-entr-5.6",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/2qbvxdg5asmjs0fjcf84mssrv5pw7apa-entr-5.6"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/xnhjmgv6svqp793vxhpfcvxig5yi9s60-entr-5.6",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/xnhjmgv6svqp793vxhpfcvxig5yi9s60-entr-5.6"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/fknw34xxmp239x81r201drmlm3g9p1bb-entr-5.6",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/fknw34xxmp239x81r201drmlm3g9p1bb-entr-5.6"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/yy1d68xcy847axfmb5xws2271xkf61xk-entr-5.6",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/yy1d68xcy847axfmb5xws2271xkf61xk-entr-5.6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ffmpeg@latest": {
|
||||
"last_modified": "2025-01-07T09:15:50Z",
|
||||
"resolved": "github:NixOS/nixpkgs/8c9fd3e564728e90829ee7dbac6edc972971cd0f#ffmpeg",
|
||||
"source": "devbox-search",
|
||||
"version": "7.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "bin",
|
||||
"path": "/nix/store/m48ypyjnl04mqigi6fbxa7k2c5bsvazz-ffmpeg-7.1-bin",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/10ncvfz8srnzckq16bn14wffcx8j04ki-ffmpeg-7.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"path": "/nix/store/rqbsc9zyzi988hwcd423qdh1vh40zlzc-ffmpeg-7.1-data"
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/6ml3pn92nbmnc40s5jfpr84y65ysizk3-ffmpeg-7.1-dev"
|
||||
},
|
||||
{
|
||||
"name": "doc",
|
||||
"path": "/nix/store/ni6gri7m1pavfjxx0yfj1msvb0cfasgg-ffmpeg-7.1-doc"
|
||||
},
|
||||
{
|
||||
"name": "lib",
|
||||
"path": "/nix/store/2v2rr9dmq4grzwmg4zcsxrmbdcshks7m-ffmpeg-7.1-lib"
|
||||
},
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/nvccyp4dra8f92ywd00lk3ra121gj162-ffmpeg-7.1"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/m48ypyjnl04mqigi6fbxa7k2c5bsvazz-ffmpeg-7.1-bin"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "bin",
|
||||
"path": "/nix/store/lj99z3ldzka2slgm94w2yl8cjkphn4m3-ffmpeg-7.1-bin",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/gisda8d2pifrrjw0yirrs0x2cyn6b96i-ffmpeg-7.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/pc332zx12j2fqf5m9mdhhs1rwksbk2fk-ffmpeg-7.1"
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"path": "/nix/store/4yhsn6lrfn91dk1kq9wyyd71p4hcfans-ffmpeg-7.1-data"
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/71103mmkxhzzmbj9mpzsrzbp988z3p98-ffmpeg-7.1-dev"
|
||||
},
|
||||
{
|
||||
"name": "doc",
|
||||
"path": "/nix/store/k9cc4d60frcn27zapkzhag5h9r0ig5xa-ffmpeg-7.1-doc"
|
||||
},
|
||||
{
|
||||
"name": "lib",
|
||||
"path": "/nix/store/dgcmpc8az51a4d2bxgrmfz8zlmvqxwa5-ffmpeg-7.1-lib"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/lj99z3ldzka2slgm94w2yl8cjkphn4m3-ffmpeg-7.1-bin"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "bin",
|
||||
"path": "/nix/store/z44kr817zx99vi2cc204i06cnmz83f1n-ffmpeg-7.1-bin",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/slrha22nqrx2xw009hd37svv2nvpp26i-ffmpeg-7.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"path": "/nix/store/n3xm2rr1k1ari7ysbp9jhg65pih28x6x-ffmpeg-7.1-data"
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/59gcv4rfg38rqnazv1iq9jssjak2l3ih-ffmpeg-7.1-dev"
|
||||
},
|
||||
{
|
||||
"name": "doc",
|
||||
"path": "/nix/store/2cqa3lc75ciqzgmxjm36fd733f3gjgil-ffmpeg-7.1-doc"
|
||||
},
|
||||
{
|
||||
"name": "lib",
|
||||
"path": "/nix/store/ir47x8skj54wilcyz2x59am4y085lf6l-ffmpeg-7.1-lib"
|
||||
},
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/gqw958wdgrbfsxczqf56vnq1iffg5qv1-ffmpeg-7.1"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/z44kr817zx99vi2cc204i06cnmz83f1n-ffmpeg-7.1-bin"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "bin",
|
||||
"path": "/nix/store/d1lv3x7iq129vb19ba9ph6k0yhy4fv34-ffmpeg-7.1-bin",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/qqgvvfw2gqp47zl5v9jhdsl8mb77l909-ffmpeg-7.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "doc",
|
||||
"path": "/nix/store/gmfj9af6za9i2830cgbj1qazz2nir2vs-ffmpeg-7.1-doc"
|
||||
},
|
||||
{
|
||||
"name": "lib",
|
||||
"path": "/nix/store/x8j2nr5qmikfaggl34wpm1dlldb7ik06-ffmpeg-7.1-lib"
|
||||
},
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/cx89mypnxgk0q4dibacg7dsrb4w66mv9-ffmpeg-7.1"
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"path": "/nix/store/5y8zk8fqpaammsnz2svgpdsayn4zlsn2-ffmpeg-7.1-data"
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/qdz8aidi7rksr4g5cpxgz9iivrlsa247-ffmpeg-7.1-dev"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/d1lv3x7iq129vb19ba9ph6k0yhy4fv34-ffmpeg-7.1-bin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ggshield@latest": {
|
||||
"last_modified": "2025-02-27T15:48:43Z",
|
||||
"resolved": "github:NixOS/nixpkgs/6c5c5f5100281f8f4ff23f13edd17d645178c87c#ggshield",
|
||||
"source": "devbox-search",
|
||||
"version": "1.36.0",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/2qsc4iii58gq54l8dys7m4jw5lz0xqk0-ggshield-1.36.0",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/1zic4rm52c81303axs6jwpv9i5cbpgpf-ggshield-1.36.0-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/2qsc4iii58gq54l8dys7m4jw5lz0xqk0-ggshield-1.36.0"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/l9inx1qgmjm9hiz1fncxx15mkyqw9abc-ggshield-1.36.0",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/1hls55sak8fi14s6wq4ar5iiwvmzpw68-ggshield-1.36.0-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/l9inx1qgmjm9hiz1fncxx15mkyqw9abc-ggshield-1.36.0"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/n2s11c74rlq64w78rnnnz5j8dz72fnvs-ggshield-1.36.0",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/9k2svwlyx8s2ac6dnhc3sq5c3bvlyrvw-ggshield-1.36.0-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/n2s11c74rlq64w78rnnnz5j8dz72fnvs-ggshield-1.36.0"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/pz8s8n5qrmhfivj51932s5gqwh64c7fy-ggshield-1.36.0",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/i29ambqhmnizdxk9njgsyza953m5mbmn-ggshield-1.36.0-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/pz8s8n5qrmhfivj51932s5gqwh64c7fy-ggshield-1.36.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"git-subrepo@latest": {
|
||||
"last_modified": "2025-02-07T11:26:36Z",
|
||||
"resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#git-subrepo",
|
||||
"source": "devbox-search",
|
||||
"version": "0.4.9",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/iagwf8k53inahcs16by5l7vzffbs01k4-git-subrepo-0.4.9",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/iagwf8k53inahcs16by5l7vzffbs01k4-git-subrepo-0.4.9"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/vn5qc1h596hj3s7qw1q75wzh8n8lw3im-git-subrepo-0.4.9",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/vn5qc1h596hj3s7qw1q75wzh8n8lw3im-git-subrepo-0.4.9"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/pxhc909zdsd1jxamzy762xhvvdh0lb5a-git-subrepo-0.4.9",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/pxhc909zdsd1jxamzy762xhvvdh0lb5a-git-subrepo-0.4.9"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/psy4x285pc5dk3z69gzwq7rafdhpjv5x-git-subrepo-0.4.9",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/psy4x285pc5dk3z69gzwq7rafdhpjv5x-git-subrepo-0.4.9"
|
||||
}
|
||||
}
|
||||
},
|
||||
"github:NixOS/nixpkgs/nixpkgs-unstable": {
|
||||
"resolved": "github:NixOS/nixpkgs/ba0939c506a03c60a765cd7f7c43794816540eec?lastModified=1739482815&narHash=sha256-%2F5Lwtmp%2F8j%2Bro32gXzitucSdyjJ6QehfJCL58WNA7N0%3D"
|
||||
},
|
||||
"lazydocker@latest": {
|
||||
"last_modified": "2024-12-23T21:10:33Z",
|
||||
"resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#lazydocker",
|
||||
"source": "devbox-search",
|
||||
"version": "0.24.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/5hv519gz95pwhg4vr9ka8g98bdd91mvx-lazydocker-0.24.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/5hv519gz95pwhg4vr9ka8g98bdd91mvx-lazydocker-0.24.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/5wb57rjn6xwyf4nc0mifgjd934i545ph-lazydocker-0.24.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/5wb57rjn6xwyf4nc0mifgjd934i545ph-lazydocker-0.24.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/bj056q5lmy3dx6xafwlmvhjqgxjr3awq-lazydocker-0.24.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/bj056q5lmy3dx6xafwlmvhjqgxjr3awq-lazydocker-0.24.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/4gwbhlb13pvdbxcb31mslkgd6pr62gyk-lazydocker-0.24.1",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/4gwbhlb13pvdbxcb31mslkgd6pr62gyk-lazydocker-0.24.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nodejs@20": {
|
||||
"last_modified": "2024-12-23T21:10:33Z",
|
||||
"plugin_version": "0.0.2",
|
||||
"resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#nodejs_20",
|
||||
"source": "devbox-search",
|
||||
"version": "20.18.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/q49zbi0pzjhg4zn085h9hyz9m1k3hvpb-nodejs-20.18.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "libv8",
|
||||
"path": "/nix/store/l08rljd2yr7i1q4x778qazcys2l4ja23-nodejs-20.18.1-libv8"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/q49zbi0pzjhg4zn085h9hyz9m1k3hvpb-nodejs-20.18.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/4m1ql1hsd6kqmzr8a657qhipjgssrr0c-nodejs-20.18.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "libv8",
|
||||
"path": "/nix/store/r8s1xalb4rpy1r44i413j84i4ny6mnsc-nodejs-20.18.1-libv8"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/4m1ql1hsd6kqmzr8a657qhipjgssrr0c-nodejs-20.18.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/7ky0mn6k33731jwzhsxq6a6dsbjqamqs-nodejs-20.18.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "libv8",
|
||||
"path": "/nix/store/jw62k3wxl38r8fcbvxaxrm696ivv3imr-nodejs-20.18.1-libv8"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/7ky0mn6k33731jwzhsxq6a6dsbjqamqs-nodejs-20.18.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/j7dx1n6m5axf9r2bvly580x2ixx546wq-nodejs-20.18.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "libv8",
|
||||
"path": "/nix/store/qljmc2skrldj0g94rib6nl4jq84193fa-nodejs-20.18.1-libv8"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/j7dx1n6m5axf9r2bvly580x2ixx546wq-nodejs-20.18.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"opentofu@latest": {
|
||||
"last_modified": "2025-02-07T11:26:36Z",
|
||||
"resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#opentofu",
|
||||
"source": "devbox-search",
|
||||
"version": "1.9.0",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/bk8lbpai9gckl24971cd7sy86nx65vqp-opentofu-1.9.0",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/bk8lbpai9gckl24971cd7sy86nx65vqp-opentofu-1.9.0"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/k56jwj34f3qj0j0q7rsqsnzcvjm83xfb-opentofu-1.9.0",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/k56jwj34f3qj0j0q7rsqsnzcvjm83xfb-opentofu-1.9.0"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/q8a4niqvlph0gbch407q19v444qyflpi-opentofu-1.9.0",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/q8a4niqvlph0gbch407q19v444qyflpi-opentofu-1.9.0"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/1gc7dl8bcrks1y98qlblr08aly4b3qry-opentofu-1.9.0",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/1gc7dl8bcrks1y98qlblr08aly4b3qry-opentofu-1.9.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"python310@latest": {
|
||||
"last_modified": "2025-02-07T11:26:36Z",
|
||||
"plugin_version": "0.0.4",
|
||||
"resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#python310",
|
||||
"source": "devbox-search",
|
||||
"version": "3.10.16",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/n3bv4blh1n8xcswpn23d8rkdf19z1z67-python3-3.10.16",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/n3bv4blh1n8xcswpn23d8rkdf19z1z67-python3-3.10.16"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/wdkg0yc6h9fwvvqwh3zss1a2rz4mrmgl-python3-3.10.16",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"path": "/nix/store/wxnpshdg4kbdmpl44qnqx29i0pszsa7f-python3-3.10.16-debug"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/wdkg0yc6h9fwvvqwh3zss1a2rz4mrmgl-python3-3.10.16"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/40lamqbgh1g2x9mml635n329h4gh1928-python3-3.10.16",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/40lamqbgh1g2x9mml635n329h4gh1928-python3-3.10.16"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/8757y4bf8d77z7c3pjz1nlwi2xlkk93h-python3-3.10.16",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"path": "/nix/store/4rj9krr4hgv14rjlsrlajksi580fg4np-python3-3.10.16-debug"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/8757y4bf8d77z7c3pjz1nlwi2xlkk93h-python3-3.10.16"
|
||||
}
|
||||
}
|
||||
},
|
||||
"python310Packages.pip@latest": {
|
||||
"last_modified": "2023-12-13T22:54:10Z",
|
||||
"resolved": "github:NixOS/nixpkgs/fd04bea4cbf76f86f244b9e2549fca066db8ddff#python310Packages.pip",
|
||||
"source": "devbox-search",
|
||||
"version": "23.2.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/vjyrxbxqsadvr9g6mzig6y406dhwcrqi-python3.10-pip-23.2.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/2ra46imgas5srgxx8mgs424akh5j1msv-python3.10-pip-23.2.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/xjj6xjh21k08rkyg6hnkbyrygqhqgn8y-python3.10-pip-23.2.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/vjyrxbxqsadvr9g6mzig6y406dhwcrqi-python3.10-pip-23.2.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/j8pxwv7vyjm8z2fqglijjvabbkmxbv9r-python3.10-pip-23.2.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/bcfliw00z123ddyi8hsfxvfn2npdcpdq-python3.10-pip-23.2.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/2326b2sr9p2z9bsghd2pzs346g2qjn7f-python3.10-pip-23.2.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/j8pxwv7vyjm8z2fqglijjvabbkmxbv9r-python3.10-pip-23.2.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/7lyvqf8wl47wzgsqmlcz39ycmwxyg9zx-python3.10-pip-23.2.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/0j02s5hbsdhfxvvay5dm9j68nhalm39v-python3.10-pip-23.2.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/8dvqh9ai83lqaaixs3bhmf1n4jxgp4v7-python3.10-pip-23.2.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/7lyvqf8wl47wzgsqmlcz39ycmwxyg9zx-python3.10-pip-23.2.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/gdhvfi5zaqzpa5l3kk0spmv71r549slf-python3.10-pip-23.2.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "man",
|
||||
"path": "/nix/store/p37y2fhm6l3nd624jmr2r680wf4p0544-python3.10-pip-23.2.1-man",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/r4qj7psryk532rkh0srhn25ygv8yk541-python3.10-pip-23.2.1-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/gdhvfi5zaqzpa5l3kk0spmv71r549slf-python3.10-pip-23.2.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"yt-dlp@latest": {
|
||||
"last_modified": "2025-01-03T14:51:55Z",
|
||||
"resolved": "github:NixOS/nixpkgs/a27871180d30ebee8aa6b11bf7fef8a52f024733#yt-dlp",
|
||||
"source": "devbox-search",
|
||||
"version": "2024.12.23",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/8fmy039278i7q31zyyrfmr4z5k35xvp6-yt-dlp-2024.12.23",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/v9mplambvs7hlcpcpnvmf7c30pk5cx8d-yt-dlp-2024.12.23-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/8fmy039278i7q31zyyrfmr4z5k35xvp6-yt-dlp-2024.12.23"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/wzna2q40a81qj4icma4q20q9fjg9md76-yt-dlp-2024.12.23",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/z0b0nv6a2wl0565f5ffrzhg2zcqflvrl-yt-dlp-2024.12.23-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/wzna2q40a81qj4icma4q20q9fjg9md76-yt-dlp-2024.12.23"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/mpbp9jar45hk22ddldm0bbk60vz5w643-yt-dlp-2024.12.23",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/gq4l9yfs7fjb05qkl97hmsq69s3k4shr-yt-dlp-2024.12.23-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/mpbp9jar45hk22ddldm0bbk60vz5w643-yt-dlp-2024.12.23"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/wqcs5crm36p603fkh9j2k868zzb8q79c-yt-dlp-2024.12.23",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/j452c5bii2slx1biix7lfc5k0aqg2rvs-yt-dlp-2024.12.23-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/wqcs5crm36p603fkh9j2k868zzb8q79c-yt-dlp-2024.12.23"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,12 +10,12 @@
|
||||
"keywords": [],
|
||||
"author": "@CJ_Clippy",
|
||||
"license": "Unlicense",
|
||||
"packageManager": "pnpm@9.6.0",
|
||||
"dependencies": {
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"types": "^0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.2.2"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad"
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
runs
|
||||
requirements.txt
|
||||
venv
|
||||
src/test
|
||||
|
||||
node_modules
|
||||
|
2
services/our/.gitignore
vendored
2
services/our/.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
runs
|
||||
venv
|
||||
vibeui
|
||||
|
||||
generated
|
||||
|
@ -58,6 +58,7 @@
|
||||
"@types/node": "^22.16.3",
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"cache-manager": "^7.0.1",
|
||||
"canvas": "^3.1.2",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"concurrently": "^9.2.0",
|
||||
"date-fns": "^4.1.0",
|
||||
@ -77,6 +78,7 @@
|
||||
"nanoid": "^5.1.5",
|
||||
"node-fetch": "^3.3.2",
|
||||
"onnxruntime-node": "1.22.0-rev",
|
||||
"protobufjs": "^7.5.3",
|
||||
"rate-limiter-flexible": "^7.1.1",
|
||||
"rimraf": "6.0.1",
|
||||
"sharp": "^0.34.3",
|
||||
|
97
services/our/pnpm-lock.yaml
generated
97
services/our/pnpm-lock.yaml
generated
@ -71,6 +71,9 @@ importers:
|
||||
cache-manager:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1
|
||||
canvas:
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2
|
||||
chokidar-cli:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
@ -128,6 +131,9 @@ importers:
|
||||
onnxruntime-node:
|
||||
specifier: 1.22.0-rev
|
||||
version: 1.22.0-rev
|
||||
protobufjs:
|
||||
specifier: ^7.5.3
|
||||
version: 7.5.3
|
||||
rate-limiter-flexible:
|
||||
specifier: ^7.1.1
|
||||
version: 7.1.1
|
||||
@ -956,6 +962,36 @@ packages:
|
||||
'@prisma/get-platform@6.8.2':
|
||||
resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==}
|
||||
|
||||
'@protobufjs/aspromise@1.1.2':
|
||||
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
|
||||
|
||||
'@protobufjs/base64@1.1.2':
|
||||
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
|
||||
|
||||
'@protobufjs/codegen@2.0.4':
|
||||
resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
|
||||
|
||||
'@protobufjs/eventemitter@1.1.0':
|
||||
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
|
||||
|
||||
'@protobufjs/fetch@1.1.0':
|
||||
resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
|
||||
|
||||
'@protobufjs/float@1.0.2':
|
||||
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
|
||||
|
||||
'@protobufjs/inquire@1.1.0':
|
||||
resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
|
||||
|
||||
'@protobufjs/path@1.1.2':
|
||||
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
|
||||
|
||||
'@protobufjs/pool@1.1.0':
|
||||
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
|
||||
|
||||
'@protobufjs/utf8@1.1.0':
|
||||
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.45.1':
|
||||
resolution: {integrity: sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==}
|
||||
cpu: [arm]
|
||||
@ -1640,6 +1676,10 @@ packages:
|
||||
canvas-renderer@2.2.1:
|
||||
resolution: {integrity: sha512-RrBgVL5qCEDIXpJ6NrzyRNoTnXxYarqm/cS/W6ERhUJts5UQtt/XPEosGN3rqUkZ4fjBArlnCbsISJ+KCFnIAg==}
|
||||
|
||||
canvas@3.1.2:
|
||||
resolution: {integrity: sha512-Z/tzFAcBzoCvJlOSlCnoekh1Gu8YMn0J51+UAuXJAbW1Z6I9l2mZgdD7738MepoeeIcUdDtbMnOg6cC7GJxy/g==}
|
||||
engines: {node: ^18.12.0 || >= 20.9.0}
|
||||
|
||||
chai@5.2.1:
|
||||
resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==}
|
||||
engines: {node: '>=18'}
|
||||
@ -2427,6 +2467,9 @@ packages:
|
||||
lodash@4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
|
||||
long@5.3.2:
|
||||
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
|
||||
|
||||
loupe@3.1.4:
|
||||
resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==}
|
||||
|
||||
@ -2563,6 +2606,9 @@ packages:
|
||||
node-addon-api@6.1.0:
|
||||
resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==}
|
||||
|
||||
node-addon-api@7.1.1:
|
||||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||
|
||||
node-addon-api@8.5.0:
|
||||
resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==}
|
||||
engines: {node: ^18 || ^20 || >= 21}
|
||||
@ -2868,6 +2914,10 @@ packages:
|
||||
process-warning@5.0.0:
|
||||
resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==}
|
||||
|
||||
protobufjs@7.5.3:
|
||||
resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
pstree.remy@1.1.8:
|
||||
resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
|
||||
|
||||
@ -4645,6 +4695,29 @@ snapshots:
|
||||
dependencies:
|
||||
'@prisma/debug': 6.8.2
|
||||
|
||||
'@protobufjs/aspromise@1.1.2': {}
|
||||
|
||||
'@protobufjs/base64@1.1.2': {}
|
||||
|
||||
'@protobufjs/codegen@2.0.4': {}
|
||||
|
||||
'@protobufjs/eventemitter@1.1.0': {}
|
||||
|
||||
'@protobufjs/fetch@1.1.0':
|
||||
dependencies:
|
||||
'@protobufjs/aspromise': 1.1.2
|
||||
'@protobufjs/inquire': 1.1.0
|
||||
|
||||
'@protobufjs/float@1.0.2': {}
|
||||
|
||||
'@protobufjs/inquire@1.1.0': {}
|
||||
|
||||
'@protobufjs/path@1.1.2': {}
|
||||
|
||||
'@protobufjs/pool@1.1.0': {}
|
||||
|
||||
'@protobufjs/utf8@1.1.0': {}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.45.1':
|
||||
optional: true
|
||||
|
||||
@ -5422,6 +5495,11 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 22.16.4
|
||||
|
||||
canvas@3.1.2:
|
||||
dependencies:
|
||||
node-addon-api: 7.1.1
|
||||
prebuild-install: 7.1.3
|
||||
|
||||
chai@5.2.1:
|
||||
dependencies:
|
||||
assertion-error: 2.0.1
|
||||
@ -6289,6 +6367,8 @@ snapshots:
|
||||
|
||||
lodash@4.17.21: {}
|
||||
|
||||
long@5.3.2: {}
|
||||
|
||||
loupe@3.1.4: {}
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
@ -6396,6 +6476,8 @@ snapshots:
|
||||
|
||||
node-addon-api@6.1.0: {}
|
||||
|
||||
node-addon-api@7.1.1: {}
|
||||
|
||||
node-addon-api@8.5.0: {}
|
||||
|
||||
node-domexception@1.0.0: {}
|
||||
@ -6686,6 +6768,21 @@ snapshots:
|
||||
|
||||
process-warning@5.0.0: {}
|
||||
|
||||
protobufjs@7.5.3:
|
||||
dependencies:
|
||||
'@protobufjs/aspromise': 1.1.2
|
||||
'@protobufjs/base64': 1.1.2
|
||||
'@protobufjs/codegen': 2.0.4
|
||||
'@protobufjs/eventemitter': 1.1.0
|
||||
'@protobufjs/fetch': 1.1.0
|
||||
'@protobufjs/float': 1.0.2
|
||||
'@protobufjs/inquire': 1.1.0
|
||||
'@protobufjs/path': 1.1.2
|
||||
'@protobufjs/pool': 1.1.0
|
||||
'@protobufjs/utf8': 1.1.0
|
||||
'@types/node': 22.16.4
|
||||
long: 5.3.2
|
||||
|
||||
pstree.remy@1.1.8: {}
|
||||
|
||||
pump@3.0.3:
|
||||
|
1
services/our/requirements.txt
Normal file
1
services/our/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
ultralytics
|
@ -8,6 +8,7 @@ dotenvx.config({ path: ['../../.env.development'] })
|
||||
|
||||
const EnvSchema = z.object({
|
||||
NODE_ENV: z.enum(['development', 'production', 'test']),
|
||||
VENV: z.string(),
|
||||
PORT: z.coerce.number().default(3000),
|
||||
DATABASE_URL: z.string().url(),
|
||||
ORIGIN: z.string(),
|
||||
@ -27,6 +28,7 @@ const EnvSchema = z.object({
|
||||
CDN_TOKEN_SECRET: z.string(),
|
||||
CACHE_ROOT: z.string().default('/tmp/our'),
|
||||
VIBEUI_DIR: z.string().default('/opt/futureporn/apps/vibeui'),
|
||||
APP_DIR: z.string().default('/app')
|
||||
});
|
||||
|
||||
const parsed = EnvSchema.safeParse(process.env);
|
||||
|
@ -60,48 +60,48 @@ async function loadDataYaml(yamlPath: string): Promise<DataYaml> {
|
||||
}
|
||||
|
||||
|
||||
// async function preparePython(helpers) {
|
||||
// const spawn = await getNanoSpawn();
|
||||
// const venvPath = join(env.VIBEUI_DIR, "venv");
|
||||
async function preparePython(helpers) {
|
||||
const spawn = await getNanoSpawn();
|
||||
const venvPath = join(env.VIBEUI_DIR, "venv");
|
||||
|
||||
// // Determine Python executable
|
||||
// let pythonCmd;
|
||||
// try {
|
||||
// pythonCmd = which.sync("python3");
|
||||
// } catch {
|
||||
// helpers.logger.error("Python is not installed or not in PATH.");
|
||||
// throw new Error("Python not found in PATH.");
|
||||
// }
|
||||
// Determine Python executable
|
||||
let pythonCmd;
|
||||
try {
|
||||
pythonCmd = which.sync("python3");
|
||||
} catch {
|
||||
helpers.logger.error("Python is not installed or not in PATH.");
|
||||
throw new Error("Python not found in PATH.");
|
||||
}
|
||||
|
||||
// // If venv doesn't exist, create it
|
||||
// if (!existsSync(venvPath)) {
|
||||
// helpers.logger.info("Python venv not found. Creating one...");
|
||||
// If venv doesn't exist, create it
|
||||
if (!existsSync(venvPath)) {
|
||||
helpers.logger.info("Python venv not found. Creating one...");
|
||||
|
||||
// try {
|
||||
// await spawn(pythonCmd, ["-m", "venv", "venv"], {
|
||||
// cwd: env.VIBEUI_DIR,
|
||||
// });
|
||||
try {
|
||||
await spawn(pythonCmd, ["-m", "venv", "venv"], {
|
||||
cwd: env.VIBEUI_DIR,
|
||||
});
|
||||
|
||||
// helpers.logger.info("Python venv successfully created.");
|
||||
// } catch (err) {
|
||||
// helpers.logger.error("Failed to create Python venv:", err);
|
||||
helpers.logger.info("Python venv successfully created.");
|
||||
} catch (err) {
|
||||
helpers.logger.error("Failed to create Python venv:", err);
|
||||
|
||||
// // Clean up partially created venv if needed
|
||||
// try {
|
||||
// if (existsSync(venvPath)) {
|
||||
// rmSync(venvPath, { recursive: true, force: true });
|
||||
// helpers.logger.warn("Removed broken venv directory.");
|
||||
// }
|
||||
// } catch (cleanupErr) {
|
||||
// helpers.logger.error("Error while cleaning up broken venv:", cleanupErr);
|
||||
// }
|
||||
// Clean up partially created venv if needed
|
||||
try {
|
||||
if (existsSync(venvPath)) {
|
||||
rmSync(venvPath, { recursive: true, force: true });
|
||||
helpers.logger.warn("Removed broken venv directory.");
|
||||
}
|
||||
} catch (cleanupErr) {
|
||||
helpers.logger.error("Error while cleaning up broken venv:", cleanupErr);
|
||||
}
|
||||
|
||||
// throw new Error("Python venv creation failed. Check if python3 and python3-venv are installed.");
|
||||
// }
|
||||
// } else {
|
||||
// helpers.logger.info("Using existing Python venv.");
|
||||
// }
|
||||
// }
|
||||
throw new Error("Python venv creation failed. Check if python3 and python3-venv are installed.");
|
||||
}
|
||||
} else {
|
||||
helpers.logger.info("Using existing Python venv.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function ffprobe(videoPath: string): Promise<{ fps: number; frames: number }> {
|
@ -1,18 +1,54 @@
|
||||
|
||||
import type { Task, Helpers } from "graphile-worker";
|
||||
import { PrismaClient } from "../../generated/prisma";
|
||||
import { withAccelerate } from "@prisma/extension-accelerate";
|
||||
import { getOrDownloadAsset } from "../utils/cache";
|
||||
import { env } from "../config/env";
|
||||
import { getS3Client, uploadFile } from "../utils/s3";
|
||||
import { buildFunscript } from '../utils/funscripts';
|
||||
import { vibeuiInference } from "../utils/vibeui";
|
||||
import { join } from "node:path";
|
||||
import { nanoid } from "nanoid";
|
||||
import { existsSync, rmSync } from "node:fs";
|
||||
import { join, basename, extname } from "node:path";
|
||||
import { readFile, writeFile, readdir } from 'node:fs/promises';
|
||||
import yaml from 'js-yaml';
|
||||
import { getNanoSpawn } from "../utils/nanoSpawn";
|
||||
import which from "which";
|
||||
import * as ort from 'onnxruntime-node';
|
||||
import { inference, loadDataYaml } from "../utils/vibeui";
|
||||
import { ffprobe } from "../utils/vibeui";
|
||||
import { preparePython } from "../utils/python";
|
||||
import { generateActions2, buildFunscript } from "../utils/funscripts";
|
||||
|
||||
|
||||
interface Payload {
|
||||
vodId: string;
|
||||
}
|
||||
|
||||
// interface Detection {
|
||||
// startFrame: number;
|
||||
// endFrame: number;
|
||||
// className: string;
|
||||
// }
|
||||
|
||||
// interface DataYaml {
|
||||
// path: string;
|
||||
// train: string;
|
||||
// val: string;
|
||||
// names: Record<string, string>;
|
||||
// }
|
||||
|
||||
// interface FunscriptAction {
|
||||
// at: number;
|
||||
// pos: number;
|
||||
// }
|
||||
|
||||
// interface Funscript {
|
||||
// version: string;
|
||||
// actions: FunscriptAction[];
|
||||
// }
|
||||
|
||||
|
||||
// interface ClassPositionMap {
|
||||
// [className: string]: number | 'pattern';
|
||||
// }
|
||||
|
||||
|
||||
const prisma = new PrismaClient().$extends(withAccelerate());
|
||||
@ -24,6 +60,209 @@ function assertPayload(payload: any): asserts payload is Payload {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// export async function buildFunscript(
|
||||
// helpers: Helpers,
|
||||
// predictionOutput: string,
|
||||
// videoPath: string
|
||||
// ): Promise<string> {
|
||||
// const labelDir = join(predictionOutput, 'labels');
|
||||
// const yamlPath = join(predictionOutput, 'data.yaml');
|
||||
// const outputPath = join(process.env.CACHE_ROOT ?? '/tmp', `${nanoid()}.funscript`);
|
||||
// helpers.logger.info('Starting Funscript generation');
|
||||
|
||||
// try {
|
||||
|
||||
// const data = await loadDataYaml(join(env.VIBEUI_DIR, 'data.yaml'))
|
||||
// const classPositionMap = await loadClassPositionMap(data, helpers);
|
||||
// const { fps, totalFrames } = await loadVideoMetadata(videoPath, helpers);
|
||||
// const detectionSegments = await processLabelFiles(labelDir, helpers, data);
|
||||
// const totalDurationMs = Math.floor((totalFrames / fps) * 1000);
|
||||
// const actions = generateActions2(totalDurationMs, fps, detectionSegments, classPositionMap);
|
||||
// await writeFunscript(outputPath, actions, helpers);
|
||||
|
||||
// return outputPath;
|
||||
// } catch (error) {
|
||||
// helpers.logger.error(`Error generating Funscript: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
// throw error;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// async function loadClassPositionMap(data: DataYaml, helpers: Helpers): Promise<ClassPositionMap> {
|
||||
// try {
|
||||
|
||||
// if (
|
||||
// !data ||
|
||||
// typeof data !== 'object' ||
|
||||
// !('names' in data) ||
|
||||
// typeof data.names !== 'object' ||
|
||||
// data.names === null ||
|
||||
// Object.keys(data.names).length === 0
|
||||
// ) {
|
||||
// throw new Error('Invalid data.yaml: "names" field is missing, not an object, or empty');
|
||||
// }
|
||||
|
||||
// const positionMap: ClassPositionMap = {
|
||||
// ControlledByTipper: 50,
|
||||
// ControlledByTipperHigh: 80,
|
||||
// ControlledByTipperLow: 20,
|
||||
// ControlledByTipperMedium: 50,
|
||||
// ControlledByTipperUltrahigh: 95,
|
||||
// Ring1: 30,
|
||||
// Ring2: 40,
|
||||
// Ring3: 50,
|
||||
// Ring4: 60,
|
||||
// Earthquake: 'pattern',
|
||||
// Fireworks: 'pattern',
|
||||
// Pulse: 'pattern',
|
||||
// Wave: 'pattern',
|
||||
// Pause: 0,
|
||||
// RandomTime: 70,
|
||||
// HighLevel: 80,
|
||||
// LowLevel: 20,
|
||||
// MediumLevel: 50,
|
||||
// UltraHighLevel: 95
|
||||
// };
|
||||
|
||||
// const names = Object.values(data.names);
|
||||
// for (const name of names) {
|
||||
// if (typeof name !== 'string' || name.trim() === '') {
|
||||
// helpers.logger.info(`Skipping invalid class name: ${name}`);
|
||||
// continue;
|
||||
// }
|
||||
// if (!(name in positionMap)) {
|
||||
// helpers.logger.info(`No position mapping for class "${name}", defaulting to 0`);
|
||||
// positionMap[name] = 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// helpers.logger.info(`Loaded class position map: ${JSON.stringify(positionMap)}`);
|
||||
// return positionMap;
|
||||
// } catch (error) {
|
||||
// helpers.logger.error(`Error loading data.yaml: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
// throw error;
|
||||
// }
|
||||
// }
|
||||
|
||||
// function generatePatternPositions(startMs: number, durationMs: number, className: string, fps: number): FunscriptAction[] {
|
||||
// const actions: FunscriptAction[] = [];
|
||||
// const frameDurationMs = 1000 / fps;
|
||||
// const totalFrames = Math.floor(durationMs / frameDurationMs);
|
||||
// const intervalMs = 100;
|
||||
|
||||
// for (let timeMs = 0; timeMs < durationMs; timeMs += intervalMs) {
|
||||
// const progress = timeMs / durationMs;
|
||||
// let pos = 0;
|
||||
|
||||
// switch (className) {
|
||||
// case 'Pulse':
|
||||
// pos = Math.round(50 * Math.sin(progress * 2 * Math.PI));
|
||||
// break;
|
||||
// case 'Wave':
|
||||
// pos = Math.round(50 + 50 * Math.sin(progress * 2 * Math.PI));
|
||||
// break;
|
||||
// case 'Fireworks':
|
||||
// pos = Math.random() > 0.5 ? 80 : 0;
|
||||
// break;
|
||||
// case 'Earthquake':
|
||||
// pos = Math.round(90 * Math.sin(progress * 4 * Math.PI) + (Math.random() - 0.5) * 10);
|
||||
// pos = Math.max(0, Math.min(90, pos));
|
||||
// break;
|
||||
// }
|
||||
|
||||
// actions.push({ at: startMs + timeMs, pos });
|
||||
// }
|
||||
|
||||
// return actions;
|
||||
// }
|
||||
|
||||
// async function loadVideoMetadata(videoPath: string, helpers: Helpers) {
|
||||
// const { fps, frames: totalFrames } = await ffprobe(videoPath);
|
||||
// helpers.logger.info(`Video metadata: fps=${fps}, frames=${totalFrames}`);
|
||||
// return { fps, totalFrames };
|
||||
// }
|
||||
|
||||
|
||||
// async function processLabelFiles(labelDir: string, helpers: Helpers, data: DataYaml): Promise<Detection[]> {
|
||||
// const labelFiles = (await readdir(labelDir)).filter(file => file.endsWith('.txt'));
|
||||
// const detections: Map<number, Detection[]> = new Map();
|
||||
// const names = data.names;
|
||||
|
||||
// for (const file of labelFiles) {
|
||||
// const match = file.match(/(\d+)\.txt$/);
|
||||
// if (!match) {
|
||||
// helpers.logger.info(`Skipping invalid filename: ${file}`);
|
||||
// continue;
|
||||
// }
|
||||
// const frameIndex = parseInt(match[1], 10);
|
||||
// if (isNaN(frameIndex)) {
|
||||
// helpers.logger.info(`Skipping invalid frame index from filename: ${file}`);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// const content = await readFile(join(labelDir, file), 'utf8');
|
||||
// const lines = content.trim().split('\n');
|
||||
// const frameDetections: Detection[] = [];
|
||||
// let maxConfidence = 0;
|
||||
// let selectedClassIndex = -1;
|
||||
|
||||
// for (const line of lines) {
|
||||
// const parts = line.trim().split(/\s+/);
|
||||
// if (parts.length < 6) continue;
|
||||
|
||||
// const classIndex = parseInt(parts[0], 10);
|
||||
// const confidence = parseFloat(parts[5]);
|
||||
// if (isNaN(classIndex) || isNaN(confidence)) continue;
|
||||
|
||||
// if (confidence >= 0.7 && confidence > maxConfidence) {
|
||||
// maxConfidence = confidence;
|
||||
// selectedClassIndex = classIndex;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (maxConfidence > 0) {
|
||||
// const className = (data.names as Record<string, string>)[selectedClassIndex.toString()];
|
||||
// if (className) {
|
||||
// frameDetections.push({ startFrame: frameIndex, endFrame: frameIndex, className });
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (frameDetections.length > 0) {
|
||||
// detections.set(frameIndex, frameDetections);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Merge overlapping detections into continuous segments
|
||||
// const detectionSegments: Detection[] = [];
|
||||
// let currentDetection: Detection | null = null;
|
||||
|
||||
// for (const [frameIndex, frameDetections] of detections.entries()) {
|
||||
// for (const detection of frameDetections) {
|
||||
// if (!currentDetection || currentDetection.className !== detection.className) {
|
||||
// if (currentDetection) detectionSegments.push(currentDetection);
|
||||
// currentDetection = { ...detection, endFrame: frameIndex };
|
||||
// } else {
|
||||
// currentDetection.endFrame = frameIndex;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (currentDetection) detectionSegments.push(currentDetection);
|
||||
|
||||
// return detectionSegments;
|
||||
// }
|
||||
|
||||
|
||||
// async function writeFunscript(outputPath: string, actions: FunscriptAction[], helpers: Helpers) {
|
||||
// const funscript: Funscript = { version: '1.0', actions };
|
||||
// await writeFile(outputPath, JSON.stringify(funscript, null, 2));
|
||||
// helpers.logger.info(`Funscript generated: ${outputPath} (${actions.length} actions)`);
|
||||
// }
|
||||
|
||||
|
||||
const createFunscript: Task = async (payload: any, helpers: Helpers) => {
|
||||
assertPayload(payload);
|
||||
const { vodId } = payload;
|
||||
@ -31,6 +270,7 @@ const createFunscript: Task = async (payload: any, helpers: Helpers) => {
|
||||
|
||||
|
||||
const vod = await prisma.vod.findFirstOrThrow({ where: { id: vodId } });
|
||||
await preparePython()
|
||||
|
||||
if (vod.funscript) {
|
||||
helpers.logger.info(`Doing nothing-- vod ${vodId} already has a funscript.`);
|
||||
@ -51,12 +291,11 @@ const createFunscript: Task = async (payload: any, helpers: Helpers) => {
|
||||
|
||||
helpers.logger.info(`Creating funscript for vod ${vodId}...`);
|
||||
|
||||
const modelPath = join(env.VIBEUI_DIR, 'vibeui.onnx')
|
||||
const predictionOutput = await vibeuiInference(modelPath, videoFilePath);
|
||||
helpers.logger.info(`prediction output ${predictionOutput}`);
|
||||
const predictionOutputPath = await inference(videoFilePath);
|
||||
helpers.logger.info(`prediction output ${predictionOutputPath}`);
|
||||
|
||||
|
||||
const funscriptFilePath = await buildFunscript(predictionOutput, videoFilePath)
|
||||
const funscriptFilePath = await buildFunscript(predictionOutputPath, videoFilePath)
|
||||
|
||||
|
||||
const s3Key = `funscripts/${vodId}.funscript`;
|
||||
|
75
services/our/src/tasks/createFunscript.ts.ai.noexec
Normal file
75
services/our/src/tasks/createFunscript.ts.ai.noexec
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
import type { Task, Helpers } from "graphile-worker";
|
||||
import { PrismaClient } from "../../generated/prisma";
|
||||
import { withAccelerate } from "@prisma/extension-accelerate";
|
||||
import { getOrDownloadAsset } from "../utils/cache";
|
||||
import { env } from "../config/env";
|
||||
import { getS3Client, uploadFile } from "../utils/s3";
|
||||
import { buildFunscript } from '../utils/funscripts';
|
||||
import { getModelClasses, vibeuiInference } from "../utils/vibeui";
|
||||
import { join } from "node:path";
|
||||
|
||||
interface Payload {
|
||||
vodId: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const prisma = new PrismaClient().$extends(withAccelerate());
|
||||
|
||||
|
||||
function assertPayload(payload: any): asserts payload is Payload {
|
||||
if (typeof payload !== "object" || !payload) throw new Error("invalid payload-- was not an object.");
|
||||
if (typeof payload.vodId !== "string") throw new Error("invalid payload-- was missing vodId");
|
||||
}
|
||||
|
||||
|
||||
const createFunscript: Task = async (payload: any, helpers: Helpers) => {
|
||||
assertPayload(payload);
|
||||
const { vodId } = payload;
|
||||
|
||||
|
||||
|
||||
const vod = await prisma.vod.findFirstOrThrow({ where: { id: vodId } });
|
||||
|
||||
if (vod.funscript) {
|
||||
helpers.logger.info(`Doing nothing-- vod ${vodId} already has a funscript.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vod.sourceVideo) {
|
||||
const msg = `Cannot create funscript: Vod ${vodId} is missing a source video.`;
|
||||
helpers.logger.warn(msg);
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const s3Client = getS3Client();
|
||||
const videoFilePath = await getOrDownloadAsset(s3Client, env.S3_BUCKET, vod.sourceVideo);
|
||||
helpers.logger.info(`Downloaded video to ${videoFilePath}`);
|
||||
|
||||
helpers.logger.info(`Creating funscript for vod ${vodId}...`);
|
||||
|
||||
const modelPath = join(env.VIBEUI_DIR, 'vibeui.onnx')
|
||||
const predictionOutput = await vibeuiInference(modelPath, videoFilePath);
|
||||
helpers.logger.info(`prediction output ${predictionOutput}`);
|
||||
const classes = await getModelClasses(modelPath)
|
||||
|
||||
const funscriptFilePath = await buildFunscript(classes, predictionOutput, videoFilePath)
|
||||
|
||||
|
||||
const s3Key = `funscripts/${vodId}.funscript`;
|
||||
const s3Url = await uploadFile(s3Client, env.S3_BUCKET, s3Key, funscriptFilePath, "application/json");
|
||||
|
||||
helpers.logger.info(`Uploaded funscript to S3: ${s3Url}`);
|
||||
|
||||
await prisma.vod.update({
|
||||
where: { id: vodId },
|
||||
data: { funscript: s3Key }
|
||||
});
|
||||
|
||||
helpers.logger.info(`Funscript saved to database for vod ${vodId}`);
|
||||
};
|
||||
|
||||
export default createFunscript;
|
141
services/our/src/tests/createFunscript.integration.test.ts
Normal file
141
services/our/src/tests/createFunscript.integration.test.ts
Normal file
@ -0,0 +1,141 @@
|
||||
|
||||
import { describe, it, expect, beforeAll } from 'vitest';
|
||||
import { join } from 'node:path';
|
||||
import { readdir, readFile } from 'node:fs/promises';
|
||||
import { loadDataYaml, loadVideoMetadata, inference } from '../utils/vibeui';
|
||||
import { env } from '../config/env';
|
||||
import { DataYaml, writeFunscript, generateActions1, classPositionMap, buildFunscript } from '../utils/funscripts';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { getNanoSpawn } from '../utils/nanoSpawn';
|
||||
import { preparePython } from '../utils/python';
|
||||
|
||||
interface Detection {
|
||||
startFrame: number;
|
||||
endFrame: number;
|
||||
className: string;
|
||||
}
|
||||
|
||||
|
||||
const __dirname = import.meta.dirname;
|
||||
|
||||
const fixturesDir = join(__dirname, '..', 'tests', 'fixtures')
|
||||
const sampleVideoPath = join(fixturesDir, 'sample.mp4')
|
||||
|
||||
|
||||
/**
|
||||
* Processes YOLO label files and constructs time-aligned detection segments.
|
||||
*
|
||||
* - Reads all `.txt` label files from a directory, one per video frame.
|
||||
* - Parses bounding box class indices and confidence scores.
|
||||
* - Selects the most confident detection per frame above a confidence threshold (0.7).
|
||||
* - Maps class indices to class names using the provided `data.yaml`.
|
||||
* - Groups consecutive frames with the same class into continuous detection segments.
|
||||
*
|
||||
* @param labelDir - Path to the directory containing YOLO label `.txt` files.
|
||||
* @param data - Parsed data.yaml object containing class name mappings.
|
||||
* @returns An array of merged `Detection` objects with start and end frame ranges.
|
||||
* @throws If file reading or parsing fails.
|
||||
*/
|
||||
async function processLabelFiles(labelDir: string, data: DataYaml): Promise<Detection[]> {
|
||||
const labelFiles = (await readdir(labelDir)).filter(file => file.endsWith('.txt'));
|
||||
console.log("Label files found:", labelFiles);
|
||||
const detections: Map<number, Detection[]> = new Map();
|
||||
const names = data.names;
|
||||
|
||||
for (const file of labelFiles) {
|
||||
const match = file.match(/(\d+)\.txt$/);
|
||||
if (!match) {
|
||||
console.log(`Skipping invalid filename: ${file}`);
|
||||
continue;
|
||||
}
|
||||
const frameIndex = parseInt(match[1], 10);
|
||||
if (isNaN(frameIndex)) {
|
||||
console.log(`Skipping invalid frame index from filename: ${file}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const content = await readFile(join(labelDir, file), 'utf8');
|
||||
const lines = content.trim().split('\n');
|
||||
const frameDetections: Detection[] = [];
|
||||
let maxConfidence = 0;
|
||||
let selectedClassIndex = -1;
|
||||
|
||||
for (const line of lines) {
|
||||
const parts = line.trim().split(/\s+/);
|
||||
if (parts.length < 6) continue;
|
||||
|
||||
const classIndex = parseInt(parts[0], 10);
|
||||
const confidence = parseFloat(parts[5]);
|
||||
if (isNaN(classIndex) || isNaN(confidence)) continue;
|
||||
|
||||
if (confidence >= 0.7 && confidence > maxConfidence) {
|
||||
maxConfidence = confidence;
|
||||
selectedClassIndex = classIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxConfidence > 0) {
|
||||
const className = (data.names as Record<string, string>)[selectedClassIndex.toString()];
|
||||
if (className) {
|
||||
frameDetections.push({ startFrame: frameIndex, endFrame: frameIndex, className });
|
||||
}
|
||||
}
|
||||
|
||||
if (frameDetections.length > 0) {
|
||||
detections.set(frameIndex, frameDetections);
|
||||
}
|
||||
}
|
||||
|
||||
// Merge overlapping detections into continuous segments
|
||||
const detectionSegments: Detection[] = [];
|
||||
let currentDetection: Detection | null = null;
|
||||
|
||||
for (const [frameIndex, frameDetections] of detections.entries()) {
|
||||
for (const detection of frameDetections) {
|
||||
if (!currentDetection || currentDetection.className !== detection.className) {
|
||||
if (currentDetection) detectionSegments.push(currentDetection);
|
||||
currentDetection = { ...detection, endFrame: frameIndex };
|
||||
} else {
|
||||
currentDetection.endFrame = frameIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentDetection) detectionSegments.push(currentDetection);
|
||||
|
||||
return detectionSegments;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
describe('createFunscript', () => {
|
||||
|
||||
let predictionOutputPath: string
|
||||
|
||||
beforeAll(async () => {
|
||||
predictionOutputPath = await inference(sampleVideoPath)
|
||||
}, 35_000)
|
||||
|
||||
it('should contain positions other than 0', async () => {
|
||||
|
||||
|
||||
const videoPath = join(__dirname, 'fixtures', 'sample.mp4');
|
||||
|
||||
const funscriptPath = await buildFunscript(predictionOutputPath, videoPath);
|
||||
console.log(`built funscript at ${funscriptPath}`)
|
||||
|
||||
|
||||
const content = JSON.parse(await readFile(funscriptPath, 'utf8') as string);
|
||||
|
||||
expect(content).toHaveProperty('version', '1.0');
|
||||
expect(Array.isArray(content.actions)).toBe(true);
|
||||
|
||||
const allPosZero = content.actions.every((a: any) => a.pos === 0);
|
||||
expect(allPosZero).toBe(false); // if this fails, it means the funscript did not generate position values that map to the various detected classes
|
||||
|
||||
expect(content.actions.length).toBeGreaterThan(0);
|
||||
})
|
||||
|
||||
|
||||
})
|
@ -1 +0,0 @@
|
||||
54 0.038431 0.089941 0.063310 0.075142 53.145020
|
@ -1 +0,0 @@
|
||||
53 0.038782 0.087836 0.061486 0.073967 52.052288
|
@ -1 +0,0 @@
|
||||
56 0.035719 0.076428 0.052471 0.062387 45.073280
|
@ -1 +0,0 @@
|
||||
55 0.035468 0.077997 0.051584 0.064488 45.364609
|
@ -1 +0,0 @@
|
||||
49 0.037174 0.075309 0.052773 0.061913 42.606949
|
@ -1 +0,0 @@
|
||||
49 0.036868 0.075512 0.051822 0.062220 42.845398
|
@ -1 +0,0 @@
|
||||
58 0.033982 0.077916 0.052823 0.061902 49.985241
|
@ -1 +0,0 @@
|
||||
55 0.031318 0.063680 0.047338 0.051505 42.080074
|
@ -1 +0,0 @@
|
||||
49 0.032635 0.051113 0.043934 0.045176 29.531828
|
@ -1 +0,0 @@
|
||||
59 0.029333 0.040158 0.037184 0.046115 42.523987
|
@ -1 +0,0 @@
|
||||
60 0.023820 0.041723 0.024071 0.052091 51.896393
|
@ -1 +0,0 @@
|
||||
59 0.028336 0.039560 0.034117 0.048055 45.588940
|
@ -1 +0,0 @@
|
||||
54 0.040177 0.089766 0.063404 0.075716 52.578529
|
@ -1 +0,0 @@
|
||||
52 0.030120 0.048511 0.038019 0.047205 38.291862
|
@ -1 +0,0 @@
|
||||
51 0.028028 0.048727 0.035394 0.045787 41.533302
|
@ -1 +0,0 @@
|
||||
53 0.030124 0.056849 0.042351 0.057114 45.306530
|
@ -1 +0,0 @@
|
||||
53 0.031095 0.054593 0.043671 0.062581 45.146286
|
@ -1 +0,0 @@
|
||||
55 0.032167 0.056456 0.045219 0.064320 46.130051
|
@ -1 +0,0 @@
|
||||
46 0.022684 0.037057 0.020501 0.039577 37.016544
|
@ -1 +0,0 @@
|
||||
44 0.020022 0.036946 0.020763 0.039563 37.264973
|
@ -1 +0,0 @@
|
||||
46 0.023001 0.038526 0.025594 0.027946 25.011108
|
@ -1 +0,0 @@
|
||||
45 0.021071 0.038914 0.026670 0.028368 23.412777
|
@ -1 +0,0 @@
|
||||
34 0.022739 0.043524 0.029497 0.030117 21.047352
|
@ -1 +0,0 @@
|
||||
54 0.038738 0.088193 0.061146 0.073904 52.342270
|
@ -1 +0,0 @@
|
||||
33 0.023468 0.047506 0.032993 0.033216 22.122324
|
@ -1 +0,0 @@
|
||||
29 0.024802 0.050099 0.036248 0.036333 23.996782
|
@ -1 +0,0 @@
|
||||
27 0.026263 0.054922 0.039299 0.039462 25.030342
|
@ -1 +0,0 @@
|
||||
27 0.027968 0.059208 0.042927 0.041978 26.387854
|
@ -1 +0,0 @@
|
||||
27 0.026905 0.057451 0.040628 0.041066 26.058964
|
@ -1 +0,0 @@
|
||||
28 0.027567 0.057046 0.041958 0.042930 27.190252
|
@ -1 +0,0 @@
|
||||
28 0.027424 0.058000 0.041726 0.043075 27.314507
|
@ -1 +0,0 @@
|
||||
28 0.027354 0.059303 0.041741 0.043003 27.271029
|
@ -1 +0,0 @@
|
||||
28 0.027216 0.060089 0.041448 0.042873 27.201962
|
@ -1 +0,0 @@
|
||||
28 0.027259 0.059818 0.041481 0.042875 27.166683
|
@ -1 +0,0 @@
|
||||
55 0.038905 0.088440 0.061114 0.074878 52.844406
|
@ -1 +0,0 @@
|
||||
28 0.027364 0.058919 0.041654 0.043002 27.260029
|
@ -1 +0,0 @@
|
||||
28 0.027422 0.059680 0.041713 0.043012 27.289568
|
@ -1 +0,0 @@
|
||||
28 0.027505 0.060784 0.041890 0.042989 27.195068
|
@ -1 +0,0 @@
|
||||
28 0.027367 0.061949 0.041727 0.043011 27.209845
|
@ -1 +0,0 @@
|
||||
28 0.027787 0.063247 0.042555 0.043069 27.263746
|
@ -1 +0,0 @@
|
||||
31 0.029057 0.066847 0.045142 0.044002 27.712589
|
@ -1 +0,0 @@
|
||||
47 0.038125 0.073041 0.063277 0.069168 46.141243
|
@ -1 +0,0 @@
|
||||
48 0.038465 0.077648 0.063928 0.070589 47.159187
|
@ -1 +0,0 @@
|
||||
48 0.038857 0.077233 0.064686 0.071919 47.977119
|
@ -1 +0,0 @@
|
||||
49 0.039132 0.078201 0.065272 0.072841 48.427032
|
@ -1 +0,0 @@
|
||||
56 0.041007 0.094351 0.065533 0.077863 53.407448
|
@ -1 +0,0 @@
|
||||
49 0.039132 0.079005 0.065348 0.073051 48.494751
|
@ -1 +0,0 @@
|
||||
48 0.039090 0.075240 0.065312 0.072294 47.814663
|
@ -1 +0,0 @@
|
||||
48 0.039028 0.076693 0.065173 0.072094 47.912033
|
@ -1 +0,0 @@
|
||||
48 0.038899 0.073056 0.064984 0.071549 47.317184
|
@ -1 +0,0 @@
|
||||
47 0.038281 0.067039 0.063682 0.068646 45.645699
|
@ -1 +0,0 @@
|
||||
47 0.037488 0.066094 0.062121 0.068092 46.430637
|
@ -1 +0,0 @@
|
||||
43 0.036806 0.065111 0.060806 0.064199 42.797428
|
@ -1 +0,0 @@
|
||||
43 0.036809 0.068780 0.060680 0.063662 42.322411
|
@ -1 +0,0 @@
|
||||
41 0.036440 0.072136 0.059879 0.061923 40.799137
|
@ -1 +0,0 @@
|
||||
48 0.036187 0.067445 0.056100 0.063240 44.677353
|
@ -1 +0,0 @@
|
||||
55 0.040299 0.095144 0.065489 0.078165 53.380753
|
@ -1 +0,0 @@
|
||||
55 0.040405 0.097322 0.066765 0.079255 53.374428
|
@ -1 +0,0 @@
|
||||
55 0.038764 0.090667 0.063157 0.076659 53.355133
|
@ -1 +0,0 @@
|
||||
53 0.038673 0.089891 0.063106 0.076448 53.004646
|
@ -1 +0,0 @@
|
||||
53 0.038899 0.091212 0.063614 0.076383 52.351440
|
@ -1 +0,0 @@
|
||||
54 0.038586 0.088787 0.063747 0.075643 53.104782
|
@ -1 +0,0 @@
|
||||
53 0.037872 0.087844 0.061520 0.075063 52.219879
|
@ -1 +0,0 @@
|
||||
50 0.037195 0.086863 0.060343 0.073201 50.691704
|
@ -1 +0,0 @@
|
||||
53 0.038759 0.092685 0.063432 0.076361 52.002579
|
@ -1 +0,0 @@
|
||||
52 0.040353 0.090205 0.065287 0.077373 51.746628
|
@ -1 +0,0 @@
|
||||
52 0.040583 0.091694 0.066280 0.077802 51.581718
|
@ -1 +0,0 @@
|
||||
49 0.041297 0.094172 0.067527 0.076987 50.565460
|
@ -1 +0,0 @@
|
||||
50 0.040312 0.090680 0.065473 0.075966 50.742157
|
@ -1 +0,0 @@
|
||||
50 0.039734 0.092913 0.064935 0.076198 50.960922
|
@ -1 +0,0 @@
|
||||
48 0.040137 0.089994 0.065064 0.074114 49.276997
|
@ -1 +0,0 @@
|
||||
47 0.040732 0.094854 0.067243 0.076296 49.356400
|
@ -1 +0,0 @@
|
||||
54 0.038630 0.087661 0.063683 0.075626 52.907776
|
@ -1 +0,0 @@
|
||||
48 0.041461 0.093046 0.068027 0.076524 49.280266
|
@ -1 +0,0 @@
|
||||
46 0.040502 0.082802 0.064679 0.074476 48.285706
|
@ -1 +0,0 @@
|
||||
48 0.040258 0.083422 0.064046 0.075326 49.381264
|
@ -1 +0,0 @@
|
||||
48 0.040601 0.090676 0.066223 0.076538 49.821045
|
@ -1 +0,0 @@
|
||||
46 0.039033 0.083210 0.063061 0.073626 48.440258
|
@ -1 +0,0 @@
|
||||
43 0.032891 0.045700 0.029322 0.035714 35.217300
|
@ -1 +0,0 @@
|
||||
50 0.041740 0.059307 0.038156 0.048756 40.737473
|
@ -1 +0,0 @@
|
||||
51 0.043773 0.062391 0.039251 0.053317 44.349907
|
@ -1 +0,0 @@
|
||||
50 0.044851 0.059177 0.037444 0.047610 41.626480
|
@ -1 +0,0 @@
|
||||
49 0.043650 0.054320 0.035061 0.041959 39.615734
|
@ -1 +0,0 @@
|
||||
55 0.039047 0.089085 0.064675 0.076483 53.375942
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user