Skip to content

Commit

Permalink
Merge pull request #18 from nightscout/master
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
inventor96 authored Sep 28, 2020
2 parents a69379b + 9315b06 commit 6544a40
Show file tree
Hide file tree
Showing 26 changed files with 394 additions and 256 deletions.
4 changes: 4 additions & 0 deletions .github/ISSUE_TEMPLATE/--bug-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ label: bug

---

**If you need support for Nightscout, PLEASE DO NOT FILE A TICKET HERE**
For support, please post a question to the "CGM in The Cloud" group in Facebook
(https://www.facebook.com/groups/cgminthecloud) or visit the WeAreNotWaiting Discord at https://discord.gg/zg7CvCQ

**Describe the bug**
A clear and concise description of what the bug is.

Expand Down
4 changes: 4 additions & 0 deletions .github/ISSUE_TEMPLATE/--feature-request--.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ about: Suggest an idea for this project

---

**If you need support for Nightscout, PLEASE DO NOT FILE A TICKET HERE**
For support, please post a question to the "CGM in The Cloud" group in Facebook
(https://www.facebook.com/groups/cgminthecloud) or visit the WeAreNotWaiting Discord at https://discord.gg/zg7CvCQ

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Expand Down
4 changes: 3 additions & 1 deletion .github/ISSUE_TEMPLATE/--individual-troubleshooting-help.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ about: Getting help with your own individual setup of Nightscout

Having issues getting Nightscout up and running? Instead of creating an issue here, please use one of the existing support channels for Nightscout.

The documentation for Nightscout lives at (https://nightscout.github.io)

The main support channel is on Facebook: please join the CGM In The Cloud Facebook group (https://www.facebook.com/groups/cgminthecloud) and start a post there.

**Suggestions to include in your post when you are asking for help:**
1. Include what you are trying to do: ("*I am trying to set up Nightscout for the first time.*")
2. Include which step you are on and what the problem is: ("*I deployed on Heroku, but I'm not seeing any BG data.*")
3. If possible, include a link to the version of documentation you are following ("*I'm following the OpenAPS Nightscout setup docs (https://openaps.readthedocs.io/en/latest/docs/While%20You%20Wait%20For%20Gear/nightscout-setup.html#nightscout-setup-with-heroku)*")

Other places you can find support and assistance for Nightscout include Gitter's [nightscout/public](https://gitter.im/nightscout/public) channel.
Other places you can find support and assistance for Nightscout include our Discord channel at (https://discord.gg/zg7CvCQ)
49 changes: 18 additions & 31 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,25 @@ function create (env, ctx) {
));
});

// Allow static resources to be cached for week
var maxAge = 7 * 24 * 60 * 60 * 1000;

if (process.env.NODE_ENV === 'development') {
maxAge = 1;
console.log('Development environment detected, setting static file cache age to 1 second');
}

var staticFiles = express.static(env.static_files, {
maxAge
});

// serve the static content
app.use(staticFiles);

if (ctx.bootErrors && ctx.bootErrors.length > 0) {
app.get('*', require('./lib/server/booterror')(ctx));
const bootErrorView = require('./lib/server/booterror')(env, ctx);
bootErrorView.setLocals(app.locals);
app.get('*', bootErrorView);
return app;
}

Expand Down Expand Up @@ -256,36 +273,6 @@ function create (env, ctx) {
res.sendFile(__dirname + '/swagger.yaml');
});

/* // FOR DEBUGGING MEMORY LEEAKS
if (env.settings.isEnabled('dumps')) {
var heapdump = require('heapdump');
app.get('/api/v2/dumps/start', function(req, res) {
var path = new Date().toISOString() + '.heapsnapshot';
path = path.replace(/:/g, '-');
console.info('writing dump to', path);
heapdump.writeSnapshot(path);
res.send('wrote dump to ' + path);
});
}
*/

// app.get('/package.json', software);

// Allow static resources to be cached for week
var maxAge = 7 * 24 * 60 * 60 * 1000;

if (process.env.NODE_ENV === 'development') {
maxAge = 1;
console.log('Development environment detected, setting static file cache age to 1 second');
}

var staticFiles = express.static(env.static_files, {
maxAge
});

// serve the static content
app.use(staticFiles);

// API docs

const swaggerUi = require('swagger-ui-express');
Expand Down
23 changes: 17 additions & 6 deletions env.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,20 @@ var env = {
settings: require('./lib/settings')()
};

var shadowEnv;

// Module to constrain all config and environment parsing to one spot.
// See README.md for info about all the supported ENV VARs
function config ( ) {

// Assume users will typo whitespaces into keys and values

shadowEnv = {};

Object.keys(process.env).forEach((key, index) => {
shadowEnv[_trim(key)] = _trim(process.env[key]);
});

env.PORT = readENV('PORT', 1337);
env.HOSTNAME = readENV('HOSTNAME', null);
env.IMPORT_CONFIG = readENV('IMPORT_CONFIG', null);
Expand Down Expand Up @@ -122,7 +133,7 @@ function updateSettings() {
});

//should always find extended settings last
env.extendedSettings = findExtendedSettings(process.env);
env.extendedSettings = findExtendedSettings(shadowEnv);

if (!readENVTruthy('TREATMENTS_AUTH', true)) {
env.settings.authDefaultRoles = env.settings.authDefaultRoles || "";
Expand All @@ -132,10 +143,10 @@ function updateSettings() {

function readENV(varName, defaultValue) {
//for some reason Azure uses this prefix, maybe there is a good reason
var value = process.env['CUSTOMCONNSTR_' + varName]
|| process.env['CUSTOMCONNSTR_' + varName.toLowerCase()]
|| process.env[varName]
|| process.env[varName.toLowerCase()];
var value = shadowEnv['CUSTOMCONNSTR_' + varName]
|| shadowEnv['CUSTOMCONNSTR_' + varName.toLowerCase()]
|| shadowEnv[varName]
|| shadowEnv[varName.toLowerCase()];

if (varName == 'DISPLAY_UNITS') {
if (value && value.toLowerCase().includes('mmol')) {
Expand All @@ -162,7 +173,7 @@ function findExtendedSettings (envs) {
extended.devicestatus = {};
extended.devicestatus.advanced = true;
extended.devicestatus.days = 1;
if(process.env['DEVICESTATUS_DAYS'] && process.env['DEVICESTATUS_DAYS'] == '2') extended.devicestatus.days = 1;
if(shadowEnv['DEVICESTATUS_DAYS'] && shadowEnv['DEVICESTATUS_DAYS'] == '2') extended.devicestatus.days = 1;

function normalizeEnv (key) {
return key.toUpperCase().replace('CUSTOMCONNSTR_', '');
Expand Down
36 changes: 14 additions & 22 deletions lib/data/dataloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

const _ = require('lodash');
const async = require('async');
const times = require('../times');
const fitTreatmentsToBGCurve = require('./treatmenttocurve');
const constants = require('../constants');

Expand Down Expand Up @@ -144,8 +143,11 @@ function init(env, ctx) {
done(err, result);
}

// clear treatments to the base set, we're going to merge from multiple queries
ddata.treatments = []; // ctx.cache.treatments ? _.cloneDeep(ctx.cache.treatments) : [];
// clear data we'll get from the cache

ddata.treatments = [];
ddata.devicestatus = [];
ddata.entries = [];

ddata.dbstats = {};

Expand Down Expand Up @@ -196,11 +198,8 @@ function loadEntries(ddata, ctx, callback) {

if (!err && results) {

const ageFilter = ddata.lastUpdated - constants.TWO_DAYS;
const r = ctx.ddata.processRawDataForRuntime(results);
ctx.cache.insertData('entries', r, ageFilter);

const currentData = ctx.cache.getData('entries').reverse();
const currentData = ctx.cache.insertData('entries', r).reverse();

const mbgs = [];
const sgvs = [];
Expand Down Expand Up @@ -324,12 +323,11 @@ function loadTreatments(ddata, ctx, callback) {

ctx.treatments.list(tq, function(err, results) {
if (!err && results) {
const ageFilter = ddata.lastUpdated - longLoad;
const r = ctx.ddata.processRawDataForRuntime(results);

// update cache
ctx.cache.insertData('treatments', r, ageFilter);
ddata.treatments = ctx.ddata.idMergePreferNew(ddata.treatments, ctx.cache.getData('treatments'));
// update cache and apply to runtime data
const r = ctx.ddata.processRawDataForRuntime(results);
const currentData = ctx.cache.insertData('treatments', r);
ddata.treatments = ctx.ddata.idMergePreferNew(ddata.treatments, currentData);
}

callback();
Expand Down Expand Up @@ -361,7 +359,6 @@ function loadProfileSwitchTreatments(ddata, ctx, callback) {
ctx.treatments.list(tq, function(err, results) {
if (!err && results) {
ddata.treatments = mergeProcessSort(ddata.treatments, results);
//mergeToTreatments(ddata, results);
}

// Store last profile switch
Expand Down Expand Up @@ -418,7 +415,6 @@ function loadLatestSingle(ddata, ctx, dataType, callback) {
ctx.treatments.list(tq, function(err, results) {
if (!err && results) {
ddata.treatments = mergeProcessSort(ddata.treatments, results);
//mergeToTreatments(ddata, results);
}
callback();
});
Expand Down Expand Up @@ -473,16 +469,12 @@ function loadDeviceStatus(ddata, env, ctx, callback) {

ctx.devicestatus.list(opts, function(err, results) {
if (!err && results) {
// ctx.cache.devicestatus = mergeProcessSort(ctx.cache.devicestatus, results, ageFilter);

const ageFilter = ddata.lastUpdated - longLoad;
// update cache and apply to runtime data
const r = ctx.ddata.processRawDataForRuntime(results);
ctx.cache.insertData('devicestatus', r, ageFilter);

const res = ctx.cache.getData('devicestatus');
const currentData = ctx.cache.insertData('devicestatus', r);

const res2 = _.map(res, function eachStatus(result) {
//result.mills = new Date(result.created_at).getTime();
const res2 = _.map(currentData, function eachStatus(result) {
if ('uploaderBattery' in result) {
result.uploader = {
battery: result.uploaderBattery
Expand All @@ -492,7 +484,7 @@ function loadDeviceStatus(ddata, env, ctx, callback) {
return result;
});

ddata.devicestatus = mergeProcessSort(ddata.devicestatus, res2, ageFilter);
ddata.devicestatus = mergeProcessSort(ddata.devicestatus, res2);
} else {
ddata.devicestatus = [];
}
Expand Down
8 changes: 5 additions & 3 deletions lib/data/ddata.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ function init () {

Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object' && obj[key]) {
if (obj[key].hasOwnProperty('_id')) {
if (Object.prototype.hasOwnProperty.call(obj[key], '_id')) {
obj[key]._id = obj[key]._id.toString();
}
if (obj[key].hasOwnProperty('created_at') && !obj[key].hasOwnProperty('mills')) {
if (Object.prototype.hasOwnProperty.call(obj[key], 'created_at')
&& !Object.prototype.hasOwnProperty.call(obj[key], 'mills')) {
obj[key].mills = new Date(obj[key].created_at).getTime();
}
if (obj[key].hasOwnProperty('sysTime') && !obj[key].hasOwnProperty('mills')) {
if (Object.prototype.hasOwnProperty.call(obj[key], 'sysTime')
&& !Object.prototype.hasOwnProperty.call(obj[key], 'mills')) {
obj[key].mills = new Date(obj[key].sysTime).getTime();
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/profilefunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ function init (profileData) {
// preprocess the timestamps to seconds for a couple orders of magnitude faster operation
profile.preprocessProfileOnLoad = function preprocessProfileOnLoad (container) {
_.each(container, function eachValue (value) {

if (value === null) return;

if (Object.prototype.toString.call(value) === '[object Array]') {
profile.preprocessProfileOnLoad(value);
}
Expand Down
40 changes: 32 additions & 8 deletions lib/server/booterror.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
'use strict';

const express = require('express');
const path = require('path');
var _ = require('lodash');

var head = '<!DOCTYPE html><html><head><title>Nightscout - Boot Error</title></head><body><h1>Nightscout - Boot Error</h1><dl>';
var tail = '</dl></body></html>';
function bootError(env, ctx) {

function bootError(ctx) {
const app = new express();
let locals = {};

app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.set("views", path.join(__dirname, "../../views/"));

app.get('*', (req, res, next) => {

if (req.url.includes('images')) return next();

return function pageHandler (req, res) {
var errors = _.map(ctx.bootErrors, function (obj) {
obj.err = _.pick(obj.err, Object.getOwnPropertyNames(obj.err));
return '<dt>' + obj.desc + '</dt><dd>' + JSON.stringify(obj.err).replace(/\\n/g, '<br/>') + '</dd>';

let message;

if (typeof obj.err === 'string' || obj.err instanceof String) {
message = obj.err;
} else {
message = JSON.stringify(_.pick(obj.err, Object.getOwnPropertyNames(obj.err)));
}
return '<dt>' + obj.desc + '</dt><dd>' + message.replace(/\\n/g, '<br/>') + '</dd>';
}).join(' ');

res.set('Content-Type', 'text/html');
res.send(head + errors + tail);
res.render('error.html', {
errors,
locals
});

});

app.setLocals = function (_locals) {
locals = _locals;
}

return app;
}

module.exports = bootError;
Loading

0 comments on commit 6544a40

Please sign in to comment.