Last active
December 2, 2016 10:52
-
-
Save maccyber/2a706be08fb55a5bc2646d7b6c4a32f2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This code is responsible for implementing all methods related to fetching | |
* and returning data for the Norwegian data sources. | |
*/ | |
'use strict'; | |
import { REQUEST_TIMEOUT } from '../lib/constants'; | |
import { default as baseRequest } from 'request'; | |
const request = baseRequest.defaults({timeout: REQUEST_TIMEOUT}); | |
import { default as moment } from 'moment-timezone'; | |
import log from '../lib/logger'; | |
exports.name = 'norway'; | |
/** | |
* Fetches the data for a given source and returns an appropriate object | |
* @param {object} source A valid source object | |
* @param {function} cb A callback of the form cb(err, data) | |
*/ | |
exports.fetchData = function (source, cb) { | |
request(source.url, function (err, res, body) { | |
if (err || res.statusCode !== 200) { | |
log.error(err || res.statusCode); | |
return cb({message: 'Failure to load data url.'}); | |
} | |
// Wrap everything in a try/catch in case something goes wrong | |
try { | |
// Format the data | |
const data = formatData(body); | |
// Make sure the data is valid | |
if (data === undefined) { | |
return cb({message: 'Failure to parse data.'}); | |
} | |
cb(null, data); | |
} catch (e) { | |
return cb({message: 'Unknown adapter error.'}); | |
} | |
}); | |
}; | |
/** | |
* Given fetched data, turn it into a format our system can use. | |
* @param {array} results Fetched source data and other metadata | |
* @return {object} Parsed and standarized data our system can use | |
*/ | |
const formatData = function (data) { | |
// Wrap the JSON.parse() in a try/catch in case it fails | |
try { | |
data = JSON.parse(data); | |
} catch (e) { | |
// Return undefined to be caught elsewhere | |
return undefined; | |
} | |
/** | |
* Given a json object, convert to aq openaq format | |
* @param {json object} item coming from source data | |
* @return {object} a repacked object | |
*/ | |
const aqRepack = (item) => { | |
const dateMoment = moment.tz(item.fromTime, 'YYYY-MM-DD HH:mm', 'Europe/Oslo'); | |
const template = { | |
name: item.station, | |
measurements: [ | |
{ | |
parameter: item.component, | |
date: { | |
utc: dateMoment.toDate(), | |
local: dateMoment.format() | |
}, | |
coordinates: { | |
latitude: item.latitude, | |
longitude: item.longitude | |
}, | |
value: item.value, | |
unit: item.unit | |
} | |
] | |
}; | |
return template; | |
}; | |
// Maps array to aq-format | |
const result = [...data.map(aqRepack).reduce((m, o) => { | |
const name = o.name.toLowerCase(); | |
let obj = m.get(name); | |
return obj ? m.set(name, { | |
name: name, | |
measurements: [...new Set(obj.measurements.concat(o.measurements))] | |
}) | |
: m.set(name, o); | |
}, | |
new Map() | |
).values() | |
]; | |
return result; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment