Merge pull request #897 from tfwiii/updated_publicip_module

Updated contrib/publicip module and util/location
This commit is contained in:
tobi-wan-kenobi 2022-07-06 14:57:08 +02:00 committed by GitHub
commit 05c28c52c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 129 additions and 16 deletions

View file

@ -1,10 +1,38 @@
"""Displays public IP address
"""
Displays zero or more of:
* Public IP address
* Country Name
* Country Code
* City Name
* Geographic Coordinates\
Maximum refresh interval should be 5 minutes to avoid free SLA breach from providers
Note: 1 request/5 minutes is 8640 requests/month
Provider information contained in core.location
Left mouse click on the widget forces immediate update
Parameters:
publicip.format: Format string (defaults to {ip} ({country_code}))
Available format strings:
ip
country_name
country_code
city_name
coordinates
Examples:
bumblebee-status -m publicip -p publicip.format="{ip} ({country_code})"
bumblebee-status -m publicip -p publicip.format="{ip} which is in {city_name}"
bumblebee-status -m publicip -p publicip.format="Your packets are right here: {coordinates}"
"""
import core.module
import core.widget
import core.decorators
import core.input
import util.format
import util.location
@ -13,16 +41,48 @@ class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.public_ip))
self.__ip = ""
# Immediate update (override default) when left click on widget
core.input.register(self, button=core.input.LEFT_MOUSE, cmd=self.__click_update)
self.__ip = "" # Public IP address
self.__country_name = "" # Country name associated with public IP address
self.__country_code = "" # Country code associated with public IP address
self.__city_name = "" # City name associated with public IP address
self.__coordinates = "" # Coordinates assoicated with public IP address
# By default show: <ip> (<2 letter country code>)
self._format = self.parameter("format", "{ip} ({country_code})")
def __click_update(self, event):
util.location.reset()
def public_ip(self, widget):
return self.__ip or "n/a"
if not self.__ip:
return "Error fetching IP"
else:
return self._format.format(
ip=self.__ip,
country_name=self.__country_name,
country_code=self.__country_code,
city_name=self.__city_name,
coordinates=self.__coordinates,
)
def update(self):
try:
self.__ip = util.location.public_ip()
__info = util.location.location_info()
self.__ip = __info["public_ip"]
self.__country_name = __info["country"]
self.__country_code = __info["country_code"]
self.__city_name = __info["city_name"]
__lat = __info["latitude"]
__lon = __info["longitude"]
__lat = "{:.2f}".format(__lat)
__lon = "{:.2f}".format(__lon)
__output = __lat + "°N" + "," + " " + __lon + "°E"
self.__coordinates = __output
except Exception:
self.__ip = None
pass
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
# vim: tabstop=7 expandtab shiftwidth=4 softtabstop=4

View file

@ -3,8 +3,10 @@ service and caches it for 12h (retries are done every
30m in case of problems)
Right now, it uses (in order of preference):
- http://free.ipwhois.io/
- http://ipapi.co/
- http://free.ipwhois.io/ - 10k free requests/month
- http://ipapi.co/ - 30k free requests/month
- http://ip-api.com/ - ~2m free requests/month
"""
@ -21,7 +23,9 @@ __sources = [
"mapping": {
"latitude": "latitude",
"longitude": "longitude",
"country_name": "country",
"country_name": "country_name",
"country_code": "country_code",
"city": "city_name",
"ip": "public_ip",
},
},
@ -30,10 +34,23 @@ __sources = [
"mapping": {
"latitude": "latitude",
"longitude": "longitude",
"country": "country",
"country": "country_name",
"country_code": "country_code",
"city": "city_name",
"ip": "public_ip",
},
}
},
{
"url": "http://ip-api.com/json",
"mapping": {
"latitude": "lat",
"longitude": "lon",
"country": "country_name",
"countryCode": "country_code",
"city": "city_name",
"query": "public_ip",
},
},
]
@ -63,12 +80,14 @@ def __get(name):
global __data
if not __data or __expired():
__load()
return __data[name]
if name in __data:
return __data[name]
else:
return None
def reset():
"""Resets the location library, ensuring that a new query will be started
"""
"""Resets the location library, ensuring that a new query will be started"""
global __next
__next = 0
@ -88,7 +107,25 @@ def country():
:return: country name
:rtype: string
"""
return __get("country")
return __get("country_name")
def country_code():
"""Returns the current country code
:return: country code
:rtype: string
"""
return __get("country_code")
def city_name():
"""Returns the current city name
:return: city name
:rtype: string
"""
return __get("city_name")
def public_ip():
@ -100,4 +137,20 @@ def public_ip():
return __get("public_ip")
def location_info():
"""Returns the current location information
:return: public IP, country name, country code, city name & coordinates
:rtype: dictionary
"""
return {
"public_ip": __get("public_ip"),
"country": __get("country_name"),
"country_code": __get("country_code"),
"city_name": __get("city_name"),
"latitude": __get("latitude"),
"longitude": __get("longitude"),
}
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4