Merge pull request #897 from tfwiii/updated_publicip_module
Updated contrib/publicip module and util/location
This commit is contained in:
commit
05c28c52c7
2 changed files with 129 additions and 16 deletions
|
@ -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.module
|
||||||
import core.widget
|
import core.widget
|
||||||
import core.decorators
|
import core.decorators
|
||||||
|
import core.input
|
||||||
|
import util.format
|
||||||
import util.location
|
import util.location
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,16 +41,48 @@ class Module(core.module.Module):
|
||||||
def __init__(self, config, theme):
|
def __init__(self, config, theme):
|
||||||
super().__init__(config, theme, core.widget.Widget(self.public_ip))
|
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):
|
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):
|
def update(self):
|
||||||
try:
|
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:
|
except Exception:
|
||||||
self.__ip = None
|
pass
|
||||||
|
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
# vim: tabstop=7 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
|
@ -3,8 +3,10 @@ service and caches it for 12h (retries are done every
|
||||||
30m in case of problems)
|
30m in case of problems)
|
||||||
|
|
||||||
Right now, it uses (in order of preference):
|
Right now, it uses (in order of preference):
|
||||||
- http://free.ipwhois.io/
|
- http://free.ipwhois.io/ - 10k free requests/month
|
||||||
- http://ipapi.co/
|
- http://ipapi.co/ - 30k free requests/month
|
||||||
|
- http://ip-api.com/ - ~2m free requests/month
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +23,9 @@ __sources = [
|
||||||
"mapping": {
|
"mapping": {
|
||||||
"latitude": "latitude",
|
"latitude": "latitude",
|
||||||
"longitude": "longitude",
|
"longitude": "longitude",
|
||||||
"country_name": "country",
|
"country_name": "country_name",
|
||||||
|
"country_code": "country_code",
|
||||||
|
"city": "city_name",
|
||||||
"ip": "public_ip",
|
"ip": "public_ip",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -30,10 +34,23 @@ __sources = [
|
||||||
"mapping": {
|
"mapping": {
|
||||||
"latitude": "latitude",
|
"latitude": "latitude",
|
||||||
"longitude": "longitude",
|
"longitude": "longitude",
|
||||||
"country": "country",
|
"country": "country_name",
|
||||||
|
"country_code": "country_code",
|
||||||
|
"city": "city_name",
|
||||||
"ip": "public_ip",
|
"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
|
global __data
|
||||||
if not __data or __expired():
|
if not __data or __expired():
|
||||||
__load()
|
__load()
|
||||||
|
if name in __data:
|
||||||
return __data[name]
|
return __data[name]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def reset():
|
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
|
global __next
|
||||||
__next = 0
|
__next = 0
|
||||||
|
|
||||||
|
@ -88,7 +107,25 @@ def country():
|
||||||
:return: country name
|
:return: country name
|
||||||
:rtype: string
|
: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():
|
def public_ip():
|
||||||
|
@ -100,4 +137,20 @@ def public_ip():
|
||||||
return __get("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
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
Loading…
Reference in a new issue