Merge branch 'bastienwirtz:main' into icon-color

This commit is contained in:
Robin Schneider 2021-10-10 21:41:23 +02:00 committed by GitHub
commit 7a4e78e8d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 136 additions and 48 deletions

View File

@ -14,5 +14,5 @@ Fixes # (issue)
- [ ] I've read & comply with the [contributing guidelines](https://github.com/bastienwirtz/homer/blob/main/CONTRIBUTING.md) - [ ] I've read & comply with the [contributing guidelines](https://github.com/bastienwirtz/homer/blob/main/CONTRIBUTING.md)
- [ ] I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers. - [ ] I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers.
- [ ] I have made corresponding changes the documentation (README.md). - [ ] I have made corresponding changes to the documentation (README.md).
- [ ] I've checked my modifications for any breaking changes, especially in the `config.yml` file - [ ] I've checked my modifications for any breaking changes, especially in the `config.yml` file

31
.github/workflows/integration.yml vendored Normal file
View File

@ -0,0 +1,31 @@
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- run: yarn install
- run: yarn lint

View File

@ -24,6 +24,11 @@ footer: '<p>Created with <span class="has-text-danger">❤️</span> with <a hre
columns: "3" # "auto" or number (must be a factor of 12: 1, 2, 3, 4, 6, 12) columns: "3" # "auto" or number (must be a factor of 12: 1, 2, 3, 4, 6, 12)
connectivityCheck: true # whether you want to display a message when the apps are not accessible anymore (VPN disconnected for example) connectivityCheck: true # whether you want to display a message when the apps are not accessible anymore (VPN disconnected for example)
# Optional: Proxy / hosting option
proxy:
# NOT All custom services implements this new option YET. Support will be extended very soon.
useCredentials: false # send cookies & authorization headers when fetching service specific data. Set to `true` if you use an authentication proxy. Can be overrided on service level.
# Optional theming # Optional theming
theme: default # 'default' or one of the themes available in 'src/assets/themes'. theme: default # 'default' or one of the themes available in 'src/assets/themes'.

View File

@ -6,6 +6,20 @@ within Homer.
If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page. If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
## Common options
```yaml
- name: "My Service"
logo: "assets/tools/sample.png"
url: "http://my-service-link"
endpoint: "http://my-service-endpoint" # Optional: alternative base URL used to fetch service data is necessary.
useCredentials: false # Optional: Override global proxy.useCredentials configuration.
type: "<type>"
```
⚠️🚧 `endpoint` & `useCredentials` new options are not yet supported by all custom services (but will be very soon).
## PiHole ## PiHole
Using the PiHole service you can display info about your local PiHole instance right on your Homer dashboard. Using the PiHole service you can display info about your local PiHole instance right on your Homer dashboard.
@ -13,12 +27,11 @@ Using the PiHole service you can display info about your local PiHole instance r
The following configuration is available for the PiHole service. The following configuration is available for the PiHole service.
```yaml ```yaml
items: - name: "Pi-hole"
- name: "Pi-hole" logo: "assets/tools/sample.png"
logo: "assets/tools/sample.png" # subtitle: "Network-wide Ad Blocking" # optional, if no subtitle is defined, PiHole statistics will be shown
# subtitle: "Network-wide Ad Blocking" # optional, if no subtitle is defined, PiHole statistics will be shown url: "http://192.168.0.151/admin"
url: "http://192.168.0.151/admin" type: "PiHole"
type: "PiHole"
``` ```
## OpenWeatherMap ## OpenWeatherMap
@ -27,14 +40,13 @@ Using the OpenWeatherMap service you can display weather information about a giv
The following configuration is available for the OpenWeatherMap service: The following configuration is available for the OpenWeatherMap service:
```yaml ```yaml
items: - name: "Weather"
- name: "Weather" location: "Amsterdam" # your location.
location: "Amsterdam" # your location. locationId: "2759794" # Optional: Specify OpenWeatherMap city ID for better accuracy
locationId: "2759794" # Optional: Specify OpenWeatherMap city ID for better accuracy apiKey: "<---insert-api-key-here--->" # insert your own API key here. Request one from https://openweathermap.org/api.
apiKey: "<---insert-api-key-here--->" # insert your own API key here. Request one from https://openweathermap.org/api. units: "metric" # units to display temperature. Can be one of: metric, imperial, kelvin. Defaults to kelvin.
units: "metric" # units to display temperature. Can be one of: metric, imperial, kelvin. Defaults to kelvin. background: "square" # choose which type of background you want behind the image. Can be one of: square, cicle, none. Defaults to none.
background: "square" # choose which type of background you want behind the image. Can be one of: square, cicle, none. Defaults to none. type: "OpenWeather"
type: "OpenWeather"
``` ```
**Remarks:** **Remarks:**
@ -46,8 +58,8 @@ This service displays News (grey), Warning (orange) or Error (red) notifications
Two lines are needed in the config.yml : Two lines are needed in the config.yml :
```yaml ```yaml
type: "Medusa" type: "Medusa"
apikey: "01234deb70424befb1f4ef6a23456789" apikey: "01234deb70424befb1f4ef6a23456789"
``` ```
The url must be the root url of Medusa application. The url must be the root url of Medusa application.
@ -59,8 +71,8 @@ This service displays Activity (blue), Warning (orange) or Error (red) notificat
Two lines are needed in the config.yml : Two lines are needed in the config.yml :
```yaml ```yaml
type: "Radarr" or "Sonarr" type: "Radarr" or "Sonarr"
apikey: "01234deb70424befb1f4ef6a23456789" apikey: "01234deb70424befb1f4ef6a23456789"
``` ```
The url must be the root url of Radarr/Sonarr application. The url must be the root url of Radarr/Sonarr application.
@ -75,10 +87,9 @@ For Paperless you need an API-Key which you have to store at the item in the fie
For Ping you need to set the type to Ping and provide a url. For Ping you need to set the type to Ping and provide a url.
```yaml ```yaml
items: - name: "Awesome app"
- name: "Awesome app" type: Ping
type: Ping logo: "assets/tools/sample.png"
logo: "assets/tools/sample.png" subtitle: "Bookmark example" tag: "app"
subtitle: "Bookmark example" tag: "app" url: "https://www.reddit.com/r/selfhosted/"
url: "https://www.reddit.com/r/selfhosted/"
``` ```

View File

@ -74,7 +74,8 @@
<Service <Service
v-for="(item, index) in group.items" v-for="(item, index) in group.items"
:key="index" :key="index"
v-bind:item="item" :item="item"
:proxy="config.proxy"
:class="['column', `is-${12 / config.columns}`]" :class="['column', `is-${12 / config.columns}`]"
/> />
</template> </template>
@ -102,7 +103,8 @@
<Service <Service
v-for="(item, index) in group.items" v-for="(item, index) in group.items"
:key="index" :key="index"
v-bind:item="item" :item="item"
:proxy="config.proxy"
/> />
</div> </div>
</div> </div>

View File

@ -44,3 +44,6 @@ colors:
message: ~ message: ~
links: [] links: []
services: [] services: []
proxy: ~

View File

@ -1,5 +1,5 @@
<template> <template>
<component v-bind:is="component" :item="item"></component> <component v-bind:is="component" :item="item" :proxy="proxy"></component>
</template> </template>
<script> <script>
@ -9,6 +9,7 @@ export default {
name: "Service", name: "Service",
props: { props: {
item: Object, item: Object,
proxy: Object,
}, },
computed: { computed: {
component() { component() {

View File

@ -20,10 +20,12 @@
</template> </template>
<script> <script>
import service from "@/mixins/service.js";
import Generic from "./Generic.vue"; import Generic from "./Generic.vue";
export default { export default {
name: "AdGuardHome", name: "AdGuardHome",
mixins: [service],
props: { props: {
item: Object, item: Object,
}, },
@ -60,18 +62,14 @@ export default {
}, },
methods: { methods: {
fetchStatus: async function () { fetchStatus: async function () {
this.status = await fetch(`${this.item.url}/control/status`, { this.status = await this.fetch("/control/status").catch((e) =>
credentials: "include", console.log(e)
}) );
.then((response) => response.json())
.catch((e) => console.log(e));
}, },
fetchStats: async function () { fetchStats: async function () {
this.stats = await fetch(`${this.item.url}/control/stats`, { this.stats = await this.fetch("/control/stats").catch((e) =>
credentials: "include", console.log(e)
}) );
.then((response) => response.json())
.catch((e) => console.log(e));
}, },
}, },
}; };

View File

@ -9,10 +9,12 @@
</template> </template>
<script> <script>
import service from "@/mixins/service.js";
import Generic from "./Generic.vue"; import Generic from "./Generic.vue";
export default { export default {
name: "Ping", name: "Ping",
mixins: [service],
props: { props: {
item: Object, item: Object,
}, },
@ -27,16 +29,8 @@ export default {
}, },
methods: { methods: {
fetchStatus: async function () { fetchStatus: async function () {
const url = `${this.item.url}`; this.fetch("/", { method: "HEAD", cache: "no-cache" }, false)
fetch(url, { .then(() => {
method: "HEAD",
cache: "no-cache",
credentials: "include",
})
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
this.status = "online"; this.status = "online";
}) })
.catch(() => { .catch(() => {

43
src/mixins/service.js Normal file
View File

@ -0,0 +1,43 @@
export default {
props: {
proxy: Object,
},
created: function () {
// custom service often consume info from an API using the item link (url) as a base url,
// but sometimes the base url is different. An optional alternative URL can be provided with the "endpoint" key.
this.endpoint = this.item.endpoint || this.item.url;
if (this.endpoint.endsWith("/")) {
this.endpoint = this.endpoint.slice(0, -1);
}
},
methods: {
fetch: function (path, init, json = true) {
let options = {};
if (this.proxy?.useCredentials) {
options.credentials = "include";
}
// Each item can override the credential settings
if (this.item.useCredentials !== undefined) {
options.credentials =
this.item.useCredentials === true ? "include" : "omit";
}
options = Object.assign(options, init);
if (path.startsWith("/")) {
path = path.slice(1);
}
return fetch(`${this.endpoint}/${path}`, options).then((response) => {
if (!response.ok) {
throw new Error("Not 2xx response");
}
return json ? response.json() : response;
});
},
},
};