Adds widget for showing public IP

This commit is contained in:
Alicia Sykes 2021-12-17 20:16:11 +00:00
parent be5188ef7d
commit 08de6b8f17
5 changed files with 138 additions and 1 deletions

View File

@ -18,6 +18,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
- [Stock Price History](#stock-price-history) - [Stock Price History](#stock-price-history)
- [Joke of the Day](#joke) - [Joke of the Day](#joke)
- [Flight Data](#flight-data) - [Flight Data](#flight-data)
- [Public IP Address](#public-ip)
- [Self-Hosted Services Widgets](#dynamic-widgets) - [Self-Hosted Services Widgets](#dynamic-widgets)
- [System Info](#system-info) - [System Info](#system-info)
- [CPU History](#cpu-history-netdata) - [CPU History](#cpu-history-netdata)
@ -430,6 +431,24 @@ Displays airport departure and arrival flights, using data from [AeroDataBox](ht
--- ---
### Public IP
Displays your public IP address, along with ISP name and approx location. Data is fetched from [IP-API.com](https://ip-api.com/).
<p align="center"><img width="400" src="https://i.ibb.co/vc3c8zN/public-ip.png" /></p>
##### Options
_No config options._
##### Example
```yaml
- type: public-ip
```
---
## Self-Hosted Services Widgets ## Self-Hosted Services Widgets
@ -441,7 +460,7 @@ Displays info about the server which Dashy is hosted on. Includes user + host, o
##### Options ##### Options
No config options. _No config options._
##### Example ##### Example

View File

@ -0,0 +1,93 @@
<template>
<div class="ip-info-wrapper">
<p class="ip-address">{{ ipAddr }}</p>
<div class="region-wrapper" title="Open in Maps">
<img class="flag-image" :src="flagImg" />
<div class="info-text">
<p class="isp-name">{{ ispName }}</p>
<a class="ip-location" :href="mapsUrl">{{ 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: {},
data() {
return {
ipAddr: null,
location: null,
ispName: null,
flagImg: null,
mapsUrl: null,
};
},
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();
});
},
/* 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 });
},
},
};
</script>
<style scoped lang="scss">
.ip-info-wrapper {
cursor: default;
p.ip-address {
font-size: 1.6rem;
margin: 0.5rem auto;
color: var(--widget-text-color);
font-family: var(--font-monospace);
}
.region-wrapper {
display: flex;
align-items: center;
img.flag-image {
width: 2rem;
border-radius: var(--curve-factor-small);
margin: 0.25rem 0.5rem 0 0;
}
a.ip-location {
font-size: 1rem;
margin: 0;
text-decoration: none;
color: var(--widget-text-color);
opacity: var(--dimming-factor);
&:hover {
text-decoration: underline;
}
}
p.isp-name {
font-size: 1rem;
margin: 0.25rem 0 0 0;
color: var(--widget-text-color);
}
}
}
</style>

View File

@ -109,6 +109,13 @@
@error="handleError" @error="handleError"
:ref="widgetRef" :ref="widgetRef"
/> />
<PublicIp
v-else-if="widgetType === 'public-ip'"
:options="widgetOptions"
@loading="setLoaderState"
@error="handleError"
:ref="widgetRef"
/>
<RssFeed <RssFeed
v-else-if="widgetType === 'rss-feed'" v-else-if="widgetType === 'rss-feed'"
:options="widgetOptions" :options="widgetOptions"
@ -186,6 +193,7 @@ import NdCpuHistory from '@/components/Widgets/NdCpuHistory.vue';
import NdLoadHistory from '@/components/Widgets/NdLoadHistory.vue'; import NdLoadHistory from '@/components/Widgets/NdLoadHistory.vue';
import NdRamHistory from '@/components/Widgets/NdRamHistory.vue'; import NdRamHistory from '@/components/Widgets/NdRamHistory.vue';
import PublicHolidays from '@/components/Widgets/PublicHolidays.vue'; import PublicHolidays from '@/components/Widgets/PublicHolidays.vue';
import PublicIp from '@/components/Widgets/PublicIp.vue';
import RssFeed from '@/components/Widgets/RssFeed.vue'; import RssFeed from '@/components/Widgets/RssFeed.vue';
import StockPriceChart from '@/components/Widgets/StockPriceChart.vue'; import StockPriceChart from '@/components/Widgets/StockPriceChart.vue';
import SystemInfo from '@/components/Widgets/SystemInfo.vue'; import SystemInfo from '@/components/Widgets/SystemInfo.vue';
@ -216,6 +224,7 @@ export default {
NdLoadHistory, NdLoadHistory,
NdRamHistory, NdRamHistory,
PublicHolidays, PublicHolidays,
PublicIp,
RssFeed, RssFeed,
StockPriceChart, StockPriceChart,
SystemInfo, SystemInfo,

View File

@ -81,6 +81,21 @@ export const findCurrencySymbol = (currencyCode) => {
return code; return code;
}; };
/* Given a 2-digit country code, return path to flag image from Flagpedia */
export const getCountryFlag = (countryCode, dimens) => {
const protocol = 'https';
const cdn = 'flagcdn.com';
const dimensions = dimens || '64x48';
const country = countryCode.toLowerCase();
const ext = 'png';
return `${protocol}://${cdn}/${dimensions}/${country}.${ext}`;
};
/* Given a Latitude & Longitude object, and optional zoom level, return link to OSM */
export const getMapUrl = (location, zoom) => {
return `https://www.openstreetmap.org/#map=${zoom || 10}/${location.lat}/${location.lon}`;
};
/* Given a large number, will add commas to make more readable */ /* Given a large number, will add commas to make more readable */
export const putCommasInBigNum = (bigNum) => { export const putCommasInBigNum = (bigNum) => {
const strNum = Number.isNaN(bigNum) ? bigNum : String(bigNum); const strNum = Number.isNaN(bigNum) ? bigNum : String(bigNum);

View File

@ -219,6 +219,7 @@ module.exports = {
rssToJson: 'https://api.rss2json.com/v1/api.json', rssToJson: 'https://api.rss2json.com/v1/api.json',
codeStats: 'https://codestats.net/', codeStats: 'https://codestats.net/',
holidays: 'https://kayaposoft.com/enrico/json/v2.0/?action=getHolidaysForDateRange', holidays: 'https://kayaposoft.com/enrico/json/v2.0/?action=getHolidaysForDateRange',
publicIp: 'http://ip-api.com/json',
}, },
/* URLs for web search engines */ /* URLs for web search engines */
searchEngineUrls: { searchEngineUrls: {