mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-08 15:59:16 +00:00
@@ -1,6 +1,7 @@
|
|||||||
export const NODE_PORT = 4001;
|
export const NODE_PORT = 4001;
|
||||||
export const EVENT_TABLE = 'event';
|
export const EVENT_TABLE = 'event';
|
||||||
export const EVENTS_TABLE = 'events';
|
export const EVENTS_TABLE = 'events';
|
||||||
|
export const APP_TABLE = 'appinfo';
|
||||||
|
|
||||||
const calculateServer = () => {
|
const calculateServer = () => {
|
||||||
return window.location.origin.replace(window.location.port, `${NODE_PORT}/`);
|
return window.location.origin.replace(window.location.port, `${NODE_PORT}/`);
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { ontimeURL } from './apiConstants';
|
import { ontimeURL } from './apiConstants';
|
||||||
|
|
||||||
|
export const ontimePlaceholderInfo = {
|
||||||
|
networkInterfaces: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getInfo = async () => {
|
||||||
|
const res = await axios.get(ontimeURL + '/info');
|
||||||
|
return res.data;
|
||||||
|
};
|
||||||
|
|
||||||
export const downloadEvents = async () => {
|
export const downloadEvents = async () => {
|
||||||
await axios({
|
await axios({
|
||||||
url: ontimeURL + '/db',
|
url: ontimeURL + '/db',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import style from './EditableText.module.css';
|
import style from './EditableText.module.css';
|
||||||
|
|
||||||
export default function EditableText(props) {
|
export default function EditableText(props) {
|
||||||
const { label, defaultValue, placeholder, submitHandler } = props;
|
const { label, defaultValue, placeholder, submitHandler, ...rest } = props;
|
||||||
const [text, setText] = useState(defaultValue || '');
|
const [text, setText] = useState(defaultValue || '');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -22,7 +22,7 @@ export default function EditableText(props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.block}>
|
<div className={style.block} {...rest}>
|
||||||
<span className={style.title}>{label}</span>
|
<span className={style.title}>{label}</span>
|
||||||
<Editable
|
<Editable
|
||||||
onChange={(v) => handleChange(v)}
|
onChange={(v) => handleChange(v)}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
import { lazy, useEffect } from 'react';
|
import { lazy, useEffect } from 'react';
|
||||||
import { Heading } from '@chakra-ui/layout';
|
import { Heading } from '@chakra-ui/layout';
|
||||||
import { Box } from '@chakra-ui/layout';
|
import { Box } from '@chakra-ui/layout';
|
||||||
import NumberedText from 'common/components/text/NumberedText';
|
|
||||||
import styles from './Editor.module.css';
|
|
||||||
import { useDisclosure } from '@chakra-ui/hooks';
|
import { useDisclosure } from '@chakra-ui/hooks';
|
||||||
import SettingsModal from '../modals/SettingsModal';
|
import styles from './Editor.module.css';
|
||||||
|
import NumberedText from 'common/components/text/NumberedText';
|
||||||
|
import SettingsModal from 'features/modals/SettingsModal';
|
||||||
import MenuBar from 'features/menu/MenuBar';
|
import MenuBar from 'features/menu/MenuBar';
|
||||||
|
|
||||||
const EventListWrapper = lazy(() =>
|
const EventListWrapper = lazy(() =>
|
||||||
@@ -13,6 +13,7 @@ const EventListWrapper = lazy(() =>
|
|||||||
);
|
);
|
||||||
const PlaybackControl = lazy(() => import('features/control/PlaybackControl'));
|
const PlaybackControl = lazy(() => import('features/control/PlaybackControl'));
|
||||||
const MessageControl = lazy(() => import('features/control/MessageControl'));
|
const MessageControl = lazy(() => import('features/control/MessageControl'));
|
||||||
|
const Info = lazy(() => import('features/info/Info'));
|
||||||
|
|
||||||
export default function Editor() {
|
export default function Editor() {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ const ExpandedBlock = (props) => {
|
|||||||
label='Note'
|
label='Note'
|
||||||
defaultValue={data.note}
|
defaultValue={data.note}
|
||||||
placeholder='Add Note'
|
placeholder='Add Note'
|
||||||
|
style={{ color: '#d69e2e' }}
|
||||||
submitHandler={(v) =>
|
submitHandler={(v) =>
|
||||||
actionHandler('update', { field: 'note', value: v })
|
actionHandler('update', { field: 'note', value: v })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useSocket } from 'app/context/socketContext';
|
||||||
|
import style from './Info.module.css';
|
||||||
|
import InfoTitle from './InfoTitle';
|
||||||
|
import InfoLogger from './InfoLogger';
|
||||||
|
import InfoNif from './InfoNif';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function Info() {
|
||||||
|
const socket = useSocket();
|
||||||
|
const [titles, setTitles] = useState({
|
||||||
|
titleNow: '',
|
||||||
|
subtitleNow: '',
|
||||||
|
presenterNow: '',
|
||||||
|
noteNow: '',
|
||||||
|
titleNext: '',
|
||||||
|
subtitleNext: '',
|
||||||
|
presenterNext: '',
|
||||||
|
noteNext: '',
|
||||||
|
});
|
||||||
|
const [selected, setSelected] = useState('-/-');
|
||||||
|
const logData = [];
|
||||||
|
|
||||||
|
// handle incoming messages
|
||||||
|
useEffect(() => {
|
||||||
|
if (socket == null) return;
|
||||||
|
|
||||||
|
// Ask for titles
|
||||||
|
socket.emit('get-titles');
|
||||||
|
|
||||||
|
// Handle titles
|
||||||
|
socket.on('titles', (data) => {
|
||||||
|
setTitles(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ask for selection data
|
||||||
|
socket.emit('get-selected');
|
||||||
|
|
||||||
|
// Handle selection data
|
||||||
|
socket.on('selected', (data) => {
|
||||||
|
const formatedCurrent = `Event ${
|
||||||
|
data.index != null ? data.index + 1 : '-'
|
||||||
|
}/${data.total != null ? data.total : '-'}`;
|
||||||
|
|
||||||
|
setSelected(formatedCurrent);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear listener
|
||||||
|
return () => {
|
||||||
|
socket.off('titles');
|
||||||
|
socket.off('selected');
|
||||||
|
};
|
||||||
|
}, [socket]);
|
||||||
|
|
||||||
|
// TODO: Put this in use effect
|
||||||
|
// prepare data
|
||||||
|
const titlesNow = {
|
||||||
|
title: titles.titleNow,
|
||||||
|
subtitle: titles.subtitleNow,
|
||||||
|
presenter: titles.presenterNow,
|
||||||
|
note: titles.noteNow,
|
||||||
|
};
|
||||||
|
|
||||||
|
const titlesNext = {
|
||||||
|
title: titles.titleNext,
|
||||||
|
subtitle: titles.subtitleNext,
|
||||||
|
presenter: titles.presenterNext,
|
||||||
|
note: titles.noteNext,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={style.main}>{selected}</div>
|
||||||
|
{/* <InfoLogger logData={logData} /> */}
|
||||||
|
<InfoNif />
|
||||||
|
<InfoTitle title={'Now'} data={titlesNow} />
|
||||||
|
<InfoTitle title={'Next'} data={titlesNext} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
.container {
|
||||||
|
margin-top: 1em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
font-size: 0.9em;
|
||||||
|
text-align: right;
|
||||||
|
color: #ff7597;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #aaa;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes {
|
||||||
|
color: #d69e2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.if {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #4bffabcc;
|
||||||
|
background-color: rgba(0, 0, 0, 0.13);
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
margin: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul > li {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log {
|
||||||
|
overflow-y: scroll;
|
||||||
|
height: 30vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.client {
|
||||||
|
color: lightblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moreExpanded,
|
||||||
|
.moreCollapsed {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moreExpanded {
|
||||||
|
transform: scaleY(-1);
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moreCollapsed {
|
||||||
|
transform: scaleY(1);
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Icon } from '@chakra-ui/react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { FiChevronUp } from 'react-icons/fi';
|
||||||
|
import style from './Info.module.css';
|
||||||
|
|
||||||
|
export default function InfoLogger(props) {
|
||||||
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
|
const { logData } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={style.container}>
|
||||||
|
<div className={style.header}>
|
||||||
|
Log
|
||||||
|
<Icon
|
||||||
|
className={collapsed ? style.moreCollapsed : style.moreExpanded}
|
||||||
|
as={FiChevronUp}
|
||||||
|
onClick={() => setCollapsed((c) => !c)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{!collapsed && (
|
||||||
|
<ul className={style.log}>
|
||||||
|
<li className={style.info}>10:35:23 [PLAYBACK] Next</li>
|
||||||
|
<li className={style.client}>
|
||||||
|
10:32:10 [CLIENT] New socket client (total: 3)
|
||||||
|
</li>
|
||||||
|
<li className={style.info}>10:28:23 [PLAYBACK] Next</li>
|
||||||
|
<li className={style.info}>10:25:23 [PLAYBACK] Play</li>
|
||||||
|
<li className={style.info}>10:23:13 [SERVER] Server Reconnected</li>
|
||||||
|
<li className={style.error}>10:23:10 [SERVER] Server Disconnected</li>
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { Icon } from '@chakra-ui/react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { FiChevronUp } from 'react-icons/fi';
|
||||||
|
import { APP_TABLE } from 'app/api/apiConstants';
|
||||||
|
import { getInfo, ontimePlaceholderInfo } from 'app/api/ontimeApi';
|
||||||
|
import { useFetch } from 'app/hooks/useFetch';
|
||||||
|
import style from './Info.module.css';
|
||||||
|
|
||||||
|
export default function InfoNif() {
|
||||||
|
const { data, status } = useFetch(APP_TABLE, getInfo, {
|
||||||
|
placeholderData: ontimePlaceholderInfo,
|
||||||
|
});
|
||||||
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
|
const isDev = process.env.NODE_ENV === 'development';
|
||||||
|
const baseURL = `http://__IP__:${isDev ? 3000 : 4001}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={style.container}>
|
||||||
|
<div className={style.header}>
|
||||||
|
Network Info
|
||||||
|
<Icon
|
||||||
|
className={collapsed ? style.moreCollapsed : style.moreExpanded}
|
||||||
|
as={FiChevronUp}
|
||||||
|
onClick={() => setCollapsed((c) => !c)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!collapsed && (
|
||||||
|
<div>
|
||||||
|
{status === 'success' && (
|
||||||
|
<>
|
||||||
|
{data?.networkInterfaces.map((e) => {
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={baseURL.replace('__IP__', e.address)}
|
||||||
|
target='_blank'
|
||||||
|
rel='noreferrer'
|
||||||
|
className={style.if}
|
||||||
|
>{`${e.name} - ${e.address}`}</a>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Icon } from '@chakra-ui/react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { FiChevronUp } from 'react-icons/fi';
|
||||||
|
import style from './Info.module.css';
|
||||||
|
|
||||||
|
export default function InfoTitle(props) {
|
||||||
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
|
const { title, data } = props;
|
||||||
|
return (
|
||||||
|
<div className={style.container}>
|
||||||
|
<div className={style.header}>
|
||||||
|
{title}
|
||||||
|
<Icon
|
||||||
|
className={collapsed ? style.moreCollapsed : style.moreExpanded}
|
||||||
|
as={FiChevronUp}
|
||||||
|
onClick={() => setCollapsed((c) => !c)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!collapsed && (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<span className={style.label}>Title: </span>
|
||||||
|
{data.title}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className={style.label}>Presenter: </span>
|
||||||
|
{data.presenter}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className={style.label}>Subtitle: </span>
|
||||||
|
{data.subtitle}
|
||||||
|
</div>
|
||||||
|
<div className={style.notes}>
|
||||||
|
<span className={style.label}>Note: </span>
|
||||||
|
{data.note}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -44,9 +44,11 @@ export class EventTimer extends Timer {
|
|||||||
titleNow: null,
|
titleNow: null,
|
||||||
subtitleNow: null,
|
subtitleNow: null,
|
||||||
presenterNow: null,
|
presenterNow: null,
|
||||||
|
noteNow: null,
|
||||||
titleNext: null,
|
titleNext: null,
|
||||||
subtitleNext: null,
|
subtitleNext: null,
|
||||||
presenterNext: null,
|
presenterNext: null,
|
||||||
|
noteNext: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
selectedEventIndex = null;
|
selectedEventIndex = null;
|
||||||
@@ -101,6 +103,7 @@ export class EventTimer extends Timer {
|
|||||||
this.io.emit('selected', {
|
this.io.emit('selected', {
|
||||||
id: this.selectedEventId,
|
id: this.selectedEventId,
|
||||||
index: this.selectedEventIndex,
|
index: this.selectedEventIndex,
|
||||||
|
total: this.numEvents,
|
||||||
});
|
});
|
||||||
this.io.emit('selected-id', this.selectedEventId);
|
this.io.emit('selected-id', this.selectedEventId);
|
||||||
this.io.emit('next-id', this.nextEventId);
|
this.io.emit('next-id', this.nextEventId);
|
||||||
@@ -297,6 +300,7 @@ export class EventTimer extends Timer {
|
|||||||
socket.emit('selected', {
|
socket.emit('selected', {
|
||||||
id: this.selectedEventId,
|
id: this.selectedEventId,
|
||||||
index: this.selectedEventIndex,
|
index: this.selectedEventIndex,
|
||||||
|
total: this.numEvents,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -596,6 +600,7 @@ export class EventTimer extends Timer {
|
|||||||
this.titles.titleNow = e.title;
|
this.titles.titleNow = e.title;
|
||||||
this.titles.subtitleNow = e.subtitle;
|
this.titles.subtitleNow = e.subtitle;
|
||||||
this.titles.presenterNow = e.presenter;
|
this.titles.presenterNow = e.presenter;
|
||||||
|
this.titles.noteNow = e.note;
|
||||||
this.selectedEventId = e.id;
|
this.selectedEventId = e.id;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -609,6 +614,7 @@ export class EventTimer extends Timer {
|
|||||||
this.titles.titleNow = e.title;
|
this.titles.titleNow = e.title;
|
||||||
this.titles.subtitleNow = e.subtitle;
|
this.titles.subtitleNow = e.subtitle;
|
||||||
this.titles.presenterNow = e.presenter;
|
this.titles.presenterNow = e.presenter;
|
||||||
|
this.titles.noteNow = e.note;
|
||||||
this.selectedEventId = e.id;
|
this.selectedEventId = e.id;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -624,6 +630,7 @@ export class EventTimer extends Timer {
|
|||||||
this.titles.titleNext = e.title;
|
this.titles.titleNext = e.title;
|
||||||
this.titles.subtitleNext = e.subtitle;
|
this.titles.subtitleNext = e.subtitle;
|
||||||
this.titles.presenterNext = e.presenter;
|
this.titles.presenterNext = e.presenter;
|
||||||
|
this.titles.noteNext = e.note;
|
||||||
this.nextEventId = e.id;
|
this.nextEventId = e.id;
|
||||||
break;
|
break;
|
||||||
case 'next-public':
|
case 'next-public':
|
||||||
@@ -636,6 +643,7 @@ export class EventTimer extends Timer {
|
|||||||
this.titles.titleNext = e.title;
|
this.titles.titleNext = e.title;
|
||||||
this.titles.subtitleNext = e.subtitle;
|
this.titles.subtitleNext = e.subtitle;
|
||||||
this.titles.presenterNext = e.presenter;
|
this.titles.presenterNext = e.presenter;
|
||||||
|
this.titles.noteNext = e.note;
|
||||||
this.nextEventId = e.id;
|
this.nextEventId = e.id;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -652,6 +660,7 @@ export class EventTimer extends Timer {
|
|||||||
this.titles.titleNext = null;
|
this.titles.titleNext = null;
|
||||||
this.titles.subtitleNext = null;
|
this.titles.subtitleNext = null;
|
||||||
this.titles.presenterNext = null;
|
this.titles.presenterNext = null;
|
||||||
|
this.titles.noteNext = null;
|
||||||
this.nextEventId = null;
|
this.nextEventId = null;
|
||||||
|
|
||||||
this.titlesPublic.titleNext = null;
|
this.titlesPublic.titleNext = null;
|
||||||
@@ -690,9 +699,11 @@ export class EventTimer extends Timer {
|
|||||||
titleNow: null,
|
titleNow: null,
|
||||||
subtitleNow: null,
|
subtitleNow: null,
|
||||||
presenterNow: null,
|
presenterNow: null,
|
||||||
|
noteNow: null,
|
||||||
titleNext: null,
|
titleNext: null,
|
||||||
subtitleNext: null,
|
subtitleNext: null,
|
||||||
presenterNext: null,
|
presenterNext: null,
|
||||||
|
noteNext: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.publicTitles = {
|
this.publicTitles = {
|
||||||
@@ -739,9 +750,11 @@ export class EventTimer extends Timer {
|
|||||||
Title Now = ${this.titles.titleNow}
|
Title Now = ${this.titles.titleNow}
|
||||||
Subtitle Now = ${this.titles.subtitleNow}
|
Subtitle Now = ${this.titles.subtitleNow}
|
||||||
Presenter Now = ${this.titles.presenterNow}
|
Presenter Now = ${this.titles.presenterNow}
|
||||||
|
Note Now = ${this.titles.noteNow}
|
||||||
Title Next = ${this.titles.titleNext}
|
Title Next = ${this.titles.titleNext}
|
||||||
Subtitle Next = ${this.titles.subtitleNext}
|
Subtitle Next = ${this.titles.subtitleNext}
|
||||||
Presenter Next = ${this.titles.presenterNext}
|
Presenter Next = ${this.titles.presenterNext}
|
||||||
|
Note Next = ${this.titles.noteNext}
|
||||||
|
|
||||||
Public Titles
|
Public Titles
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
block as blockDef,
|
block as blockDef,
|
||||||
} from '../data/eventsDefinition.js';
|
} from '../data/eventsDefinition.js';
|
||||||
import { dbModel } from '../data/dataModel.js';
|
import { dbModel } from '../data/dataModel.js';
|
||||||
|
import { networkInterfaces } from 'os';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
@@ -132,6 +133,37 @@ const upload = async (file, req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Gets information on IPV4 non internal interfaces
|
||||||
|
* @returns {array} - Array of objects {name: ip}
|
||||||
|
*/
|
||||||
|
const getNetworkInterfaces = () => {
|
||||||
|
const nets = networkInterfaces();
|
||||||
|
const results = [];
|
||||||
|
|
||||||
|
for (const name of Object.keys(nets)) {
|
||||||
|
for (const net of nets[name]) {
|
||||||
|
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
|
||||||
|
if (net.family === 'IPv4' && !net.internal) {
|
||||||
|
results.push({
|
||||||
|
name: name,
|
||||||
|
address: net.address,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create controller for POST request to '/ontime/info'
|
||||||
|
// Returns -
|
||||||
|
// TODO: Add version
|
||||||
|
export const getInfo = async (req, res) => {
|
||||||
|
const ni = getNetworkInterfaces();
|
||||||
|
res.status(200).send({
|
||||||
|
networkInterfaces: ni,
|
||||||
|
});
|
||||||
|
|
||||||
// Create controller for POST request to '/ontime/db'
|
// Create controller for POST request to '/ontime/db'
|
||||||
// Returns -
|
// Returns -
|
||||||
export const dbUpload = async (req, res) => {
|
export const dbUpload = async (req, res) => {
|
||||||
@@ -152,4 +184,5 @@ export const dbPathToUpload = async (req, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
upload(req.body.path, req, res);
|
upload(req.body.path, req, res);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const router = express.Router();
|
|||||||
import {
|
import {
|
||||||
dbDownload,
|
dbDownload,
|
||||||
dbUpload,
|
dbUpload,
|
||||||
|
getInfo,
|
||||||
dbPathToUpload,
|
dbPathToUpload,
|
||||||
} from '../controllers/ontimeController.js';
|
} from '../controllers/ontimeController.js';
|
||||||
|
|
||||||
@@ -14,5 +15,8 @@ router.get('/db', dbDownload);
|
|||||||
// create route between controller and '/ontime/db' endpoint
|
// create route between controller and '/ontime/db' endpoint
|
||||||
router.post('/db', uploadJson, dbUpload);
|
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
|
// create route between controller and '/ontime/dbpath' endpoint
|
||||||
router.post('/dbpath', dbPathToUpload);
|
router.post('/dbpath', dbPathToUpload);
|
||||||
|
|||||||
Reference in New Issue
Block a user