2017-04-09 15:51:17 +00:00
|
|
|
"use strict";
|
2017-04-08 16:05:39 +00:00
|
|
|
|
|
|
|
const config = require('./config.json')
|
|
|
|
|
2017-04-09 20:57:32 +00:00
|
|
|
const library = require('./jukebox/library');
|
|
|
|
|
2019-12-14 21:19:06 +00:00
|
|
|
const ScriptRunner = require('./jukebox/scripts')(config);
|
|
|
|
|
2017-03-26 01:45:57 +00:00
|
|
|
const express = require('express');
|
2019-12-15 16:50:53 +00:00
|
|
|
const morgan = require('morgan');
|
|
|
|
const handlebars = require('express-handlebars');
|
2017-03-26 01:45:57 +00:00
|
|
|
|
2019-12-14 19:20:18 +00:00
|
|
|
const { createLogger, format, transports } = require('winston');
|
|
|
|
|
2019-12-14 21:19:06 +00:00
|
|
|
const { throttle } = require('throttle-debounce');
|
|
|
|
|
2019-12-14 19:20:18 +00:00
|
|
|
var logger = createLogger({
|
2017-04-09 17:55:11 +00:00
|
|
|
transports: [
|
2019-12-14 19:20:18 +00:00
|
|
|
new transports.Console()
|
2017-04-09 17:55:11 +00:00
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
logger.level = config.debug ? 'debug' : 'info';
|
|
|
|
|
|
|
|
const MediaPlayer = require('./jukebox/media-player')(config, logger);
|
|
|
|
const TagReader = require('./jukebox/tag-reader')(config, logger);
|
2017-04-10 02:05:52 +00:00
|
|
|
const play_log = require('./jukebox/library/play-log');
|
|
|
|
|
2019-12-15 16:50:53 +00:00
|
|
|
const sqlite3 = require('sqlite3');
|
|
|
|
var db = new sqlite3.Database(config.db);
|
|
|
|
|
|
|
|
const MediaLibrarySqliteBackend = require('./jukebox/library/sqlite-backend')(config, db);
|
|
|
|
const MediaLibrary = new library.Library(config, MediaLibrarySqliteBackend);
|
|
|
|
|
2017-04-10 02:05:52 +00:00
|
|
|
const PlayLog = new play_log.PlayLog();
|
2017-04-09 13:41:17 +00:00
|
|
|
|
2017-03-26 01:45:57 +00:00
|
|
|
var app = express();
|
|
|
|
var server = require('http').createServer();
|
|
|
|
|
|
|
|
const WebSocket = require('ws');
|
|
|
|
const WebSocketServer = WebSocket.Server;
|
|
|
|
var wss = new WebSocketServer({server: server});
|
|
|
|
|
2017-04-09 16:30:20 +00:00
|
|
|
function exitHandler(options, err) {
|
2017-04-09 17:55:11 +00:00
|
|
|
logger.debug('closing child tasks');
|
|
|
|
if (err) logger.debug(err.stack);
|
2017-04-08 02:01:12 +00:00
|
|
|
|
2017-04-10 02:05:52 +00:00
|
|
|
// FIXME When do we actually need to call this? Adding these seems
|
|
|
|
// to have fixed a problem with orphaned children, but not we get
|
|
|
|
// two sets of "closing child tasks" messages when we shut down.
|
2017-04-09 16:30:20 +00:00
|
|
|
TagReader.kill();
|
|
|
|
MediaPlayer.kill();
|
|
|
|
|
|
|
|
if (options.exit) {
|
|
|
|
process.exit();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
process.on('exit', exitHandler.bind(null));
|
|
|
|
process.on('SIGINT', exitHandler.bind(null, {exit:true}));
|
2019-12-15 02:08:08 +00:00
|
|
|
process.on('SIGUSR2', exitHandler.bind(null, {exit:true}));
|
2017-04-08 02:01:12 +00:00
|
|
|
|
2019-12-14 21:19:06 +00:00
|
|
|
const throttledTag = throttle(config.global_throttle, true, tag => {
|
|
|
|
ScriptRunner.find(tag).then((fulfilled) => {
|
|
|
|
if (false === fulfilled) {
|
|
|
|
MediaLibrary.find(tag)
|
|
|
|
}
|
|
|
|
}).catch(err => {
|
|
|
|
logger.error("got an error handling the tag: " + err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-04-09 20:57:32 +00:00
|
|
|
TagReader.on('message', tag => {
|
2017-04-10 02:45:21 +00:00
|
|
|
if (tag == 'E1' || tag == 'E2') {
|
|
|
|
logger.debug("tagreader had rfid read error", { tag: tag });
|
|
|
|
return;
|
|
|
|
}
|
2017-04-10 01:46:18 +00:00
|
|
|
logger.debug("got tag from tagreader", { tag: tag });
|
2019-12-14 21:19:06 +00:00
|
|
|
throttledTag(tag);
|
2017-04-09 13:41:17 +00:00
|
|
|
});
|
2016-11-20 01:13:19 +00:00
|
|
|
|
2017-04-09 15:52:37 +00:00
|
|
|
if (config.debug) {
|
2017-04-09 19:08:32 +00:00
|
|
|
MediaPlayer.on('message', line => {
|
|
|
|
logger.debug("mediaplayer sent message", { line: line });
|
2017-04-09 15:52:37 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-04-10 02:05:52 +00:00
|
|
|
MediaPlayer.on('command', tag => {
|
|
|
|
PlayLog.updateLog(tag);
|
|
|
|
});
|
|
|
|
|
2019-12-15 16:50:53 +00:00
|
|
|
var hbs = handlebars.create({
|
|
|
|
extname: ".hbs",
|
2017-04-09 20:57:32 +00:00
|
|
|
});
|
2017-03-26 01:45:57 +00:00
|
|
|
|
2017-04-10 02:05:52 +00:00
|
|
|
MediaLibrary.on('action', MediaPlayer.handleTag.bind(MediaPlayer));
|
2017-04-08 02:02:07 +00:00
|
|
|
|
2019-12-15 16:50:53 +00:00
|
|
|
app.engine(".hbs", hbs.engine);
|
|
|
|
|
|
|
|
app.set('view engine', '.hbs');
|
|
|
|
app.set('views', __dirname + '/views');
|
|
|
|
|
2017-04-09 17:55:11 +00:00
|
|
|
app.use(morgan('dev'))
|
2016-11-20 01:13:19 +00:00
|
|
|
app.use(express.static(__dirname + '/static'))
|
|
|
|
|
2019-12-15 16:50:53 +00:00
|
|
|
PlayLog.on('update', tag => {
|
|
|
|
app.render("log", { layout: false, play_log: PlayLog.getLog(), }, (err, html) => {
|
|
|
|
var data = {
|
|
|
|
html: html,
|
|
|
|
tag: tag.tag
|
|
|
|
};
|
|
|
|
|
|
|
|
wss.broadcast(JSON.stringify(data));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-11-20 01:13:19 +00:00
|
|
|
app.get('/', function (req, res, next) {
|
2019-12-15 16:50:53 +00:00
|
|
|
res.render('index', {
|
|
|
|
last_tag: PlayLog.getLastTag(),
|
|
|
|
config: config,
|
|
|
|
play_log: PlayLog.getLog(),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
app.get('/library', function (req, res, next) {
|
|
|
|
db.all("SELECT * FROM tags", (err, rows) => {
|
|
|
|
var content = views.library.render({
|
|
|
|
rows: rows,
|
|
|
|
config: config,
|
2017-04-09 15:51:17 +00:00
|
|
|
});
|
|
|
|
|
2017-04-09 14:46:59 +00:00
|
|
|
var html = views.base.render({
|
2019-12-15 16:50:53 +00:00
|
|
|
title: 'Library',
|
|
|
|
content: content,
|
|
|
|
});
|
2017-04-09 15:51:17 +00:00
|
|
|
|
2019-12-15 16:50:53 +00:00
|
|
|
res.send(html);
|
|
|
|
});
|
2017-03-26 01:45:57 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
wss.broadcast = function broadcast(data) {
|
|
|
|
wss.clients.forEach(function each(client) {
|
|
|
|
if (client.readyState === WebSocket.OPEN) {
|
|
|
|
client.send(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
wss.on('connection', function (ws) {
|
2017-04-09 17:55:11 +00:00
|
|
|
logger.info('websocket client connected');
|
2017-03-26 01:45:57 +00:00
|
|
|
ws.on('close', function () {
|
2017-04-09 17:55:11 +00:00
|
|
|
logger.info('websocket client disconnected');
|
2017-03-26 01:45:57 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
server.on('request', app);
|
2016-11-20 01:13:19 +00:00
|
|
|
|
2017-04-08 16:05:39 +00:00
|
|
|
server.listen(config.port, function () {
|
2017-04-09 17:55:11 +00:00
|
|
|
logger.info('express listening on http://localhost:' + config.port)
|
2016-11-20 01:13:19 +00:00
|
|
|
})
|
2017-04-08 16:05:39 +00:00
|
|
|
|
|
|
|
// vim:ts=2 sw=2 et:
|