Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging @bewest's wip/api-modules branch #43

Merged
merged 13 commits into from
Jul 18, 2014
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
language: node_js
node_js:
- 0.10
- 0.11
- 0.11
services:
- mongodb
before_script:
- sleep 10
- echo mongo mongo_travis
148 changes: 28 additions & 120 deletions lib/api.js → lib/api/entries/index.js
Original file line number Diff line number Diff line change
@@ -1,84 +1,29 @@
'use strict';

var consts = require('./constants');
var consts = require('../../constants');
var es = require('event-stream');
var sgvdata = require('sgvdata');

/*
* API - Expose Nightscout HTTP API
* This api is designed to work with express.
*/
function api (env, entries, settings) {

// our globals
var express = require('express'),
api = express()
/**********\
* Entries
\**********/
function configure (app, wares, entries) {
var express = require('express'),
api = express.Router( )
;

// some middleware
var verifyAuthorization = require('./middleware/verify-token')(env),
sendJSONStatus = require('./middleware/send-json-status')( ),
bodyParser = require('body-parser')
;

// set up express basics
api.set('title', 'Nightscout API v1');

// invoke common middleware
api.use(sendJSONStatus);
api.use(wares.sendJSONStatus);
// text body types get handled as raw buffer stream
api.use(bodyParser.raw());
api.use(wares.bodyParser.raw());
// json body types get handled as parsed json
api.use(bodyParser.json());
api.use(wares.bodyParser.json());
// shortcut to use extension to specify output content-type
api.use(require('express-extension-to-accept')([
// api.use(require('express-extension-to-accept')([
api.use(wares.extensions([
'json', 'svg', 'csv', 'txt', 'png', 'html', 'tsv'
]));

// also support url-encoded content-type
api.use(bodyParser.urlencoded({
extended: true
}));

/*
* Start setting up routes
*/

// Some experiments
api.get('/authorized/:secret/test', verifyAuthorization, function (req, res, next) {
return res.json({status: 'ok'});
});

api.get('/authorized/test', verifyAuthorization, function (req, res, next) {
return res.json({status: 'ok'});
});

// Status badge/text/json
api.get('/status', function (req, res, next) {
var status = {status: 'ok'};
var badge = 'http://img.shields.io/badge/Nightscout-OK-green';
return res.format({
html: function ( ) {
res.send("<h1>STATUS OK</h1>");
},
png: function ( ) {
res.redirect(302, badge + '.png');
},
svg: function ( ) {
res.redirect(302, badge + '.svg');
},
text: function ( ) {
res.send("STATUS OK");
},
json: function ( ) {
res.json(status);
}
});
});

/**********\
* Entries
\**********/
api.use(wares.bodyParser.urlencoded({ extended: true }));

// Middleware to format any response involving entries.
function format_entries (req, res, next) {
Expand Down Expand Up @@ -158,7 +103,7 @@ function api (env, entries, settings) {
es.pipeline(inputs( ), persist(done));
}

api.get('/entries', function(req, res, next) {
api.get('/', function(req, res, next) {
// If "?count=" is present, use that number to decided how many to return.
var query = req.query;
entries.list(query, function(err, entries) {
Expand All @@ -169,9 +114,9 @@ function api (env, entries, settings) {
return;
}, format_entries);

api.get('/entries/current', function(req, res, next) {
entries.list({count: 1}, function(err, entries) {
res.entries = entries;
api.get('/current', function(req, res, next) {
entries.list({count: 1}, function(err, records) {
res.entries = records;
res.entries_err = err;
return next( );
});
Expand All @@ -181,21 +126,23 @@ function api (env, entries, settings) {

// Allow previewing your post content, just echos everything you
// posted back out.
api.post('/entries/preview', function (req, res, next) {
api.post('/preview', function (req, res, next) {
req.persist_entries = false;
next( );
return;
}, insert_entries, format_entries);

// Create and store new sgv entries
api.post('/entries', verifyAuthorization, function (req, res, next) {
req.persist_entries = true;
next( );
return;
}, insert_entries, format_entries);
if (app.enabled('api')) {
// Create and store new sgv entries
api.post('/', wares.verifyAuthorization, function (req, res, next) {
req.persist_entries = true;
next( );
return;
}, insert_entries, format_entries);
}

// Fetch one entry by id
api.get('/entries/:id', function(req, res) {
api.get('/find/:id', function(req, res) {
entries.getEntry(function(err, entry) {
if (err)
res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err);
Expand All @@ -204,46 +151,7 @@ function api (env, entries, settings) {
}, req.params.id);
});

// Fetch settings
api.get('/settings', function(req, res) {
settings.getSettings(function(err, settings) {
if (err)
res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err);
else
return res.json(settings);
});
});

// Delete settings
api.delete('/settings', verifyAuthorization, function(req, res) {
settings.remove(function ( ) {
res.json({ });
});
});

// Replace settings
api.put('/settings', verifyAuthorization, function(req, res) {
// Retrieve the JSON formatted record.
var json = req.body;
console.log(req.body, json);


// Send the new settings to mongodb.
settings.updateSettings(json, function(err, config) {
if (err)
res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err);
else {
// Add a warning to the outgoing status when HTTPS is not being used.
var warning = '';
if (req.secure === false)
warning = 'WARNING: HTTPS is required to secure your data!';

res.json(config);
}
});
});

return api;
}
module.exports = api;

module.exports = configure;
Empty file added lib/api/entries/middleware.js
Empty file.
23 changes: 23 additions & 0 deletions lib/api/experiments/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

var consts = require('../../constants');

function configure (app, wares) {
var express = require('express'),
api = express.Router( )
;

if (app.enabled('api')) {
api.use(wares.sendJSONStatus);
api.get('/:secret/test', wares.verifyAuthorization, function (req, res, next) {
return res.json({status: 'ok'});
});

api.get('/test', wares.verifyAuthorization, function (req, res, next) {
return res.json({status: 'ok'});
});
}

return api;
}

module.exports = configure;
41 changes: 41 additions & 0 deletions lib/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

function create (env, entries, settings) {
var express = require('express'),
app = express( )
;

var wares = require('../middleware/')(env);

// Only allow access to the API if API_SECRET is set on the server.
app.disable('api');
if (env.api_secret) {
console.log("API_SECRET", env.api_secret);
app.enable('api');
}

// set up express basics
app.set('title', 'Nightscout API v1');

/*
* Start setting up routes
*/

if (app.enabled('api')) {
app.use('/experiments', require('./experiments/')(app, wares));
}

/**********\
* Entries
\**********/
app.use('/entries', require('./entries/')(app, wares, entries));

/**********\
* Settings
\**********/
app.use('/settings', require('./settings/')(app, wares, settings));

app.use('/status', require('./status')(app, wares));
return app;
}

module.exports = create;
69 changes: 69 additions & 0 deletions lib/api/settings/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

var consts = require('../../constants');

function configure (app, wares, settings) {
var express = require('express'),
api = express.Router( )
;
// invoke common middleware
api.use(wares.sendJSONStatus);
// text body types get handled as raw buffer stream
api.use(wares.bodyParser.raw( ));
// json body types get handled as parsed json
api.use(wares.bodyParser.json( ));
// also support url-encoded content-type
api.use(wares.bodyParser.urlencoded({ extended: true }));


/**********\
* Settings
\**********/
// Fetch settings
api.get('/', function(req, res) {
settings.getSettings(function(err, settings) {
if (err)
res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err);
else
return res.json(settings);
});
});

function config_authed (app, api, wares, settings) {

// Delete settings
api.delete('/', wares.verifyAuthorization, function(req, res) {
settings.remove(function ( ) {
res.json({ });
});
});

// Replace settings
api.put('/', wares.verifyAuthorization, function(req, res) {
// Retrieve the JSON formatted record.
var json = req.body;

// Send the new settings to mongodb.
settings.updateSettings(json, function(err, config) {
if (err)
res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err);
else {
// Add a warning to the outgoing status when HTTPS is not being used.
var warning = '';
if (req.secure === false)
warning = 'WARNING: HTTPS is required to secure your data!';

res.json(config);
}
});
});
}

if (app.enabled('api')) {
config_authed(app, api, wares, settings);
}

return api;
}

module.exports = configure;

35 changes: 35 additions & 0 deletions lib/api/status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

function configure (app, wares) {
var express = require('express'),
api = express.Router( )
;

api.use(wares.extensions([
'json', 'svg', 'csv', 'txt', 'png', 'html'
]));
// Status badge/text/json
api.get('/', function (req, res, next) {
var status = {status: 'ok'};
var badge = 'http://img.shields.io/badge/Nightscout-OK-green';
return res.format({
html: function ( ) {
res.send("<h1>STATUS OK</h1>");
},
png: function ( ) {
res.redirect(302, badge + '.png');
},
svg: function ( ) {
res.redirect(302, badge + '.svg');
},
text: function ( ) {
res.send("STATUS OK");
},
json: function ( ) {
res.json(status);
}
});
});

return api;
}
module.exports = configure;
Loading