From 6d29bc27e78bc549479cbbc203c683137ace9d48 Mon Sep 17 00:00:00 2001 From: luixal Date: Mon, 4 Jan 2021 09:43:58 +0100 Subject: Adds mapping remote field to Homer expected ones when loading message from url --- docs/configuration.md | 9 +++++++ docs/tips-and-tricks.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++ src/components/Message.vue | 10 +++++++- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index a43d7f1..93fa898 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -66,6 +66,15 @@ colors: # Optional message message: # url: "https://" # Can fetch information from an endpoint to override value below. + # mapping: # allows to map fields from the remote format to the one expected by Homer + # title: 'id' # use value from field 'id' as title + # content: 'value' # value from field 'value' as content + # + # Real example using chucknorris.io for showing Chuck Norris facts as messages: + # url: https://api.chucknorris.io/jokes/random + # mapping: + # title: 'id' + # content: 'value' style: "is-warning" title: "Optional message!" icon: "fa fa-exclamation-triangle" diff --git a/docs/tips-and-tricks.md b/docs/tips-and-tricks.md index 2719fc5..63eeeaf 100644 --- a/docs/tips-and-tricks.md +++ b/docs/tips-and-tricks.md @@ -113,6 +113,64 @@ docker create \ ## Get the news headlines in Homer + +### Mapping Fields +Most times, the url you're getting headlines from follows a different schema than the one expected by Homer. + +For example, if you would like to show jokes from ChuckNorris.io, you'll find that the url https://api.chucknorris.io/jokes/random is giving you info like this: + +```json +{ + "categories": [], + "created_at": "2020-01-05 13:42:22.089095", + "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png", + "id": "MR2-BnMBR667xSpQBIleUg", + "updated_at": "2020-01-05 13:42:22.089095", + "url": "https://api.chucknorris.io/jokes/MR2-BnMBR667xSpQBIleUg", + "value": "Chuck Norris can quitely sneak up on himself" +} +``` + +but... you need that info to be transformed to something like this: + +```json +{ + "title": "MR2-BnMBR667xSpQBIleUg", + "content": "Chuck Norris can quitely sneak up on himself" +} +``` + +Now, you can do that using the `mapping` field in your `message` configuration. This example would be something like this: + +```yml +message: + url: https://api.chucknorris.io/jokes/random + mapping: + title: 'id' + content: 'value' +``` + +As you would see, using the ID as a title doesn't seem nice, that's why when a field is empty it would keep the default values, like this: + +```yml +message: + url: https://api.chucknorris.io/jokes/random + mapping: + content: 'value' + title: "Chuck Norris Facts!" +``` + +and even an error message in case the `url` didn't respond or threw an error: + +```yml +message: + url: https://api.chucknorris.io/jokes/random + mapping: + content: 'value' + title: "Chuck Norris Facts!" + content: "Message could not be loaded" +``` + #### `by @JamiePhonic` Homer allows you to set a "message" that will appear at the top of the page, however, you can also supply a `url:`. diff --git a/src/components/Message.vue b/src/components/Message.vue index 5a1e0ea..df203ae 100644 --- a/src/components/Message.vue +++ b/src/components/Message.vue @@ -30,7 +30,8 @@ export default { // Look for a new message if an endpoint is provided. this.message = Object.assign({}, this.item); if (this.item && this.item.url) { - const fetchedMessage = await this.getMessage(this.item.url); + let fetchedMessage = await this.getMessage(this.item.url); + if (this.item.mapping) fetchedMessage = this.mapRemoteMessage(fetchedMessage); // keep the original config value if no value is provided by the endpoint for (const prop of ["title", "style", "content"]) { if (prop in fetchedMessage && fetchedMessage[prop] !== null) { @@ -49,6 +50,13 @@ export default { return response.json(); }); }, + + mapRemoteMessage: function (message) { + let mapped = {}; + // map property from message into mapped according to mapping config (only if field has a value): + for (const prop in this.item.mapping) if (message[this.item.mapping[prop]]) mapped[prop] = message[this.item.mapping[prop]]; + return mapped; + }, }, }; -- cgit v1.2.3 From 1ddf394176ffe7e1c4118ead46b9fa76c6f3c614 Mon Sep 17 00:00:00 2001 From: luixal Date: Thu, 7 Jan 2021 21:23:13 +0100 Subject: Refactors created function (splits logic for getting message) and adds timeout according to refreshInterval field --- docs/configuration.md | 2 ++ src/components/Message.vue | 29 ++++++++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 93fa898..8bff54f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -69,12 +69,14 @@ message: # mapping: # allows to map fields from the remote format to the one expected by Homer # title: 'id' # use value from field 'id' as title # content: 'value' # value from field 'value' as content + # refreshInterval: 10000 # time interval to refresh message # # Real example using chucknorris.io for showing Chuck Norris facts as messages: # url: https://api.chucknorris.io/jokes/random # mapping: # title: 'id' # content: 'value' + # refreshInterval: 10000 style: "is-warning" title: "Optional message!" icon: "fa fa-exclamation-triangle" diff --git a/src/components/Message.vue b/src/components/Message.vue index df203ae..72106c2 100644 --- a/src/components/Message.vue +++ b/src/components/Message.vue @@ -29,20 +29,27 @@ export default { created: async function () { // Look for a new message if an endpoint is provided. this.message = Object.assign({}, this.item); - if (this.item && this.item.url) { - let fetchedMessage = await this.getMessage(this.item.url); - if (this.item.mapping) fetchedMessage = this.mapRemoteMessage(fetchedMessage); - // keep the original config value if no value is provided by the endpoint - for (const prop of ["title", "style", "content"]) { - if (prop in fetchedMessage && fetchedMessage[prop] !== null) { - this.message[prop] = fetchedMessage[prop]; - } - } - } + await this.getMessage(); this.show = this.message.title || this.message.content; }, + methods: { - getMessage: function (url) { + getMessage: async function() { + if (this.item && this.item.url) { + let fetchedMessage = await this.downloadMessage(this.item.url); + if (this.item.mapping) fetchedMessage = this.mapRemoteMessage(fetchedMessage); + // keep the original config value if no value is provided by the endpoint + for (const prop of ["title", "style", "content"]) { + if (prop in fetchedMessage && fetchedMessage[prop] !== null) { + this.message[prop] = fetchedMessage[prop]; + } + } + } + console.log(this.item.refreshInterval); + if (this.item.refreshInterval) setTimeout(this.getMessage, this.item.refreshInterval); + }, + + downloadMessage: function (url) { return fetch(url).then(function (response) { if (response.status != 200) { return; -- cgit v1.2.3 From b6782c92b5ee91c4d6ac19ee01768363d4f0dc8b Mon Sep 17 00:00:00 2001 From: luixal Date: Thu, 7 Jan 2021 21:26:22 +0100 Subject: Removes forgotten console.log --- src/components/Message.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Message.vue b/src/components/Message.vue index 72106c2..2f71f3f 100644 --- a/src/components/Message.vue +++ b/src/components/Message.vue @@ -45,7 +45,6 @@ export default { } } } - console.log(this.item.refreshInterval); if (this.item.refreshInterval) setTimeout(this.getMessage, this.item.refreshInterval); }, -- cgit v1.2.3 From 9542de6eb25bfa20b376920b607db864c9e20a7a Mon Sep 17 00:00:00 2001 From: luixal Date: Tue, 23 Feb 2021 20:17:51 +0100 Subject: Fixes identations and link docs. --- docs/configuration.md | 4 ++-- docs/tips-and-tricks.md | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 8bff54f..5785e56 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -69,7 +69,7 @@ message: # mapping: # allows to map fields from the remote format to the one expected by Homer # title: 'id' # use value from field 'id' as title # content: 'value' # value from field 'value' as content - # refreshInterval: 10000 # time interval to refresh message + # refreshInterval: 10000 # Optional: time interval to refresh message # # Real example using chucknorris.io for showing Chuck Norris facts as messages: # url: https://api.chucknorris.io/jokes/random @@ -129,7 +129,7 @@ services: # background: red # optional color for card to set color directly without custom stylesheet ``` -If you choose to fetch message information from an endpoint, the output format should be: +If you choose to fetch message information from an endpoint, the output format should be as follows (or you can [custom map fields as shown in tips-and-tricks](./tips-and-tricks.md#mapping-fields)): ```json { diff --git a/docs/tips-and-tricks.md b/docs/tips-and-tricks.md index 63eeeaf..94167fb 100644 --- a/docs/tips-and-tricks.md +++ b/docs/tips-and-tricks.md @@ -145,9 +145,9 @@ Now, you can do that using the `mapping` field in your `message` configuration. ```yml message: url: https://api.chucknorris.io/jokes/random - mapping: - title: 'id' - content: 'value' + mapping: + title: 'id' + content: 'value' ``` As you would see, using the ID as a title doesn't seem nice, that's why when a field is empty it would keep the default values, like this: @@ -155,8 +155,8 @@ As you would see, using the ID as a title doesn't seem nice, that's why when a f ```yml message: url: https://api.chucknorris.io/jokes/random - mapping: - content: 'value' + mapping: + content: 'value' title: "Chuck Norris Facts!" ``` @@ -165,8 +165,8 @@ and even an error message in case the `url` didn't respond or threw an error: ```yml message: url: https://api.chucknorris.io/jokes/random - mapping: - content: 'value' + mapping: + content: 'value' title: "Chuck Norris Facts!" content: "Message could not be loaded" ``` -- cgit v1.2.3