rewind time and fix our past mistakes
ci / build (push) Has been cancelled
Details
ci / build (push) Has been cancelled
Details
This commit is contained in:
parent
3384bb8f45
commit
4e0dbbb2c8
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -75,7 +75,6 @@ export default {
|
||||||
const discordMessageId = message.id
|
const discordMessageId = message.id
|
||||||
await workerUtils.addJob('startRecording', { url, discordMessageId }, { maxAttempts: 3 })
|
await workerUtils.addJob('startRecording', { url, discordMessageId }, { maxAttempts: 3 })
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
@ -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}`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
|
@ -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": {
|
||||||
|
|
Loading…
Reference in New Issue