From ee1ecd6949d15b4b481f12b22c4fd16066827b00 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Thu, 29 Dec 2016 20:18:10 +0200 Subject: [PATCH 1/8] New tool to sync profile data from OpenAPS to Nightscout --- bin/oref0-upload-profile.js | 229 ++++++++++++++++++++++++++++++++++++++++++++ lib/profile/index.js | 22 ++++- package.json | 1 + 3 files changed, 250 insertions(+), 2 deletions(-) create mode 100755 bin/oref0-upload-profile.js diff --git a/bin/oref0-upload-profile.js b/bin/oref0-upload-profile.js new file mode 100755 index 00000000..aa4914a6 --- /dev/null +++ b/bin/oref0-upload-profile.js @@ -0,0 +1,229 @@ +#!/usr/bin/env node + +/* + oref0 Nightscout profile update tool + + Checks the ISF / Basal profile in Nightscout and updates the profile if + necessary to match the profile collected by OpenAPS + + Released under MIT license. See the accompanying LICENSE.txt file for + full terms and conditions + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +var request = require('request'); +var _ = require('lodash'); + +if (!module.parent) { + + var argv = require('yargs') + .usage("$0 profile.json NSURL api-secret") + // error and show help if some other args given + .strict(true) + .help('help') + ; + + function usage ( ) { + argv.showHelp( ); + } + + var params = argv.argv; + var errors = [ ]; + var warnings = [ ]; + + var profile_input = params._.slice(0, 1).pop(); + + if ([null, '--help', '-h', 'help'].indexOf(profile_input) > 0) { + usage( ); + process.exit(0) + } + + var nsurl = params._.slice(1, 2).pop(); + var apisecret = params._.slice(2, 3).pop(); + + if (!profile_input || !nsurl || !apisecret) { + usage( ); + process.exit(1); + } + + try { + var cwd = process.cwd(); + var profiledata = require(cwd + '/' + profile_input); + } catch (e) { + return console.error("Could not parse input data: ", e); + } + + + var options = { + uri: nsurl + '/api/v1/profile/current', + json: true, + headers: {'api-secret': apisecret} + }; + + request(options, function (error, res, data) { + if (error || res.statusCode != 200) { + console.log('Loading current profile from Nightscout failed'); + process.exit(1); + } + + var original_profile = data; + var new_profile = _.cloneDeep(data); + + var profile_id = data.defaultProfile; + var profile_store = new_profile.store[profile_id]; + + profile_store.dia = profiledata.dia; + + // Basals + + var new_basal = []; + + _.forEach(profiledata.basalprofile, function(basalentry) { + + var newEntry = { + time : '' + basalentry.start.substring(0,5) + , value : '' + +(Math.round(basalentry.rate + "e+3") + "e-3") + , timeAsSeconds : '' + basalentry.minutes * 60 + }; + + new_basal.push(newEntry); + + }); + + profile_store.basal = new_basal; + + // BG Targets + + var new_target_low = []; + var new_target_high = []; + + _.forEach(profiledata.bg_targets.targets, function(target_entry) { + + var time = target_entry.start.substring(0,5); + var seconds = parseInt(time.substring(0,2))*60*60 + parseInt(time.substring(3,5))*60; + var low_value = Math.round(target_entry.low); + var high_value = Math.round(target_entry.high); + + if (new_profile.units == 'mmol' && profiledata.bg_targets.units == 'mg/dL') { + low_value = +(Math.round(target_entry.low / 18 + "e+1") + "e-1"); + high_value = +(Math.round(target_entry.high / 18 + "e+1") + "e-1"); + } + + var new_low_entry = { + time: '' + time + , value: '' + low_value + , timeAsSeconds: '' + seconds + }; + + var new_high_entry = { + time: '' + time + , value: '' + high_value + , timeAsSeconds: '' + seconds + + }; + + new_target_low.push(new_low_entry); + new_target_high.push(new_high_entry); + }); + + profile_store.target_low = new_target_low; + profile_store.target_high = new_target_high; + + // ISF + + var new_sens = []; + + _.forEach(profiledata.isfProfile.sensitivities, function(isf_entry) { + + var value = Math.round(isf_entry.sensitivity); + + if (new_profile.units == 'mmol' && profiledata.isfProfile.units == 'mg/dL') { + value = +(Math.round(isf_entry.sensitivity / 18 + "e+1") + "e-1"); + } + + var new_isf_entry = { + time: isf_entry.start.substring(0,5) + , value: '' + value + , timeAsSeconds: '' + isf_entry.offset * 60 + }; + + new_sens.push(new_isf_entry); + }); + + profile_store.sens = new_sens; + + // Carb ratios + + var new_carb_ratios = []; + + _.forEach(profiledata.carb_ratios.schedule, function(carb_entry) { + + var new_entry = { + time: carb_entry.start.substring(0,5) + , value: '' + carb_entry.ratio + , timeAsSeconds: '' + carb_entry.offset * 60 + }; + + new_carb_ratios.push(new_entry); + }); + + profile_store.carbratio = new_carb_ratios; + +/* console.log('------------- NEW PROFILE'); + console.log(profile_store); + + console.log("Profiles are still equal",_.isEqual(original_profile, new_profile)); +*/ + if (!_.isEqual(original_profile, new_profile)) { + + // Upload to NS + + var upload_profile = new_profile; + + var d = new Date(); + + profile_store.startDate = d.toISOString(); + + if (profile_id != 'OpenAPS Autosync') { + upload_profile = _.cloneDeep(data); + upload_profile.defaultProfile = 'OpenAPS Autosync'; + upload_profile.store['OpenAPS Autosync'] = profile_store; + } + + delete upload_profile._id; + + upload_profile.startDate = profile_store.startDate; + upload_profile.created_at = profile_store.startDate; + upload_profile.mills = d.getTime(); + + console.log('Profile for upload',upload_profile); + + options = { + uri: nsurl + '/api/v1/profile/', + json: true, + method: 'POST', + headers: {'api-secret': apisecret}, + body: upload_profile + }; + + request(options, function (error, res, data) { + console.log(res.body); + if (error) { + console.log(error); + } else { + console.log('Profile uploaded to Nightscout'); + } + }); + } else { + console.log('Profiles match, no upload needed'); + } + }); +} \ No newline at end of file diff --git a/lib/profile/index.js b/lib/profile/index.js index 8a466fd7..a68c7f02 100644 --- a/lib/profile/index.js +++ b/lib/profile/index.js @@ -3,6 +3,7 @@ var basal = require('./basal'); var targets = require('./targets'); var isf = require('./isf'); var carb_ratios = require('./carbs'); +var _ = require('lodash'); function defaults ( ) { var profile = { @@ -48,6 +49,11 @@ function generate (inputs, opts) { profile.current_basal = basal.basalLookup(inputs.basals); profile.basalprofile = inputs.basals; + + _.forEach(profile.basalprofile, function(basalentry) { + basalentry.rate = +(Math.round(basalentry.rate + "e+3") + "e-3"); + }); + profile.max_daily_basal = basal.maxDailyBasal(inputs); profile.max_basal = basal.maxBasalLookup(inputs); if (profile.basal < 0.1) { @@ -57,8 +63,19 @@ function generate (inputs, opts) { var range = targets.bgTargetsLookup(inputs, profile); profile.out_units = inputs.targets.user_preferred_units; - profile.min_bg = range.min_bg; - profile.max_bg = range.max_bg; + profile.min_bg = Math.round(range.min_bg); + profile.max_bg = Math.round(range.max_bg); + profile.bg_targets = inputs.targets; + + _.forEach(profile.bg_targets.targets, function(bg_entry) { + bg_entry.high = Math.round(bg_entry.high); + bg_entry.low = Math.round(bg_entry.low); + bg_entry.min_bg = Math.round(bg_entry.min_bg); + bg_entry.max_bg = Math.round(bg_entry.max_bg); + }); + + delete profile.bg_targets.raw; + profile.temptargetSet = range.temptargetSet; profile.sens = isf.isfLookup(inputs.isf); profile.isfProfile = inputs.isf; @@ -68,6 +85,7 @@ function generate (inputs, opts) { } if (typeof(inputs.carbratio) != "undefined") { profile.carb_ratio = carb_ratios.carbRatioLookup(inputs, profile); + profile.carb_ratios = inputs.carbratio; } else { console.error("Profile wasn't given carb ratio data, cannot calculate carb_ratio"); } diff --git a/package.json b/package.json index 73f27003..8814b736 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "dependencies": { "lodash": "^4.15.0", "moment": "^2.14.1", + "request": "^2.79.0", "share2nightscout-bridge": "^0.1.5", "timezone": "0.0.47", "yargs": "~4.3.2" From e70777a8860b80e48996f58f7d204943803bf45e Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Thu, 29 Dec 2016 20:58:43 +0200 Subject: [PATCH 2/8] Hashing the secret --- bin/oref0-upload-profile.js | 17 +++++++++++------ package.json | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/bin/oref0-upload-profile.js b/bin/oref0-upload-profile.js index aa4914a6..3f8e90f9 100755 --- a/bin/oref0-upload-profile.js +++ b/bin/oref0-upload-profile.js @@ -19,6 +19,7 @@ */ +var crypto = require('crypto'); var request = require('request'); var _ = require('lodash'); @@ -43,11 +44,15 @@ if (!module.parent) { if ([null, '--help', '-h', 'help'].indexOf(profile_input) > 0) { usage( ); - process.exit(0) + process.exit(0); } var nsurl = params._.slice(1, 2).pop(); var apisecret = params._.slice(2, 3).pop(); + + var shasum = crypto.createHash('sha1'); + shasum.update(apisecret); + apisecret = shasum.digest('hex'); if (!profile_input || !nsurl || !apisecret) { usage( ); @@ -58,7 +63,7 @@ if (!module.parent) { var cwd = process.cwd(); var profiledata = require(cwd + '/' + profile_input); } catch (e) { - return console.error("Could not parse input data: ", e); + return console.error('Could not parse input data: ', e); } @@ -90,7 +95,7 @@ if (!module.parent) { var newEntry = { time : '' + basalentry.start.substring(0,5) - , value : '' + +(Math.round(basalentry.rate + "e+3") + "e-3") + , value : '' + +(Math.round(basalentry.rate + 'e+3') + 'e-3') , timeAsSeconds : '' + basalentry.minutes * 60 }; @@ -113,8 +118,8 @@ if (!module.parent) { var high_value = Math.round(target_entry.high); if (new_profile.units == 'mmol' && profiledata.bg_targets.units == 'mg/dL') { - low_value = +(Math.round(target_entry.low / 18 + "e+1") + "e-1"); - high_value = +(Math.round(target_entry.high / 18 + "e+1") + "e-1"); + low_value = +(Math.round(target_entry.low / 18 + 'e+1') + 'e-1'); + high_value = +(Math.round(target_entry.high / 18 + 'e+1') + 'e-1'); } var new_low_entry = { @@ -146,7 +151,7 @@ if (!module.parent) { var value = Math.round(isf_entry.sensitivity); if (new_profile.units == 'mmol' && profiledata.isfProfile.units == 'mg/dL') { - value = +(Math.round(isf_entry.sensitivity / 18 + "e+1") + "e-1"); + value = +(Math.round(isf_entry.sensitivity / 18 + 'e+1') + 'e-1'); } var new_isf_entry = { diff --git a/package.json b/package.json index 8814b736..6822ce52 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ }, "homepage": "https://github.com/openaps/oref0", "dependencies": { + "crypto": "0.0.3", "lodash": "^4.15.0", "moment": "^2.14.1", "request": "^2.79.0", From edcc0f8223abf100bd9a4581f2b9abd2a323555a Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Thu, 29 Dec 2016 21:38:20 +0200 Subject: [PATCH 3/8] Added tool to package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6822ce52..6c75d20b 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,8 @@ "oref0-dex-time-since": "./bin/oref0-dex-time-since.sh", "oref0-dex-wait-until-expected": "./bin/oref0-dex-wait-until-expected.sh", "oref0-online": "./bin/oref0-online.sh", - "bt-pan": "./bin/bt-pan" + "bt-pan": "./bin/bt-pan", + "oref0-upload-profile": "./bin/oref0-upload-profile.js" }, "homepage": "https://github.com/openaps/oref0", "dependencies": { From f41aa9e0447525119a51f5d48462c24bb60b1be4 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Thu, 29 Dec 2016 23:13:32 +0200 Subject: [PATCH 4/8] Support both hashed and unhashed api key --- bin/oref0-upload-profile.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bin/oref0-upload-profile.js b/bin/oref0-upload-profile.js index 3f8e90f9..0b8b9e9d 100755 --- a/bin/oref0-upload-profile.js +++ b/bin/oref0-upload-profile.js @@ -50,9 +50,11 @@ if (!module.parent) { var nsurl = params._.slice(1, 2).pop(); var apisecret = params._.slice(2, 3).pop(); - var shasum = crypto.createHash('sha1'); - shasum.update(apisecret); - apisecret = shasum.digest('hex'); + if (apisecret.length != 40) { + var shasum = crypto.createHash('sha1'); + shasum.update(apisecret); + apisecret = shasum.digest('hex'); + }; if (!profile_input || !nsurl || !apisecret) { usage( ); From 9f4806c8f35a4fe1533b5447acdbe1683871b285 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Fri, 30 Dec 2016 10:00:32 +0200 Subject: [PATCH 5/8] Added --preview support. Code run through js-beautify. Less console logging. --- bin/oref0-upload-profile.js | 380 ++++++++++++++++++++++++-------------------- 1 file changed, 205 insertions(+), 175 deletions(-) diff --git a/bin/oref0-upload-profile.js b/bin/oref0-upload-profile.js index 0b8b9e9d..8174ff15 100755 --- a/bin/oref0-upload-profile.js +++ b/bin/oref0-upload-profile.js @@ -26,30 +26,33 @@ var _ = require('lodash'); if (!module.parent) { var argv = require('yargs') - .usage("$0 profile.json NSURL api-secret") - // error and show help if some other args given - .strict(true) - .help('help') - ; - - function usage ( ) { - argv.showHelp( ); + .usage("$0 profile.json NSURL api-secret [--preview]") + .option('preview', { + alias: 'p' + , describe: "Give a preview of the outcome without uploading" + , default: false + }) + .strict(true) + .help('help'); + + function usage() { + argv.showHelp(); } var params = argv.argv; - var errors = [ ]; - var warnings = [ ]; + var errors = []; + var warnings = []; var profile_input = params._.slice(0, 1).pop(); - + if ([null, '--help', '-h', 'help'].indexOf(profile_input) > 0) { - usage( ); - process.exit(0); + usage(); + process.exit(0); } - + var nsurl = params._.slice(1, 2).pop(); var apisecret = params._.slice(2, 3).pop(); - + if (apisecret.length != 40) { var shasum = crypto.createHash('sha1'); shasum.update(apisecret); @@ -57,10 +60,10 @@ if (!module.parent) { }; if (!profile_input || !nsurl || !apisecret) { - usage( ); + usage(); process.exit(1); } - + try { var cwd = process.cwd(); var profiledata = require(cwd + '/' + profile_input); @@ -69,168 +72,195 @@ if (!module.parent) { } - var options = { - uri: nsurl + '/api/v1/profile/current', - json: true, - headers: {'api-secret': apisecret} + var options = { + uri: nsurl + '/api/v1/profile/current' + , json: true + , headers: { + 'api-secret': apisecret + } }; - request(options, function (error, res, data) { - if (error || res.statusCode != 200) { - console.log('Loading current profile from Nightscout failed'); - process.exit(1); - } - - var original_profile = data; - var new_profile = _.cloneDeep(data); - - var profile_id = data.defaultProfile; - var profile_store = new_profile.store[profile_id]; - - profile_store.dia = profiledata.dia; - - // Basals - - var new_basal = []; - - _.forEach(profiledata.basalprofile, function(basalentry) { - - var newEntry = { - time : '' + basalentry.start.substring(0,5) - , value : '' + +(Math.round(basalentry.rate + 'e+3') + 'e-3') - , timeAsSeconds : '' + basalentry.minutes * 60 - }; - - new_basal.push(newEntry); - + request(options, function(error, res, data) { + if (error || res.statusCode != 200) { + console.log('Loading current profile from Nightscout failed'); + process.exit(1); + } + + var original_profile = data; + var new_profile = _.cloneDeep(data); + + var profile_id = data.defaultProfile; + var profile_store = new_profile.store[profile_id]; + + profile_store.dia = profiledata.dia; + + // Basals + + var new_basal = []; + + _.forEach(profiledata.basalprofile, function(basalentry) { + + var newEntry = { + time: '' + basalentry.start.substring(0, 5) + , value: '' + +(Math.round(basalentry.rate + 'e+3') + 'e-3') + , timeAsSeconds: '' + basalentry.minutes * 60 + }; + + new_basal.push(newEntry); + + }); + + profile_store.basal = new_basal; + + // BG Targets + + var new_target_low = []; + var new_target_high = []; + + _.forEach(profiledata.bg_targets.targets, function(target_entry) { + + var time = target_entry.start.substring(0, 5); + var seconds = parseInt(time.substring(0, 2)) * 60 * 60 + parseInt(time.substring(3, 5)) * 60; + var low_value = Math.round(target_entry.low); + var high_value = Math.round(target_entry.high); + + if (new_profile.units == 'mmol' && profiledata.bg_targets.units == 'mg/dL') { + low_value = +(Math.round(target_entry.low / 18 + 'e+1') + 'e-1'); + high_value = +(Math.round(target_entry.high / 18 + 'e+1') + 'e-1'); + } + + var new_low_entry = { + time: '' + time + , value: '' + low_value + , timeAsSeconds: '' + seconds + }; + + var new_high_entry = { + time: '' + time + , value: '' + high_value + , timeAsSeconds: '' + seconds + + }; + + new_target_low.push(new_low_entry); + new_target_high.push(new_high_entry); + }); + + profile_store.target_low = new_target_low; + profile_store.target_high = new_target_high; + + // ISF + + var new_sens = []; + + _.forEach(profiledata.isfProfile.sensitivities, function(isf_entry) { + + var value = Math.round(isf_entry.sensitivity); + + if (new_profile.units == 'mmol' && profiledata.isfProfile.units == 'mg/dL') { + value = +(Math.round(isf_entry.sensitivity / 18 + 'e+1') + 'e-1'); + } + + var new_isf_entry = { + time: isf_entry.start.substring(0, 5) + , value: '' + value + , timeAsSeconds: '' + isf_entry.offset * 60 + }; + + new_sens.push(new_isf_entry); }); - - profile_store.basal = new_basal; - - // BG Targets - - var new_target_low = []; - var new_target_high = []; - - _.forEach(profiledata.bg_targets.targets, function(target_entry) { - - var time = target_entry.start.substring(0,5); - var seconds = parseInt(time.substring(0,2))*60*60 + parseInt(time.substring(3,5))*60; - var low_value = Math.round(target_entry.low); - var high_value = Math.round(target_entry.high); - - if (new_profile.units == 'mmol' && profiledata.bg_targets.units == 'mg/dL') { - low_value = +(Math.round(target_entry.low / 18 + 'e+1') + 'e-1'); - high_value = +(Math.round(target_entry.high / 18 + 'e+1') + 'e-1'); + + profile_store.sens = new_sens; + + // Carb ratios + + var new_carb_ratios = []; + + _.forEach(profiledata.carb_ratios.schedule, function(carb_entry) { + + var new_entry = { + time: carb_entry.start.substring(0, 5) + , value: '' + carb_entry.ratio + , timeAsSeconds: '' + carb_entry.offset * 60 + }; + + new_carb_ratios.push(new_entry); + }); + + profile_store.carbratio = new_carb_ratios; + + // change dates & remove Mongo ID from new profile to create a new object + // Inserts the new profile with name "OpenAPS Autosync" to not overwrite + // human-entered data + + var upload_profile; + + if (profile_id != 'OpenAPS Autosync') { + upload_profile = _.cloneDeep(data); + } else { + upload_profile = new_profile; } - - var new_low_entry = { - time: '' + time - , value: '' + low_value - , timeAsSeconds: '' + seconds - }; - - var new_high_entry = { - time: '' + time - , value: '' + high_value - , timeAsSeconds: '' + seconds - - }; - - new_target_low.push(new_low_entry); - new_target_high.push(new_high_entry); - }); - - profile_store.target_low = new_target_low; - profile_store.target_high = new_target_high; - - // ISF - - var new_sens = []; - - _.forEach(profiledata.isfProfile.sensitivities, function(isf_entry) { - - var value = Math.round(isf_entry.sensitivity); - - if (new_profile.units == 'mmol' && profiledata.isfProfile.units == 'mg/dL') { - value = +(Math.round(isf_entry.sensitivity / 18 + 'e+1') + 'e-1'); + + var do_upload = !_.isEqual(original_profile, new_profile); + + if (do_upload) { + + var d = new Date(); + profile_store.startDate = d.toISOString(); + + if (profile_id != 'OpenAPS Autosync') { + upload_profile.defaultProfile = 'OpenAPS Autosync'; + upload_profile.store['OpenAPS Autosync'] = profile_store; + } + + delete upload_profile._id; + + upload_profile.startDate = profile_store.startDate; + upload_profile.created_at = profile_store.startDate; + upload_profile.mills = d.getTime(); } - - var new_isf_entry = { - time: isf_entry.start.substring(0,5) - , value: '' + value - , timeAsSeconds: '' + isf_entry.offset * 60 - }; - - new_sens.push(new_isf_entry); - }); - - profile_store.sens = new_sens; - - // Carb ratios - - var new_carb_ratios = []; - - _.forEach(profiledata.carb_ratios.schedule, function(carb_entry) { - - var new_entry = { - time: carb_entry.start.substring(0,5) - , value: '' + carb_entry.ratio - , timeAsSeconds: '' + carb_entry.offset * 60 - }; - - new_carb_ratios.push(new_entry); - }); - - profile_store.carbratio = new_carb_ratios; - -/* console.log('------------- NEW PROFILE'); - console.log(profile_store); - - console.log("Profiles are still equal",_.isEqual(original_profile, new_profile)); -*/ - if (!_.isEqual(original_profile, new_profile)) { - - // Upload to NS - - var upload_profile = new_profile; - - var d = new Date(); - - profile_store.startDate = d.toISOString(); - - if (profile_id != 'OpenAPS Autosync') { - upload_profile = _.cloneDeep(data); - upload_profile.defaultProfile = 'OpenAPS Autosync'; - upload_profile.store['OpenAPS Autosync'] = profile_store; + + // render preview + + if (params.preview) { + + if (_.isEqual(original_profile, new_profile)) { + console.log('Profile in Nightscout and OpenAPS are identical'); + } else { + console.log('Profile in Nightscout and OpenAPS differ'); + console.log('-------------- Nightscout Profile ----------------'); + console.log(JSON.stringify(original_profile, null, 2)); + console.log('-------------- New profile from OpenAPS data ----------------'); + console.log(JSON.stringify(upload_profile, null, 2)); + } + + process.exit(0); } - - delete upload_profile._id; - - upload_profile.startDate = profile_store.startDate; - upload_profile.created_at = profile_store.startDate; - upload_profile.mills = d.getTime(); - - console.log('Profile for upload',upload_profile); - - options = { - uri: nsurl + '/api/v1/profile/', - json: true, - method: 'POST', - headers: {'api-secret': apisecret}, - body: upload_profile - }; - - request(options, function (error, res, data) { - console.log(res.body); - if (error) { - console.log(error); - } else { - console.log('Profile uploaded to Nightscout'); - } - }); - } else { - console.log('Profiles match, no upload needed'); - } - }); + + if (do_upload) { + + console.log('Uploading changed profile to Nightscout'); + + options = { + uri: nsurl + '/api/v1/profile/' + , json: true + , method: 'POST' + , headers: { + 'api-secret': apisecret + } + , body: upload_profile + }; + + request(options, function(error, res, data) { + console.log(res.body); + if (error) { + console.log(error); + } else { + console.log('Profile uploaded to Nightscout'); + } + }); + } else { + console.log('Profiles match, no upload needed'); + } + }); } \ No newline at end of file From 41188a5a1e86274d92f3472c1ac520307362a79c Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Fri, 30 Dec 2016 10:16:11 +0200 Subject: [PATCH 6/8] Fixed bug with parameter checking order, better logging in case of error / success on upload --- bin/oref0-upload-profile.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bin/oref0-upload-profile.js b/bin/oref0-upload-profile.js index 8174ff15..81660043 100755 --- a/bin/oref0-upload-profile.js +++ b/bin/oref0-upload-profile.js @@ -53,17 +53,17 @@ if (!module.parent) { var nsurl = params._.slice(1, 2).pop(); var apisecret = params._.slice(2, 3).pop(); + if (!profile_input || !nsurl || !apisecret) { + usage(); + process.exit(1); + } + if (apisecret.length != 40) { var shasum = crypto.createHash('sha1'); shasum.update(apisecret); apisecret = shasum.digest('hex'); }; - if (!profile_input || !nsurl || !apisecret) { - usage(); - process.exit(1); - } - try { var cwd = process.cwd(); var profiledata = require(cwd + '/' + profile_input); @@ -239,7 +239,7 @@ if (!module.parent) { if (do_upload) { - console.log('Uploading changed profile to Nightscout'); + console.log('Profile changed, uploading to Nightscout'); options = { uri: nsurl + '/api/v1/profile/' @@ -252,9 +252,9 @@ if (!module.parent) { }; request(options, function(error, res, data) { - console.log(res.body); - if (error) { + if (error || res.statusCode != 200) { console.log(error); + console.log(res.body); } else { console.log('Profile uploaded to Nightscout'); } From 973efe2552185320b4c1e28f78c73b40a40e6d5b Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 12:34:31 +0200 Subject: [PATCH 7/8] Added profile JSON validity checking --- bin/oref0-upload-profile.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bin/oref0-upload-profile.js b/bin/oref0-upload-profile.js index 81660043..82ffa6b1 100755 --- a/bin/oref0-upload-profile.js +++ b/bin/oref0-upload-profile.js @@ -67,8 +67,18 @@ if (!module.parent) { try { var cwd = process.cwd(); var profiledata = require(cwd + '/' + profile_input); + + // Rudimentary check that the profile is valid + + if (!profiledata.dia + || profiledata.basalprofile.length < 1 + || profiledata.bg_targets.length < 1 + || profiledata.isfProfile.length < 1 ) + { throw "Profile JSON missing data"; } + } catch (e) { return console.error('Could not parse input data: ', e); + process.exit(1); } From 10aa9ffe726c614388bcb487be5893aa864faa83 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 12:45:43 +0200 Subject: [PATCH 8/8] One more check for the downloaded profile --- bin/oref0-upload-profile.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/oref0-upload-profile.js b/bin/oref0-upload-profile.js index 82ffa6b1..0627eb72 100755 --- a/bin/oref0-upload-profile.js +++ b/bin/oref0-upload-profile.js @@ -78,7 +78,6 @@ if (!module.parent) { } catch (e) { return console.error('Could not parse input data: ', e); - process.exit(1); } @@ -99,6 +98,11 @@ if (!module.parent) { var original_profile = data; var new_profile = _.cloneDeep(data); + if (!data.defaultProfile) { + console.error('Nightscout profile missing data'); + process.exit(1); + } + var profile_id = data.defaultProfile; var profile_store = new_profile.store[profile_id];