From 4780a1e4e56c749b30dcce47839d1768654f1ec1 Mon Sep 17 00:00:00 2001 From: Beau Gunderson Date: Wed, 21 Mar 2012 01:34:25 -0700 Subject: [PATCH] First attempt at a Zeo connector. Includes a change to registry.js to allow POSTs to /auth/:id/auth (so that passwords can be sent as POST data and not via the querystring). --- Connectors/Zeo/auth.js | 22 +++++++++++++ Connectors/Zeo/lib.js | 62 ++++++++++++++++++++++++++++++++++++ Connectors/Zeo/package.json | 21 ++++++++++++ Connectors/Zeo/sleep.js | 47 +++++++++++++++++++++++++++ Connectors/Zeo/synclets.json | 5 +++ Connectors/Zeo/test.js | 10 ++++++ Ops/registry.js | 1 + 7 files changed, 168 insertions(+) create mode 100644 Connectors/Zeo/auth.js create mode 100644 Connectors/Zeo/lib.js create mode 100644 Connectors/Zeo/package.json create mode 100644 Connectors/Zeo/sleep.js create mode 100644 Connectors/Zeo/synclets.json create mode 100644 Connectors/Zeo/test.js diff --git a/Connectors/Zeo/auth.js b/Connectors/Zeo/auth.js new file mode 100644 index 000000000..c799d3488 --- /dev/null +++ b/Connectors/Zeo/auth.js @@ -0,0 +1,22 @@ +module.exports = { + handler: function (host, apiKeys, done, req, res) { + if (req.method === 'POST') { + done(null, { + appKey: apiKeys.appKey, + username: req.body.username, + password: req.body.password + }); + + return; + } + + res.writeHead(200, { 'Content-Type': 'text/html' }); + + res.end('Please enter your Zeo credentials:' + + '
' + + '

' + + '

' + + '' + + '
'); + } +}; diff --git a/Connectors/Zeo/lib.js b/Connectors/Zeo/lib.js new file mode 100644 index 000000000..a516a21bd --- /dev/null +++ b/Connectors/Zeo/lib.js @@ -0,0 +1,62 @@ +exports.callApi = function(pi, cb, pather, querier, arrayer) { + var https = require('https'); + + var authorization = 'Basic ' + new Buffer(pi.auth.username + ':' + + pi.auth.password).toString('base64'); + + var options = { + host: 'api.myzeo.com', + port: 8443, + path: '/zeows/api/v1/json' + pather(pi) + querier(pi), + headers: { + 'Accept': '*/*', + 'Connection': 'close', + 'Referer': pi.uri, + 'Authorization': authorization + } + }; + + // Send the request + https.get(options, function(res) { + res.setEncoding('utf8'); + + var data = ''; + + res.on('data', function(chunk) { + data += chunk; + }); + + // Once we've got the full response... + res.on('end', function() { + cb(data); + }); + }); +}; + +exports.genericSync = function(type, pather, querier, arrayer) { + return function(pi, cb) { + exports.callApi(pi, function(data) { + var js; + + try { + js = JSON.parse(data); + } catch(E) { + return cb(err); + } + + arrayer(pi, js, function(arrayData) { + var array = {}; + + array[type] = arrayData; + + // And return it using the passed in callback, + // with (optionally) updated auth and config data + cb(null, { + auth: pi.auth, + config: pi.config, + data: array + }); + }); + }, pather, querier, arrayer); + }; +}; diff --git a/Connectors/Zeo/package.json b/Connectors/Zeo/package.json new file mode 100644 index 000000000..d63ff9f25 --- /dev/null +++ b/Connectors/Zeo/package.json @@ -0,0 +1,21 @@ +{ + "author": "Beau Gunderson ", + "name": "zeo", + "description": "Zeo", + "version": "0.1.2", + "repository": { + "title": "Zeo", + "handle": "zeo", + "author": "Beau Gunderson ", + "update": "auto", + "github": "https://github.com/LockerProject/Locker", + "type": "connector", + "static": "false", + "url": "" + }, + "engines": { + "node": ">=0.4.9" + }, + "dependencies": {}, + "devDependencies": {} +} diff --git a/Connectors/Zeo/sleep.js b/Connectors/Zeo/sleep.js new file mode 100644 index 000000000..157365915 --- /dev/null +++ b/Connectors/Zeo/sleep.js @@ -0,0 +1,47 @@ +var async = require('async'), + lib = require('./lib'); + +exports.sync = lib.genericSync('sleep', function(pi) { + return '/sleeperService/getAllDatesWithSleepData'; +}, function(pi) { + return '?key=' + pi.auth.appKey; +}, function(pi, js, cb) { + var dates = js.response.dateList.date; + + if (!js || !dates) { + return []; + } + + // For each date with a sleep record... + async.mapSeries(dates, function(date, mapped) { + // Retrieve the record... + lib.callApi(pi, function(data) { + var js; + + try { + js = JSON.parse(data); + } catch(E) { + mapped(E); + } + + var record = js.response.sleepRecord; + + if (!js || !record) { + mapped(); + } + + record.id = record.startDate.year + '-' + + record.startDate.month + '-' + + record.startDate.day; + + mapped(null, record); + }, function(pi) { + return '/sleeperService/getSleepRecordForDate'; + }, function(pi) { + return '?key=' + pi.auth.appKey + '&date=' + date.year + '-' + date.month + '-' + date.day; + }); + }, function(err, results){ + // And return them all up the chain. + cb(results); + }); +}); diff --git a/Connectors/Zeo/synclets.json b/Connectors/Zeo/synclets.json new file mode 100644 index 000000000..709594e40 --- /dev/null +++ b/Connectors/Zeo/synclets.json @@ -0,0 +1,5 @@ +{ + "synclets": [ + { "name": "sleep", "frequency": 86400, "threshold": 0 } + ] +} diff --git a/Connectors/Zeo/test.js b/Connectors/Zeo/test.js new file mode 100644 index 000000000..17374feb4 --- /dev/null +++ b/Connectors/Zeo/test.js @@ -0,0 +1,10 @@ +var fs = require('fs'); +var pi = JSON.parse(fs.readFileSync("../../Me/zeo/me.json")); + +var sync = require(process.argv[2]); + +sync.sync(pi, function(e, js) { + console.error('error', e); + + console.error("got js", JSON.stringify(js)); +}); diff --git a/Ops/registry.js b/Ops/registry.js index 3939a0f8c..0582a0995 100644 --- a/Ops/registry.js +++ b/Ops/registry.js @@ -91,6 +91,7 @@ exports.app = function (app) { app.get('/auth/:id', authIsAwesome); app.get('/auth/:id/auth', authIsAuth); + app.post('/auth/:id/auth', express.bodyParser(), authIsAuth); app.get('/deauth/:id', deauthIsAwesomer); };