rewind time and fix our past mistakes
ci / build (push) Has been cancelled Details

This commit is contained in:
CJ_Clippy 2024-08-02 15:00:49 -08:00
parent 3384bb8f45
commit 4e0dbbb2c8
10 changed files with 38 additions and 23 deletions

View File

@ -18,6 +18,7 @@
"author": "@CJ_Clippy", "author": "@CJ_Clippy",
"license": "Unlicense", "license": "Unlicense",
"dependencies": { "dependencies": {
"date-fns": "^3.6.0",
"discord.js": "^14.15.3", "discord.js": "^14.15.3",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"graphile-config": "0.0.1-beta.9", "graphile-config": "0.0.1-beta.9",

View File

@ -8,6 +8,9 @@ importers:
.: .:
dependencies: dependencies:
date-fns:
specifier: ^3.6.0
version: 3.6.0
discord.js: discord.js:
specifier: ^14.15.3 specifier: ^14.15.3
version: 14.15.3 version: 14.15.3
@ -418,6 +421,9 @@ packages:
create-require@1.1.1: create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
date-fns@3.6.0:
resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==}
debug@4.3.6: debug@4.3.6:
resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}
@ -1113,6 +1119,8 @@ snapshots:
create-require@1.1.1: {} create-require@1.1.1: {}
date-fns@3.6.0: {}
debug@4.3.6(supports-color@5.5.0): debug@4.3.6(supports-color@5.5.0):
dependencies: dependencies:
ms: 2.1.2 ms: 2.1.2

View File

@ -74,7 +74,6 @@ export default {
const message = await idk.fetch() const message = await idk.fetch()
const discordMessageId = message.id const discordMessageId = message.id
await workerUtils.addJob('startRecording', { url, discordMessageId }, { maxAttempts: 3 }) await workerUtils.addJob('startRecording', { url, discordMessageId }, { maxAttempts: 3 })
}, },
}; };

View File

@ -1,6 +1,7 @@
import 'dotenv/config' import 'dotenv/config'
import type { RecordingState } from '@futureporn/types' import type { RecordingState } from '@futureporn/types'
import { type Task, type Helpers } from 'graphile-worker'; import { type Task, type Helpers } from 'graphile-worker'
import { add } from 'date-fns'
import { import {
Client, Client,
GatewayIntentBits, GatewayIntentBits,
@ -13,11 +14,6 @@ import {
Guild Guild
} from 'discord.js'; } from 'discord.js';
// export interface DiscordMessageUpdateJob extends Job {
// data: {
// captureJobId: string;
// }
// }
interface Payload { interface Payload {
recordId: number; recordId: number;
@ -41,7 +37,7 @@ if (!process.env.DISCORD_GUILD_ID) throw new Error("DISCORD_GUILD_ID was missing
async function editDiscordMessage({ helpers, state, discordMessageId }: { helpers: Helpers, state: RecordingState, discordMessageId: string }) { async function editDiscordMessage({ helpers, state, discordMessageId }: { helpers: Helpers, state: RecordingState, discordMessageId: string }) {
// const { captureJobId } = job.data // const { captureJobId } = job.data
helpers.logger.info(`discordMessageUpdate job has begun with discordMessageId=${discordMessageId}, state=${state}`) helpers.logger.info(`editDiscordMessage has begun with discordMessageId=${discordMessageId}, state=${state}`)
// create a discord.js client // create a discord.js client
@ -94,7 +90,7 @@ async function getRecordFromDatabase(recordId: number) {
if (!res.ok) { if (!res.ok) {
throw new Error(`failed fetching record ${recordId}. status=${res.status}, statusText=${res.statusText}`) throw new Error(`failed fetching record ${recordId}. status=${res.status}, statusText=${res.statusText}`)
} }
const body = await res.json() as any const body = await res.json() as any
return body[0]; return body[0];
} }
@ -114,6 +110,12 @@ export const updateDiscordMessage: Task = async function (payload, helpers: Help
const record = await getRecordFromDatabase(payload.recordId) const record = await getRecordFromDatabase(payload.recordId)
const { discordMessageId, state } = record const { discordMessageId, state } = record
editDiscordMessage({ helpers, state, discordMessageId }) editDiscordMessage({ helpers, state, discordMessageId })
// schedule the next update 10s from now, but only if the recording is still happening
if (state !== 'ended') {
const runAt = add(new Date(), { seconds: 10 })
const recordId = record.id
await helpers.addJob('updateDiscordMessage', { recordId }, { jobKey: `record_${recordId}_update_discord_message`, maxAttempts: 3, runAt })
}
} catch (e) { } catch (e) {
helpers.logger.error(`caught an error during updateDiscordMessage. e=${e}`) helpers.logger.error(`caught an error during updateDiscordMessage. e=${e}`)
} }

View File

@ -27,6 +27,7 @@
"@types/chai": "^4.3.16", "@types/chai": "^4.3.16",
"@types/fluent-ffmpeg": "^2.1.24", "@types/fluent-ffmpeg": "^2.1.24",
"@types/mocha": "^10.0.7", "@types/mocha": "^10.0.7",
"date-fns": "^3.6.0",
"diskusage": "^1.2.0", "diskusage": "^1.2.0",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"execa": "^6.1.0", "execa": "^6.1.0",

View File

@ -38,6 +38,9 @@ importers:
'@types/mocha': '@types/mocha':
specifier: ^10.0.7 specifier: ^10.0.7
version: 10.0.7 version: 10.0.7
date-fns:
specifier: ^3.6.0
version: 3.6.0
diskusage: diskusage:
specifier: ^1.2.0 specifier: ^1.2.0
version: 1.2.0 version: 1.2.0
@ -1395,6 +1398,9 @@ packages:
resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
date-fns@3.6.0:
resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==}
dateformat@4.6.3: dateformat@4.6.3:
resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
@ -4514,6 +4520,8 @@ snapshots:
es-errors: 1.3.0 es-errors: 1.3.0
is-data-view: 1.0.1 is-data-view: 1.0.1
date-fns@3.6.0: {}
dateformat@4.6.3: {} dateformat@4.6.3: {}
debug@3.2.7(supports-color@5.5.0): debug@3.2.7(supports-color@5.5.0):

View File

@ -1,5 +1,6 @@
import { Helpers, type Task } from 'graphile-worker' import { Helpers, type Task } from 'graphile-worker'
import { add } from 'date-fns'
/** /**
* url is the URL to be recorded. Ex: chaturbate.com/projektmelody * url is the URL to be recorded. Ex: chaturbate.com/projektmelody
@ -20,6 +21,7 @@ function assertPayload(payload: any): asserts payload is Payload {
function assertEnv() { function assertEnv() {
if (!process.env.AUTOMATION_USER_JWT) throw new Error('AUTOMATION_USER_JWT was missing in env'); if (!process.env.AUTOMATION_USER_JWT) throw new Error('AUTOMATION_USER_JWT was missing in env');
if (!process.env.POSTGREST_URL) throw new Error('POSTGREST_URL was missing in env');
} }
async function createRecordingRecord(payload: Payload, helpers: Helpers): Promise<number> { async function createRecordingRecord(payload: Payload, helpers: Helpers): Promise<number> {
@ -29,7 +31,7 @@ async function createRecordingRecord(payload: Payload, helpers: Helpers): Promis
discord_message_id: discordMessageId, discord_message_id: discordMessageId,
is_aborted: false is_aborted: false
} }
const res = await fetch('http://postgrest.futureporn.svc.cluster.local:9000/records', { const res = await fetch(`${process.env.POSTGREST_URL}/records`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -55,8 +57,10 @@ export const startRecording: Task = async function (payload, helpers) {
assertEnv() assertEnv()
const recordId = await createRecordingRecord(payload, helpers) const recordId = await createRecordingRecord(payload, helpers)
const { url } = payload; const { url } = payload;
console.log(`@todo simulated start_recording with url=${url}, recordId=${recordId}`) console.log(`@todo simulated startRecording with url=${url}, recordId=${recordId}`)
await helpers.addJob('record', { url, recordId }, { maxAttempts: 3 }) await helpers.addJob('record', { url, recordId }, { maxAttempts: 3, jobKey: `record_${recordId}` })
const runAt = add(new Date(), { seconds: 10 })
await helpers.addJob('updateDiscordMessage', { recordId }, { jobKey: `record_${recordId}_update_discord_message`, maxAttempts: 3, runAt })
} }
export default startRecording export default startRecording

View File

@ -3,7 +3,8 @@ CREATE TABLE api.records (
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
url TEXT NOT NULL, url TEXT NOT NULL,
discord_message_id TEXT NOT NULL, discord_message_id TEXT NOT NULL,
is_aborted BOOLEAN DEFAULT FALSE recording_state TEXT NOT NULL DEFAULT 'pending',
file_size BIGINT NOT NULL DEFAULT 0;
); );
-- roles & permissions for our backend automation user -- roles & permissions for our backend automation user

View File

@ -1,9 +0,0 @@
ALTER TABLE api.records
ADD COLUMN recording_state TEXT NOT NULL DEFAULT 'pending' CHECK(recording_state IN ('pending', 'recording', 'aborted', 'ended')),
ADD COLUMN file_size BIGINT NOT NULL DEFAULT 0;
-- Grant permissions to the new columns for our backend automation user
GRANT UPDATE (recording_state, file_size) ON api.records TO automation;
-- Grant read-only access to the new columns for our web anon user
GRANT SELECT (recording_state, file_size) ON api.records TO web_anon;

View File

@ -1,7 +1,7 @@
{ {
"name": "@futureporn/migrations", "name": "@futureporn/migrations",
"type": "module", "type": "module",
"version": "0.3.0", "version": "0.4.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {