forked from mirrors/Scribe.js
185 lines
5.2 KiB
JavaScript
185 lines
5.2 KiB
JavaScript
|
import express, {Router} from 'express';
|
||
|
import mongoose from 'mongoose';
|
||
|
import jade from 'jade';
|
||
|
import basicAuth from 'basic-auth-connect';
|
||
|
import bodyParser from 'body-parser'
|
||
|
import JSONStream from 'JSONStream';
|
||
|
import NwBuilder from 'nw-builder';
|
||
|
import nativePackage from '../../native/package.json';
|
||
|
import {format} from 'url';
|
||
|
import {EntrySchema} from '../writer/MongoDB';
|
||
|
import extend from 'extend';
|
||
|
import fs from 'fs';
|
||
|
|
||
|
function getObject(d, def) {
|
||
|
if (typeof d === 'undefined' || d === null) {
|
||
|
return def || {};
|
||
|
} else if (typeof d === 'object') {
|
||
|
return d;
|
||
|
} else {
|
||
|
try {
|
||
|
return JSON.parse(d);
|
||
|
} catch (e) {
|
||
|
return def || {};
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const viewer = jade.compileFile(`${__dirname}/../../views/viewer.jade`);
|
||
|
|
||
|
export default class Viewer {
|
||
|
constructor(scribe) {
|
||
|
this.scribe = scribe;
|
||
|
}
|
||
|
|
||
|
getRouter() {
|
||
|
const scribe = this.scribe;
|
||
|
const routerOptions = scribe.module('router/Viewer').options;
|
||
|
const clientOptions = scribe.module('router/Viewer/client').options;
|
||
|
|
||
|
let conn, Entry;
|
||
|
|
||
|
mongoose.set('debug', routerOptions.debug);
|
||
|
conn = mongoose.createConnection(routerOptions.mongoUri);
|
||
|
Entry = conn.model('Entry', EntrySchema);
|
||
|
|
||
|
const router = new Router();
|
||
|
|
||
|
if (routerOptions.username && routerOptions.password) {
|
||
|
router.use(basicAuth(routerOptions.username, routerOptions.password));
|
||
|
}
|
||
|
|
||
|
router.use(express.static(`${__dirname}/../../public`));
|
||
|
|
||
|
if (routerOptions.useBodyParser) {
|
||
|
router.use(bodyParser.json());
|
||
|
}
|
||
|
|
||
|
const render = (req, res)=> res.send(viewer({config: JSON.stringify(clientOptions)}));
|
||
|
|
||
|
router.get('/', render);
|
||
|
router.get('/viewer', render);
|
||
|
|
||
|
router.post('/rest/timeseries', (req, res) => {
|
||
|
try {
|
||
|
if (req.body && req.body.date) {
|
||
|
req.body.date = req.body.date || {};
|
||
|
|
||
|
if (req.body.date.$gt) req.body.date.$gt = new Date(req.body.date.$gt);
|
||
|
if (req.body.date.$gte) req.body.date.$gte = new Date(req.body.date.$gte);
|
||
|
if (req.body.date.$eq) req.body.date.$eq = new Date(req.body.date.$eq);
|
||
|
if (req.body.date.$lt) req.body.date.$lt = new Date(req.body.date.$lt);
|
||
|
if (req.body.date.$lte) req.body.date.$lte = new Date(req.body.date.$lte);
|
||
|
if (req.body._id && Array.isArray(req.body._id.$in)) req.body._id.$in = req.body._id.$in.map(a => mongoose.Types.ObjectId(a));
|
||
|
if (req.body._id && typeof req.body._id === 'string') req.body._id = mongoose.Types.ObjectId(req.body._id);
|
||
|
}
|
||
|
} catch (e) {
|
||
|
// ignore
|
||
|
}
|
||
|
|
||
|
Entry.aggregate(
|
||
|
[
|
||
|
{$match: req.body},
|
||
|
{
|
||
|
$project: {
|
||
|
hour: {
|
||
|
year: {$year: '$date'},
|
||
|
month: {$month: '$date'},
|
||
|
day: {$dayOfMonth: '$date'},
|
||
|
hour: {$hour: '$date'}
|
||
|
},
|
||
|
expose: '$expose'
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
$group: {
|
||
|
_id: {hour: '$hour', expose: '$expose'},
|
||
|
number: {$sum: 1}
|
||
|
}
|
||
|
}
|
||
|
], (err, out) => res.json(out || []));
|
||
|
});
|
||
|
|
||
|
router.get('/rest/db/:collection', (req, res)=> {
|
||
|
if (!routerOptions.mongoUri) {
|
||
|
return res.json({err: 0, docs: []});
|
||
|
}
|
||
|
|
||
|
var selector = getObject(req.query.selector);
|
||
|
var fields = typeof req.query.fields === 'string' ? req.query.fields : '';
|
||
|
var sort = getObject(req.query.sort, {_id: -1});
|
||
|
var limit = !isNaN(req.query.limit) ? Math.max(0, parseInt(req.query.limit)) : Number.MAX_SAFE_INTEGER;
|
||
|
var skip = !isNaN(req.query.skip) ? Math.max(0, parseInt(req.query.skip)) : 0;
|
||
|
|
||
|
res.type('application/json');
|
||
|
|
||
|
const stream = Entry.find(selector)
|
||
|
.select(...fields.split(' '))
|
||
|
.skip(skip)
|
||
|
.limit(limit)
|
||
|
.sort(sort)
|
||
|
.stream();
|
||
|
|
||
|
stream
|
||
|
.pipe(JSONStream.stringify())
|
||
|
.pipe(res);
|
||
|
});
|
||
|
|
||
|
router.delete('/rest/db/:collection', (req, res)=> {
|
||
|
if (!routerOptions.mongoUri) {
|
||
|
res.status(410);
|
||
|
return res.send();
|
||
|
}
|
||
|
|
||
|
var ids = req.query.id;
|
||
|
|
||
|
try {
|
||
|
ids = JSON.parse(ids);
|
||
|
} catch (e) {
|
||
|
// ignore
|
||
|
}
|
||
|
|
||
|
if (!Array.isArray(ids)) {
|
||
|
ids = [req.param('id')];
|
||
|
}
|
||
|
|
||
|
Entry.remove({_id: {$in: ids}}, err => {
|
||
|
res.status(err ? 410 : 200);
|
||
|
res.send();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
if (routerOptions.native) {
|
||
|
|
||
|
}
|
||
|
|
||
|
return router;
|
||
|
}
|
||
|
|
||
|
getNative() {
|
||
|
const scribe = this.scribe;
|
||
|
const nativeOptions = scribe.module('router/Viewer/native').options;
|
||
|
|
||
|
// update
|
||
|
nativePackage.main = format(nativeOptions);
|
||
|
|
||
|
// save
|
||
|
fs.writeFileSync(`${__dirname}/../../native/package.json`,
|
||
|
JSON.stringify(nativePackage, null, 4), {encoding: 'utf8'});
|
||
|
|
||
|
const nw = new NwBuilder(extend(true, {
|
||
|
platforms: ['win', 'osx', 'linux'],
|
||
|
buildDir: `${__dirname}/../../public/native`,
|
||
|
version: '0.12.3',
|
||
|
zip: true
|
||
|
}, nativeOptions, {files: `${__dirname}/../../native/**/**`}));
|
||
|
|
||
|
if (nativeOptions.debug) {
|
||
|
nw.on('log', d => console.log(d));
|
||
|
}
|
||
|
|
||
|
return nw.build();
|
||
|
}
|
||
|
}
|
||
|
|