Skip to content

Commit

Permalink
refactor: initialise data
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente committed Jul 11, 2024
1 parent 73f8717 commit b033b1d
Show file tree
Hide file tree
Showing 31 changed files with 998 additions and 512 deletions.
2 changes: 1 addition & 1 deletion apps/server/src/api-data/db/db.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function createProjectFile(req: Request, res: Response<{ filename:
*/
export async function projectDownload(req: Request, res: Response) {
const { filename } = req.body;
const pathToFile = await doesProjectExist(filename);
const pathToFile = doesProjectExist(filename);
if (!pathToFile) {
return res.status(404).send({ message: `Project ${filename} not found.` });
}
Expand Down
10 changes: 5 additions & 5 deletions apps/server/src/api-data/http/http.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { ErrorResponse, HttpSettings } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';

import { Request, Response } from 'express';
import type { Request, Response } from 'express';

import { DataProvider } from '../../classes/data-provider/DataProvider.js';
import { failEmptyObjects } from '../../utils/routerUtils.js';
import { httpIntegration } from '../../services/integration-service/HttpIntegration.js';
import { getErrorMessage } from 'ontime-utils';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';

export async function getHTTP(_req: Request, res: Response<HttpSettings>) {
const http = DataProvider.getHttp();
const http = getDataProvider().getHttp();
res.status(200).send(http);
}

Expand All @@ -22,7 +22,7 @@ export async function postHTTP(req: Request, res: Response<HttpSettings | ErrorR

httpIntegration.init(httpSettings);
// we persist the data after init to avoid persisting invalid data
const result = await DataProvider.setHttp(httpSettings);
const result = await getDataProvider().setHttp(httpSettings);
res.send(result).status(200);
} catch (error) {
const message = getErrorMessage(error);
Expand Down
10 changes: 5 additions & 5 deletions apps/server/src/api-data/osc/osc.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { ErrorResponse, OSCSettings } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';

import { Request, Response } from 'express';
import type { Request, Response } from 'express';

import { DataProvider } from '../../classes/data-provider/DataProvider.js';
import { failEmptyObjects } from '../../utils/routerUtils.js';
import { oscIntegration } from '../../services/integration-service/OscIntegration.js';
import { getErrorMessage } from 'ontime-utils';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';

export async function getOSC(_req: Request, res: Response<OSCSettings>) {
const osc = DataProvider.getOsc();
const osc = getDataProvider().getOsc();
res.status(200).send(osc);
}

Expand All @@ -22,7 +22,7 @@ export async function postOSC(req: Request, res: Response<OSCSettings | ErrorRes

oscIntegration.init(oscSettings);
// we persist the data after init to avoid persisting invalid data
const result = await DataProvider.setOsc(oscSettings);
const result = await getDataProvider().setOsc(oscSettings);

res.send(result).status(200);
} catch (error) {
Expand Down
9 changes: 5 additions & 4 deletions apps/server/src/api-data/project/project.controller.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ErrorResponse, ProjectData } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';

import type { Request, Response } from 'express';
import { DataProvider } from '../../classes/data-provider/DataProvider.js';

import { removeUndefined } from '../../utils/parserUtils.js';
import { failEmptyObjects } from '../../utils/routerUtils.js';
import { getErrorMessage } from 'ontime-utils';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';

export async function getProjectData(_req: Request, res: Response<ProjectData>) {
res.json(DataProvider.getProjectData());
res.json(getDataProvider().getProjectData());
}

export async function postProjectData(req: Request, res: Response<ProjectData | ErrorResponse>) {
Expand All @@ -25,7 +26,7 @@ export async function postProjectData(req: Request, res: Response<ProjectData |
backstageInfo: req.body?.backstageInfo,
endMessage: req.body?.endMessage,
});
const newData = await DataProvider.setProjectData(newEvent);
const newData = await getDataProvider().setProjectData(newEvent);
res.status(200).send(newData);
} catch (error) {
const message = getErrorMessage(error);
Expand Down
10 changes: 5 additions & 5 deletions apps/server/src/api-data/settings/settings.controller.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { ErrorResponse, Settings } from 'ontime-types';
import { getErrorMessage, obfuscate } from 'ontime-utils';

import { Request, Response } from 'express';
import type { Request, Response } from 'express';

import { DataProvider } from '../../classes/data-provider/DataProvider.js';
import { failEmptyObjects } from '../../utils/routerUtils.js';
import { isDocker } from '../../setup/index.js';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';

import { extractPin } from './settings.utils.js';

export async function getSettings(_req: Request, res: Response<Settings>) {
const settings = DataProvider.getSettings();
const settings = getDataProvider().getSettings();
const obfuscatedSettings = { ...settings };
if (settings.editorKey) {
obfuscatedSettings.editorKey = obfuscate(settings.editorKey);
Expand All @@ -28,7 +28,7 @@ export async function postSettings(req: Request, res: Response<Settings | ErrorR
return;
}
try {
const settings = DataProvider.getSettings();
const settings = getDataProvider().getSettings();
const editorKey = extractPin(req.body?.editorKey, settings.editorKey);
const operatorKey = extractPin(req.body?.operatorKey, settings.operatorKey);
const serverPort = Number(req.body?.serverPort);
Expand Down Expand Up @@ -58,7 +58,7 @@ export async function postSettings(req: Request, res: Response<Settings | ErrorR
language,
serverPort,
};
await DataProvider.setSettings(newData);
await getDataProvider().setSettings(newData);
res.status(200).send(newData);
} catch (error) {
const message = getErrorMessage(error);
Expand Down
10 changes: 5 additions & 5 deletions apps/server/src/api-data/url-presets/urlPresets.controller.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { ErrorResponse, URLPreset } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';

import { Request, Response } from 'express';
import type { Request, Response } from 'express';

import { DataProvider } from '../../classes/data-provider/DataProvider.js';
import { failIsNotArray } from '../../utils/routerUtils.js';
import { getErrorMessage } from 'ontime-utils';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';

export async function getUrlPresets(_req: Request, res: Response<URLPreset[]>) {
const presets = DataProvider.getUrlPresets();
const presets = getDataProvider().getUrlPresets();
res.status(200).send(presets as URLPreset[]);
}

Expand All @@ -21,7 +21,7 @@ export async function postUrlPresets(req: Request, res: Response<URLPreset[] | E
alias: preset.alias,
pathAndParams: preset.pathAndParams,
}));
await DataProvider.setUrlPresets(newPresets);
await getDataProvider().setUrlPresets(newPresets);
res.status(200).send(newPresets);
} catch (error) {
const message = getErrorMessage(error);
Expand Down
19 changes: 7 additions & 12 deletions apps/server/src/api-data/view-settings/viewSettings.controller.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import type { ErrorResponse, ViewSettings } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';

import { Request, Response } from 'express';
import type { Request, Response } from 'express';

import { DataProvider } from '../../classes/data-provider/DataProvider.js';
import { failEmptyObjects } from '../../utils/routerUtils.js';
import { getErrorMessage } from 'ontime-utils';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';

export async function getViewSettings(_req: Request, res: Response<ViewSettings>) {
const views = DataProvider.getViewSettings();
const views = getDataProvider().getViewSettings();
res.status(200).send(views);
}

export async function postViewSettings(req: Request, res: Response<ViewSettings | ErrorResponse>) {
if (failEmptyObjects(req.body, res)) {
return;
}

try {
const newData = {
dangerColor: req.body.dangerColor,
endMessage: req.body?.endMessage ?? '',
endMessage: req.body.endMessage,
freezeEnd: req.body.freezeEnd,
normalColor: req.body.normalColor,
overrideStyles: req.body.overrideStyles,
warningColor: req.body.warningColor,
};
await DataProvider.setViewSettings(newData);
} as ViewSettings;
await getDataProvider().setViewSettings(newData);
res.status(200).send(newData);
} catch (error) {
const message = getErrorMessage(error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import { Request, Response, NextFunction } from 'express';
* @description Validates object for POST /ontime/views
*/
export const validateViewSettings = [
check('overrideStyles').isBoolean().withMessage('overrideStyles value must be boolean'),
check('endMessage').isString().trim().withMessage('endMessage value must be string'),
check('normalColor').isString().trim().withMessage('normalColor value must be string'),
check('warningColor').isString().trim().withMessage('warningColor value must be string'),
check('dangerColor').isString().trim().withMessage('dangerColor value must be string'),
check('dangerColor').exists().isString().trim().withMessage('dangerColor value must be string'),
check('endMessage').exists().isString().trim().withMessage('endMessage value must be string'),
check('freezeEnd').exists().isBoolean().withMessage('freezeEnd value must be boolean'),
check('normalColor').exists().isString().trim().withMessage('normalColor value must be string'),
check('overrideStyles').exists().isBoolean().withMessage('overrideStyles value must be boolean'),
check('warningColor').exists().isString().trim().withMessage('warningColor value must be string'),

(req: Request, res: Response, next: NextFunction) => {
const errors = validationResult(req);
Expand Down
19 changes: 10 additions & 9 deletions apps/server/src/api-integration/integration.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,17 @@ const actionHandlers: Record<string, ActionHandler> = {
throw new Error('Invalid property or value');
}

const newObjectProperty = parseProperty(property, value);
// parseProperty is async because of the data lock
parseProperty(property, value).then((newObjectProperty) => {
const key = Object.keys(newObjectProperty)[0] as keyof OntimeEvent;
shouldThrottle = willCauseRegeneration(key) || shouldThrottle;

const key = Object.keys(newObjectProperty)[0] as keyof OntimeEvent;
shouldThrottle = willCauseRegeneration(key) || shouldThrottle;

if (patchEvent.custom && newObjectProperty.custom) {
Object.assign(patchEvent.custom, newObjectProperty.custom);
} else {
Object.assign(patchEvent, newObjectProperty);
}
if (patchEvent.custom && newObjectProperty.custom) {
Object.assign(patchEvent.custom, newObjectProperty.custom);
} else {
Object.assign(patchEvent, newObjectProperty);
}
});
});

if (shouldThrottle) {
Expand Down
9 changes: 5 additions & 4 deletions apps/server/src/api-integration/integration.utils.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { EndAction, OntimeEvent, TimerType, isKeyOfType, isOntimeEvent } from 'ontime-types';
import { MILLIS_PER_SECOND, maxDuration } from 'ontime-utils';

import { DataProvider } from '../classes/data-provider/DataProvider.js';
import { editEvent } from '../services/rundown-service/RundownService.js';
import { getEventWithId } from '../services/rundown-service/rundownUtils.js';
import { coerceBoolean, coerceColour, coerceEnum, coerceNumber, coerceString } from '../utils/coerceType.js';
import { getDataProvider } from '../classes/data-provider/DataProvider.js';

/**
*
* @param {number} value time amount in seconds
* @returns {number} time in milliseconds clamped to 0 and max duration
*/
function clampDuration(value: number) {
function clampDuration(value: number): number {
const valueInMillis = value * MILLIS_PER_SECOND;
if (valueInMillis > maxDuration || valueInMillis < 0) {
throw new Error('Times should be from 0 to 23:59:59');
Expand Down Expand Up @@ -42,10 +42,11 @@ const propertyConversion = {
timeEnd: (value: unknown) => clampDuration(coerceNumber(value)),
};

export function parseProperty(property: string, value: unknown) {
export async function parseProperty(property: string, value: unknown) {
if (property.startsWith('custom:')) {
const customKey = property.split(':')[1].toLocaleLowerCase(); // all custom fields keys are lowercase
if (!(customKey in DataProvider.getCustomFields())) {
const customFields = getDataProvider().getCustomFields();
if (!(customKey in customFields)) {
throw new Error(`Custom field ${customKey} not found`);
}
const parserFn = propertyConversion.custom;
Expand Down
26 changes: 13 additions & 13 deletions apps/server/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HttpSettings, LogOrigin, OSCSettings, Playback, SimpleDirection, SimplePlayback } from 'ontime-types';
import { LogOrigin, Playback, SimpleDirection, SimplePlayback } from 'ontime-types';

import 'dotenv/config';
import express from 'express';
Expand All @@ -13,10 +13,10 @@ import {
srcDirectory,
environment,
isProduction,
resolveDbPath,
resolveExternalsDirectory,
resolveStylesDirectory,
resolvedPath,
resolvePublicDirectoy,
} from './setup/index.js';
import { ONTIME_VERSION } from './ONTIME_VERSION.js';
import { consoleSuccess, consoleHighlight } from './utils/console.js';
Expand All @@ -27,8 +27,7 @@ import { integrationRouter } from './api-integration/integration.router.js';

// Import adapters
import { socket } from './adapters/WebsocketAdapter.js';
import { DataProvider } from './classes/data-provider/DataProvider.js';
import { dbLoadingProcess } from './setup/loadDb.js';
import { getDataProvider } from './classes/data-provider/DataProvider.js';

// Services
import { integrationService } from './services/integration-service/IntegrationService.js';
Expand All @@ -43,6 +42,7 @@ import { messageService } from './services/message-service/MessageService.js';
import { populateDemo } from './setup/loadDemo.js';
import { getState } from './stores/runtimeState.js';
import { initRundown } from './services/rundown-service/RundownService.js';
import { initialiseProject } from './services/project-service/ProjectService.js';

// Utilities
import { clearUploadfolder } from './utils/upload.js';
Expand All @@ -55,8 +55,8 @@ consoleHighlight(`Starting Ontime version ${ONTIME_VERSION}`);
const canLog = isProduction;
if (!canLog) {
console.log(`Ontime running in ${environment} environment`);
console.log(`Ontime directory at ${srcDirectory} `);
console.log(`Ontime database at ${resolveDbPath}`);
console.log(`Ontime source directory at ${srcDirectory} `);
console.log(`Ontime public directory at ${resolvePublicDirectoy} `);
}

// Create express APP
Expand Down Expand Up @@ -149,10 +149,11 @@ const checkStart = (currentState: OntimeStartOrder) => {

export const initAssets = async () => {
checkStart(OntimeStartOrder.InitAssets);
await dbLoadingProcess;
await clearUploadfolder();
populateStyles();
populateDemo();
const project = await initialiseProject();
logger.info(LogOrigin.Server, `Initialised Ontime with ${project}`);
};

/**
Expand All @@ -162,8 +163,7 @@ export const startServer = async (
escalateErrorFn?: (error: string) => void,
): Promise<{ message: string; serverPort: number }> => {
checkStart(OntimeStartOrder.InitServer);

const { serverPort } = DataProvider.getSettings();
const { serverPort } = getDataProvider().getSettings();

expressServer = http.createServer(app);
socket.init(expressServer);
Expand Down Expand Up @@ -194,8 +194,8 @@ export const startServer = async (
logger.init(escalateErrorFn);

// initialise rundown service
const persistedRundown = DataProvider.getRundown();
const persistedCustomFields = DataProvider.getCustomFields();
const persistedRundown = getDataProvider().getRundown();
const persistedCustomFields = getDataProvider().getCustomFields();
initRundown(persistedRundown, persistedCustomFields);

// load restore point if it exists
Expand Down Expand Up @@ -225,11 +225,11 @@ export const startServer = async (
/**
* starts integrations
*/
export const startIntegrations = async (config?: { osc: OSCSettings; http: HttpSettings }) => {
export const startIntegrations = async () => {
checkStart(OntimeStartOrder.InitIO);

// if a config is not provided, we use the persisted one
const { osc, http } = config ?? DataProvider.getData();
const { osc, http } = getDataProvider().getData();

if (osc) {
logger.info(LogOrigin.Tx, 'Initialising OSC Integration...');
Expand Down
Loading

0 comments on commit b033b1d

Please sign in to comment.