From b404bb09beebc418e386f2072ce4adfe022cd635 Mon Sep 17 00:00:00 2001 From: Matthias Bilger Date: Sun, 8 Jan 2023 19:05:23 +0100 Subject: [PATCH 1/5] Added Mvg Widget Display mvg departure times for MVG station. --- docs/widgets.md | 36 +++ src/components/Widgets/Mvg.vue | 361 ++++++++++++++++++++++++++ src/components/Widgets/WidgetBase.vue | 1 + src/utils/defaults.js | 1 + 4 files changed, 399 insertions(+) create mode 100644 src/components/Widgets/Mvg.vue diff --git a/docs/widgets.md b/docs/widgets.md index 4a1d6551..611e559a 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -35,6 +35,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a - [GitHub Trending](#github-trending) - [GitHub Profile Stats](#github-profile-stats) - [Healthchecks Status](#healthchecks status) + - [Mvg Departure](#mvg-departure) - **[Self-Hosted Services Widgets](#self-hosted-services-widgets)** - [System Info](#system-info) - [Cron Monitoring](#cron-monitoring-health-checks) @@ -1173,6 +1174,41 @@ Display status of one or more HealthChecks project(s). Works with healthcheck.io --- +### MVG Departure + +Display departure time of a MVG (Münchner Verkehrs Gesellschaft) station. + +From https://www.mvg.de/impressum.html: + +> [...] Die Verarbeitung unserer Inhalte oder Daten durch Dritte erfordert unsere ausdrückliche Zustimmung. Für private, nicht-kommerzielle Zwecke, wird eine gemäßigte Nutzung ohne unsere ausdrückliche Zustimmung geduldet. Jegliche Form von Data-Mining stellt keine gemäßigte Nutzung dar.[...] + +In other words: Private, noncomercial, moderate use of the API is tolerated. They don’t consider data mining as moderate use. + +#### Options + +**Field** | **Type** | **Required** | **Description** +--- | --- | --- | --- +**`location`** | `string` | Required | The name of the location (exact) or the location id, startin with `de:09162:` +**`limit`** | `integer` | _Optional_ | Limit number of entries, defaults to 10. + +```yaml +- type: mvg + options: + location: Marienplatz + limit: 5 +``` + +#### Info + +- **CORS**: 🟢 Enabled +- **Auth**: 🟢 Required +- **Price**: 🟢 Free / Paid / Self-hosted +- **Host**: Managed Instance or Self-Hosted (see [healthchecks/healthchecks](https://github.com/healthchecks/healthchecks)) +- **Privacy**: _See [Healthchecks.io Privacy Policy](https://healthchecks.io/privacy/)_ + +--- + + ## Self-Hosted Services Widgets ### System Info diff --git a/src/components/Widgets/Mvg.vue b/src/components/Widgets/Mvg.vue new file mode 100644 index 00000000..564d25de --- /dev/null +++ b/src/components/Widgets/Mvg.vue @@ -0,0 +1,361 @@ + + + + + + + + diff --git a/src/components/Widgets/WidgetBase.vue b/src/components/Widgets/WidgetBase.vue index ecd7b536..60d25bb9 100644 --- a/src/components/Widgets/WidgetBase.vue +++ b/src/components/Widgets/WidgetBase.vue @@ -82,6 +82,7 @@ const COMPAT = { image: 'ImageWidget', joke: 'Jokes', 'mullvad-status': 'MullvadStatus', + mvg: 'Mvg', 'nd-cpu-history': 'NdCpuHistory', 'nd-load-history': 'NdLoadHistory', 'nd-ram-history': 'NdRamHistory', diff --git a/src/utils/defaults.js b/src/utils/defaults.js index 8d609684..8f51df94 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -236,6 +236,7 @@ module.exports = { jokes: 'https://v2.jokeapi.dev/joke/', news: 'https://api.currentsapi.services/v1/latest-news', mullvad: 'https://am.i.mullvad.net/json', + mvg: 'https://www.mvg.de/api/fib/v2/', publicIp: 'https://ipapi.co/json', publicIp2: 'https://api.ipgeolocation.io/ipgeo', publicIp3: 'http://ip-api.com/json', From 4cb3332e3e4138f6dce13717dec6660dc095d0e1 Mon Sep 17 00:00:00 2001 From: Matthias Bilger Date: Sun, 22 Jan 2023 12:57:02 +0100 Subject: [PATCH 2/5] Added mvg connection + doc updates --- docs/widgets.md | 62 +++- src/components/Widgets/MvgConnection.vue | 376 +++++++++++++++++++++++ src/components/Widgets/WidgetBase.vue | 1 + 3 files changed, 434 insertions(+), 5 deletions(-) create mode 100644 src/components/Widgets/MvgConnection.vue diff --git a/docs/widgets.md b/docs/widgets.md index 611e559a..04548233 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -36,6 +36,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a - [GitHub Profile Stats](#github-profile-stats) - [Healthchecks Status](#healthchecks status) - [Mvg Departure](#mvg-departure) + - [Mvg Connection](#mvg-connection) - **[Self-Hosted Services Widgets](#self-hosted-services-widgets)** - [System Info](#system-info) - [Cron Monitoring](#cron-monitoring-health-checks) @@ -1182,7 +1183,7 @@ From https://www.mvg.de/impressum.html: > [...] Die Verarbeitung unserer Inhalte oder Daten durch Dritte erfordert unsere ausdrückliche Zustimmung. Für private, nicht-kommerzielle Zwecke, wird eine gemäßigte Nutzung ohne unsere ausdrückliche Zustimmung geduldet. Jegliche Form von Data-Mining stellt keine gemäßigte Nutzung dar.[...] -In other words: Private, noncomercial, moderate use of the API is tolerated. They don’t consider data mining as moderate use. +In other words: Private, noncomercial, moderate use of the API is tolerated. They don’t consider data mining as moderate use. (This is not a legal advice) #### Options @@ -1190,6 +1191,12 @@ In other words: Private, noncomercial, moderate use of the API is tolerated. The --- | --- | --- | --- **`location`** | `string` | Required | The name of the location (exact) or the location id, startin with `de:09162:` **`limit`** | `integer` | _Optional_ | Limit number of entries, defaults to 10. +**`title`** | `string` | _Optional_ | A custom title to be displayed. +**`header`** | `bool` | _Optional_ | Shall the title be shown? +**`filters`** | `object` | _Optional_ | Filter results +**`filters.line`** | `string/array` | _Optional_ | Filter results for given line(s). +**`filters.product`** | `string/array` | _Optional_ | Filter results for specific product (TRAM, UBAHN, SBAHN, BUS). +**`filters.destination`** | `string/object` | _Optional_ | Filter results for specific destination(s) ```yaml - type: mvg @@ -1201,10 +1208,55 @@ In other words: Private, noncomercial, moderate use of the API is tolerated. The #### Info - **CORS**: 🟢 Enabled -- **Auth**: 🟢 Required -- **Price**: 🟢 Free / Paid / Self-hosted -- **Host**: Managed Instance or Self-Hosted (see [healthchecks/healthchecks](https://github.com/healthchecks/healthchecks)) -- **Privacy**: _See [Healthchecks.io Privacy Policy](https://healthchecks.io/privacy/)_ +- **Auth**: 🟢 Not Required +- **Price**: 🟢 Free / Private use only +- **Host**: [MVG](https://mvg.de) +- **Privacy**: _See [MVG Datenschutz](https://www.mvg.de/datenschutz-mvg.html)_ + +--- + +### MVG Connection + +Display the next connection for two addresses/coordinates, stations or POI within Munich using MVG MVG (Münchner Verkehrs Gesellschaft). + +From https://www.mvg.de/impressum.html: + +> [...] Die Verarbeitung unserer Inhalte oder Daten durch Dritte erfordert unsere ausdrückliche Zustimmung. Für private, nicht-kommerzielle Zwecke, wird eine gemäßigte Nutzung ohne unsere ausdrückliche Zustimmung geduldet. Jegliche Form von Data-Mining stellt keine gemäßigte Nutzung dar.[...] + +In other words: Private, noncomercial, moderate use of the API is tolerated. They don’t consider data mining as moderate use. (This is not a legal advice) + +#### Options + +**Field** | **Type** | **Required** | **Description** +--- | --- | --- | --- +**`origin`** | `string` | Required | Origin of the connection. +**`destination`** | `string` | Required | Destination of the connection. +**`title`** | `string` | _Optional_ | A custom title to be displayed. +**`header`** | `bool` | _Optional_ | Shall the title be shown? +**`filters`** | `object` | _Optional_ | Filter results +**`filters.line`** | `string/array` | _Optional_ | Filter results for given line(s). +**`filters.product`** | `string/array` | _Optional_ | Filter results for specific product (TRAM, UBAHN, SBAHN, BUS). +**`filters.destination`** | `string/object` | _Optional_ | Filter results for specific destination(s) + +```yaml +- type: mvg-connection + options: + from: Marienplatz + from: Dachauer Straße 123 + header: true + filters: + product: [UBAHN] + line: [U1,U2,U4,U5] + +``` + +#### Info + +- **CORS**: 🟢 Enabled +- **Auth**: 🟢 Not Required +- **Price**: 🟢 Free / Private use only +- **Host**: [MVG](https://mvg.de) +- **Privacy**: _See [MVG Datenschutz](https://www.mvg.de/datenschutz-mvg.html)_ --- diff --git a/src/components/Widgets/MvgConnection.vue b/src/components/Widgets/MvgConnection.vue new file mode 100644 index 00000000..9f644c7c --- /dev/null +++ b/src/components/Widgets/MvgConnection.vue @@ -0,0 +1,376 @@ + + + + + + + + diff --git a/src/components/Widgets/WidgetBase.vue b/src/components/Widgets/WidgetBase.vue index 60d25bb9..98f333a2 100644 --- a/src/components/Widgets/WidgetBase.vue +++ b/src/components/Widgets/WidgetBase.vue @@ -83,6 +83,7 @@ const COMPAT = { joke: 'Jokes', 'mullvad-status': 'MullvadStatus', mvg: 'Mvg', + 'mvg-connection': 'MvgConnection', 'nd-cpu-history': 'NdCpuHistory', 'nd-load-history': 'NdLoadHistory', 'nd-ram-history': 'NdRamHistory', From 1e84f51825c62962b589283ff8d3cf9ce136cb17 Mon Sep 17 00:00:00 2001 From: Matthias Bilger Date: Sun, 22 Jan 2023 15:50:02 +0100 Subject: [PATCH 3/5] Fixed deepscan analysis warnings --- src/components/Widgets/Mvg.vue | 4 +--- src/components/Widgets/MvgConnection.vue | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/Widgets/Mvg.vue b/src/components/Widgets/Mvg.vue index 564d25de..a4f74c8b 100644 --- a/src/components/Widgets/Mvg.vue +++ b/src/components/Widgets/Mvg.vue @@ -135,9 +135,7 @@ export default { }, filter_results(value) { if (!this.options.filters) return true; - let useEntry = true; - useEntry = useEntry - && ( + let useEntry = ( (!this.options.filters.line) || this.ensure_array(this.options.filters.line).includes(value.label) ); diff --git a/src/components/Widgets/MvgConnection.vue b/src/components/Widgets/MvgConnection.vue index 9f644c7c..2bd76da1 100644 --- a/src/components/Widgets/MvgConnection.vue +++ b/src/components/Widgets/MvgConnection.vue @@ -108,7 +108,7 @@ export default { if (s.length < 2) s = `0${s}`; return s; } - return `${Math.floor(val / 3600000, 0)}:${ii(Math.floor(val / 60000, 0))}`; + return `${Math.floor(val / 3600000)}:${ii(Math.floor(val / 60000))}`; }, }, computed: { From 75b06f8af80b14f44f40b92b18df994729dd53d8 Mon Sep 17 00:00:00 2001 From: Matthias Bilger Date: Sun, 22 Jan 2023 15:51:34 +0100 Subject: [PATCH 4/5] Fix CodeSonar warnings --- src/components/Widgets/Mvg.vue | 1 - src/components/Widgets/MvgConnection.vue | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/Widgets/Mvg.vue b/src/components/Widgets/Mvg.vue index a4f74c8b..fa9ff3f7 100644 --- a/src/components/Widgets/Mvg.vue +++ b/src/components/Widgets/Mvg.vue @@ -240,7 +240,6 @@ export default { color: #FFFFFF; margin-right: 0.40em; text-align: center; - over span { min-width: 2em; display: inline-block; diff --git a/src/components/Widgets/MvgConnection.vue b/src/components/Widgets/MvgConnection.vue index 2bd76da1..998e6356 100644 --- a/src/components/Widgets/MvgConnection.vue +++ b/src/components/Widgets/MvgConnection.vue @@ -250,7 +250,6 @@ export default { margin-right: 0.40em; margin-left: 0.40em; text-align: center; - over span { min-width: 2em; display: inline-block; From 59118a54dd84ad39f1b197dcb32b606d2dfedd58 Mon Sep 17 00:00:00 2001 From: Matthias Bilger Date: Sun, 22 Jan 2023 18:22:24 +0100 Subject: [PATCH 5/5] Fixed as suggested --- src/components/Widgets/Mvg.vue | 7 +------ src/components/Widgets/MvgConnection.vue | 5 +---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/components/Widgets/Mvg.vue b/src/components/Widgets/Mvg.vue index fa9ff3f7..166eed00 100644 --- a/src/components/Widgets/Mvg.vue +++ b/src/components/Widgets/Mvg.vue @@ -72,12 +72,8 @@ export default { const diff = Math.max(0, Math.round(msDifference / 60000)); return diff; }, - limitLength(str) { - return str; - }, }, computed: { - /* API endpoint, either for self-hosted or managed instance */ isLocationId() { if (!this.options.location) { this.error('Location is required'); @@ -91,8 +87,7 @@ export default { return 0; }, limit() { - if (this.options.limit) return this.options.limit; - return 10; + return this.options.limit || 10; }, endpointDeparture() { return `${widgetApiEndpoints.mvg}/departure?globalId=${this.location}&limit=30&offsetInMinutes=${this.offset}&transportTypes=UBAHN,TRAM,BUS,SBAHN`; diff --git a/src/components/Widgets/MvgConnection.vue b/src/components/Widgets/MvgConnection.vue index 998e6356..b4eae501 100644 --- a/src/components/Widgets/MvgConnection.vue +++ b/src/components/Widgets/MvgConnection.vue @@ -90,9 +90,6 @@ export default { const diff = Math.max(0, Math.round(msDifference / 60000)); return diff; }, - limitLength(str) { - return str; - }, formatTime(str) { const d = new Date(Date.parse(str)); function ii(i) { @@ -155,7 +152,7 @@ export default { return `${widgetApiEndpoints.mvg}/location?query=${encodeURIComponent(loc)}`; }, endpointConnection() { - return `${widgetApiEndpoints.mvg}/connection?${this.formatPoint(this.locations.origin, 'origin')}&${this.formatPoint(this.locations.destination, 'destination')}&routingDateTime=${(new Date()).toISOString()}&limit=30&offsetInMinutes=${this.offset}&transportTypes=${this.transportTypes}`; + return `${widgetApiEndpoints.mvg}/connection?${this.formatPoint(this.locations.origin, 'origin')}&${this.formatPoint(this.locations.destination, 'destination')}&routingDateTime=${(new Date()).toISOString()}&offsetInMinutes=${this.offset}&transportTypes=${this.transportTypes}`; }, update() { this.startLoading();