mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-05 07:28:01 +00:00
52f02f153c
* hotfix 4.0.2: implement playback router * hotfix 4.0.2: fix studio clock styles * hotfix 4.0.2: broadcast clock always * hotfix 4.0.2: fix overflow in timer control
195 lines
4.9 KiB
JavaScript
195 lines
4.9 KiB
JavaScript
// get environment vars
|
|
import 'dotenv/config';
|
|
import { sessionId, user } from './utils/analytics.js';
|
|
user.screenview('Node service', 'ontime').send();
|
|
user.event('NODE', 'started', 'starting node service').send();
|
|
|
|
// import config
|
|
import { config } from './config/config.js';
|
|
|
|
// init database
|
|
import { Low, JSONFile } from 'lowdb';
|
|
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const env = process.env.NODE_ENV || 'prod';
|
|
|
|
const file = path.join(__dirname, 'data/', config.database.filename);
|
|
const adapter = new JSONFile(file);
|
|
export const db = new Low(adapter);
|
|
|
|
// dependencies
|
|
import { Client } from 'node-osc';
|
|
import express from 'express';
|
|
import http from 'http';
|
|
import cors from 'cors';
|
|
import { dbModelv1 as dbModel } from './models/dataModel.js';
|
|
import { parseJsonv1 as parseJson, validateFile } from './utils/parser.js';
|
|
import ua from 'universal-analytics';
|
|
|
|
// validate JSON before attempting read
|
|
let isValid = validateFile(file);
|
|
|
|
if (isValid) {
|
|
// Read data from JSON file, this will set db.data content
|
|
await db.read();
|
|
}
|
|
|
|
// If file.json doesn't exist, db.data will be null
|
|
// Set default data
|
|
// db.data ||= { events: [] }; NODE v15 - v16
|
|
if (db.data == null || !isValid) {
|
|
db.data = dbModel;
|
|
await db.write();
|
|
}
|
|
|
|
// get data
|
|
// there is also the case of the db being corrupt
|
|
// try to parse the data
|
|
export const data = await parseJson(db.data);
|
|
db.data = data;
|
|
await db.write();
|
|
|
|
// Import Routes
|
|
import { router as eventsRouter } from './routes/eventsRouter.js';
|
|
import { router as eventRouter } from './routes/eventRouter.js';
|
|
import { router as ontimeRouter } from './routes/ontimeRouter.js';
|
|
import { router as playbackRouter } from './routes/playbackRouter.js';
|
|
|
|
// Global Objects
|
|
import { EventTimer } from './classes/EventTimer.js';
|
|
|
|
// Create express APP
|
|
const app = express();
|
|
|
|
// setup cors for all routes
|
|
app.use(cors());
|
|
|
|
// enable pre-flight cors
|
|
app.options('*', cors());
|
|
|
|
// Implement middleware
|
|
app.use(ua.middleware(process.env.ANALYTICS_ID, sessionId));
|
|
app.use(express.urlencoded({ extended: true }));
|
|
app.use(express.json({ limit: '1mb' }));
|
|
|
|
app.use('/uploads', express.static('uploads'));
|
|
|
|
// Implement route endpoints
|
|
app.use('/events', eventsRouter);
|
|
app.use('/event', eventRouter);
|
|
app.use('/ontime', ontimeRouter);
|
|
app.use('/playback', playbackRouter);
|
|
|
|
// serve react
|
|
app.use(
|
|
express.static(
|
|
path.join(__dirname, env === 'prod' ? '../' : '../../', 'client/build')
|
|
)
|
|
);
|
|
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(
|
|
path.resolve(
|
|
__dirname,
|
|
env === 'prod' ? '../' : '../../',
|
|
'client',
|
|
'build',
|
|
'index.html'
|
|
)
|
|
);
|
|
});
|
|
|
|
// Implement route for errors
|
|
app.use((err, req, res, next) => {
|
|
res.status(500).send(err.stack);
|
|
});
|
|
|
|
/*************** START SERVICES ***************/
|
|
/* Override config
|
|
* ----------------
|
|
*
|
|
* Configuration of services comes from app general config
|
|
* It can be overriden here by the settings in the db
|
|
* It can also be overriden on call
|
|
*
|
|
*/
|
|
|
|
const s = data.settings;
|
|
const oscIP = s.oscOutIP || config.osc.ipOut;
|
|
const oscOutPort = s.oscOutPort || config.osc.portOut;
|
|
const oscInPort = s.oscInPort || config.osc.port;
|
|
|
|
const serverPort = s.serverPort || config.server.port;
|
|
|
|
// Start OSC server
|
|
import { initiateOSC, shutdownOSCServer } from './controllers/OscController.js';
|
|
|
|
export const startOSCServer = async (overrideConfig = null) => {
|
|
// Setup default port
|
|
const oscSettings = {
|
|
port: overrideConfig?.port || oscInPort,
|
|
ipOut: oscIP,
|
|
portOut: oscOutPort,
|
|
};
|
|
|
|
// Start OSC Server
|
|
initiateOSC(oscSettings);
|
|
};
|
|
|
|
// Start OSC Client
|
|
let oscClient = null;
|
|
|
|
export const startOSCClient = async (overrideConfig = null) => {
|
|
// Setup default port
|
|
const port = overrideConfig?.port || oscOutPort;
|
|
console.log('initialise OSC Client on port: ', port);
|
|
|
|
oscClient = new Client(oscIP, oscOutPort);
|
|
};
|
|
|
|
// create HTTP server
|
|
const server = http.createServer(app);
|
|
|
|
export const startServer = async (overrideConfig = null) => {
|
|
// Setup default port
|
|
// const port = overrideConfig?.port || serverPort;
|
|
|
|
/* Note: Port is hardcoded
|
|
* need to find a good solution for sharing
|
|
* the dynamic info with the frontend
|
|
*/
|
|
const port = 4001;
|
|
|
|
// Start server
|
|
const returnMessage = `HTTP Server is listening on port ${port}`;
|
|
server.listen(port, '0.0.0.0', () => console.log(returnMessage));
|
|
|
|
// init timer
|
|
global.timer = new EventTimer(server, oscClient, config);
|
|
global.timer.setupWithEventList(data.events);
|
|
|
|
return returnMessage;
|
|
};
|
|
|
|
export const shutdown = async () => {
|
|
console.log('Node service shutdown');
|
|
|
|
user.event('NODE', 'shutdown', 'requesting node shutfown').send();
|
|
|
|
// shutdown express server
|
|
server.close();
|
|
|
|
// shutdown OSC Server
|
|
shutdownOSCServer();
|
|
|
|
// shutdown OSC Client
|
|
oscClient.close();
|
|
|
|
// shutdown timer
|
|
global.timer.shutdown();
|
|
};
|