mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-10 00:29:41 +00:00
Fix/121 (#124)
* fix/121: database is in public directory * fix/121: refact loading sequence * fix/121: populate with demo db * fix/121: ensure path exists (linux issues)
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ontime",
|
"name": "ontime",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"author": "Carlos Valente",
|
"author": "Carlos Valente",
|
||||||
"description": "Time keeping for live events",
|
"description": "Time keeping for live events",
|
||||||
"repository": "https://github.com/cpvalente/ontime",
|
"repository": "https://github.com/cpvalente/ontime",
|
||||||
|
|||||||
+17
-58
@@ -4,53 +4,14 @@ import 'dotenv/config';
|
|||||||
// import config
|
// import config
|
||||||
import { config } from './config/config.js';
|
import { config } from './config/config.js';
|
||||||
|
|
||||||
|
// import dependencies
|
||||||
|
import { dirname, join, resolve } from 'path';
|
||||||
// init database
|
// init database
|
||||||
import { Low, JSONFile } from 'lowdb';
|
import loadDb from './modules/loadDb.js';
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
console.log(`Starting ontime version ${process.env.npm_package_version}`)
|
|
||||||
|
|
||||||
// dependencies
|
// dependencies
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { dbModelv1 as dbModel } from './models/dataModel.js';
|
|
||||||
import { parseJson_v1 as parseJson } from './utils/parser.js';
|
|
||||||
import { validateFile } from './utils/parserUtils.js';
|
|
||||||
|
|
||||||
// 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, make sure that all fields exist (enforce)
|
|
||||||
export const data = await parseJson(db.data, true);
|
|
||||||
db.data = data;
|
|
||||||
await db.write();
|
|
||||||
|
|
||||||
// Import Routes
|
// Import Routes
|
||||||
import { router as eventsRouter } from './routes/eventsRouter.js';
|
import { router as eventsRouter } from './routes/eventsRouter.js';
|
||||||
@@ -60,6 +21,18 @@ import { router as playbackRouter } from './routes/playbackRouter.js';
|
|||||||
|
|
||||||
// Global Objects
|
// Global Objects
|
||||||
import { EventTimer } from './classes/EventTimer.js';
|
import { EventTimer } from './classes/EventTimer.js';
|
||||||
|
// Start OSC server
|
||||||
|
import { initiateOSC, shutdownOSCServer } from './controllers/OscController.js';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
// get environment
|
||||||
|
const env = process.env.NODE_ENV || 'prod';
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
export const { db, data } = await loadDb(__dirname);
|
||||||
|
|
||||||
|
console.log(`Starting ontime version ${process.env.npm_package_version}`);
|
||||||
|
|
||||||
// Create express APP
|
// Create express APP
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -83,21 +56,11 @@ app.use('/ontime', ontimeRouter);
|
|||||||
app.use('/playback', playbackRouter);
|
app.use('/playback', playbackRouter);
|
||||||
|
|
||||||
// serve react
|
// serve react
|
||||||
app.use(
|
app.use(express.static(join(__dirname, env === 'prod' ? '../' : '../../', 'client/build')));
|
||||||
express.static(
|
|
||||||
path.join(__dirname, env === 'prod' ? '../' : '../../', 'client/build'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
app.get('*', (req, res) => {
|
app.get('*', (req, res) => {
|
||||||
res.sendFile(
|
res.sendFile(
|
||||||
path.resolve(
|
resolve(__dirname, env === 'prod' ? '../' : '../../', 'client', 'build', 'index.html')
|
||||||
__dirname,
|
|
||||||
env === 'prod' ? '../' : '../../',
|
|
||||||
'client',
|
|
||||||
'build',
|
|
||||||
'index.html',
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -124,11 +87,7 @@ const oscInEnabled = osc?.enabled !== undefined ? osc.enabled : config.osc.input
|
|||||||
|
|
||||||
const serverPort = data.settings.serverPort || config.server.port;
|
const serverPort = data.settings.serverPort || config.server.port;
|
||||||
|
|
||||||
// Start OSC server
|
|
||||||
import { initiateOSC, shutdownOSCServer } from './controllers/OscController.js';
|
|
||||||
|
|
||||||
export const startOSCServer = async (overrideConfig = null) => {
|
export const startOSCServer = async (overrideConfig = null) => {
|
||||||
|
|
||||||
if (!oscInEnabled) {
|
if (!oscInEnabled) {
|
||||||
global.timer.info('RX', 'OSC Input Disabled');
|
global.timer.info('RX', 'OSC Input Disabled');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { JSONFile, Low } from 'lowdb';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { copyFileSync, existsSync } from 'fs';
|
||||||
|
import { ensureDirectory, getAppDataPath } from '../utils/fileManagement.js';
|
||||||
|
import { config } from '../config/config.js';
|
||||||
|
import { validateFile } from '../utils/parserUtils.js';
|
||||||
|
import { dbModelv1 as dbModel } from '../models/dataModel.js';
|
||||||
|
import { parseJson_v1 as parseJson } from '../utils/parser.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description ensures directories exist and picks available db path
|
||||||
|
* @param runningDirectory
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
const checkDirectories = (runningDirectory) => {
|
||||||
|
const appPath = getAppDataPath();
|
||||||
|
const dbDirectory = join(appPath, 'data');
|
||||||
|
const dbInDisk = join(dbDirectory, config.database.filename);
|
||||||
|
const startupDb = join(runningDirectory, 'data', config.database.filename);
|
||||||
|
ensureDirectory(dbDirectory);
|
||||||
|
|
||||||
|
// if dbInDisk doesnt exist we want to use startup db
|
||||||
|
if (!existsSync(dbInDisk)) {
|
||||||
|
try {
|
||||||
|
copyFileSync(startupDb, dbInDisk);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbInDisk;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description parses a json file to the adapter
|
||||||
|
* @param fileToRead
|
||||||
|
* @param adapterToUse
|
||||||
|
* @return {Promise<number|*>}
|
||||||
|
*/
|
||||||
|
const parseDb = async (fileToRead, adapterToUse) => {
|
||||||
|
if (validateFile(fileToRead)) {
|
||||||
|
await adapterToUse.read();
|
||||||
|
} else {
|
||||||
|
adapterToUse.data = dbModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseJson(adapterToUse.data, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Modules loads ontime db
|
||||||
|
* @param runningDirectory
|
||||||
|
* @return {Promise<{data: (number|*), db: Low<unknown>}>}
|
||||||
|
*/
|
||||||
|
export default async function loadDb(runningDirectory) {
|
||||||
|
const dbInDisk = checkDirectories(runningDirectory);
|
||||||
|
|
||||||
|
const adapter = new JSONFile(dbInDisk);
|
||||||
|
const db = new Low(adapter);
|
||||||
|
|
||||||
|
const data = await parseDb(dbInDisk, db);
|
||||||
|
|
||||||
|
db.data = data;
|
||||||
|
await db.write();
|
||||||
|
|
||||||
|
return { db, data };
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ontime-server",
|
"name": "ontime-server",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.20.0",
|
"body-parser": "^1.20.0",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { existsSync, mkdirSync } from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Creates a directory if it doesnt exist
|
||||||
|
* @param directory
|
||||||
|
*/
|
||||||
|
export function ensureDirectory(directory) {
|
||||||
|
if (!existsSync(directory)) {
|
||||||
|
try {
|
||||||
|
mkdirSync(directory, { recursive: true });
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Could not create directory: ${err}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Whether a file exists
|
||||||
|
* @param directory
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
export function doesFileExist(directory) {
|
||||||
|
return existsSync(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Returns public path depending on OS
|
||||||
|
* @return {string|*}
|
||||||
|
*/
|
||||||
|
export function getAppDataPath() {
|
||||||
|
switch (process.platform) {
|
||||||
|
case 'darwin': {
|
||||||
|
return path.join(process.env.HOME, 'Library', 'Application Support', 'Ontime');
|
||||||
|
}
|
||||||
|
case 'win32': {
|
||||||
|
return path.join(process.env.APPDATA, 'Ontime');
|
||||||
|
}
|
||||||
|
case 'linux': {
|
||||||
|
return path.join(process.env.HOME, '.Ontime');
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error('Could not resolve public folder for platform');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,7 @@
|
|||||||
import multer from 'multer';
|
import multer from 'multer';
|
||||||
import { existsSync, mkdirSync } from 'fs';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { EXCEL_MIME, JSON_MIME } from './parser.js';
|
import { EXCEL_MIME, JSON_MIME } from './parser.js';
|
||||||
|
import { ensureDirectory, getAppDataPath } from './fileManagement.js';
|
||||||
/**
|
|
||||||
* @description Returns public path depending on os
|
|
||||||
* @return {string|*}
|
|
||||||
*/
|
|
||||||
function getAppDataPath() {
|
|
||||||
switch (process.platform) {
|
|
||||||
case 'darwin': {
|
|
||||||
return path.join(process.env.HOME, 'Library', 'Application Support', 'Ontime');
|
|
||||||
}
|
|
||||||
case 'win32': {
|
|
||||||
return path.join(process.env.APPDATA, 'Ontime');
|
|
||||||
}
|
|
||||||
case 'linux': {
|
|
||||||
return path.join(process.env.HOME, '.Ontime');
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define multer storage object
|
// Define multer storage object
|
||||||
const storage = multer.diskStorage({
|
const storage = multer.diskStorage({
|
||||||
@@ -36,13 +15,7 @@ const storage = multer.diskStorage({
|
|||||||
const newDestination = path.join(appDataPath, 'uploads');
|
const newDestination = path.join(appDataPath, 'uploads');
|
||||||
|
|
||||||
// Create directory if not exist
|
// Create directory if not exist
|
||||||
if (!existsSync(newDestination)) {
|
ensureDirectory(newDestination);
|
||||||
try {
|
|
||||||
mkdirSync(newDestination);
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error('Could not create directory');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cb(null, newDestination);
|
cb(null, newDestination);
|
||||||
},
|
},
|
||||||
filename: function (req, file, cb) {
|
filename: function (req, file, cb) {
|
||||||
|
|||||||
Reference in New Issue
Block a user