From c2fa3a25a961fdfad31fdf9a1e9047dfd0739e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20H=C3=B3lm?= Date: Sat, 23 Feb 2019 22:27:24 +0000 Subject: [PATCH 1/5] Added /road endpoint for vegagerdin --- endpoints/road/all.js | 63 ++++++++++++++++++++++++ endpoints/road/documentation.md | 16 ++++++ endpoints/road/index.js | 19 +++++++ endpoints/road/tests/integration_test.js | 38 ++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 endpoints/road/all.js create mode 100644 endpoints/road/documentation.md create mode 100644 endpoints/road/index.js create mode 100644 endpoints/road/tests/integration_test.js diff --git a/endpoints/road/all.js b/endpoints/road/all.js new file mode 100644 index 00000000..f77440cd --- /dev/null +++ b/endpoints/road/all.js @@ -0,0 +1,63 @@ +const request = require('request') +const xml2js = require('xml2js') +const h = require('apis-helpers') +const app = require('../../server') + +const parseString = xml2js.parseString +// return callback(null, JSON.parse(data)) +const parseFeed = function (callback, data) { + parseString(data, { explicitRoot: false }, (err, result, title) => { + if (err) return callback(new Error(`Parsing of XML failed. Title ${err}`)) + const roads = [] + + for (let i = 0; i < result.Faerd.length; ++i) { + const Road = result.Faerd[i] + roads.push({ + routeId: Road.IdLeid[0].length > 0 ? Road.IdLeid[0] : null, // Can be null + routeName: Road.LeidNafn[0].length > 0 ? Road.LeidNafn[0] : null, // Can be null + segmentId: parseInt(Road.IdButur[0]), + segmentSerial: Road.Rodun[0], + segmentName: Road.LangtNafn[0], + segmentShortName: Road.StuttNafn[0], + segmentSignal: Road.Skilti[0].length > 0 ? Road.Skilti[0] : null, + conditionId: Road.IdAstand[0], + conditionDescription: Road.FulltAstand[0], + conditionShortDescription: Road.StuttAstand[0], + priority: parseInt(Road.Forgangur[0]), + comment: Road.Aths[0].length > 0 ? Road.Aths[0] : null, + date: Road.DagsKeyrtUt[0], + isHighlands: parseInt(Road.ErHalendi[0]) === 1 ? true : false, + colorCode: Road.Linulitur[0].length > 0 ? Road.Linulitur[0] : null, + conditionUpdated: Road.DagsSkrad[0], + surfaceCondition: Road.AstandYfirbords[0], + }) + } + return callback(null, roads) + }) +} + +const getFeed = function (url, callback) { + request.get({ + headers: { 'User-Agent': h.browser(), 'Content-Type': 'application/xml; charset=utf-8' }, + encoding: 'utf-8', + url, + }, (error, response, body) => { + console.log(body) + if (error) return callback(new Error(`${url} did not respond ${JSON.stringify(error)}`)) + parseFeed(callback, body) + }) +} + +const serve = function (url, res, next) { + getFeed(url, (err, data) => { + if (err) { + return res.status(500).json({ error: 'www.vegagerdin.is refuses to respond or give back data ' + err }) + } + res.cache(1800).json({ results: data }) + }) +} + +app.get('/road/all', (req, res, next) => { + const url = 'http://gagnaveita.vegagerdin.is/api/faerd2014_1' + serve(url, res, next) +}) \ No newline at end of file diff --git a/endpoints/road/documentation.md b/endpoints/road/documentation.md new file mode 100644 index 00000000..dcf3b053 --- /dev/null +++ b/endpoints/road/documentation.md @@ -0,0 +1,16 @@ +# Road conditions in Iceland + +Source: [Vegagerdin](http://gagnaveita.vegagerdin.is/api/faerd2014_1) + +http://www.vegagerdin.is/upplysingar-og-utgafa/gagnaveita-vegagerdarinnar/ + +- GET [/road](https://apis.is/road) +- GET [/road/all](https://apis.is/road/all) + +Lookup road conditions in Iceland + +| Endpoints | Description | Example | +|------------|------------------------------------------------|---------------------------------| +| :endpoint | Which region in Iceland to get road conditions | [all](https://apis.is/road/all) | + +--- diff --git a/endpoints/road/index.js b/endpoints/road/index.js new file mode 100644 index 00000000..8aaa6ebe --- /dev/null +++ b/endpoints/road/index.js @@ -0,0 +1,19 @@ +const app = require('../../server') + +/* Root Vegagerdin */ +app.get('/road', (req, res) => { + return res.json({ + results: [ + { + info: 'This is an Api for Iceland\'s roads conditions', + endpoints: { + all: '/road/all', + // sudurland: '/road/sudurland', + // nordurland: '/road/nordurland', + // austurland: '/road/austurland', + // vesturland: '/road/vesturland', + }, + }, + ], + }) +}) diff --git a/endpoints/road/tests/integration_test.js b/endpoints/road/tests/integration_test.js new file mode 100644 index 00000000..2cc41b1e --- /dev/null +++ b/endpoints/road/tests/integration_test.js @@ -0,0 +1,38 @@ +const request = require('request') +const helpers = require('../../../lib/test_helpers') + +describe('tv root', () => { + it('should return info', (done) => { + const fieldsToCheckFor = ['info'] + const params = helpers.testRequestParams('/road/') + const resultHandler = helpers.testRequestHandlerForFields(done, fieldsToCheckFor) + request.get(params, resultHandler) + }) +}) + +describe('road - all', () => { + it('should return an array of objects containing correct fields', (done) => { + const fieldsToCheckFor = [ + 'routeId', + 'routeName', + 'segmentId', + 'segmentSerial', + 'segmentName', + 'segmentShortName', + 'segmentSignal', + 'conditionId', + 'conditionDescription', + 'conditionShortDescription', + 'priority', + 'comment', + 'date', + 'isHighlands', + 'colorCode', + 'conditionUpdated', + 'surfaceCondition', + ] + const params = helpers.testRequestParams('/road') + const resultHandler = helpers.testRequestHandlerForFields(done, fieldsToCheckFor) + request.get(params, resultHandler) + }) +}) \ No newline at end of file From ef8f556cfc6f78eb85831e6468091547faa0945a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20H=C3=B3lm?= Date: Sat, 23 Feb 2019 22:43:58 +0000 Subject: [PATCH 2/5] Fixed the test path on road - all --- endpoints/road/tests/integration_test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/endpoints/road/tests/integration_test.js b/endpoints/road/tests/integration_test.js index 2cc41b1e..dc866cd9 100644 --- a/endpoints/road/tests/integration_test.js +++ b/endpoints/road/tests/integration_test.js @@ -1,7 +1,7 @@ const request = require('request') const helpers = require('../../../lib/test_helpers') -describe('tv root', () => { +describe('road root', () => { it('should return info', (done) => { const fieldsToCheckFor = ['info'] const params = helpers.testRequestParams('/road/') @@ -31,7 +31,7 @@ describe('road - all', () => { 'conditionUpdated', 'surfaceCondition', ] - const params = helpers.testRequestParams('/road') + const params = helpers.testRequestParams('/road/all') const resultHandler = helpers.testRequestHandlerForFields(done, fieldsToCheckFor) request.get(params, resultHandler) }) From 2e25d17f1c1f6f86bed241514991e39b81856dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20H=C3=B3lm?= Date: Sat, 23 Feb 2019 22:51:17 +0000 Subject: [PATCH 3/5] fix linting --- endpoints/road/all.js | 18 ++++++++++++------ endpoints/road/tests/integration_test.js | 10 +++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/endpoints/road/all.js b/endpoints/road/all.js index f77440cd..80010f56 100644 --- a/endpoints/road/all.js +++ b/endpoints/road/all.js @@ -1,3 +1,8 @@ +/* eslint-disable no-plusplus */ +/* eslint-disable no-prototype-builtins */ +/* eslint-disable prefer-destructuring */ +/* eslint-disable no-unneeded-ternary */ + const request = require('request') const xml2js = require('xml2js') const h = require('apis-helpers') @@ -6,7 +11,7 @@ const app = require('../../server') const parseString = xml2js.parseString // return callback(null, JSON.parse(data)) const parseFeed = function (callback, data) { - parseString(data, { explicitRoot: false }, (err, result, title) => { + parseString(data, { explicitRoot: false }, (err, result) => { if (err) return callback(new Error(`Parsing of XML failed. Title ${err}`)) const roads = [] @@ -15,7 +20,7 @@ const parseFeed = function (callback, data) { roads.push({ routeId: Road.IdLeid[0].length > 0 ? Road.IdLeid[0] : null, // Can be null routeName: Road.LeidNafn[0].length > 0 ? Road.LeidNafn[0] : null, // Can be null - segmentId: parseInt(Road.IdButur[0]), + segmentId: parseInt(Road.IdButur[0], 10), segmentSerial: Road.Rodun[0], segmentName: Road.LangtNafn[0], segmentShortName: Road.StuttNafn[0], @@ -23,10 +28,10 @@ const parseFeed = function (callback, data) { conditionId: Road.IdAstand[0], conditionDescription: Road.FulltAstand[0], conditionShortDescription: Road.StuttAstand[0], - priority: parseInt(Road.Forgangur[0]), + priority: parseInt(Road.Forgangur[0], 10), comment: Road.Aths[0].length > 0 ? Road.Aths[0] : null, date: Road.DagsKeyrtUt[0], - isHighlands: parseInt(Road.ErHalendi[0]) === 1 ? true : false, + isHighlands: parseInt(Road.ErHalendi[0], 2) === 1 ? true : false, colorCode: Road.Linulitur[0].length > 0 ? Road.Linulitur[0] : null, conditionUpdated: Road.DagsSkrad[0], surfaceCondition: Road.AstandYfirbords[0], @@ -51,7 +56,8 @@ const getFeed = function (url, callback) { const serve = function (url, res, next) { getFeed(url, (err, data) => { if (err) { - return res.status(500).json({ error: 'www.vegagerdin.is refuses to respond or give back data ' + err }) + console.error(err) + return next(502) } res.cache(1800).json({ results: data }) }) @@ -60,4 +66,4 @@ const serve = function (url, res, next) { app.get('/road/all', (req, res, next) => { const url = 'http://gagnaveita.vegagerdin.is/api/faerd2014_1' serve(url, res, next) -}) \ No newline at end of file +}) diff --git a/endpoints/road/tests/integration_test.js b/endpoints/road/tests/integration_test.js index dc866cd9..b9141a96 100644 --- a/endpoints/road/tests/integration_test.js +++ b/endpoints/road/tests/integration_test.js @@ -14,10 +14,10 @@ describe('road - all', () => { it('should return an array of objects containing correct fields', (done) => { const fieldsToCheckFor = [ 'routeId', - 'routeName', - 'segmentId', - 'segmentSerial', - 'segmentName', + 'routeName', + 'segmentId', + 'segmentSerial', + 'segmentName', 'segmentShortName', 'segmentSignal', 'conditionId', @@ -35,4 +35,4 @@ describe('road - all', () => { const resultHandler = helpers.testRequestHandlerForFields(done, fieldsToCheckFor) request.get(params, resultHandler) }) -}) \ No newline at end of file +}) From 9c3a57dbde5ecd0beec08c25ae4a22d8dc5de603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20H=C3=B3lm?= Date: Sun, 24 Feb 2019 01:14:21 +0000 Subject: [PATCH 4/5] Added endpoints for all regions in Iceland --- endpoints/road/all.js | 2 +- endpoints/road/documentation.md | 5 +- endpoints/road/index.js | 13 ++- endpoints/road/regions.js | 149 ++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 7 deletions(-) create mode 100644 endpoints/road/regions.js diff --git a/endpoints/road/all.js b/endpoints/road/all.js index 80010f56..45c516a3 100644 --- a/endpoints/road/all.js +++ b/endpoints/road/all.js @@ -9,7 +9,7 @@ const h = require('apis-helpers') const app = require('../../server') const parseString = xml2js.parseString -// return callback(null, JSON.parse(data)) + const parseFeed = function (callback, data) { parseString(data, { explicitRoot: false }, (err, result) => { if (err) return callback(new Error(`Parsing of XML failed. Title ${err}`)) diff --git a/endpoints/road/documentation.md b/endpoints/road/documentation.md index dcf3b053..02e2f97e 100644 --- a/endpoints/road/documentation.md +++ b/endpoints/road/documentation.md @@ -10,7 +10,8 @@ http://www.vegagerdin.is/upplysingar-og-utgafa/gagnaveita-vegagerdarinnar/ Lookup road conditions in Iceland | Endpoints | Description | Example | -|------------|------------------------------------------------|---------------------------------| -| :endpoint | Which region in Iceland to get road conditions | [all](https://apis.is/road/all) | +|------------|------------------------------------------------|---------------------------------------------| +| :endpoint | Which region in Iceland to get road conditions | [all](https://apis.is/road/all) | +| /reykjavik | | [reykjavik](https://apis.is/road/reykjavik) | --- diff --git a/endpoints/road/index.js b/endpoints/road/index.js index 8aaa6ebe..c84ad67d 100644 --- a/endpoints/road/index.js +++ b/endpoints/road/index.js @@ -8,10 +8,15 @@ app.get('/road', (req, res) => { info: 'This is an Api for Iceland\'s roads conditions', endpoints: { all: '/road/all', - // sudurland: '/road/sudurland', - // nordurland: '/road/nordurland', - // austurland: '/road/austurland', - // vesturland: '/road/vesturland', + reykjavik: '/road/reykjavik', + south: '/road/south', + southeast: '/road/southeast', + southwest: '/road/southwest', + westfjords: '/road/westfjords', + north: '/road/north', + northeast: '/road/northeast', + east: '/road/east', + highlands: '/road/highlands', }, }, ], diff --git a/endpoints/road/regions.js b/endpoints/road/regions.js new file mode 100644 index 00000000..8cf5ddfe --- /dev/null +++ b/endpoints/road/regions.js @@ -0,0 +1,149 @@ +/* eslint-disable no-plusplus */ +/* eslint-disable no-prototype-builtins */ +/* eslint-disable prefer-destructuring */ +/* eslint-disable no-unneeded-ternary */ + +const request = require('request') +const xml2js = require('xml2js') +const h = require('apis-helpers') +const cheerio = require('cheerio') +const app = require('../../server') + +const parseString = xml2js.parseString + +const sourceUrl = 'http://gagnaveita.vegagerdin.is/api/faerd2014_1' + +const getRegionSegments = (url) => new Promise((resolve, reject) => { + request(url, (error, response, body) => { + if (error) { + reject(error) + } + + let $ + + try { + $ = cheerio.load(body) + } catch (e) { + return res.status(500).json({ error: 'Could not load the body with cherrio.' }) + } + const hotspots = $('.vg-roadmap-hotspot') + + const segments = [] + // Loop through hotspots + hotspots.each(function () { + // This hotspot + const hotspot = $(this) + + // Find hotspot info + const hotspotinfo = hotspot.attr('data-hotspotinfo') + const obj = JSON.parse(hotspotinfo.replace(/'/g, '"')) + if(obj.idleid) + segments.push(parseInt(obj.idleid, 10)) + }) + resolve(segments) + }) +}) + +const parseFeed = function (callback, data, regionUrl) { + parseString(data, { explicitRoot: false }, (err, result) => { + if (err) return callback(new Error(`Parsing of XML failed. Title ${err}`)) + const regionSegments = getRegionSegments(regionUrl) + regionSegments.then((segments) => { + const roads = [] + + for (let i = 0; i < result.Faerd.length; ++i) { + const Road = result.Faerd[i] + const segmentId = parseInt(Road.IdButur[0], 10) + const shortSegmentId = parseInt(Road.IdButur[0].slice(0, 5)) + if (segments.includes(shortSegmentId)) + roads.push({ + routeId: Road.IdLeid[0].length > 0 ? Road.IdLeid[0] : null, // Can be null + routeName: Road.LeidNafn[0].length > 0 ? Road.LeidNafn[0] : null, // Can be null + segmentId: parseInt(Road.IdButur[0], 10), + segmentSerial: Road.Rodun[0], + segmentName: Road.LangtNafn[0], + segmentShortName: Road.StuttNafn[0], + segmentSignal: Road.Skilti[0].length > 0 ? Road.Skilti[0] : null, + conditionId: Road.IdAstand[0], + conditionDescription: Road.FulltAstand[0], + conditionShortDescription: Road.StuttAstand[0], + priority: parseInt(Road.Forgangur[0], 10), + comment: Road.Aths[0].length > 0 ? Road.Aths[0] : null, + date: Road.DagsKeyrtUt[0], + isHighlands: parseInt(Road.ErHalendi[0], 2) === 1 ? true : false, + colorCode: Road.Linulitur[0].length > 0 ? Road.Linulitur[0] : null, + conditionUpdated: Road.DagsSkrad[0], + surfaceCondition: Road.AstandYfirbords[0], + }) + } + return callback(null, roads) + }) + }) +} + +const getFeed = function (url,regionUrl, callback,) { + request.get({ + headers: { 'User-Agent': h.browser(), 'Content-Type': 'application/xml; charset=utf-8' }, + encoding: 'utf-8', + url, + }, (error, response, body) => { + if (error) return callback(new Error(`${url} did not respond ${JSON.stringify(error)}`)) + parseFeed(callback, body, regionUrl) + }) +} + +const serve = function (url, regionUrl, res, next) { + getFeed(url, regionUrl, (err, data) => { + if (err) { + console.error(err) + return next(502) + } + res.cache(1800).json({ results: data }) + }) +} + + +app.get('/road/reykjavik', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/reykjavik-og-nagrenni-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) +app.get('/road/west', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/vesturland-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) +app.get('/road/southwest', (req, res, next) => { + const regionUrl = 'http://vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudvesturland-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) +app.get('/road/westfjords', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/vestfirdir-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) +app.get('/road/south', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudurland-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) + +app.get('/road/north', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/nordurland-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) +app.get('/road/east', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/austurland-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) + +app.get('/road/northeast', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/nordausturland-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) + +app.get('/road/southeast', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudausturland-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) + +app.get('/road/highlands', (req, res, next) => { + const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/midhalendid-faerd-kort/' + serve(sourceUrl, regionUrl, res, next) +}) \ No newline at end of file From dfa7dfeec4200779751e5b1475e9d4803f10677c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20H=C3=B3lm?= Date: Sun, 24 Feb 2019 01:50:30 +0000 Subject: [PATCH 5/5] Fix tests and added :region --- endpoints/road/all.js | 69 ------------- endpoints/road/index.js | 81 +++++++++++---- endpoints/road/regions.js | 122 +++++++++-------------- endpoints/road/tests/integration_test.js | 13 +-- 4 files changed, 111 insertions(+), 174 deletions(-) delete mode 100644 endpoints/road/all.js diff --git a/endpoints/road/all.js b/endpoints/road/all.js deleted file mode 100644 index 45c516a3..00000000 --- a/endpoints/road/all.js +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable no-plusplus */ -/* eslint-disable no-prototype-builtins */ -/* eslint-disable prefer-destructuring */ -/* eslint-disable no-unneeded-ternary */ - -const request = require('request') -const xml2js = require('xml2js') -const h = require('apis-helpers') -const app = require('../../server') - -const parseString = xml2js.parseString - -const parseFeed = function (callback, data) { - parseString(data, { explicitRoot: false }, (err, result) => { - if (err) return callback(new Error(`Parsing of XML failed. Title ${err}`)) - const roads = [] - - for (let i = 0; i < result.Faerd.length; ++i) { - const Road = result.Faerd[i] - roads.push({ - routeId: Road.IdLeid[0].length > 0 ? Road.IdLeid[0] : null, // Can be null - routeName: Road.LeidNafn[0].length > 0 ? Road.LeidNafn[0] : null, // Can be null - segmentId: parseInt(Road.IdButur[0], 10), - segmentSerial: Road.Rodun[0], - segmentName: Road.LangtNafn[0], - segmentShortName: Road.StuttNafn[0], - segmentSignal: Road.Skilti[0].length > 0 ? Road.Skilti[0] : null, - conditionId: Road.IdAstand[0], - conditionDescription: Road.FulltAstand[0], - conditionShortDescription: Road.StuttAstand[0], - priority: parseInt(Road.Forgangur[0], 10), - comment: Road.Aths[0].length > 0 ? Road.Aths[0] : null, - date: Road.DagsKeyrtUt[0], - isHighlands: parseInt(Road.ErHalendi[0], 2) === 1 ? true : false, - colorCode: Road.Linulitur[0].length > 0 ? Road.Linulitur[0] : null, - conditionUpdated: Road.DagsSkrad[0], - surfaceCondition: Road.AstandYfirbords[0], - }) - } - return callback(null, roads) - }) -} - -const getFeed = function (url, callback) { - request.get({ - headers: { 'User-Agent': h.browser(), 'Content-Type': 'application/xml; charset=utf-8' }, - encoding: 'utf-8', - url, - }, (error, response, body) => { - console.log(body) - if (error) return callback(new Error(`${url} did not respond ${JSON.stringify(error)}`)) - parseFeed(callback, body) - }) -} - -const serve = function (url, res, next) { - getFeed(url, (err, data) => { - if (err) { - console.error(err) - return next(502) - } - res.cache(1800).json({ results: data }) - }) -} - -app.get('/road/all', (req, res, next) => { - const url = 'http://gagnaveita.vegagerdin.is/api/faerd2014_1' - serve(url, res, next) -}) diff --git a/endpoints/road/index.js b/endpoints/road/index.js index c84ad67d..5541061d 100644 --- a/endpoints/road/index.js +++ b/endpoints/road/index.js @@ -1,24 +1,65 @@ +/* eslint-disable no-plusplus */ +/* eslint-disable no-prototype-builtins */ +/* eslint-disable prefer-destructuring */ +/* eslint-disable no-unneeded-ternary */ + +const request = require('request') +const xml2js = require('xml2js') +const h = require('apis-helpers') const app = require('../../server') -/* Root Vegagerdin */ -app.get('/road', (req, res) => { - return res.json({ - results: [ - { - info: 'This is an Api for Iceland\'s roads conditions', - endpoints: { - all: '/road/all', - reykjavik: '/road/reykjavik', - south: '/road/south', - southeast: '/road/southeast', - southwest: '/road/southwest', - westfjords: '/road/westfjords', - north: '/road/north', - northeast: '/road/northeast', - east: '/road/east', - highlands: '/road/highlands', - }, - }, - ], +const parseString = xml2js.parseString + +const parseFeed = function (callback, data) { + parseString(data, { explicitRoot: false }, (err, result) => { + if (err) return callback(new Error(`Parsing of XML failed. Title ${err}`)) + const roads = [] + for (let i = 0; i < result.Faerd.length; ++i) { + const Road = result.Faerd[i] + roads.push({ + routeId: Road.IdLeid[0].length > 0 ? Road.IdLeid[0] : null, // Can be null + routeName: Road.LeidNafn[0].length > 0 ? Road.LeidNafn[0] : null, // Can be null + segmentId: parseInt(Road.IdButur[0], 10), + segmentSerial: Road.Rodun[0], + segmentName: Road.LangtNafn[0], + segmentShortName: Road.StuttNafn[0], + segmentSignal: Road.Skilti[0].length > 0 ? Road.Skilti[0] : null, + conditionId: Road.IdAstand[0], + conditionDescription: Road.FulltAstand[0], + conditionShortDescription: Road.StuttAstand[0], + priority: parseInt(Road.Forgangur[0], 10), + comment: Road.Aths[0].length > 0 ? Road.Aths[0] : null, + date: Road.DagsKeyrtUt[0], + isHighlands: parseInt(Road.ErHalendi[0], 2) === 1 ? true : false, + colorCode: Road.Linulitur[0].length > 0 ? Road.Linulitur[0] : null, + conditionUpdated: Road.DagsSkrad[0], + surfaceCondition: Road.AstandYfirbords[0], + }) + } + return callback(null, roads) + }) +} +const getFeed = function (url, callback) { + request.get({ + headers: { 'User-Agent': h.browser(), 'Content-Type': 'application/xml; charset=utf-8' }, + encoding: 'utf-8', + url, + }, (error, response, body) => { + console.log(body) + if (error) return callback(new Error(`${url} did not respond ${JSON.stringify(error)}`)) + parseFeed(callback, body) + }) +} +const serve = function (url, res, next) { + getFeed(url, (err, data) => { + if (err) { + console.error(err) + return next(502) + } + res.cache(1800).json({ results: data }) }) +} +app.get('/road', (req, res, next) => { + const url = 'http://gagnaveita.vegagerdin.is/api/faerd2014_1' + serve(url, res, next) }) diff --git a/endpoints/road/regions.js b/endpoints/road/regions.js index 8cf5ddfe..a684d93f 100644 --- a/endpoints/road/regions.js +++ b/endpoints/road/regions.js @@ -1,7 +1,4 @@ -/* eslint-disable no-plusplus */ -/* eslint-disable no-prototype-builtins */ -/* eslint-disable prefer-destructuring */ -/* eslint-disable no-unneeded-ternary */ +/* eslint-disable */ const request = require('request') const xml2js = require('xml2js') @@ -13,7 +10,7 @@ const parseString = xml2js.parseString const sourceUrl = 'http://gagnaveita.vegagerdin.is/api/faerd2014_1' -const getRegionSegments = (url) => new Promise((resolve, reject) => { +const getRegionSegments = (url) => new Promise((resolve, reject) => { request(url, (error, response, body) => { if (error) { reject(error) @@ -24,7 +21,7 @@ const getRegionSegments = (url) => new Promise((resolve, reject) => { try { $ = cheerio.load(body) } catch (e) { - return res.status(500).json({ error: 'Could not load the body with cherrio.' }) + return reject(error) } const hotspots = $('.vg-roadmap-hotspot') @@ -37,13 +34,12 @@ const getRegionSegments = (url) => new Promise((resolve, reject) => { // Find hotspot info const hotspotinfo = hotspot.attr('data-hotspotinfo') const obj = JSON.parse(hotspotinfo.replace(/'/g, '"')) - if(obj.idleid) + if (obj.idleid) segments.push(parseInt(obj.idleid, 10)) }) resolve(segments) }) }) - const parseFeed = function (callback, data, regionUrl) { parseString(data, { explicitRoot: false }, (err, result) => { if (err) return callback(new Error(`Parsing of XML failed. Title ${err}`)) @@ -53,35 +49,33 @@ const parseFeed = function (callback, data, regionUrl) { for (let i = 0; i < result.Faerd.length; ++i) { const Road = result.Faerd[i] - const segmentId = parseInt(Road.IdButur[0], 10) - const shortSegmentId = parseInt(Road.IdButur[0].slice(0, 5)) + const shortSegmentId = parseInt(Road.IdButur[0].slice(0, 5), 10) if (segments.includes(shortSegmentId)) - roads.push({ - routeId: Road.IdLeid[0].length > 0 ? Road.IdLeid[0] : null, // Can be null - routeName: Road.LeidNafn[0].length > 0 ? Road.LeidNafn[0] : null, // Can be null - segmentId: parseInt(Road.IdButur[0], 10), - segmentSerial: Road.Rodun[0], - segmentName: Road.LangtNafn[0], - segmentShortName: Road.StuttNafn[0], - segmentSignal: Road.Skilti[0].length > 0 ? Road.Skilti[0] : null, - conditionId: Road.IdAstand[0], - conditionDescription: Road.FulltAstand[0], - conditionShortDescription: Road.StuttAstand[0], - priority: parseInt(Road.Forgangur[0], 10), - comment: Road.Aths[0].length > 0 ? Road.Aths[0] : null, - date: Road.DagsKeyrtUt[0], - isHighlands: parseInt(Road.ErHalendi[0], 2) === 1 ? true : false, - colorCode: Road.Linulitur[0].length > 0 ? Road.Linulitur[0] : null, - conditionUpdated: Road.DagsSkrad[0], - surfaceCondition: Road.AstandYfirbords[0], - }) + roads.push({ + routeId: Road.IdLeid[0].length > 0 ? Road.IdLeid[0] : null, // Can be null + routeName: Road.LeidNafn[0].length > 0 ? Road.LeidNafn[0] : null, // Can be null + segmentId: parseInt(Road.IdButur[0], 10), + segmentSerial: Road.Rodun[0], + segmentName: Road.LangtNafn[0], + segmentShortName: Road.StuttNafn[0], + segmentSignal: Road.Skilti[0].length > 0 ? Road.Skilti[0] : null, + conditionId: Road.IdAstand[0], + conditionDescription: Road.FulltAstand[0], + conditionShortDescription: Road.StuttAstand[0], + priority: parseInt(Road.Forgangur[0], 10), + comment: Road.Aths[0].length > 0 ? Road.Aths[0] : null, + date: Road.DagsKeyrtUt[0], + isHighlands: parseInt(Road.ErHalendi[0], 2) === 1 ? true : false, + colorCode: Road.Linulitur[0].length > 0 ? Road.Linulitur[0] : null, + conditionUpdated: Road.DagsSkrad[0], + surfaceCondition: Road.AstandYfirbords[0], + }) } return callback(null, roads) }) }) } - -const getFeed = function (url,regionUrl, callback,) { +const getFeed = function (url, regionUrl, callback) { request.get({ headers: { 'User-Agent': h.browser(), 'Content-Type': 'application/xml; charset=utf-8' }, encoding: 'utf-8', @@ -102,48 +96,28 @@ const serve = function (url, regionUrl, res, next) { }) } - -app.get('/road/reykjavik', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/reykjavik-og-nagrenni-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) -app.get('/road/west', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/vesturland-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) -app.get('/road/southwest', (req, res, next) => { - const regionUrl = 'http://vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudvesturland-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) -app.get('/road/westfjords', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/vestfirdir-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) -app.get('/road/south', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudurland-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) - -app.get('/road/north', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/nordurland-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) -app.get('/road/east', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/austurland-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) - -app.get('/road/northeast', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/nordausturland-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) - -app.get('/road/southeast', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudausturland-faerd-kort/' +app.get('/road/:region', (req, res, next) => { + const regionParam = req.params.region + let regionUrl = null + if (regionParam === 'reykjavik') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/reykjavik-og-nagrenni-faerd-kort/' + else if (regionParam === 'west') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/vesturland-faerd-kort/' + else if (regionParam === 'southwest') + regionUrl = 'http://vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudvesturland-faerd-kort/' + else if (regionParam === 'westfjords') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/vestfirdir-faerd-kort/' + else if (regionParam === 'south') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudurland-faerd-kort/' + else if (regionParam === 'north') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/nordurland-faerd-kort/' + else if (regionParam === 'east') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/austurland-faerd-kort/' + else if (regionParam === 'northeast') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/nordausturland-faerd-kort/' + else if (regionParam === 'southeast') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/sudausturland-faerd-kort/' + else if (regionParam === 'highlands') + regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/midhalendid-faerd-kort/' serve(sourceUrl, regionUrl, res, next) }) - -app.get('/road/highlands', (req, res, next) => { - const regionUrl = 'http://www.vegagerdin.is/ferdaupplysingar/faerd-og-vedur/midhalendid-faerd-kort/' - serve(sourceUrl, regionUrl, res, next) -}) \ No newline at end of file diff --git a/endpoints/road/tests/integration_test.js b/endpoints/road/tests/integration_test.js index b9141a96..a25a9d71 100644 --- a/endpoints/road/tests/integration_test.js +++ b/endpoints/road/tests/integration_test.js @@ -1,16 +1,7 @@ const request = require('request') const helpers = require('../../../lib/test_helpers') -describe('road root', () => { - it('should return info', (done) => { - const fieldsToCheckFor = ['info'] - const params = helpers.testRequestParams('/road/') - const resultHandler = helpers.testRequestHandlerForFields(done, fieldsToCheckFor) - request.get(params, resultHandler) - }) -}) - -describe('road - all', () => { +describe('road', () => { it('should return an array of objects containing correct fields', (done) => { const fieldsToCheckFor = [ 'routeId', @@ -31,7 +22,7 @@ describe('road - all', () => { 'conditionUpdated', 'surfaceCondition', ] - const params = helpers.testRequestParams('/road/all') + const params = helpers.testRequestParams('/road') const resultHandler = helpers.testRequestHandlerForFields(done, fieldsToCheckFor) request.get(params, resultHandler) })