mirror of
https://github.com/Lissy93/dashy.git
synced 2024-12-23 17:03:59 +03:00
🔀 Merge pull request #438 from Lissy93/FEATURE/ip-address-widget
[FEATURE] IP Address Widget Fixes #437 and #427
This commit is contained in:
commit
7f5a5ed861
@ -56,6 +56,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
|
||||
- [Network Interfaces](#network-interfaces)
|
||||
- [Network Traffic](#network-traffic)
|
||||
- [Resource Usage Alerts](#resource-usage-alerts)
|
||||
- [Public & Private IP](#ip-address)
|
||||
- **[Dynamic Widgets](#dynamic-widgets)**
|
||||
- [Iframe Widget](#iframe-widget)
|
||||
- [HTML Embed Widget](#html-embedded-widget)
|
||||
@ -210,13 +211,17 @@ Display news and updates from any RSS-enabled service.
|
||||
|
||||
### Public IP
|
||||
|
||||
Often find yourself searching "What's my IP", just so you can check your VPN is still connected? This widget displays your public IP address, along with ISP name and approx location. Data is fetched from [IP-API.com](https://ip-api.com/).
|
||||
Often find yourself searching "What's my IP", just so you can check your VPN is still connected? This widget displays your public IP address, along with ISP name and approx location. Data can be fetched from either [IpApi.co](https://ipapi.co/), [IP-API.com](https://ip-api.com/) or [IpGeolocation.io](https://ipgeolocation.io/).
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/vc3c8zN/public-ip.png" /></p>
|
||||
|
||||
##### Options
|
||||
_All fields are optional_
|
||||
|
||||
_No config options._
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`provider`** | `string` | _Optional_ | The name of the service to fetch IP address from. Can be either `ipapi.co`, `ip-api` or `ipgeolocation`. Defaults to `ipapi.co`. Note, `ip-api` doesn't work on HTTPS, and if you set to `ipgeolocation` then you must also provide an API key
|
||||
**`apiKey`** | `string` | _Optional_ | Only required if provider is set to `ipgeolocation`. You can get a free API key [here](https://ipgeolocation.io/signup.html)
|
||||
|
||||
##### Example
|
||||
|
||||
@ -224,12 +229,21 @@ _No config options._
|
||||
- type: public-ip
|
||||
```
|
||||
|
||||
Or
|
||||
|
||||
```yaml
|
||||
- type: public-ip
|
||||
options:
|
||||
provider: ipgeolocation
|
||||
apiKey: xxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
##### Info
|
||||
- **CORS**: 🟢 Enabled
|
||||
- **Auth**: 🟠 Optional
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: Managed Instance Only
|
||||
- **Privacy**: _See [IP-API Privacy Policy](https://ip-api.com/docs/legal)_
|
||||
- **Privacy**: _See [IPGeoLocation Privacy Policy](https://ipgeolocation.io/privacy.html) or [IP-API Privacy Policy](https://ip-api.com/docs/legal)_
|
||||
|
||||
---
|
||||
|
||||
@ -1458,6 +1472,22 @@ Lists recent high resource usage alerts (e.g. CPU, mem, IO, load, temp)
|
||||
|
||||
---
|
||||
|
||||
### IP Address
|
||||
|
||||
Shows public and private IP address. Note that the ip plugin is not available on all instances of Glances.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/ZhXBxZr/gl-ip-address.png" /></p>
|
||||
|
||||
##### Example
|
||||
|
||||
```yaml
|
||||
- type: gl-ip-address
|
||||
options:
|
||||
hostname: http://192.168.130.2:61208
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dynamic Widgets
|
||||
|
||||
### Iframe Widget
|
||||
|
74
src/components/Widgets/GlIpAddress.vue
Normal file
74
src/components/Widgets/GlIpAddress.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="glances-ip-addr-wrapper" v-if="ipAddresses">
|
||||
<div class="ip-row public-ip" v-if="ipAddresses.public_address">
|
||||
<span class="lbl">Public IP</span>
|
||||
<span class="val">{{ ipAddresses.public_address }}</span>
|
||||
</div>
|
||||
<div class="ip-row" v-if="ipAddresses.address">
|
||||
<span class="lbl">Local Address</span>
|
||||
<span class="val">{{ ipAddresses.address }}</span>
|
||||
</div>
|
||||
<div class="ip-row" v-if="ipAddresses.gateway">
|
||||
<span class="lbl">Gateway</span>
|
||||
<span class="val">{{ ipAddresses.gateway }}</span>
|
||||
</div>
|
||||
<div class="ip-row" v-if="ipAddresses.mask">
|
||||
<span class="lbl">Mask</span>
|
||||
<span class="val">{{ ipAddresses.mask }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import GlancesMixin from '@/mixins/GlancesMixin';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin, GlancesMixin],
|
||||
data() {
|
||||
return {
|
||||
ipAddresses: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
endpoint() {
|
||||
return this.makeGlancesUrl('ip');
|
||||
},
|
||||
},
|
||||
filters: {},
|
||||
methods: {
|
||||
processData(ipData) {
|
||||
this.ipAddresses = ipData;
|
||||
if (Object.keys(ipData).length === 0) {
|
||||
this.error('The IP plugin is not supported in this instance of Glances');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.glances-ip-addr-wrapper {
|
||||
.ip-row {
|
||||
display: flex;
|
||||
padding: 0.1rem 0.1rem 0.5rem 0.1rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--widget-text-color);
|
||||
max-width: 400px;
|
||||
margin: 0.5rem auto;
|
||||
span.lbl {
|
||||
font-weight: bold;
|
||||
}
|
||||
span.val {
|
||||
font-family: var(--font-monospace);
|
||||
}
|
||||
&:not(.public-ip) {
|
||||
opacity: var(--dimming-factor);
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px dashed var(--widget-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,25 +1,43 @@
|
||||
<template>
|
||||
<div class="ip-info-wrapper">
|
||||
<p class="ip-address">{{ ipAddr }}</p>
|
||||
<div class="region-wrapper" title="Open in Maps">
|
||||
<div class="region-wrapper">
|
||||
<img class="flag-image" :src="flagImg" alt="Flag" />
|
||||
<div class="info-text">
|
||||
<p class="isp-name">{{ ispName }}</p>
|
||||
<a class="ip-location" :href="mapsUrl">{{ location }}</a>
|
||||
<a class="ip-location" :href="mapsUrl" title="🗺️ Open in Maps">
|
||||
{{ location }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import { widgetApiEndpoints } from '@/utils/defaults';
|
||||
import { getCountryFlag, getMapUrl } from '@/utils/MiscHelpers';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin],
|
||||
components: {},
|
||||
computed: {
|
||||
endpoint() {
|
||||
if (this.provider === 'ipgeolocation') {
|
||||
return `${widgetApiEndpoints.publicIp2}?apiKey=${this.apiKey}`;
|
||||
} else if (this.provider === 'ipapi') {
|
||||
return widgetApiEndpoints.publicIp3;
|
||||
}
|
||||
return widgetApiEndpoints.publicIp;
|
||||
},
|
||||
apiKey() {
|
||||
if (this.provider === 'ipgeolocation' && !this.options.apiKey) this.error('Missing API Key');
|
||||
return this.options.apiKey;
|
||||
},
|
||||
provider() {
|
||||
// Can be either `ip-api`, `ipapi.co` or `ipgeolocation`
|
||||
return this.options.provider || 'ipapi.co';
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ipAddr: null,
|
||||
@ -32,24 +50,31 @@ export default {
|
||||
methods: {
|
||||
/* Make GET request to CoinGecko API endpoint */
|
||||
fetchData() {
|
||||
axios.get(widgetApiEndpoints.publicIp)
|
||||
.then((response) => {
|
||||
this.processData(response.data);
|
||||
})
|
||||
.catch((dataFetchError) => {
|
||||
this.error('Unable to fetch IP info', dataFetchError);
|
||||
})
|
||||
.finally(() => {
|
||||
this.finishLoading();
|
||||
});
|
||||
this.makeRequest(this.endpoint).then(this.processData);
|
||||
},
|
||||
/* Assign data variables to the returned data */
|
||||
processData(ipInfo) {
|
||||
this.ipAddr = ipInfo.query;
|
||||
this.ispName = ipInfo.isp;
|
||||
this.location = `${ipInfo.city}, ${ipInfo.regionName}`;
|
||||
this.flagImg = getCountryFlag(ipInfo.countryCode);
|
||||
this.mapsUrl = getMapUrl({ lat: ipInfo.lat, lon: ipInfo.lon });
|
||||
if (this.provider === 'ipapi.co') {
|
||||
this.ipAddr = ipInfo.ip;
|
||||
this.ispName = ipInfo.org;
|
||||
this.location = `${ipInfo.city}, ${ipInfo.region}`;
|
||||
this.flagImg = getCountryFlag(ipInfo.country_code);
|
||||
this.mapsUrl = getMapUrl({ lat: ipInfo.latitude, lon: ipInfo.longitude });
|
||||
} else if (this.provider === 'ipgeolocation') {
|
||||
this.ipAddr = ipInfo.ip;
|
||||
this.ispName = ipInfo.organization || ipInfo.isp;
|
||||
this.location = `${ipInfo.city}, ${ipInfo.country_name}`;
|
||||
this.flagImg = ipInfo.country_flag;
|
||||
this.mapsUrl = getMapUrl({ lat: ipInfo.latitude, lon: ipInfo.longitude });
|
||||
} else if (this.provider === 'ip-api') {
|
||||
this.ipAddr = ipInfo.query;
|
||||
this.ispName = ipInfo.isp;
|
||||
this.location = `${ipInfo.city}, ${ipInfo.regionName}`;
|
||||
this.flagImg = getCountryFlag(ipInfo.countryCode);
|
||||
this.mapsUrl = getMapUrl({ lat: ipInfo.lat, lon: ipInfo.lon });
|
||||
} else {
|
||||
this.error('Unknown API provider fo IP address');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -160,6 +160,13 @@
|
||||
@error="handleError"
|
||||
:ref="widgetRef"
|
||||
/>
|
||||
<GlIpAddress
|
||||
v-else-if="widgetType === 'gl-ip-address'"
|
||||
:options="widgetOptions"
|
||||
@loading="setLoaderState"
|
||||
@error="handleError"
|
||||
:ref="widgetRef"
|
||||
/>
|
||||
<GlLoadHistory
|
||||
v-else-if="widgetType === 'gl-load-history'"
|
||||
:options="widgetOptions"
|
||||
@ -399,6 +406,7 @@ export default {
|
||||
GlCpuHistory: () => import('@/components/Widgets/GlCpuHistory.vue'),
|
||||
GlDiskIo: () => import('@/components/Widgets/GlDiskIo.vue'),
|
||||
GlDiskSpace: () => import('@/components/Widgets/GlDiskSpace.vue'),
|
||||
GlIpAddress: () => import('@/components/Widgets/GlIpAddress.vue'),
|
||||
GlLoadHistory: () => import('@/components/Widgets/GlLoadHistory.vue'),
|
||||
GlMemGauge: () => import('@/components/Widgets/GlMemGauge.vue'),
|
||||
GlMemHistory: () => import('@/components/Widgets/GlMemHistory.vue'),
|
||||
|
@ -222,7 +222,9 @@ module.exports = {
|
||||
holidays: 'https://kayaposoft.com/enrico/json/v2.0/?action=getHolidaysForDateRange',
|
||||
jokes: 'https://v2.jokeapi.dev/joke/',
|
||||
news: 'https://api.currentsapi.services/v1/latest-news',
|
||||
publicIp: 'http://ip-api.com/json',
|
||||
publicIp: 'https://ipapi.co/json',
|
||||
publicIp2: 'https://api.ipgeolocation.io/ipgeo',
|
||||
publicIp3: 'http://ip-api.com/json',
|
||||
readMeStats: 'https://github-readme-stats.vercel.app/api',
|
||||
rssToJson: 'https://api.rss2json.com/v1/api.json',
|
||||
sportsScores: 'https://www.thesportsdb.com/api/v1/json',
|
||||
|
Loading…
Reference in New Issue
Block a user