diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f81274..9f52368 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # MMM-Fuel Changelog +## [2.5.0] + +Thanks to [marcx28](https://github.com/marcx28) for their contributions. + +### Fixed + +* [Sorting by price](https://github.com/fewieden/MMM-Fuel/issues/110) + +### Added + +* Dependency: `lodash` + +### Changed + +* [Allow custom header text](https://github.com/fewieden/MMM-Fuel/pull/102) + ## [2.4.0] ### Added diff --git a/MMM-Fuel.js b/MMM-Fuel.js index 843805e..98104c1 100644 --- a/MMM-Fuel.js +++ b/MMM-Fuel.js @@ -161,6 +161,7 @@ Module.register('MMM-Fuel', { return { config: this.config, + header: this.data.header, priceList: this.priceList, sortByPrice: this.sortByPrice, gasStations diff --git a/README.md b/README.md index 4172a53..0fc6cbc 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,9 @@ Gas Station Price Module for MagicMirror2 * An installation of [MagicMirror2](https://github.com/MichMich/MagicMirror) * OPTIONAL: [Voice Control](https://github.com/fewieden/MMM-voice) and [MMM-Modal](https://github.com/fewieden/MMM-Modal) * npm -* [node-fetch](https://www.npmjs.com/package/node-fetch) +* [lodash](https://www.npmjs.com/package/lodash) * [moment](https://www.npmjs.com/package/moment) +* [node-fetch](https://www.npmjs.com/package/node-fetch) * [node-html-parser](https://www.npmjs.com/package/node-html-parser) ## Installation @@ -60,7 +61,7 @@ Gas Station Price Module for MagicMirror2 | `showOpenOnly` | `false` | Boolean to show only open gas stations or all. | | `showDistance` | `true` | Boolean to show the distance to your specified position. | | `showBrand` | `false` | Boolean to show the brand instead of the name. | -| `iconHeader` | `true` | Boolean to display the car icon in the header. | +| `iconHeader` | `true` | Boolean to display the car icon in the header (works only if no custom header is set). | | `rotate` | `true` | Boolean to enable/disable rotation between sort by price and distance. | | `rotateInterval` | `60000` (1 min) | How fast the sorting should be switched between byPrice and byDistance. | | `updateInterval` | `900000` (15 mins) | How often should the data be fetched. **If your value is to small, you risk to get banned from the API provider. I suggest a minimum of 15mins** | diff --git a/apis/autoblog.js b/apis/autoblog.js index d95d60c..de0c1ec 100644 --- a/apis/autoblog.js +++ b/apis/autoblog.js @@ -7,6 +7,12 @@ * @see https://github.com/fewieden/MMM-Fuel */ +/** + * @external lodash + * @see https://www.npmjs.com/package/lodash + */ +const _ = require('lodash'); + /** * @external node-fetch * @see https://www.npmjs.com/package/node-fetch @@ -19,7 +25,7 @@ const fetch = require('node-fetch'); */ const { parse } = require('node-html-parser'); -const { fillMissingPrices, sortByDistance, sortByPrice, mergePrices } = require('./utils'); +const { fillMissingPrices, mergePrices, sortByPrice } = require('./utils'); const BASE_URL = 'https://www.autoblog.com'; const MAX_PAGE = 2; @@ -156,15 +162,12 @@ async function getData() { const filteredStations = stations.filter(station => station.distance <= config.radius); - const stationsSortedByDistance = filteredStations.sort(sortByDistance); - const stationsSortedByPrice = [...stationsSortedByDistance].sort(sortByPrice.bind(null, config)); - return { types: ['regular', 'premium', 'mid-grade', 'diesel'], unit: 'mile', currency: 'USD', - byPrice: stationsSortedByPrice, - byDistance: stationsSortedByDistance + byPrice: _.sortBy(filteredStations, sortByPrice.bind(null, config)), + byDistance: _.sortBy(filteredStations, 'distance') }; } diff --git a/apis/gasbuddy.js b/apis/gasbuddy.js index c0008a7..0bf12a8 100644 --- a/apis/gasbuddy.js +++ b/apis/gasbuddy.js @@ -7,6 +7,12 @@ * @see https://github.com/fewieden/MMM-Fuel */ +/** + * @external lodash + * @see https://www.npmjs.com/package/lodash + */ +const _ = require('lodash'); + /** * @external node-fetch * @see https://www.npmjs.com/package/node-fetch @@ -160,7 +166,7 @@ async function getData() { stations.forEach(station => fillMissingPrices(config, station, maxPricesByType)); // Webpage doesn't support distance (only zip code). - const stationsSortedByPrice = stations.sort(sortByPrice.bind(null, config)); + const stationsSortedByPrice = _.sortBy(stations, sortByPrice.bind(null, config)); const stationsSortedByDistance = stationsSortedByPrice; return { diff --git a/apis/nsw.js b/apis/nsw.js index 0c697d1..09093d9 100644 --- a/apis/nsw.js +++ b/apis/nsw.js @@ -7,6 +7,12 @@ * @see https://github.com/fewieden/MMM-Fuel */ +/** + * @external lodash + * @see https://www.npmjs.com/package/lodash + */ +const _ = require('lodash'); + /** * @external node-fetch * @see https://www.npmjs.com/package/node-fetch @@ -25,7 +31,7 @@ const moment = require('moment'); */ const Log = require('logger'); -const { filterStations, sortByDistance } = require('./utils'); +const { filterStations } = require('./utils'); const SECOND = 1000; const MINUTE = 60 * SECOND; @@ -126,15 +132,12 @@ async function getData() { stations = stations.filter(filterStations); - const distance = stations.slice(0); - distance.sort(sortByDistance); - return { types: ['diesel', 'e5'], unit: 'kilometer', currency: 'AUD', byPrice: stations, - byDistance: distance + byDistance: _.sortBy(stations, 'distance') }; } diff --git a/apis/spritpreisrechner.js b/apis/spritpreisrechner.js index 186d35c..7148472 100644 --- a/apis/spritpreisrechner.js +++ b/apis/spritpreisrechner.js @@ -7,13 +7,19 @@ * @see https://github.com/fewieden/MMM-Fuel */ +/** + * @external lodash + * @see https://www.npmjs.com/package/lodash + */ +const _ = require('lodash'); + /** * @external node-fetch * @see https://www.npmjs.com/package/node-fetch */ const fetch = require('node-fetch'); -const { filterStations, sortByDistance } = require('./utils'); +const { filterStations } = require('./utils'); const BASE_URL = 'https://api.e-control.at/sprit/1.0'; const TYPES = { @@ -176,15 +182,12 @@ async function getData() { stations = stations.filter(filterStations); - const distance = stations.slice(0); - distance.sort(sortByDistance); - return { types: ['diesel', 'e5', 'gas'], unit: 'kilometer', currency: 'EUR', byPrice: stations, - byDistance: distance + byDistance: _.sortBy(stations, 'distance') }; } diff --git a/apis/tankerkoenig.js b/apis/tankerkoenig.js index eb1f685..8492e81 100644 --- a/apis/tankerkoenig.js +++ b/apis/tankerkoenig.js @@ -7,6 +7,12 @@ * @see https://github.com/fewieden/MMM-Fuel */ +/** + * @external lodash + * @see https://www.npmjs.com/package/lodash + */ +const _ = require('lodash'); + /** * @external node-fetch * @see https://www.npmjs.com/package/node-fetch @@ -19,6 +25,8 @@ const fetch = require('node-fetch'); */ const Log = require('logger'); +const { sortByPrice } = require('./utils'); + const BASE_URL = 'https://creativecommons.tankerkoenig.de/json'; let config; @@ -59,44 +67,6 @@ function generateStationInfoUrl(id) { return `${BASE_URL}/detail.php?id=${id}&apikey=${config.api_key}`; } -/** - * @function sortByPrice - * @description Helper function to sort gas stations by price. - * - * @param {Object} a - Gas Station - * @param {Object} b - Gas Station - * - * @returns {number} Sorting weight. - */ -function 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 sortByDistance - * @description Helper function to sort gas stations by distance. - * - * @param {Object} a - Gas Station - * @param {Object} b - Gas Station - * - * @returns {number} Sorting weight. - */ -function sortByDistance(a, b) { - if (b.dist === 0) { - return Number.MIN_SAFE_INTEGER; - } else if (a.dist === 0) { - return Number.MAX_SAFE_INTEGER; - } - - return a.dist - b.dist; -} - /** * @function filterStations * @description Helper function to filter gas stations. @@ -323,18 +293,12 @@ async function getData() { const stationsFiltered = stations.filter(filterStations); stationsFiltered.forEach(normalizeStations); - const distance = stationsFiltered.slice(0); - distance.sort(sortByDistance); - - const price = stationsFiltered.slice(0); - price.sort(sortByPrice); - return { types: ['diesel', 'e5', 'e10'], unit: 'kilometer', currency: 'EUR', - byPrice: price, - byDistance: distance + byPrice: _.sortBy(stationsFiltered, sortByPrice.bind(null, config)), + byDistance: _.sortBy(stationsFiltered, 'dist') }; } diff --git a/apis/utils/index.js b/apis/utils/index.js index f2b7b5b..93bfa07 100644 --- a/apis/utils/index.js +++ b/apis/utils/index.js @@ -7,6 +7,12 @@ * @see https://github.com/fewieden/MMM-Fuel */ +/** + * @external lodash + * @see https://www.npmjs.com/package/lodash + */ +const _ = require('lodash'); + /** * @function filterStations * @description Helper function to filter gas stations. @@ -16,22 +22,9 @@ * @returns {boolean} To keep or filter the station. */ function filterStations(station) { - const prices = Object.keys(station.prices); + const prices = _.keys(station.prices); - return !prices.every(type => station.prices[type] === -1); -} - -/** - * @function sortByDistance - * @description Helper function to sort gas stations by distance. - * - * @param {Object} a - Gas Station - * @param {Object} b - Gas Station - * - * @returns {number} Sorting weight. - */ -function sortByDistance(a, b) { - return a.distance - b.distance; + return !_.every(prices, type => _.get(station, `prices.${type}`) === -1); } /** @@ -45,8 +38,8 @@ function sortByDistance(a, b) { */ function fillMissingPrices(config, station, maxPricesByType) { for (const type of config.types) { - if (!station.prices[type]) { - station.prices[type] = `>${maxPricesByType[type]}`; + if (!_.get(station, `prices.${type}`)) { + _.set(station, `prices.${type}`, `>${maxPricesByType[type]}`); } } } @@ -60,15 +53,14 @@ function fillMissingPrices(config, station, maxPricesByType) { * * @returns {number} Sorting weight. */ -function sortByPrice(config, a, b) { - const aPrice = a.prices[config.sortBy]; - const bPrice = b.prices[config.sortBy]; +function sortByPrice(config, station) { + const price = _.get(station, `prices.${config.sortBy}`); - if (!isNaN(aPrice) || !isNaN(bPrice)) { - return isNaN(aPrice) ? 1 : -1; + if (_.isNumber(price)) { + return price; } - return 0; + return Number.POSITIVE_INFINITY; } /** @@ -108,6 +100,5 @@ module.exports = { fillMissingPrices, filterStations, mergePrices, - sortByDistance, sortByPrice }; diff --git a/package-lock.json b/package-lock.json index 1794753..9d2f770 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "mmm-fuel", - "version": "2.4.0", + "version": "2.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3176,10 +3176,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.merge": { "version": "4.6.2", diff --git a/package.json b/package.json index f01df20..149bf80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mmm-fuel", - "version": "2.4.0", + "version": "2.5.0", "description": "Gas Station price Module for MagicMirror2", "scripts": { "lint": "eslint . && stylelint **/*.css", @@ -29,6 +29,7 @@ "stylelint-config-standard": "^27.0.0" }, "dependencies": { + "lodash": "^4.17.21", "moment": "^2.29.4", "node-fetch": "^2.6.7", "node-html-parser": "^5.4.1" diff --git a/templates/MMM-Fuel.njk b/templates/MMM-Fuel.njk index 88f6cda..a4875eb 100644 --- a/templates/MMM-Fuel.njk +++ b/templates/MMM-Fuel.njk @@ -1,9 +1,12 @@ -
- {% if config.iconHeader %} - - {% endif %} - {{ "FUEL_PRICES" | translate }} -
+{% if not header %} +
+ {% if config.iconHeader %} + + {% endif %} + + {{ "FUEL_PRICES" | translate }} +
+{% endif %} {% if not priceList %}
{{ "LOADING" | translate | safe }}
{% else %}