From 2f772230aee69a44a57aae90b6559dce09b2e930 Mon Sep 17 00:00:00 2001 From: jrtechs Date: Sat, 1 May 2021 14:42:38 -0400 Subject: [PATCH] fitbit api aggregation --- python/parseTCX.py | 0 server.js | 185 ++++++++++++++++++++++++++++++++++++++++++++- utils.js | 15 ++++ 3 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 python/parseTCX.py diff --git a/python/parseTCX.py b/python/parseTCX.py new file mode 100644 index 0000000..e69de29 diff --git a/server.js b/server.js index 032ab4c..e6b0434 100644 --- a/server.js +++ b/server.js @@ -15,8 +15,6 @@ const utils = require("./utils.js"); const config = utils.getFileAsJSON("config.json"); - - app.use(passport.initialize()); app.use(passport.session({ resave: false, @@ -114,9 +112,107 @@ app.get('/steps', (request, result)=> }); }); + +//2021-06-01T00:00:00 + +app.get('/list-activities/:startTime', (request, result)=> +{ + var startTime = request.params.startTime; + + fetchActivities(result, startTime).then((data)=> + { + result.writeHead(200, {'Content-Type': 'text/json'}); + result.write(JSON.stringify(data)); + result.end(); + }).catch((error)=> + { + console.log(error); + result.writeHead(500, {'Content-Type': 'text/json'}); + result.end(); + }); +}); + + +function fetchActivities(result, startTime) +{ + return new Promise((resolve, reject)=> + { + queryAPI(result, 'https://api.fitbit.com/1/user/-/activities/list.json?beforeDate=' + startTime + '&sort=desc&offset=0&limit=100').then((data)=> + { + if(data != false) + { + resolve(data.activities); + } + reject("Error with API, are you authenticated") + }); + }); +} + +//2021-06-01T00:00:00 +//2020-04-06T17:16:19.000-04:00 +function fetchAllRuns(result, startTime) +{ + var runs = []; + console.log(startTime); + return new Promise((resolve, reject)=> + { + fetchActivities(result, startTime).then((events)=> + { + if(events.length < 10) + { + resolve(runs); + } + else + { + for(var i = 0; i < events.length; i++) + { + if(events[i].logType === "mobile_run") + { + console.log(events[i]); + runs.push(events[i]); + } + } + var newStart = events[events.length -1].startTime.slice(0, -10); + fetchAllRuns(result, newStart).then((run_rec)=> + { + resolve(runs.concat(run_rec)); + }).catch((err)=> + { + reject(err); + }); + } + }).catch((error)=> + { + reject(error); + }); + }); +} + + + +//2021-06-01T00:00:00 +app.get('/all-logged-runs', (request, result)=> +{ + var startTime = '2030-06-01T00:00:00'; + + fetchAllRuns(result, startTime).then((data)=> + { + result.writeHead(200, {'Content-Type': 'text/json'}); + result.write(JSON.stringify(data)); + result.end(); + }).catch((error)=> + { + console.log(error); + result.writeHead(500, {'Content-Type': 'text/json'}); + result.end(); + }); +}); + + + app.get('/activities', (request, result)=> { - queryAPI(result, 'https://api.fitbit.com/1/user/-/activities/date/1M.json').then((data)=> + queryAPI(result, 'https://api.fitbit.com/1/user/-/activities/recent.json').then((data)=> { if(data != false) { @@ -132,6 +228,89 @@ app.get('/activities', (request, result)=> }); +function fetchTCX(result, tcxID) +{ + console.log("Fetching tcx event: " + tcxID); + return new Promise((resolve, reject)=> + { + queryAPI(result, 'https://api.fitbit.com/1/user/-/activities/' + tcxID + ".tcx").then((data)=> + { + if(data != false) + { + resolve(data); + } + reject("Error with API, are you authenticated") + }); + }); +} + + +function saveTCX(result, tcxID) +{ + return new Promise((resolve, reject)=> + { + fetchTCX(result, tcxID).then((tcx)=> + { + utils.saveFile(tcxID + ".tcx", tcx); + resolve(); + }).catch((err)=> + { + reject(err); + }) + }); +} + + +app.get('/save-all-tcx', (request, result)=> +{ + var tcxID = request.params.id; + + var startTime = '2030-06-01T00:00:00'; + + fetchAllRuns(result, startTime).then((data)=> + { + var promises = []; + for(var i =0; i < data.length; i++) + { + promises.push(saveTCX(result, data[i].logId)); + } + Promise.all(promises).then(function(content) + { + result.write("All events saved"); + result.end(); + }).catch(function(err) + { + console.log(err); + throw err; + }); + }).catch((error)=> + { + console.log(error); + result.writeHead(500, {'Content-Type': 'text/json'}); + result.end(); + }); +}); + + +app.get('/tcx/:id', (request, result)=> +{ + var tcxID = request.params.id; + + fetchTCX(result, tcxID).then((data)=> + { + result.writeHead(200, {'Content-Type': 'text/xml'}); + result.write(data); + result.end(); + }).catch((error)=> + { + console.log(error); + result.writeHead(500, {'Content-Type': 'text/json'}); + result.end(); + }); + +}); + + app.get('/', (request, result) => { result.write(utils.getFile("index.html")); diff --git a/utils.js b/utils.js index b7b3533..36a56f8 100644 --- a/utils.js +++ b/utils.js @@ -16,5 +16,20 @@ module.exports= getFile: function(filename) { return fs.readFileSync(filename, 'utf8'); + }, + + saveFile: function(filename, contents) + { + fs.writeFile(filename, contents, function(err) + { + if(err) + { + console.log(err); + } + else + { + console.log(filename + " saved"); + } + }); } };