paywall the extras
This commit is contained in:
parent
afc9e2d1c8
commit
93d67045a1
@ -50,6 +50,13 @@ COPY . .
|
||||
# Build the app
|
||||
RUN npm run build
|
||||
|
||||
# Setup Python virtualenv
|
||||
RUN python3 -m venv /app/venv
|
||||
ENV PATH="/app/venv/bin:$PATH"
|
||||
|
||||
# Install torrentfile & other python deps
|
||||
RUN ./venv/pip install -r requirements.txt
|
||||
|
||||
# Expose the port
|
||||
EXPOSE 5000
|
||||
|
||||
|
241
services/our/package-lock.json
generated
241
services/our/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "futureporn",
|
||||
"version": "2.0.1",
|
||||
"version": "2.2.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "futureporn",
|
||||
"version": "2.0.1",
|
||||
"version": "2.2.1",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "3.726.1",
|
||||
"@aws-sdk/s3-request-presigner": "^3.844.0",
|
||||
@ -32,6 +32,7 @@
|
||||
"canvas": "^3.1.2",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"concurrently": "^9.2.0",
|
||||
"create-torrent": "^6.1.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"fastify": "^5.4.0",
|
||||
"fastify-plugin": "^5.0.1",
|
||||
@ -58,6 +59,7 @@
|
||||
"sharp": "^0.34.3",
|
||||
"slugify": "^1.6.6",
|
||||
"slvtt": "^0.3.4",
|
||||
"ssh2-sftp-client": "^12.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsup": "^8.5.0",
|
||||
"tsx": "^4.20.3",
|
||||
@ -5065,6 +5067,15 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
|
||||
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/assertion-error": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
||||
@ -5244,6 +5255,15 @@
|
||||
"bare-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
@ -5264,6 +5284,27 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"node_modules/bencode": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz",
|
||||
"integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uint8-util": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
@ -5311,6 +5352,12 @@
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/block-iterator": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.1.1.tgz",
|
||||
"integrity": "sha512-DrjdVWZemVO4iBf4tiOXjUrY5cNesjzy0t7sIiu2rdl8cOCHRxAgKjSJFc3vBZYYMMmshUAxajl8QQh/uxXTKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/boolean": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||
@ -5371,6 +5418,21 @@
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/buildcheck": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz",
|
||||
"integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bundle-require": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz",
|
||||
@ -5768,6 +5830,21 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||
"engines": [
|
||||
"node >= 6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.0.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/concurrently": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.0.tgz",
|
||||
@ -5963,12 +6040,66 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/cpu-features": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz",
|
||||
"integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"buildcheck": "~0.0.6",
|
||||
"nan": "^2.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/create-torrent": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-6.1.0.tgz",
|
||||
"integrity": "sha512-War593HCsg4TotHgMGWTJqnDHN0pmEU2RM13xUzzSZ78TpRNOC2bbcsC5yMO3pqIkedHEWFzYNqH1yhwuuBYTg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bencode": "^4.0.0",
|
||||
"block-iterator": "^1.1.1",
|
||||
"fast-readable-async-iterator": "^2.0.0",
|
||||
"is-file": "^1.0.0",
|
||||
"join-async-iterator": "^1.1.1",
|
||||
"junk": "^4.0.1",
|
||||
"minimist": "^1.2.8",
|
||||
"once": "^1.4.0",
|
||||
"piece-length": "^2.0.1",
|
||||
"queue-microtask": "^1.2.3",
|
||||
"run-parallel": "^1.2.0",
|
||||
"uint8-util": "^2.2.5"
|
||||
},
|
||||
"bin": {
|
||||
"create-torrent": "bin/cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
@ -6795,6 +6926,12 @@
|
||||
"fast-decode-uri-component": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-readable-async-iterator": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-readable-async-iterator/-/fast-readable-async-iterator-2.0.0.tgz",
|
||||
"integrity": "sha512-8Sld+DuyWRIftl86ZguJxR2oXCBccOiJxrY/Rj9/7ZBynW8pYMWzIcqxFL1da+25jaWJZVa+HHX/8SsA21JdTA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-redact": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz",
|
||||
@ -7891,6 +8028,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-file": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-file/-/is-file-1.0.0.tgz",
|
||||
"integrity": "sha512-ZGMuc+xA8mRnrXtmtf2l/EkIW2zaD2LSBWlaOVEF6yH4RTndHob65V4SwWWdtGKVthQfXPVKsXqw4TDUjbVxVQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
@ -8036,6 +8179,12 @@
|
||||
"integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/join-async-iterator": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/join-async-iterator/-/join-async-iterator-1.1.1.tgz",
|
||||
"integrity": "sha512-ATse+nuNeKZ9K1y27LKdvPe/GCe9R/u9dw9vI248e+vILeRK3IcJP4JUPAlSmKRCDK0cKhEwfmiw4Skqx7UnGQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/joycon": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
|
||||
@ -8155,6 +8304,18 @@
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/junk": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz",
|
||||
"integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
@ -8563,6 +8724,13 @@
|
||||
"thenify-all": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nan": {
|
||||
"version": "2.23.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
|
||||
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/nano-spawn": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.2.tgz",
|
||||
@ -9127,6 +9295,12 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/piece-length": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/piece-length/-/piece-length-2.0.1.tgz",
|
||||
"integrity": "sha512-dBILiDmm43y0JPISWEmVGKBETQjwJe6mSU9GND+P9KW0SJGUwoU/odyH1nbalOP9i8WSYuqf1lQnaj92Bhw+Ug==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pino": {
|
||||
"version": "9.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-9.7.0.tgz",
|
||||
@ -9563,7 +9737,6 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -9822,7 +9995,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -9899,6 +10071,12 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/secure-json-parse": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-3.0.2.tgz",
|
||||
@ -10224,6 +10402,40 @@
|
||||
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/ssh2": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz",
|
||||
"integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"asn1": "^0.2.6",
|
||||
"bcrypt-pbkdf": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.16.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"cpu-features": "~0.0.10",
|
||||
"nan": "^2.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ssh2-sftp-client": {
|
||||
"version": "12.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ssh2-sftp-client/-/ssh2-sftp-client-12.0.1.tgz",
|
||||
"integrity": "sha512-ICJ1L2PmBel2Q2ctbyxzTFZCPKSHYYD6s2TFZv7NXmZDrDNGk8lHBb/SK2WgXLMXNANH78qoumeJzxlWZqSqWg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"concat-stream": "^2.0.0",
|
||||
"ssh2": "^1.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.20.4"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://square.link/u/4g7sPflL"
|
||||
}
|
||||
},
|
||||
"node_modules/stackback": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
|
||||
@ -11054,6 +11266,12 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
|
||||
"license": "Unlicense"
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
@ -11067,6 +11285,12 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||
@ -11122,6 +11346,15 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uint8-util": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/uint8-util/-/uint8-util-2.2.5.tgz",
|
||||
"integrity": "sha512-/QxVQD7CttWpVUKVPz9znO+3Dd4BdTSnFQ7pv/4drVhC9m4BaL2LFHTkJn6EsYoxT79VDq/2Gg8L0H22PrzyMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/undefsafe": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||
|
@ -4,11 +4,12 @@
|
||||
"version": "2.2.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "concurrently npm:dev:serve npm:dev:build npm:dev:worker npm:dev:compose",
|
||||
"dev": "concurrently npm:dev:serve npm:dev:build npm:dev:worker npm:dev:compose npm:dev:sftp",
|
||||
"dev:serve": "npx @dotenvx/dotenvx run -f ../../.env.development.local -- tsx watch ./src/index.ts",
|
||||
"dev:compose": "docker compose -f compose.development.yaml up",
|
||||
"dev:worker": "npx @dotenvx/dotenvx run -e GRAPHILE_LOGGER_DEBUG=1 -f ../../.env.development.local -- tsx watch ./src/worker.ts",
|
||||
"dev:build": "chokidar 'src/**/*.{js,ts}' -c tsup --clean",
|
||||
"dev:sftp": "docker run -p 2222:22 --rm atmoz/sftp user:pass:::watch",
|
||||
"start": "echo please use either start:server or start:worker; exit 1",
|
||||
"start:server": "tsx ./src/index.ts",
|
||||
"start:worker": "tsx ./src/worker.ts",
|
||||
@ -62,6 +63,7 @@
|
||||
"canvas": "^3.1.2",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"concurrently": "^9.2.0",
|
||||
"create-torrent": "^6.1.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"fastify": "^5.4.0",
|
||||
"fastify-plugin": "^5.0.1",
|
||||
@ -88,6 +90,7 @@
|
||||
"sharp": "^0.34.3",
|
||||
"slugify": "^1.6.6",
|
||||
"slvtt": "^0.3.4",
|
||||
"ssh2-sftp-client": "^12.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsup": "^8.5.0",
|
||||
"tsx": "^4.20.3",
|
||||
|
@ -1,2 +1,3 @@
|
||||
ultralytics
|
||||
vcsi
|
||||
torrentfile
|
@ -324,8 +324,8 @@ export default async function vtubersRoutes(
|
||||
|
||||
const items = vtuber.vods.map(vod => ({
|
||||
title: `Stream on ${vod.streamDate.toDateString()}`,
|
||||
link: `${env.ORIGIN}/vod/${vod.id}`,
|
||||
guid: `${env.ORIGIN}/vod/${vod.id}`,
|
||||
link: `${env.ORIGIN}/vods/${vod.id}`,
|
||||
guid: `${env.ORIGIN}/vods/${vod.id}`,
|
||||
pubDate: vod.streamDate.toUTCString(),
|
||||
description: vod.notes || 'No description available',
|
||||
}));
|
||||
@ -337,7 +337,7 @@ export default async function vtubersRoutes(
|
||||
.view('/feed.hbs', {
|
||||
title,
|
||||
description: vtuber.description || title,
|
||||
link: `${env.ORIGIN}/vtuber/${vtuber.slug || vtuber.id}`,
|
||||
link: `${env.ORIGIN}/vtubers/${vtuber.slug || vtuber.id}`,
|
||||
items,
|
||||
}, { layout: 'layouts/xml.hbs' });
|
||||
});
|
||||
|
@ -49,7 +49,8 @@
|
||||
<video id="player" class="video-js vjs-fluid" controls preload="auto" poster="{{getCdnUrl vod.thumbnail}}"
|
||||
data-setup='{}' data-playlist="{{signedHlsUrl vod.hlsPlaylist}}">
|
||||
<source src="/hls/{{vod.id}}/master.m3u8" type="application/x-mpegURL">
|
||||
<track kind="captions" src="{{getCdnUrl vod.asrVttKey}}" srclang="en" label="English" default>
|
||||
{{#if (hasRole "supporterTier1" user)}}
|
||||
<track kind="captions" src="{{getCdnUrl vod.asrVttKey}}" srclang="en" label="English" default>{{/if}}
|
||||
<p class="vjs-no-js">
|
||||
To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that
|
||||
@ -99,9 +100,9 @@
|
||||
|
||||
<h1>
|
||||
{{#each vod.vtubers}}
|
||||
{{this.displayName}}{{#unless @last}}, {{/unless}}
|
||||
<a href="/vtubers/{{this.slug}}">{{this.displayName}}</a>{{#unless @last}}, {{/unless}}
|
||||
{{/each}}
|
||||
– {{formatDate vod.streamDate}}
|
||||
- {{formatDate vod.streamDate}}
|
||||
</h1>
|
||||
|
||||
<div class="overflow-auto">
|
||||
@ -119,21 +120,7 @@
|
||||
|
||||
|
||||
<h2>Downloads</h2>
|
||||
<h3>Raw Segments</h3>
|
||||
{{#if vod.segmentKeys}}
|
||||
<ul>
|
||||
{{#each vod.segmentKeys}}
|
||||
<li><a data-source-video="{{getCdnUrl this.key}}" data-file-name="{{this.name}}" target="_blank"
|
||||
download="{{this.name}}" x-on:click.prevent="download($el.dataset.sourceVideo, $el.dataset.fileName)"
|
||||
href="{{getCdnUrl this.key}}">{{icon "download" 24}} {{this.name}}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<article>
|
||||
This VOD has no file segments.
|
||||
</article>
|
||||
{{/if}}
|
||||
|
||||
|
||||
<h3>VOD</h3>
|
||||
{{#if vod.sourceVideo}}
|
||||
@ -168,25 +155,67 @@
|
||||
Magnet Link is processing.
|
||||
</article>
|
||||
{{/if}}
|
||||
|
||||
|
||||
<h4>Raw Segments</h4>
|
||||
{{#if vod.segmentKeys}}
|
||||
{{#if (hasRole "supporterTier1" user)}}
|
||||
<ul>
|
||||
{{#each vod.segmentKeys}}
|
||||
<li><a data-source-video="{{getCdnUrl this.key}}" data-file-name="{{this.name}}" target="_blank"
|
||||
download="{{this.name}}" x-on:click.prevent="download($el.dataset.sourceVideo, $el.dataset.fileName)"
|
||||
href="{{getCdnUrl this.key}}">{{icon "download" 24}} {{this.name}}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<p>
|
||||
<a href="/perks">{{icon "patreon" 24}}</a>
|
||||
<del>
|
||||
Raw Segments CDN Download
|
||||
</del>
|
||||
</p>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
|
||||
<article>
|
||||
This VOD has no file segments.
|
||||
</article>
|
||||
{{/if}} {{!-- end of raw segments --}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{else}}
|
||||
<article>
|
||||
Video Source is processing.
|
||||
</article>
|
||||
{{/if}}
|
||||
{{/if}} {{!-- end of vod.sourceVideo --}}
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>HLS Playlist</h3>
|
||||
<h4>HLS Playlist</h4>
|
||||
{{#if vod.hlsPlaylist}}
|
||||
{{#if (hasRole "supporterTier1" user)}}
|
||||
<a href="{{signedHlsUrl vod.hlsPlaylist}}">{{signedHlsUrl vod.hlsPlaylist}}</a>
|
||||
{{else}}
|
||||
<p>
|
||||
<a href="/perks">{{icon "patreon" 24}}</a>
|
||||
<del>
|
||||
HLS Playlist CDN Download
|
||||
</del>
|
||||
</p>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<article>
|
||||
HLS Playlist is processing.
|
||||
</article>
|
||||
{{/if}}
|
||||
|
||||
<h3>Thumbnail Image</h3>
|
||||
<h4>Thumbnail Image</h4>
|
||||
{{#if vod.thumbnail}}
|
||||
<img src="{{getCdnUrl vod.thumbnail}}" alt="{{this.vtuber.displayName}} thumbnail">
|
||||
<div class="mx-5"></div>
|
||||
@ -198,13 +227,29 @@
|
||||
|
||||
|
||||
|
||||
<h3>Funscript (sex toy sync)</h3>
|
||||
<h4>Funscripts (sex toy sync)</h4>
|
||||
{{#if vod.funscript}}
|
||||
|
||||
{{#if (hasRole "supporterTier1" user)}}
|
||||
<p>
|
||||
{{!-- @todo change this id to funscript-vibrate --}}
|
||||
<a id="funscript" data-url="{{getCdnUrl vod.funscript}}" data-file-name="{{basename vod.funscript}}"
|
||||
x-on:click.prevent="download($el.dataset.url, $el.dataset.fileName)" href="{{getCdnUrl vod.funscript}}"
|
||||
alt="{{this.vtuber.displayName}} funscript file">{{icon "download" 24}}
|
||||
{{this.vtuber.displayName}}
|
||||
Funscript</a>
|
||||
vibrate.funscript</a>
|
||||
</p>
|
||||
<p>
|
||||
<s><a id="funscript-thrust">{{icon "download" 24}} thrust.funscript</a></s> (coming soon)
|
||||
</p>
|
||||
{{else}}
|
||||
<p>
|
||||
<a href="/perks">{{icon "patreon" 24}}</a>
|
||||
<del>
|
||||
Funscripts
|
||||
</del>
|
||||
</p>
|
||||
{{/if}}
|
||||
<div class="mx-5"></div>
|
||||
{{else}}
|
||||
<article>
|
||||
@ -213,11 +258,25 @@
|
||||
{{/if}}
|
||||
|
||||
|
||||
<h3>Closed Captions / Subtitles</h3>
|
||||
<h4>Closed Captions / Subtitles</h4>
|
||||
|
||||
|
||||
{{#if vod.asrVttKey}}
|
||||
{{#if (hasRole "supporterTier1" user)}}
|
||||
<a id="asr-vtt" data-url="{{getCdnUrl vod.asrVttKey}}" data-file-name="{{basename vod.asrVttKey}}"
|
||||
x-on:click.prevent="download($el.dataset.url, $el.dataset.fileName)" href="{{getCdnUrl vod.asrVttKey}}"
|
||||
alt="Closed Captions VTT file">{{icon "download" 24}} Closed Captions</a>
|
||||
{{else}}
|
||||
<p>
|
||||
<a href="/perks">{{icon "patreon" 24}}</a>
|
||||
<del>
|
||||
Closed Captions / Subtitles
|
||||
</del>
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
|
||||
|
||||
{{else}}
|
||||
<article>
|
||||
Closed captions are processing.
|
||||
@ -229,6 +288,8 @@
|
||||
|
||||
|
||||
{{#if (isModerator user)}}
|
||||
<article>
|
||||
<h2>Moderator section</h2>
|
||||
|
||||
<h3>Storyboard Images</h3>
|
||||
{{#if vod.slvttVTTKey}}
|
||||
@ -241,9 +302,10 @@
|
||||
</article>
|
||||
{{/if}}
|
||||
|
||||
<h2>Moderator Controls</h2>
|
||||
<h3>Controls</h3>
|
||||
<button hx-post="/vods/{{vod.id}}/process" hx-target="body">{{icon "processing" 24}} Re-Schedule Vod
|
||||
Processing</button>
|
||||
</article>
|
||||
{{/if}}
|
||||
|
||||
|
||||
@ -287,7 +349,7 @@
|
||||
|
||||
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/Teyuto/videojs-vtt-thumbnails@main/src/videojs-vtt-thumbnails.min.js"></script>
|
||||
{{!-- <script src="https://cdn.jsdelivr.net/gh/Teyuto/videojs-vtt-thumbnails@main/src/videojs-vtt-thumbnails.min.js"></script> --}}
|
||||
{{!-- <script src="https://cdn.jsdelivr.net/npm/video.js@8.23.3/dist/video.min.js"></script> --}}
|
||||
{{!-- <script src="https://cdn.jsdelivr.net/npm/videojs-vtt-thumbnails@0.0.13/dist/videojs-vtt-thumbnails.min.js"></script> --}}
|
||||
{{!-- <script type="module">
|
||||
@ -297,58 +359,25 @@
|
||||
caca()
|
||||
</script> --}}
|
||||
|
||||
{{!--
|
||||
Script 4: Initialize the buttplug plugin and pass in the funscript URL from the DOM
|
||||
--}}
|
||||
<script type="module">
|
||||
//import videojs from 'https://cdn.jsdelivr.net/npm/video.js@8/+esm'
|
||||
//import 'https://esm.sh/gh/mayeaux/videojs-vtt-thumbnails';
|
||||
|
||||
const player = videojs('#player');
|
||||
const funscriptElement = document.querySelector('#funscript');
|
||||
|
||||
//if (funscriptElement) {
|
||||
// player.buttplug({
|
||||
// funscriptUrl: funscriptElement.dataset.url
|
||||
// });
|
||||
//} else {
|
||||
// console.error('Element with id "funscript" not found.');
|
||||
//}
|
||||
|
||||
//console.log('vtt-thumbnails')
|
||||
//console.log(player.vttThumbnails)
|
||||
// Initialize videojs-vtt-thumbnails
|
||||
//player.vttThumbnails({
|
||||
// src: "{{getCdnUrl vod.slvttVTTKey}}",
|
||||
// showTimestamp: true
|
||||
//});
|
||||
player.vttThumbnails({
|
||||
//spriteUrl: 'path/to/sprite.jpg',
|
||||
vttData: {
|
||||
url: '{{getCdnUrl vod.slvttVTTKey}}'
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{{!--
|
||||
Script 1: Load Buttplug.js from Skypack CDN and expose it to window.buttplug
|
||||
--}}
|
||||
{{!-- <script type="module">
|
||||
<script type="module">
|
||||
import {
|
||||
ButtplugClient,
|
||||
ButtplugBrowserWebsocketClientConnector
|
||||
} from 'https://cdn.skypack.dev/buttplug';
|
||||
|
||||
window.buttplug = { ButtplugClient, ButtplugBrowserWebsocketClientConnector };
|
||||
</script> --}}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
{{!--
|
||||
Script 2: Define reusable utility components for funscript and buttplug indicators
|
||||
--}}
|
||||
{{!-- <script type="module">
|
||||
<script type="module">
|
||||
const Plugin = videojs.getPlugin('plugin');
|
||||
|
||||
const createIndicator = (Component, className, defaultText) => {
|
||||
@ -370,13 +399,13 @@
|
||||
'ButtplugIndicator',
|
||||
createIndicator(videojs.getComponent('Component'), 'vjs-buttplug-indicator', 'Buttplug.js not connected')
|
||||
);
|
||||
</script> --}}
|
||||
</script>
|
||||
|
||||
|
||||
{{!--
|
||||
Script 3: Main ButtplugPlugin class — handles connection, syncing, and device control
|
||||
--}}
|
||||
{{!-- <script type="module">
|
||||
<script type="module">
|
||||
class ButtplugPlugin extends videojs.getPlugin('plugin') {
|
||||
constructor(player, options) {
|
||||
super(player, options);
|
||||
@ -568,9 +597,42 @@
|
||||
}
|
||||
|
||||
videojs.registerPlugin('buttplug', ButtplugPlugin);
|
||||
</script> --}}
|
||||
</script>
|
||||
|
||||
|
||||
{{!--
|
||||
Script 4: Initialize the buttplug plugin and pass in the funscript URL from the DOM
|
||||
--}}
|
||||
<script type="module">
|
||||
//import videojs from 'https://cdn.jsdelivr.net/npm/video.js@8/+esm'
|
||||
//import 'https://esm.sh/gh/mayeaux/videojs-vtt-thumbnails';
|
||||
|
||||
const player = videojs('#player');
|
||||
const funscriptElement = document.querySelector('#funscript');
|
||||
|
||||
if (funscriptElement) {
|
||||
player.buttplug({
|
||||
funscriptUrl: funscriptElement?.dataset.url || null
|
||||
});
|
||||
} else {
|
||||
console.error('Element with id "funscript" not found.');
|
||||
}
|
||||
|
||||
//console.log('vtt-thumbnails')
|
||||
//console.log(player.vttThumbnails)
|
||||
// Initialize videojs-vtt-thumbnails
|
||||
//player.vttThumbnails({
|
||||
// src: "{{getCdnUrl vod.slvttVTTKey}}",
|
||||
// showTimestamp: true
|
||||
//});
|
||||
//player.vttThumbnails({
|
||||
// //spriteUrl: 'path/to/sprite.jpg',
|
||||
// vttData: {
|
||||
// url: '{{getCdnUrl vod.slvttVTTKey}}'
|
||||
// }
|
||||
//});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
@ -40,8 +40,7 @@
|
||||
</video> --}}
|
||||
|
||||
<h1>
|
||||
{{vtuber.displayName}} <a href="/vtubers/{{vtuber.slug}}/rss"
|
||||
alt="RSS feed for {{vtuber.displayName}}">{{icon "rss" 32}}</a>
|
||||
{{vtuber.displayName}}
|
||||
</h1>
|
||||
|
||||
<div class="grid">
|
||||
@ -288,6 +287,11 @@
|
||||
<h2><s>🚧Toys</s></h2>
|
||||
<p>🚧</p>
|
||||
|
||||
<h2>Feeds</h2>
|
||||
<p>
|
||||
<a href="/vtubers/{{vtuber.slug}}/rss" alt="RSS feed for {{vtuber.displayName}}">RSS {{icon "rss" 32}}</a>
|
||||
</p>
|
||||
|
||||
|
||||
<div class="overflow-auto">
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user