Merge branch 'master' into feat/info

This commit is contained in:
Carlos Valente
2021-06-13 14:34:20 +02:00
committed by GitHub
71 changed files with 6100 additions and 754 deletions
+70
View File
@@ -0,0 +1,70 @@
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `yarn start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.
### `yarn test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `yarn build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `yarn eject`
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `yarn build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

+21
View File
@@ -0,0 +1,21 @@
<svg xmlns="http://www.w3.org/2000/svg" width="275" height="275" fill="none" viewBox="0 0 275 275">
<path fill="#4D4D4D" d="M49.83 133.919c0-18.343 3.531-34.692 10.595-49.048 7.064-14.355 17.204-25.464 30.42-33.325 13.33-7.861 28.768-11.792 46.313-11.792 24.952 0 45.288 7.633 61.011 22.9 15.837 15.267 24.666 36.003 26.489 62.207l.342 12.647c0 28.369-7.918 51.155-23.755 68.359-15.836 17.09-37.085 25.635-63.745 25.635-26.66 0-47.965-8.545-63.916-25.635-15.836-17.09-23.755-40.332-23.755-69.726v-2.222zm49.389 3.589c0 17.545 3.304 30.989 9.912 40.332 6.608 9.228 16.064 13.843 28.369 13.843 11.963 0 21.305-4.558 28.028-13.672 6.722-9.229 10.083-23.926 10.083-44.092 0-17.204-3.361-30.534-10.083-39.99-6.723-9.457-16.179-14.185-28.37-14.185-12.076 0-21.419 4.728-28.027 14.185-6.608 9.342-9.912 23.869-9.912 43.579z"/>
<mask id="a" width="177" height="193" x="49" y="39" maskUnits="userSpaceOnUse">
<path fill="#fff" d="M49.83 133.919c0-18.343 3.531-34.692 10.595-49.048 7.064-14.355 17.204-25.464 30.42-33.325 13.33-7.861 28.768-11.792 46.313-11.792 24.952 0 45.288 7.633 61.011 22.9 15.837 15.267 24.666 36.003 26.489 62.207l.342 12.647c0 28.369-7.918 51.155-23.755 68.359-15.836 17.09-37.085 25.635-63.745 25.635-26.66 0-47.965-8.545-63.916-25.635-15.836-17.09-23.755-40.332-23.755-69.726v-2.222zm49.389 3.589c0 17.545 3.304 30.989 9.912 40.332 6.608 9.228 16.064 13.843 28.369 13.843 11.963 0 21.305-4.558 28.028-13.672 6.722-9.229 10.083-23.926 10.083-44.092 0-17.204-3.361-30.534-10.083-39.99-6.723-9.457-16.179-14.185-28.37-14.185-12.076 0-21.419 4.728-28.027 14.185-6.608 9.342-9.912 23.869-9.912 43.579z"/>
</mask>
<g mask="url(#a)">
<path fill="url(#paint0_linear)" d="M19.07 95.347c15.556-6.524 14.288-34.989 22.08-30.11 9.74 6.099 0-23.084 13.549-16.56 21.714 10.455-10.977 18.645 12.296 32.007 23.274 13.362 117.508 24.346 150.898 90.045 12.812 25.21 19.341 32.653 21.836 34.543 1.508-.13 1.78 1.349 0 0-.38.033-.838.168-1.362.476-5.516 3.245-106.876 85.867-148.54 34.124C48.162 188.129 2.25 140.221 14.31 127.463c9.648-10.205 1.393-25.103 4.76-32.116z"/>
<path fill="url(#paint1_linear)" d="M42.153 69.754c-7.791-4.88-.412 13.939-24.087 22.582-3.366 7.013 4.63 19.904-5.018 30.109-12.06 12.757 37.623 69.197 79.288 120.94 41.664 51.743 123.453-24.356 128.969-27.6 5.515-3.245 14.092 10.618-10.114-37.154-33.382-65.882-126.481-75.197-149.59-98.582-20.018-20.26 33.92-42.547 10.662-37.896-30.11 6.022-20.37 33.7-30.11 27.6z"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="93.96" x2="67.62" y1="-33.993" y2="351.251" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-color="#414141" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="88.433" x2="62.092" y1="-37.321" y2="347.924" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF005C" stop-opacity=".74"/>
<stop offset="0"/>
<stop offset="1" stop-color="#242424" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

+1
View File
@@ -0,0 +1 @@
window.require = require;
+104
View File
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; style-src 'unsafe-inline'; script-src 'self'"
/>
<title>ontime</title>
<style>
body {
-webkit-user-select: none;
user-select: none;
-webkit-app-region: drag;
animation: fadein 0s;
background-color: #0005;
}
h1 {
font-family: Roboto, sans-serif;
font-weight: 100;
color: #fffa;
font-size: 24px;
}
.container {
margin-top: 5vh;
display: grid;
place-items: center;
}
.lds-ellipsis {
display: inline-block;
position: relative;
width: 71px;
}
.lds-ellipsis div {
position: absolute;
width: 8px;
height: 8px;
border-radius: 50%;
background: #ff7597aa;
animation-timing-function: cubic-bezier(0, 1, 1, 0);
}
.lds-ellipsis div:nth-child(1) {
left: 8px;
animation: lds-ellipsis1 0.6s infinite;
}
.lds-ellipsis div:nth-child(2) {
left: 8px;
animation: lds-ellipsis2 0.6s infinite;
}
.lds-ellipsis div:nth-child(3) {
left: 32px;
animation: lds-ellipsis2 0.6s infinite;
}
.lds-ellipsis div:nth-child(4) {
left: 56px;
animation: lds-ellipsis3 0.6s infinite;
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes lds-ellipsis1 {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
@keyframes lds-ellipsis3 {
0% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
@keyframes lds-ellipsis2 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(24px, 0);
}
}
</style>
</head>
<body>
<div class="container">
<img src="../../assets/logo.png" />
<h1>ontime · event timers</h1>
<div class="lds-ellipsis">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</body>
</html>
+260
View File
@@ -0,0 +1,260 @@
const {
app,
BrowserWindow,
Menu,
globalShortcut,
Tray,
dialog,
ipcMain,
shell,
Notification,
} = require('electron');
const path = require('path');
const env = process.env.NODE_ENV || 'prod';
let loaded = 'Nothing loaded';
let isQuitting = false;
const nodePath =
env != 'prod'
? path.join('file://', __dirname, 'src/app.js')
: path.join('file://', __dirname, '../', 'extraResources', 'src/app.js');
(async () => {
try {
const { startServer, startOSCServer, startOSCClient } = await import(
nodePath
);
// Start express server
loaded = startServer();
// Start OSC Server (API)
startOSCServer();
// Start OSC Client (Feedback)
startOSCClient();
} catch (error) {
loaded = error;
}
})();
// Load Icons
// TODO: Icons appear pixelated
const trayIcon = path.join(__dirname, './assets/images/logos/LOGO-512.png');
const appIcon = path.join(__dirname, './assets/images/logos/LOGO-512.png');
function showNotification(text) {
new Notification({
title: 'ontime',
body: text,
silent: true,
}).show();
}
let win;
let splash;
let tray = null;
// Ensure there isn't another instance of the app running already
const lock = app.requestSingleInstanceLock();
if (!lock) {
dialog.showErrorBox(
'Multiple instances',
'An instance if the App is already running.'
);
app.quit();
return;
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (win) {
if (win.isMinimized()) win.restore();
win.show();
}
});
}
function createWindow() {
// create a new `splash`-Window
splash = new BrowserWindow({
width: 333,
height: 333,
transparent: true,
icon: appIcon,
resizable: false,
frame: false,
alwaysOnTop: true,
});
splash.loadURL(`file://${__dirname}/electron/splash/splash.html`);
win = new BrowserWindow({
width: 1920,
height: 1000,
minWidth: 500,
minHeight: 530,
maxWidth: 1920,
maxHeight: 1440,
backgroundColor: '#202020',
icon: appIcon,
show: false,
textAreasAreResizable: false,
enableWebSQL: false,
webPreferences: {
preload: path.join(__dirname, './electron/preload.js'),
// TODO: what are recommended alternatives to node integration?
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
},
});
win.setMenu(null);
// Load page served by node
const reactApp =
env == 'prod'
? 'http://localhost:4001/editor'
: 'http://localhost:3000/editor';
win.loadURL(reactApp).then(() => {
win.webContents.setBackgroundThrottling(false);
});
}
app.whenReady().then(() => {
createWindow();
/* ======================================
* CONTEXT MENU CREATION ON REACT SIDE
// Create context menu
// const contextMenu = new Menu();
// contextMenu.append(
// new MenuItem({
// label: 'Build context menu here',
// })
// );
// open context menu when clicked
// win.webContents.on('context-menu', (e, params) => {
// contextMenu.popup(win, params.x, params.y);
// });
* ======================================
*/
// register global shortcuts
// (available regardless of wheter app is in focus)
// bring focus to window
globalShortcut.register('Alt+1', () => {
win.show();
});
globalShortcut.register('Alt+t', () => {
// Show dev tools
win.webContents.openDevTools({ mode: 'detach' });
});
// recreate window if no others open
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
win.once('ready-to-show', () => {
setTimeout(() => {
// window stuff
win.show();
splash.destroy();
showNotification(loaded.toString());
// tray stuff
// TODO: get IP Address
tray.setToolTip(loaded);
}, 2000);
});
// Hide on close
win.on('close', function (event) {
event.preventDefault();
if (!isQuitting) {
showNotification('App running in background');
win.hide();
return false;
}
return true;
});
// create tray
// TODO: Design better icon
tray = new Tray(trayIcon);
// TODO: Move to separate file
// Define context menu
const trayMenuTemplate = [
{
label: 'Show App',
click: () => win.show(),
},
{
label: 'Close',
click: () => {
win.destroy();
app.quit();
},
},
];
const trayContextMenu = Menu.buildFromTemplate(trayMenuTemplate);
tray.setContextMenu(trayContextMenu);
});
// unregister shortcuts before quitting
app.once('will-quit', () => {
globalShortcut.unregisterAll();
});
// Get messages from react
// Test message
ipcMain.on('test-message', (event, arg) => {
showNotification('testing 1-2', arg);
});
// Terminate
ipcMain.on('shutdown', (event, arg) => {
console.log('Got IPC shutdown');
// terminate node service
(async () => {
const { shutdown } = await import(nodePath);
// Shutdown service
await shutdown();
})();
isQuitting = true;
tray.destroy();
win.destroy();
app.quit();
});
// Window manipulation
ipcMain.on('set-window', (event, arg) => {
console.log('Got IPC set-window', arg);
if (arg === 'to-max') {
// window full
win.setContentSize(1920, 1000);
win.setPosition(0, 0);
} else if (arg === 'to-tray') {
// window to tray
win.hide();
}
});
// Open links external
ipcMain.on('send-to-link', (event, arg) => {
console.log('Got IPC send-to-link', arg);
// send to help URL
if (arg === 'help') {
shell.openExternal('https://cpvalente.gitbook.io/ontime/');
}
});
+76 -17
View File
@@ -1,21 +1,80 @@
{
"name": "passport-example",
"version": "0.0.1",
"description": "Example with Passport (http://www.passportjs.org/)",
"type": "module",
"dependencies": {
"body-parser": "~1.19.0",
"express": "~4.17.1",
"express-session": "~1.17.1",
"lowdb": "2.1.0",
"multer": "^1.4.2",
"nanoid": "^3.1.22",
"node-osc": "6.0.2",
"passport": "~0.4.1",
"passport-local": "~1.0.0",
"socket.io": "^4.0.0"
"name": "ontime",
"version": "0.1.0",
"author": "Carlos Valente",
"description": "Time keeping for live events",
"repository": "https://github.com/cpvalente/ontime",
"keywords": [ "lighdev", "ontime", "timer" ],
"license": "MIT",
"main": "main.js",
"devDependencies": {
"concurrently": "^6.1.0",
"electron": "^13.1.2",
"electron-builder": "^22.11.3",
"eslint": "^7.26.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-simple-import-sort": "^7.0.0"
},
"scripts": {
"start": "node src/app.js"
}
"nodestart": "NODE_ENV=development node app.js",
"start": "NODE_ENV=development electron .",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"dist-win": "electron-builder --publish=never --x64 --win",
"dist-mac": "electron-builder --publish=never --x64 --mac",
"dist-all": "electron-builder -mw"
},
"build": {
"productName": "ontime",
"appId": "no.lightdev.ontime",
"asar": true,
"dmg": {
"artifactName": "ontime-macOS.dmg",
"icon": "icon.icns"
},
"mac": {
"target": "dmg",
"category": "public.app-category.productivity",
"icon": "icon.icns"
},
"win": {
"target": "nsis"
},
"nsis": {
"artifactName": "ontime-win64.exe",
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"deleteAppDataOnUninstall": true,
"installerIcon": "icon.ico"
},
"files": [
"**/*",
"assets/"
],
"directories": {
"buildResources": "./assets/"
},
"extraResources": [
{
"from": "../client/build",
"to": "extraResources/client/build",
"filter": [
"**/*"
]
},
{
"from": "src",
"to": "extraResources/src",
"filter": [
"**/*"
]
}
]
},
"postinstall": "electron-builder install-app-deps"
}
+64 -19
View File
@@ -3,9 +3,15 @@ import { config } from './config/config.js';
// init database
import { Low, JSONFile } from 'lowdb';
import { join } from 'path';
const file = join('data/', config.database.filename);
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);
@@ -34,9 +40,6 @@ import { router as eventsRouter } from './routes/eventsRouter.js';
import { router as eventRouter } from './routes/eventRouter.js';
import { router as ontimeRouter } from './routes/ontimeRouter.js';
// Setup default port
const port = process.env.PORT || config.server.port;
// Global Objects
import { EventTimer } from './classes/EventTimer.js';
@@ -60,30 +63,72 @@ app.use('/events', eventsRouter);
app.use('/event', eventRouter);
app.use('/ontime', ontimeRouter);
// implement general router
app.get('/', (req, res) => {
res.send('ontime API');
// 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) => {
console.error(err.stack);
res.status(500).send('Something broke!');
res.status(500).send(err.stack);
});
// create HTTP server
const server = http.createServer(app);
// init timer
global.timer = new EventTimer(server, config);
global.timer.setupWithEventList(data.events);
export const startServer = (overrideConfig = null) => {
// Setup default port
const serverPort = overrideConfig?.port || config.server.port;
// Start server
server.listen(port, () =>
console.log(`HTTP Server is listening on port ${port}`)
);
// Start server
const returnMessage = `HTTP Server is listening on port ${serverPort}`;
server.listen(serverPort, '0.0.0.0', () => console.log(returnMessage));
// init timer
global.timer = new EventTimer(server, config);
global.timer.setupWithEventList(data.events);
return returnMessage;
};
// Start OSC server
import { initiateOSC } from './controllers/OscController.js';
import { initiateOSC, shutdownOSCServer } from './controllers/OscController.js';
initiateOSC(config.osc);
export const startOSCServer = (overrideConfig = null) => {
// Setup default port
const oscInPort = overrideConfig?.port || config.osc.port;
initiateOSC(config.osc);
};
export const startOSCClient = (overrideConfig = null) => {
// Setup default port
const oscOutPort = overrideConfig?.port || config.osc.portOut;
console.log('initialise OSC Client at port: ', oscOutPort);
};
export const shutdown = () => {
console.log('Node service shutdown');
// shutdown express server
server.close();
// shutdown OSC Server
shutdownOSCServer();
// shutdown OSC Client
// shutdown timer
global.timer.shutdown();
};
+8
View File
@@ -83,6 +83,14 @@ export class EventTimer extends Timer {
this._listenToConnections();
}
/**
* @description Shutdown process
*/
shutdown() {
console.log('Closing socket server');
this.io.close();
}
// send current timer
broadcastTimer() {
this.io.emit('timer', this.getObject());
+1
View File
@@ -11,5 +11,6 @@ export const config = {
},
osc: {
port: 8888,
portOut: 8889,
},
};
+7 -1
View File
@@ -1,7 +1,13 @@
import { Server } from 'node-osc';
let oscServer = null;
export const shutdownOSCServer = () => {
if (oscServer != null) oscServer.close();
};
export const initiateOSC = (config) => {
const oscServer = new Server(config.port, '0.0.0.0', () => {
oscServer = new Server(config.port, '0.0.0.0', () => {
console.log(`OSC Server is listening on port ${config.port}`);
});
+40 -13
View File
@@ -1,6 +1,9 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// get database
import { db, data } from '../app.js';
import fs from 'fs';
import {
event as eventDef,
delay as delayDef,
@@ -9,6 +12,9 @@ import {
import { dbModel } from '../data/dataModel.js';
import { networkInterfaces } from 'os';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
function getEventTitle() {
return data.event.title;
}
@@ -24,6 +30,7 @@ async function deleteFile(file) {
// parses version 1 of the data system
async function parsev1(jsonData) {
let numEntries = 0;
if ('events' in jsonData) {
let events = [];
let ids = [];
@@ -46,15 +53,19 @@ async function parsev1(jsonData) {
isPublic: e.isPublic,
id: e.id,
});
numEntries++;
} else if (e.type === 'delay') {
events.push({ ...delayDef, duration: e.duration });
numEntries++;
} else if (e.type === 'block') {
events.push({ ...blockDef });
numEntries++;
}
}
// write to db
db.data.events = events;
db.write();
console.log(`Uploaded file with ${numEntries} entries`);
}
if ('event' in jsonData) {
@@ -83,7 +94,9 @@ async function parsev1(jsonData) {
// Returns -
export const dbDownload = async (req, res) => {
const fileTitle = getEventTitle() || 'ontime events';
res.download('db.json', `${fileTitle}.json`, (err) => {
const dbFile = path.resolve(__dirname, '../', 'data/db.json');
res.download(dbFile, `${fileTitle}.json`, (err) => {
if (err) {
res.status(500).send({
message: 'Could not download the file. ' + err,
@@ -92,15 +105,7 @@ export const dbDownload = async (req, res) => {
});
};
// Create controller for POST request to '/ontime/db'
// Returns -
export const dbUpload = async (req, res) => {
if (!req.file) {
res.status(400).send({ message: 'File not found' });
return;
}
const file = req.file.path;
const upload = async (file, req, res) => {
if (!fs.existsSync(file)) {
res.status(500).send({ message: 'Upload failed' });
return;
@@ -108,8 +113,8 @@ export const dbUpload = async (req, res) => {
try {
// get file
let rawdata = fs.readFileSync(file);
let uploadedJson = JSON.parse(rawdata);
const rawdata = fs.readFileSync(file);
const uploadedJson = JSON.parse(rawdata);
// delete file
deleteFile(file);
@@ -158,4 +163,26 @@ export const getInfo = async (req, res) => {
res.status(200).send({
networkInterfaces: ni,
});
// Create controller for POST request to '/ontime/db'
// Returns -
export const dbUpload = async (req, res) => {
if (!req.file) {
res.status(400).send({ message: 'File not found' });
return;
}
const file = req.file.path;
upload(file, req, res);
};
// Create controller for POST request to '/ontime/dbpath'
// Returns -
export const dbPathToUpload = async (req, res) => {
if (!req.body.path) {
res.status(400).send({ message: 'Path to file not found' });
return;
}
upload(req.body.path, req, res);
};
+28
View File
@@ -0,0 +1,28 @@
{
"type": "module",
"dependencies": {
"body-parser": "~1.19.0",
"express": "~4.17.1",
"express-session": "~1.17.1",
"lowdb": "2.1.0",
"multer": "^1.4.2",
"nanoid": "^3.1.22",
"node-osc": "6.0.2",
"passport": "~0.4.1",
"passport-local": "~1.0.0",
"socket.io": "^4.0.0"
},
"devDependencies": {
"eslint": "^7.26.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-simple-import-sort": "^7.0.0"
},
"scripts": {
"nodestart": "nodemon app.js",
"start": "node app.js"
}
}
+4
View File
@@ -6,6 +6,7 @@ import {
dbDownload,
dbUpload,
getInfo,
dbPathToUpload,
} from '../controllers/ontimeController.js';
// create route between controller and '/ontime/db' endpoint
@@ -16,3 +17,6 @@ router.post('/db', uploadJson, dbUpload);
// create route between controller and '/ontime/info' endpoint
router.get('/info', uploadJson, getInfo);
// create route between controller and '/ontime/dbpath' endpoint
router.post('/dbpath', dbPathToUpload);
+2189
View File
File diff suppressed because it is too large Load Diff
+2865 -518
View File
File diff suppressed because it is too large Load Diff