add scout email
ci / build (push) Has been cancelled
Details
ci / build (push) Has been cancelled
Details
This commit is contained in:
parent
76e1ee60eb
commit
2faa8cfa21
|
@ -1,22 +1,23 @@
|
|||
Dockerfile
|
||||
*.dockerfile
|
||||
.dockerignore
|
||||
.gitignore
|
||||
*~
|
||||
node_modules
|
||||
npm-debug.log
|
||||
README.md
|
||||
.next
|
||||
.git
|
||||
LICENSE
|
||||
.nvmrc
|
||||
CHECKS
|
||||
app.json
|
||||
.env*
|
||||
compose/
|
||||
docker-compose.*
|
||||
.vscode
|
||||
charts/**/charts
|
||||
**/Dockerfile
|
||||
**/*.dockerfile
|
||||
**/.dockerignore
|
||||
**/.gitignore
|
||||
**/*~
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/README.md
|
||||
**/.next
|
||||
**/.git
|
||||
**/LICENSE
|
||||
**/.nvmrc
|
||||
**/CHECKS
|
||||
**/app.json
|
||||
**/.env*
|
||||
**/compose/
|
||||
**/docker-compose.*
|
||||
**/.vscode
|
||||
**/charts/**/charts
|
||||
**/.mocharc.json
|
||||
|
||||
**/.env
|
||||
**/node_modules
|
||||
|
@ -29,3 +30,4 @@ packages/strapi/build/
|
|||
packages/strapi/node_modules/
|
||||
packages/strapi/data/
|
||||
packages/strapi/backup
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ metadata:
|
|||
# create a tunnel to uwu-exit-node (chisel server)
|
||||
# this allows us to have SSL in development
|
||||
annotations:
|
||||
chisel-operator.io/exit-node-name: "uwu-exit-node"
|
||||
chisel-operator.io/exit-node-name: "next-exit-node"
|
||||
{{ end }}
|
||||
spec:
|
||||
selector:
|
||||
|
|
|
@ -7,9 +7,10 @@ spec:
|
|||
selector:
|
||||
app.kubernetes.io/name: scout
|
||||
ports:
|
||||
- name: web
|
||||
- name: http
|
||||
port: 3000
|
||||
targetPort: 3000
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
|
@ -33,7 +34,8 @@ spec:
|
|||
- name: scout
|
||||
image: "{{ .Values.scout.containerName }}"
|
||||
ports:
|
||||
- containerPort: 5000
|
||||
- name: http
|
||||
containerPort: 3000
|
||||
env:
|
||||
- name: POSTGRES_REALTIME_CONNECTION_STRING
|
||||
valueFrom:
|
||||
|
@ -41,7 +43,7 @@ spec:
|
|||
name: realtime
|
||||
key: postgresRealtimeConnectionString
|
||||
- name: STRAPI_URL
|
||||
value: https://strapi.futureporn.svc.cluster.local
|
||||
value: https://strapi.piko.sbtp.xyz
|
||||
- name: SCOUT_RECENTS_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
|
@ -101,8 +103,8 @@ rules:
|
|||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: scout
|
||||
port:
|
||||
number: 3000
|
||||
service:
|
||||
name: scout
|
||||
port:
|
||||
number: 3000
|
||||
{{ end }}
|
|
@ -21,7 +21,7 @@ metadata:
|
|||
# create a tunnel to uwu-exit-node (chisel server)
|
||||
# this allows us to have SSL in development
|
||||
annotations:
|
||||
chisel-operator.io/exit-node-name: "uwu-exit-node"
|
||||
chisel-operator.io/exit-node-name: "strapi-exit-node"
|
||||
{{ end }}
|
||||
spec:
|
||||
selector:
|
||||
|
|
|
@ -11,8 +11,7 @@ COPY . /usr/src/app
|
|||
WORKDIR /usr/src/app
|
||||
RUN mkdir -p /prod/scout
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
||||
RUN ls -la ./packages
|
||||
RUN pnpm deploy --filter=@futureporn/scout --prod /prod/scout
|
||||
RUN pnpm deploy --filter=scout --prod /prod/scout
|
||||
# COPY pnpm-lock.yaml ./
|
||||
# RUN pnpm fetch
|
||||
# COPY ./packages/scout /app
|
||||
|
@ -21,6 +20,5 @@ RUN pnpm deploy --filter=@futureporn/scout --prod /prod/scout
|
|||
FROM base AS scout
|
||||
COPY --from=build /prod/scout /app
|
||||
WORKDIR /app
|
||||
RUN ls -la
|
||||
ENTRYPOINT ["pnpm"]
|
||||
CMD ["run", "start"]
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extension": ["js"],
|
||||
"spec": "src/**/*.spec.js"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "common",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "regular expressions, constants, and helper functions which are used app-wide",
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"exports": {
|
||||
"fansly": "./src/fansly.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "@CJ_Clippy",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"chai": "^5.1.1",
|
||||
"mocha": "^10.4.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,621 @@
|
|||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
chai:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
mocha:
|
||||
specifier: ^10.4.0
|
||||
version: 10.4.0
|
||||
|
||||
packages:
|
||||
|
||||
ansi-colors@4.1.1:
|
||||
resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
anymatch@3.1.3:
|
||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
assertion-error@2.0.1:
|
||||
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
binary-extensions@2.3.0:
|
||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
|
||||
braces@3.0.3:
|
||||
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
browser-stdout@1.3.1:
|
||||
resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
|
||||
|
||||
camelcase@6.3.0:
|
||||
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
chai@5.1.1:
|
||||
resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
check-error@2.1.1:
|
||||
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
chokidar@3.5.3:
|
||||
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
|
||||
cliui@7.0.4:
|
||||
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
debug@4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decamelize@4.0.0:
|
||||
resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
deep-eql@5.0.1:
|
||||
resolution: {integrity: sha512-nwQCf6ne2gez3o1MxWifqkciwt0zhl0LO1/UwVu4uMBuPmflWM4oQ70XMqHqnBJA+nhzncaqL9HVL6KkHJ28lw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
diff@5.0.0:
|
||||
resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
escalade@3.1.2:
|
||||
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
fill-range@7.1.1:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
find-up@5.0.0:
|
||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
flat@5.0.2:
|
||||
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
|
||||
hasBin: true
|
||||
|
||||
fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
get-caller-file@2.0.5:
|
||||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
|
||||
get-func-name@2.0.2:
|
||||
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
glob@8.1.0:
|
||||
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
|
||||
engines: {node: '>=12'}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
|
||||
has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
he@1.2.0:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
hasBin: true
|
||||
|
||||
inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
|
||||
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-extglob@2.1.1:
|
||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-glob@4.0.3:
|
||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-number@7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
|
||||
is-plain-obj@2.1.0:
|
||||
resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-unicode-supported@0.1.0:
|
||||
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
|
||||
locate-path@6.0.0:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
log-symbols@4.1.0:
|
||||
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
loupe@3.1.1:
|
||||
resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==}
|
||||
|
||||
minimatch@5.0.1:
|
||||
resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
mocha@10.4.0:
|
||||
resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==}
|
||||
engines: {node: '>= 14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
normalize-path@3.0.0:
|
||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
|
||||
p-limit@3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
p-locate@5.0.0:
|
||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
pathval@2.0.0:
|
||||
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
|
||||
engines: {node: '>= 14.16'}
|
||||
|
||||
picomatch@2.3.1:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
randombytes@2.1.0:
|
||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||
|
||||
readdirp@3.6.0:
|
||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
serialize-javascript@6.0.0:
|
||||
resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-json-comments@3.1.1:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
supports-color@8.1.1:
|
||||
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
||||
workerpool@6.2.1:
|
||||
resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yargs-parser@20.2.4:
|
||||
resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yargs-unparser@2.0.0:
|
||||
resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yargs@16.2.0:
|
||||
resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
snapshots:
|
||||
|
||||
ansi-colors@4.1.1: {}
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
anymatch@3.1.3:
|
||||
dependencies:
|
||||
normalize-path: 3.0.0
|
||||
picomatch: 2.3.1
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
assertion-error@2.0.1: {}
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
braces@3.0.3:
|
||||
dependencies:
|
||||
fill-range: 7.1.1
|
||||
|
||||
browser-stdout@1.3.1: {}
|
||||
|
||||
camelcase@6.3.0: {}
|
||||
|
||||
chai@5.1.1:
|
||||
dependencies:
|
||||
assertion-error: 2.0.1
|
||||
check-error: 2.1.1
|
||||
deep-eql: 5.0.1
|
||||
loupe: 3.1.1
|
||||
pathval: 2.0.0
|
||||
|
||||
chalk@4.1.2:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
|
||||
check-error@2.1.1: {}
|
||||
|
||||
chokidar@3.5.3:
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
braces: 3.0.3
|
||||
glob-parent: 5.1.2
|
||||
is-binary-path: 2.1.0
|
||||
is-glob: 4.0.3
|
||||
normalize-path: 3.0.0
|
||||
readdirp: 3.6.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
cliui@7.0.4:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
debug@4.3.4(supports-color@8.1.1):
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
optionalDependencies:
|
||||
supports-color: 8.1.1
|
||||
|
||||
decamelize@4.0.0: {}
|
||||
|
||||
deep-eql@5.0.1: {}
|
||||
|
||||
diff@5.0.0: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
escalade@3.1.2: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
fill-range@7.1.1:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
find-up@5.0.0:
|
||||
dependencies:
|
||||
locate-path: 6.0.0
|
||||
path-exists: 4.0.0
|
||||
|
||||
flat@5.0.2: {}
|
||||
|
||||
fs.realpath@1.0.0: {}
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
|
||||
get-func-name@2.0.2: {}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
|
||||
glob@8.1.0:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 5.0.1
|
||||
once: 1.4.0
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
he@1.2.0: {}
|
||||
|
||||
inflight@1.0.6:
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
wrappy: 1.0.2
|
||||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
dependencies:
|
||||
binary-extensions: 2.3.0
|
||||
|
||||
is-extglob@2.1.1: {}
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
is-glob@4.0.3:
|
||||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
is-plain-obj@2.1.0: {}
|
||||
|
||||
is-unicode-supported@0.1.0: {}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
locate-path@6.0.0:
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
|
||||
log-symbols@4.1.0:
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
is-unicode-supported: 0.1.0
|
||||
|
||||
loupe@3.1.1:
|
||||
dependencies:
|
||||
get-func-name: 2.0.2
|
||||
|
||||
minimatch@5.0.1:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
mocha@10.4.0:
|
||||
dependencies:
|
||||
ansi-colors: 4.1.1
|
||||
browser-stdout: 1.3.1
|
||||
chokidar: 3.5.3
|
||||
debug: 4.3.4(supports-color@8.1.1)
|
||||
diff: 5.0.0
|
||||
escape-string-regexp: 4.0.0
|
||||
find-up: 5.0.0
|
||||
glob: 8.1.0
|
||||
he: 1.2.0
|
||||
js-yaml: 4.1.0
|
||||
log-symbols: 4.1.0
|
||||
minimatch: 5.0.1
|
||||
ms: 2.1.3
|
||||
serialize-javascript: 6.0.0
|
||||
strip-json-comments: 3.1.1
|
||||
supports-color: 8.1.1
|
||||
workerpool: 6.2.1
|
||||
yargs: 16.2.0
|
||||
yargs-parser: 20.2.4
|
||||
yargs-unparser: 2.0.0
|
||||
|
||||
ms@2.1.2: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
normalize-path@3.0.0: {}
|
||||
|
||||
once@1.4.0:
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
|
||||
p-limit@3.1.0:
|
||||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
|
||||
p-locate@5.0.0:
|
||||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
|
||||
path-exists@4.0.0: {}
|
||||
|
||||
pathval@2.0.0: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
randombytes@2.1.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
readdirp@3.6.0:
|
||||
dependencies:
|
||||
picomatch: 2.3.1
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
serialize-javascript@6.0.0:
|
||||
dependencies:
|
||||
randombytes: 2.1.0
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
strip-json-comments@3.1.1: {}
|
||||
|
||||
supports-color@7.2.0:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
supports-color@8.1.1:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
dependencies:
|
||||
is-number: 7.0.0
|
||||
|
||||
workerpool@6.2.1: {}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yargs-parser@20.2.4: {}
|
||||
|
||||
yargs-unparser@2.0.0:
|
||||
dependencies:
|
||||
camelcase: 6.3.0
|
||||
decamelize: 4.0.0
|
||||
flat: 5.0.2
|
||||
is-plain-obj: 2.1.0
|
||||
|
||||
yargs@16.2.0:
|
||||
dependencies:
|
||||
cliui: 7.0.4
|
||||
escalade: 3.1.2
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 20.2.4
|
||||
|
||||
yocto-queue@0.1.0: {}
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
|
||||
const fansly = {
|
||||
regex: {
|
||||
username: new RegExp(/^https:\/\/fansly\.com\/(?:live\/)?([^\/]+)/)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default fansly
|
|
@ -0,0 +1,16 @@
|
|||
import { expect } from 'chai'
|
||||
import fansly from './fansly.js'
|
||||
|
||||
describe('fansly', function () {
|
||||
describe('regex', function () {
|
||||
describe('username', function () {
|
||||
it('should get the username of the channel', function () {
|
||||
expect(fansly.regex.username.exec('https://fansly.com/18Plus/posts').at(1)).to.equal('18Plus')
|
||||
expect(fansly.regex.username.exec('https://fansly.com/projektmelody/posts').at(1)).to.equal('projektmelody')
|
||||
expect(fansly.regex.username.exec('https://fansly.com/GoodKittenVR').at(1)).to.equal('GoodKittenVR')
|
||||
expect(fansly.regex.username.exec('https://fansly.com/live/MzLewdieB').at(1)).to.equal('MzLewdieB')
|
||||
expect(fansly.regex.username.exec('https://fansly.com/live/340602399334871040').at(1)).to.equal('340602399334871040')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
import fansly from './fansly.js'
|
||||
|
||||
export default {
|
||||
fansly
|
||||
}
|
|
@ -1,9 +1,4 @@
|
|||
.dockerignore
|
||||
.gitignore
|
||||
*~
|
||||
node_modules
|
||||
npm-debug.log
|
||||
README.md
|
||||
.git
|
||||
LICENSE
|
||||
.nvmrc
|
||||
# STOP! This .dockerignore is probably not the .dockerignore you are looking for.
|
||||
# The dockerignore in the ROOT of the Docker context is the .dockerignore that docker uses.
|
||||
# We are using a monorepo and the docker build context is the root of this git repo.
|
||||
# thus, see ../../.dockerignore
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
lts/iron
|
|
@ -19,3 +19,15 @@ Support for
|
|||
* [ ] runs browser headless
|
||||
* [ ] runs in the cloud
|
||||
* [ ] runs in k8s cluster
|
||||
|
||||
|
||||
|
||||
|
||||
## Puppeteer
|
||||
|
||||
For when we get to the point where we need it, here are the packages we used with success during past testing.
|
||||
|
||||
"puppeteer": "^22.7.1",
|
||||
"puppeteer-extra": "^3.3.6",
|
||||
"puppeteer-extra-plugin-repl": "^2.3.3",
|
||||
"puppeteer-extra-plugin-stealth": "^2.11.2"
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"name": "@futureporn/scout",
|
||||
"name": "scout",
|
||||
"type": "module",
|
||||
"version": "3.3.0",
|
||||
"description": "detect when a stream goes live",
|
||||
"main": "index.js",
|
||||
"main": "src/index.email.js",
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"start": "node ./src/index.email.js",
|
||||
|
@ -13,22 +13,22 @@
|
|||
"author": "@CJ_Clippy",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"pg-pubsub": "workspace:*",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"common": "workspace:*",
|
||||
"concurrently": "^8.2.2",
|
||||
"date-fns": "^3.6.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"fastq": "^1.17.1",
|
||||
"faye": "^1.4.0",
|
||||
"imapflow": "^1.0.160",
|
||||
"limiter": "2.0.1",
|
||||
"mailparser": "^3.7.1",
|
||||
"puppeteer": "^22.7.1",
|
||||
"puppeteer-extra": "^3.3.6",
|
||||
"puppeteer-extra-plugin-repl": "^2.3.3",
|
||||
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
||||
"pg-pubsub": "workspace:*",
|
||||
"qs": "^6.12.1",
|
||||
"slugify": "^1.6.6",
|
||||
"xpath": "^0.0.34"
|
||||
},
|
||||
"packageManager": "pnpm@9.1.2",
|
||||
"packageManager": "pnpm@9.1.3",
|
||||
"devDependencies": {
|
||||
"chai": "^5.1.0",
|
||||
"mocha": "^10.4.0"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -49,7 +49,8 @@ export class Email extends EventEmitter {
|
|||
auth: {
|
||||
user: process.env.SCOUT_IMAP_USERNAME,
|
||||
pass: process.env.SCOUT_IMAP_PASSWORD
|
||||
}
|
||||
},
|
||||
logger: false
|
||||
});
|
||||
|
||||
this.registerEventListeners()
|
||||
|
@ -82,7 +83,7 @@ export class Email extends EventEmitter {
|
|||
let lock = await this.client.getMailboxLock('INBOX');
|
||||
let dl, body
|
||||
try {
|
||||
dl = await this.client.download(uid, undefined, { uid: true })
|
||||
dl = await this.client.download(uid, null, { uid: true })
|
||||
body = await streamToString(dl.content)
|
||||
} finally {
|
||||
lock.release()
|
||||
|
@ -97,8 +98,9 @@ export class Email extends EventEmitter {
|
|||
for await (let message of this.client.fetch('1:*', { envelope: true })) {
|
||||
// it is tempting to call this.client.download here, but that is not possible while the mailbox is locked.
|
||||
// client.download must be called outside of this lock
|
||||
// commenting these out because it lags Tilt
|
||||
// console.log('here is a message')
|
||||
console.log(JSON.stringify(message, null, 2))
|
||||
// console.log(JSON.stringify(message, null, 2))
|
||||
this.emit('message', message)
|
||||
}
|
||||
} finally {
|
||||
|
@ -110,7 +112,7 @@ export class Email extends EventEmitter {
|
|||
console.log(` > REGISTERING EVENT LISTENERS <`)
|
||||
this.client.once('end', () => this.reconnect())
|
||||
this.client.on('exists', (evt) => {
|
||||
// console.log(`exists event! count=${evt.count} prevCount=${evt.prevCount}`)
|
||||
console.log(`exists event! count=${evt.count} prevCount=${evt.prevCount}`)
|
||||
// console.log(evt)
|
||||
if (evt.path === 'INBOX') {
|
||||
this.emitAllMessages()
|
||||
|
|
|
@ -25,14 +25,15 @@ async function handleMessage({email, msg}) {
|
|||
await signalRealtime({ url, platform, channel, displayName, date })
|
||||
|
||||
console.log(' ✏️✏️ creating stream entry in db')
|
||||
await createStreamInDb({ platform, channel, date })
|
||||
await createStreamInDb({ source: 'email', platform, channel, date, url })
|
||||
}
|
||||
|
||||
console.log(' ✏️ archiving e-mail')
|
||||
await email.archiveMessage(msg.uid)
|
||||
} catch (e) {
|
||||
// console.error('error encoutered')
|
||||
console.error(` An error was encountered while handling the following e-mail message.\n${JSON.stringify(msg, null, 2)}\nError as follows.\n${e}`)
|
||||
console.error(` An error was encountered while handling the following e-mail message.\n${JSON.stringify(msg, null, 2)}\nError as follows.`)
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { load } from 'cheerio'
|
|||
|
||||
const definitions = [
|
||||
{
|
||||
platform: 'Chaturbate',
|
||||
platform: 'chaturbate',
|
||||
selectors: {
|
||||
channel: 'td[id*="onlinemessage"] a:nth-child(1)'
|
||||
},
|
||||
|
@ -12,7 +12,7 @@ const definitions = [
|
|||
template: 'https://chaturbate.com/:channel'
|
||||
},
|
||||
{
|
||||
platform: 'Fansly',
|
||||
platform: 'fansly',
|
||||
selectors: {
|
||||
url: ($) => $("a[href*='/live/']").attr('href'),
|
||||
displayName: 'div[class*="message-col"] div:nth-child(5)'
|
||||
|
@ -38,10 +38,16 @@ function render(template, values) {
|
|||
*
|
||||
* Check an e-mail for go-live notification content.
|
||||
*
|
||||
* { isMatch, url, platform, channel, displayName, date }
|
||||
*
|
||||
* @param {String} body -- raw mail body
|
||||
* @returns {Object} result
|
||||
* @returns {Boolean} result.isMatch true if e-mail contains a go-live notification
|
||||
* @returns {String} result.channel
|
||||
* @returns {Boolean} result.isMatch true if e-mail contains a go-live notification
|
||||
* @returns {String} result.url example: https://fansly.com/projektmelody
|
||||
* @returns {String} result.platform example: fansly
|
||||
* @returns {String} result.channel example: projektmelody
|
||||
* @returns {String} result.displayName example: ProjektMelody
|
||||
* @returns {String} result.date example: 2024-05-31T01:02:00.000Z
|
||||
*/
|
||||
export async function checkEmail (body) {
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ describe('parsers', function () {
|
|||
const mailBody = await fs.readFile(path.join(__dirname, './fixtures/fansly.fixture.txt'), { encoding: 'utf8' })
|
||||
const { isMatch, channel, platform, url, date } = await checkEmail(mailBody)
|
||||
expect(isMatch).to.equal(true, 'a Fansly heuristic was not found')
|
||||
expect(platform).to.equal('Fansly')
|
||||
expect(platform).to.equal('fansly')
|
||||
expect(channel).to.equal('SkiaObsidian')
|
||||
expect(url).to.equal('https://fansly.com/live/SkiaObsidian')
|
||||
expect(date).to.equal('2024-05-05T03:04:33.000Z')
|
||||
|
@ -21,7 +21,7 @@ describe('parsers', function () {
|
|||
const mailBody = await fs.readFile(path.join(__dirname, './fixtures/chaturbate.fixture.txt'), { encoding: 'utf8' })
|
||||
const { isMatch, channel, platform, url, date } = await checkEmail(mailBody)
|
||||
expect(isMatch).to.equal(true, 'a CB heuristic was not found')
|
||||
expect(platform).to.equal('Chaturbate')
|
||||
expect(platform).to.equal('chaturbate')
|
||||
expect(channel).to.equal('skyeanette')
|
||||
expect(url).to.equal('https://chaturbate.com/skyeanette')
|
||||
expect(date).to.equal('2023-07-24T01:08:28.000Z')
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
import 'dotenv/config'
|
||||
// import { PgPubSub } from '@imqueue/pg-pubsub'; // @see https://github.com/imqueue/pg-pubsub/issues/20
|
||||
import { PgPubSub } from 'pg-pubsub'
|
||||
import qs from 'qs'
|
||||
import { subMinutes, addMinutes } from 'date-fns'
|
||||
import slugify from 'slugify'
|
||||
|
||||
// alternative js libraries for postgres notify/wait
|
||||
// * https://github.com/imqueue/pg-pubsub
|
||||
|
@ -36,27 +39,214 @@ export async function signalRealtime ({ url, platform, channel, displayName, dat
|
|||
|
||||
/**
|
||||
* Create a database record which shows this stream exists
|
||||
*
|
||||
* It's kind of complicated, but we do it this way so we don't need a backend batch processor.
|
||||
* Instead, Scout takes as much responsibility as possible and does the work that a human would do if they were creating the records.
|
||||
*
|
||||
* In Strapi, we are finding or updating or creating the following content-types.
|
||||
* * vtuber
|
||||
* * platform-notification
|
||||
* * stream
|
||||
*
|
||||
* It's a 3 step process, with each step outlined in the function body.
|
||||
*/
|
||||
export async function createStreamInDb ({ platform, channel, date }) {
|
||||
const url = `${process.env.STRAPI_URL}/api/streams`
|
||||
console.log(`we are going to fetch POST ${url} now.`)
|
||||
const res = await fetch(url, {
|
||||
export async function createStreamInDb ({ source, platform, channel, date, url }) {
|
||||
|
||||
let vtuberId, streamId
|
||||
|
||||
console.log('>># Step 1')
|
||||
// # Step 1.
|
||||
// First we find or create the vtuber
|
||||
// The vtuber may already be in the db, so we look for that record. All we need is the Vtuber ID.
|
||||
// If the vtuber is not in the db, we create the vtuber record.
|
||||
|
||||
// GET /api/:pluralApiId?filters[field][operator]=value
|
||||
const findVtubersQueryString = qs.stringify({
|
||||
filters: {
|
||||
chaturbate: (platform === 'chaturbate') ? { '$eq': url } : null,
|
||||
fansly: (platform === 'fansly') ? { '$eq': url } : null
|
||||
}
|
||||
})
|
||||
|
||||
console.log('>> findVtuber')
|
||||
const findVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers?${findVtubersQueryString}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
const findVtuberJson = await findVtuberRes.json()
|
||||
if (findVtuberJson.data.length > 0) {
|
||||
console.log('>>a vtuber was FOUND')
|
||||
vtuberId = findVtuberJson.data.id
|
||||
console.log('here is the findVtuberJson (as follows)')
|
||||
console.log(findVtuberJson)
|
||||
console.log(`the matching vtuber has ID=${vtuberId} (${findVtuberJson.data.attributes.displayName})`)
|
||||
}
|
||||
|
||||
if (!vtuberId) {
|
||||
console.log('>> vtuberId was not found so we create')
|
||||
const createVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
'displayName': channel,
|
||||
'fansly': (platform === 'fansly') ? url : null,
|
||||
'chaturbate': (platform === 'chaturbate') ? url : null,
|
||||
'slug': slugify(channel),
|
||||
'description1': ' ',
|
||||
'image': 'https://placehold.co/200x200.png',
|
||||
'themeColor': '#dde1ec'
|
||||
}
|
||||
})
|
||||
})
|
||||
const createVtuberJson = await createVtuberRes.json()
|
||||
console.log('>> createVtuberJson as follows')
|
||||
console.log(createVtuberJson)
|
||||
if (createVtuberJson.data) {
|
||||
vtuberId = createVtuberJson.data.id
|
||||
console.log(`>>> vtuber created with id=${vtuberId}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (!vtuberId) throw new Error(`>> we weren't able to find or create a vtuberId so we are panicking. (this should not happen under normal circumstances. Bug desu ka?)`)
|
||||
console.log(`>># Step 2. vtuberId=${vtuberId}`)
|
||||
// # Step 2.
|
||||
// Next we create the platform-notification record.
|
||||
// This probably doesn't already exist, so we don't check for a pre-existing platform-notification.
|
||||
const pNotifPayload = {
|
||||
data: {
|
||||
source: source,
|
||||
date: date,
|
||||
date2: date,
|
||||
platform: platform,
|
||||
vtuber: vtuberId,
|
||||
}
|
||||
}
|
||||
console.log('pNotifPayload as follows')
|
||||
console.log(pNotifPayload)
|
||||
|
||||
const pNotifCreateRes = await fetch(`${process.env.STRAPI_URL}/api/platform-notifications`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
body: JSON.stringify(pNotifPayload)
|
||||
})
|
||||
const pNotifData = await pNotifCreateRes.json()
|
||||
if (pNotifData.error) {
|
||||
console.error('>> we failed to create platform-notification, there was an error in the response')
|
||||
console.error(pNotifData.error)
|
||||
throw new Error(pNotifData.error)
|
||||
}
|
||||
console.log(`>> pNotifData (json response) is as follows`)
|
||||
console.log(pNotifData)
|
||||
if (!pNotifData.data?.id) throw new Error('failed to created pNotifData! The response was missing an id');
|
||||
|
||||
// # Step 3.
|
||||
// Finally we find or create the stream record
|
||||
// The stream may already be in the db (the streamer is multi-platform streaming), so we look for that record.
|
||||
// This gets a bit tricky. How do we determine one stream from another?
|
||||
// For now, the rule is 30 minutes of separation.
|
||||
// Anything <=30m is interpreted as the same stream. Anything >30m is interpreted as a different stream.
|
||||
// If the stream is not in the db, we create the stream record
|
||||
|
||||
|
||||
|
||||
// qs.stringify({
|
||||
// populate: 'vtuber',
|
||||
// filters: {
|
||||
// date: {
|
||||
// "$eq": '2024-01-09T08:00:00.000Z'
|
||||
// },
|
||||
// vtuber: {
|
||||
// id: {
|
||||
// '$eq': 1
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }, {
|
||||
// encode: false
|
||||
// })
|
||||
|
||||
|
||||
|
||||
const dateSinceRange = subMinutes(new Date(date), 30)
|
||||
const dateUntilRange = addMinutes(new Date(date), 30)
|
||||
console.log(`Find a stream within + or - 30 mins of the notif date=${new Date(date).toISOString()}. dateSinceRange=${dateSinceRange.toISOString()}, dateUntilRange=${dateUntilRange.toISOString()}`)
|
||||
const findStreamQueryString = qs.stringify({
|
||||
populate: '*',
|
||||
filters: {
|
||||
date: {
|
||||
$gte: dateSinceRange,
|
||||
$lte: dateUntilRange
|
||||
},
|
||||
vtuber: {
|
||||
id: {
|
||||
'$eq': vtuberId
|
||||
}
|
||||
}
|
||||
}
|
||||
}, { encode: false })
|
||||
|
||||
console.log('>> findStream')
|
||||
const findStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams?${findStreamQueryString}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
const findStreamData = await findStreamRes.json()
|
||||
if (findStreamData.data) {
|
||||
console.log('>> we found a findStreamData json')
|
||||
console.log(findStreamData)
|
||||
streamId = findStreamData.data?.id
|
||||
}
|
||||
|
||||
if (!streamId) {
|
||||
console.log('>> did not find a streamId')
|
||||
const createStreamPayload = {
|
||||
data: {
|
||||
isFanslyStream: (platform === 'Fansly') ? true : false,
|
||||
isChaturbateStream: (platform === 'Chaturbate') ? true : false,
|
||||
archiveStatus: 'missing',
|
||||
date: date
|
||||
date: date,
|
||||
date2: date,
|
||||
date_str: date,
|
||||
vtuber: vtuberId,
|
||||
platformNotifications: [
|
||||
pNotifData.data.id
|
||||
]
|
||||
}
|
||||
}
|
||||
console.log('>>createStreamPayload as follows')
|
||||
console.log(createStreamPayload)
|
||||
const createStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(createStreamPayload)
|
||||
})
|
||||
})
|
||||
const json = await res.json()
|
||||
console.log('we got the json')
|
||||
console.log(json)
|
||||
const createStreamJson = await createStreamRes.json()
|
||||
console.log('>>we got the createStreamJson')
|
||||
console.log(createStreamJson)
|
||||
if (createStreamJson.error) {
|
||||
console.error(JSON.stringify(createStreamJson.error, null, 2))
|
||||
throw new Error('Failed to create stream in DB due to an error. (see above)')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ docker_build(
|
|||
docker_build(
|
||||
'fp/scout',
|
||||
'.',
|
||||
only=['./pnpm-lock.yaml', './package.json', './packages/scout', './packages/pg-pubsub'],
|
||||
only=['./pnpm-lock.yaml', './package.json', './packages/scout', './packages/pg-pubsub', './packages/common'],
|
||||
dockerfile='d.scout.dockerfile',
|
||||
target='scout',
|
||||
live_update=[
|
||||
|
@ -181,13 +181,7 @@ k8s_resource(
|
|||
# workload='strapi-app',
|
||||
# port_forwards=['1338']
|
||||
# )
|
||||
k8s_resource(
|
||||
workload='postgres',
|
||||
)
|
||||
k8s_resource(
|
||||
workload='scout',
|
||||
port_forwards=['5000']
|
||||
)
|
||||
|
||||
k8s_resource(
|
||||
workload='postgres',
|
||||
port_forwards=['5432']
|
||||
|
|
Loading…
Reference in New Issue