const request = require('request'); const FeedMe = require('feedme'); const http = require('http'); const logger = require('log4js').getLogger('Directions'); logger.level = 'debug'; const { reduceEstDirections, reduceIncidents, combine } = require('./reducers/directions'); module.exports = { 'getTraffic': doGetEstDirections, 'getIncidents' : doGetTraffic, doGetEstDirectionsWithIncidents }; const headers = {}; const lastGood = {}; // // https://maps.googleapis.com/maps/api/directions/json?origin=Toronto&destination=Montreal&key=AIzaSyBl7O9LHIthCagcqIaDkQ4um_hghYG5reE async function doGetEstDirectionsWithIncidents(olat, olon, dlat, dlon) { let traff = await doGetEstDirections(olat, olon, dlat, dlon); let incid = await doGetTraffic(); logger.debug('after...'); let combined = combine(traff, incid); return combined; } async function doGetEstDirections(olat, olon, dlat, dlon) { logger.debug('doGetEstDirections'); const url = `https://sgws2.maps.yahoo.com/Directions?time=now&cache=n&flags=J&olat=${olat}&olon=${olon}&dlat=${dlat}&dlon=${dlon}&mode=11`; logger.debug(url); return new Promise(function(resolve, reject) { request(url, function(err, resp, body) { if (err) // Logger.error(err); return reject(err); // Throw err; const output = reduceEstDirections(body); output.fullBody = JSON.parse(body); output.timestamp = new Date().getTime(); console.log(output); return resolve(output); }, function(error, response, body) { console.log(response); if (response.statusCode !== 200) { logger.error(response.statusCode); logger.error(body); return reject(error); } }); }); } async function doGetTraffic() { logger.debug('doGetTraffic'); return new Promise((resolve, reject) => { // https://trafficscotland.org/rss/feeds/currentincidents.aspx const options = { 'hostname': 'trafficscotland.org', 'path': '/rss/feeds/currentincidents.aspx', 'method': 'GET', 'headers': headers }; http.get(options, (res) => { const { statusCode } = res; const contentType = res.headers['content-type']; const reqLastModified = res.headers['date']; logger.debug(res.headers); let error; logger.debug('contentType', contentType); if (statusCode !== 200 && statusCode !== 304) error = new Error('Request Failed.\n' + `Status Code: ${statusCode}`); else if (!/^application\/rss\+xml/.test(contentType) && statusCode === 200) error = new Error('Invalid content-type.\n' + `Expected application/rss+xml but received ${contentType}`); if (error) { logger.error(error.message); // consume response data to free up memory res.resume(); return reject(error); } if ( statusCode === 200) { headers['If-Modified-Since'] = reqLastModified; const parser = new FeedMe(true); res.pipe(parser); parser.on('end', () => { lastGood.page = reduceIncidents(parser.done()); logger.info('Traffic Feed cached'); // return resolve(parser.done()); return resolve(lastGood.page); }); } else if (statusCode === 304) { logger.info('Traffic Feed changed'); return resolve(lastGood.page); } }); }); }