-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathtankerkoenig.js
141 lines (130 loc) · 4.37 KB
/
tankerkoenig.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
* @file apis/tankerkoenig.js
*
* @author fewieden
* @license MIT
*
* @see https://github.com/fewieden/MMM-Fuel
*/
/**
* @external request
* @see https://www.npmjs.com/package/request
*/
const request = require('request');
/**
* @module apis/tankerkoenig
* @description Queries data from tankerkoenig.de
*
* @requires external:request
*
* @param {Object} config - Configuration.
* @param {number} config.lat - Latitude of Coordinate.
* @param {number} config.lng - Longitude of Coordinate.
* @param {int} config.radius - Lookup area for gas stations.
* @param {string} config.sortBy - Type to sort by price.
* @param {string[]} config.types - Requested fuel types.
* @param {boolean} config.showOpenOnly - Flag to show only open gas stations.
*
* @see https://creativecommons.tankerkoenig.de/
*/
module.exports = (config) => {
/** @member {string} baseUrl - API url */
const baseUrl = 'https://creativecommons.tankerkoenig.de/json/list.php';
/** @member {Object} options - API url combined with config options. */
const options = {
url: `${baseUrl}?lat=${config.lat}&lng=${config.lng}&rad=${config.radius}&type=all&apikey=${
config.api_key}&sort=dist`
};
/**
* @function sortByPrice
* @description Helper function to sort gas stations by price.
*
* @param {Object} a - Gas Station
* @param {Object} b - Gas Station
* @returns {number}
*/
const sortByPrice = (a, b) => {
if (b[config.sortBy] === 0) {
return Number.MIN_SAFE_INTEGER;
} else if (a[config.sortBy] === 0) {
return Number.MAX_SAFE_INTEGER;
}
return a[config.sortBy] - b[config.sortBy];
};
/**
* @function filterStations
* @description Helper function to filter gas stations.
*
* @param {Object} station - Gas Station
* @returns {boolean}
*/
const filterStations = (station) => {
for (let i = 0; i < config.types.length; i += 1) {
if (station[config.types[i]] <= 0 || (config.showOpenOnly && !station.isOpen)) {
return false;
}
}
return true;
};
/**
* @function normalizeStations
* @description Helper function to normalize the structure of gas stations for the UI.
*
* @param {Object} value - Gas Station
* @param {int} index - Array index
* @param {Object[]} stations - Original Array.
*
* @see apis/README.md
*/
const normalizeStations = (value, index, stations) => {
/* eslint-disable no-param-reassign */
stations[index].prices = {
diesel: value.diesel,
e5: value.e5,
e10: value.e10
};
stations[index].distance = value.dist;
stations[index].address = `${(`0${value.postCode}`).slice(-5)} ${
value.place} - ${value.street} ${value.houseNumber}`;
/* eslint-enable no-param-reassign */
};
return {
/**
* @callback getDataCallback
* @param {?string} error - Error message.
* @param {Object} data - API data.
*
* @see apis/README.md
*/
/**
* @function getData
* @description Performs the data query and processing.
*
* @param {getDataCallback} callback - Callback that handles the API data.
*/
getData(callback) {
request(options, (error, response, body) => {
if (response.statusCode === 200) {
const parsedBody = JSON.parse(body);
if (parsedBody.ok) {
const stations = parsedBody.stations.filter(filterStations);
stations.forEach(normalizeStations);
const price = stations.slice(0);
price.sort(sortByPrice);
callback(null, {
types: ['diesel', 'e5', 'e10'],
unit: 'km',
currency: 'EUR',
byPrice: price,
byDistance: stations
});
} else {
callback('Error no fuel data');
}
} else {
callback(`Error getting fuel data ${response.statusCode}`);
}
});
}
};
};