UNPKG

@arisan/data-api

Version:

The Universal Database API Gateway for CLIO's Modules

392 lines (379 loc) 14.4 kB
'use strict'; // eslint-disable-line strict /* Platform Libraries */ const ObjectID = require('mongodb').ObjectID; /* Project Libraries */ const BaseHandler = require('./base-handler'); const stripUndefined = require('../Utils').stripUndefined; const valueOf = require('../Utils').valueOf; class CameraHandler extends BaseHandler { constructor(logger, cameras) { super(logger); this.cameras = cameras; this.debug(`${ this.constructor.name } Constructed`); } /** * @param {Object} req * @param {string} req.body.projectId * @param {string} req.body.usePublicRtspPort * @param {Object} res */ createCamera(req, res) { const tag = 'createCamera> '; this.debug(`${ tag }Body ${ JSON.stringify(req.body, null, 2) }`); const now = new Date(); const camera = { project_id: req.body.projectId, public_address: req.body.publicAddress, web_port: req.body.webPort, title: req.body.title, username: req.body.username, password: req.body.password, public_rtsp_port: req.body.publicRtspPort, use_public_rtsp_port: req.body.usePublicRtspPort, private_address: req.body.privateAddress, privateMjpegPort: req.body.privateMjpegPort, created: now, updated: now }; if (!this.checkValidProjectId(camera.project_id)) { return; } if (!this.checkValidPublicAddress(camera.public_address)) { return; } if (!this.checkValidWebPort(camera.web_port)) { return; } this.cameras.insertOne(camera, (insertOneErr, insertOneRes) => { if (insertOneErr) { if (insertOneErr.code === 11000) { this.handleError(res, 409, `${ tag }${ insertOneErr.message }`); } else { this.handleError(res, 500, `${ tag }${ insertOneErr.message }`); } return; } this.info(`${ tag }ID ${ insertOneRes.insertedId } Created`); res.type('text/plain'); res.status(201).send(new Buffer(`${ insertOneRes.insertedId }`)); }); } createEvent(req, res) { const tag = 'createEvent> '; const cameraId = req.params.cameraId; const streamIndex = req.params.streamIndex; this.debug(`${ tag }ID ${ cameraId }/${ streamIndex } Body ${ JSON.stringify(req.body, null, 2) }`); let objectId; try { objectId = new ObjectID(cameraId); } catch (err) { this.handleError(res, 400, `${ tag }${ err.message }`); } if (!this.checkRequestBodyProperties(req.body, res, tag, `${ cameraId }/${ streamIndex }`, 'type', 'time')) { return; } const diff = {}; diff[`streams.${ streamIndex }.events`] = { type: req.body.type, time: parseInt(req.body.time, 10), status: 'Pending', videos: [] }; this.cameras.updateOne({ _id: objectId }, { $push: diff }, (updateOneErr, updateOneRes) => { if (updateOneErr) { this.handleError(res, 500, `${ tag }${ updateOneErr.message }`); return; } if (!updateOneRes.matchedCount) { this.handleError(res, 404, `${ tag }ID ${ objectId } Not Found`); return; } this.info(`${ tag }Stream ID ${ cameraId }/${ streamIndex } Updated`); res.sendStatus(200); }); } readCamera(req, res) { const tag = 'readCamera> '; const cameraId = req.params.cameraId; this.debug(`${ tag }ID ${ cameraId }`); let objectId; try { objectId = new ObjectID(cameraId); } catch (err) { this.handleError(res, 400, `${ tag }${ err.message }`); return; } this.cameras.findOne({ _id: objectId }, (findOneErr, findOneRes) => { if (findOneErr) { this.handleError(res, 500, `${ tag }${ findOneErr.message }`); return; } if (!findOneRes) { this.handleError(res, 404, `${ tag }ID ${ cameraId } Not Found`); return; } const reply = { _id: findOneRes._id, projectId: findOneRes.project_id, publicAddress: findOneRes.public_address, webPort: findOneRes.web_port, title: findOneRes.title, username: findOneRes.username, password: findOneRes.password, publicRtspPort: findOneRes.public_rtsp_port, usePublicRtspPort: findOneRes.use_public_rtsp_port, privateAddress: findOneRes.private_address, privateMjpegPort: findOneRes.private_mjpeg_port, publicIp: req.body.public_ip, analysisStatus: req.body.analysis_status, checkStatus: req.body.check_status, created: findOneRes.created, updated: findOneRes.updated }; if (findOneRes.streams) { reply.streams = {}; for (let i = 0; i < Object.keys(findOneRes.streams).length; i++) { const streamIndex = Object.keys(findOneRes.streams)[i]; reply.streams[streamIndex] = { rtspUrl: findOneRes.streams[streamIndex].rtsp_url, availablePlans: findOneRes.streams[streamIndex].available_plans, intendedPlan: findOneRes.streams[streamIndex].intended_plan, currentPlan: findOneRes.streams[streamIndex].current_plan, archiveStatus: findOneRes.streams[streamIndex].archive_status, setStatus: findOneRes.streams[streamIndex].set_status }; } } if (findOneRes.audio) { reply.audio = { encoding: findOneRes.audio.encoding, bitRate: findOneRes.audio.bit_rate, sampleRate: findOneRes.audio.sample_rate }; } this.info(`${ tag }ID ${ findOneRes._id } reply ${ JSON.stringify(reply, null, 2) }`); res.status(200).send(reply); }); } readEventInfo(req, res) { const tag = 'readEventInfo> '; const cameraId = req.params.cameraId; const streamIndex = req.params.streamIndex; this.debug(`${ tag }ID ${ cameraId }/${ streamIndex }`); let objectId; try { objectId = new ObjectID(cameraId); } catch (err) { this.handleError(res, 400, `${ tag }${ err.message }`); return; } this.cameras.findOne({ _id: objectId }, (findOneErr, findOneRes) => { if (findOneErr) { this.handleError(res, 500, `${ tag }${ findOneErr.message }`); return; } const rtspUrl = valueOf(findOneRes, 'streams', streamIndex, 'rtsp_url'); if (!rtspUrl) { this.handleError(res, 404, `${ tag }ID ${ cameraId }/${ streamIndex } RTSP URL Not Found`); return; } this.debug(`${ tag } rtspUrl ${ rtspUrl }`); // const plan = valueOf(findOneRes, 'streams', streamIndex, 'selected_plan'); // if (!plan) { // this.handleError(res, 404, `${tag}ID ${cameraId}/${streamIndex} Plan Not Found`); // return; // } // this.debug(`${tag} plan ${plan}`); // const frameRateRef = parseInt(plan.substring(plan.indexOf('f') + 1, plan.indexOf('b')), 10); // const frameRateRef = valueOf(findOneRes, 'streams', streamIndex, 'rate_control', 'frame_rate_limit'); // const gopSizeRef = parseInt(plan.substring(plan.indexOf('g') + 1), 10); // const gopSizeRef = valueOf(findOneRes, 'streams', streamIndex, 'h264', 'gov_length'); // if (!frameRateRef) { // this.handleError(res, 404, `${tag}ID ${cameraId}/${streamIndex} Frame Rate Not Found`); // return; // } // if (!gopSizeRef) { // this.handleError(res, 404, `${tag}ID ${cameraId}/${streamIndex} GOV Length Not Found`); // return; // } const reply = { rtspUrl, httpUrl: `http://${ findOneRes.username }:${ findOneRes.password }@` + `${ findOneRes.public_address }:${ findOneRes.web_port }`, idleTime: 120000 }; this.info(`${ tag }ID ${ cameraId }/${ streamIndex } reply ${ JSON.stringify(reply, null, 2) }`); res.status(200).send(reply); }); } updateCamera(req, res) { const tag = 'updateCamera> '; const cameraId = req.params.cameraId; this.debug(`${ tag }ID ${ cameraId } Body ${ JSON.stringify(req.body, null, 2) }`); let objectId; try { objectId = new ObjectID(cameraId); } catch (err) { this.handleError(res, 400, `${ tag }${ err.message }`); return; } if (Object.keys(req.body).length === 0) { this.handleError(res, 400, `${ tag }ID ${ cameraId } No Body`); return; } let diff = { project_id: req.body.projectId, public_address: req.body.publicAddress, web_port: req.body.webPort, title: req.body.title, username: req.body.username, password: req.body.password, public_rtsp_port: req.body.publicRtspPort, use_public_rtsp_port: req.body.usePublicRtspPort, private_address: req.body.privateAddress, private_mjpeg_port: req.body.privateMjpegPort, public_ip: req.body.publicIp, analysis_status: req.body.analysisStatus, check_status: req.body.checkStatus, updated: new Date() }; if (req.body.streams) { Object.keys(req.body.streams).forEach(streamIndex => { const stream = req.body.streams[streamIndex]; diff[`streams.${ streamIndex }.rtsp_url`] = stream.rtspUrl; diff[`streams.${ streamIndex }.available_plans`] = stream.availablePlans; diff[`streams.${ streamIndex }.intended_plan`] = stream.intendedPlan; diff[`streams.${ streamIndex }.current_plan`] = stream.currentPlan; diff[`streams.${ streamIndex }.archive_status`] = stream.archiveStatus; diff[`streams.${ streamIndex }.set_status`] = stream.setStatus; }); } if (req.body.audio) { diff['audio.encoding'] = req.body.audio.encoding; diff['audio.bit_rate'] = req.body.audio.bitRate; diff['audio.sample_rate'] = req.body.audio.sampleRate; } diff = stripUndefined(diff); this.cameras.updateOne({ _id: objectId }, { $set: diff }, (updateOneErr, updateOneRes) => { if (updateOneErr) { this.handleError(res, 500, `${ tag }${ updateOneErr.message }`); return; } if (!updateOneRes.matchedCount) { this.handleError(res, 404, `${ tag }ID ${ cameraId } Not Found`); return; } this.info(`${ tag }ID ${ cameraId } Updated`); res.sendStatus(200); }); } updateStreamStatus(req, res) { const tag = 'updateStreamStatus> '; const cameraId = req.params.cameraId; const streamIndex = req.params.streamIndex; this.debug(`${ tag }ID ${ cameraId }/${ streamIndex } Body ${ JSON.stringify(req.body, null, 2) }`); let objectId; try { objectId = new ObjectID(cameraId); } catch (err) { this.handleError(res, 400, `${ tag }${ err.message }`); return; } if (!this.checkRequestBodyProperties(req.body, res, tag, cameraId, 'recorderId', 'status', 'module')) { return; } const now = new Date(); const diff = {}; diff[`streams.${ streamIndex }.status.${ req.body.module }`] = { $each: [{ message: req.body.status, recorderId: req.body.recorderId, updated: now }], $slice: 1000 }; this.cameras.updateOne({ _id: objectId }, { $push: diff }, (updateOneErr, updateOneRes) => { if (updateOneErr) { this.handleError(res, 500, `${ tag }${ updateOneErr.message }`); return; } if (!updateOneRes.matchedCount) { this.handleError(res, 404, `${ tag }ID ${ cameraId } Not Found`); return; } this.info(`${ tag }ID ${ cameraId }/${ streamIndex } Status ${ req.body.status } Updated`); res.sendStatus(200); }); } updateEventStatus(req, res) { const tag = 'updateEventStatus> '; const cameraId = req.params.cameraId; const streamIndex = req.params.streamIndex; this.debug(`${ tag }ID ${ cameraId }/${ streamIndex } Body ${ JSON.stringify(req.body, null, 2) }`); let objectId; try { objectId = new ObjectID(cameraId); } catch (err) { this.handleError(res, 400, `${ tag }${ err.message }`); return; } if (!this.checkRequestBodyProperties(req.body, res, tag, `${ cameraId }/${ streamIndex }`, 'status')) { return; } const now = new Date(); const diff = {}; diff[`streams.${ streamIndex }.status.event`] = { message: req.body.status, updated: now }; this.cameras.updateOne({ _id: objectId }, { $push: diff }, (updateOneErr, updateOneRes) => { if (updateOneErr) { this.handleError(res, 500, `${ tag }${ updateOneErr.message }`); return; } if (!updateOneRes.matchedCount) { this.handleError(res, 404, `${ tag }ID ${ cameraId } Not Found`); return; } this.info(`${ tag }ID ${ cameraId }/${ streamIndex } Status ${ req.body.status } Updated`); res.sendStatus(200); }); } updateEventVideoInfo(req, res) { const tag = 'updateEventVideoInfo> '; const cameraId = req.params.cameraId; const streamIndex = req.params.streamIndex; const time = req.query.time; this.debug(`${ tag }ID ${ cameraId }${ streamIndex } time ${ time } ` + `Body ${ JSON.stringify(req.body, null, 2) }`); let objectId; try { objectId = new ObjectID(cameraId); } catch (err) { this.handleError(res, 400, `${ tag }${ err.message }`); return; } if (!this.checkRequestBodyProperties(req.body, res, tag, `${ cameraId }/${ streamIndex }`, 'videoInfo')) { return; } const query = { _id: objectId }; query[`streams.${ streamIndex }.events.time`] = parseInt(time, 10); this.debug(`${ tag }query ${ JSON.stringify(query, null, 2) }`); const diff = {}; diff[`streams.${ streamIndex }.events.\$.videos`] = [req.body.videoInfo]; this.debug(`${ tag }diff ${ JSON.stringify(diff, null, 2) }`); this.cameras.updateOne(query, { $set: diff }, (updateOneErr, updateOneRes) => { if (updateOneErr) { this.handleError(res, 500, `${ tag }${ updateOneErr.message }`); return; } this.debug(`${ tag }updateOneRes ${ JSON.stringify(updateOneRes, null, 2) }`); if (!updateOneRes.matchedCount) { this.handleError(res, 404, `${ tag }ID ${ cameraId } Not Found`); return; } this.info(`${ tag }ID ${ cameraId }/${ streamIndex } Video Info ${ time } Updated`); res.sendStatus(200); }); } } module.exports = CameraHandler; //# sourceMappingURL=camera-handler.js.map