Updated publicip to automatically update on detecting a change to default route

This commit is contained in:
Tom Watson 2022-07-07 18:08:20 +07:00
parent 05c28c52c7
commit 9a6e61173f

View file

@ -1,88 +1,114 @@
"""
Displays zero or more of:
Displays information about the public IP address associated with the default route:
* 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
* Geographic Coordinates
Left mouse click on the widget forces immediate update
Any change to the default route will cause the widget to update
Requirements:
* netifaces
Parameters:
publicip.format: Format string (defaults to {ip} ({country_code}))
Available format strings:
ip
country_name
country_code
city_name
coordinates
* 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}"
* 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}"
contributed by `tfwiii <https://github.com/tfwiii>`_ - many thanks!
"""
import re
import threading
import netifaces
import time
import core.module
import core.widget
import core.decorators
import core.input
import core.decorators
import util.format
import util.location
def update_publicip_information(module):
widget = module.widget()
__previous_default_route = None
__current_default_route = None
__interval = 5 # Interval between default route change checks
while True:
__current_default_route = netifaces.gateways()["default"][2]
# Updates public ip information if a change to default route is detected
if __current_default_route != __previous_default_route:
# Sets __previous_default_route in preparation for next change check
__previous_default_route = __current_default_route
# Refresh location information
util.location.reset()
# Fetch fresh location information
__info = util.location.location_info()
# Contstruct coordinates string
__lat = "{:.2f}".format(__info["latitude"])
__lon = "{:.2f}".format(__info["longitude"])
__coords = __lat + "°N" + "," + " " + __lon + "°E"
# Set widget values
widget.set("public_ip", __info["public_ip"])
widget.set("country_name", __info["country"])
widget.set("country_code", __info["country_code"])
widget.set("city_name", __info["city_name"])
widget.set("coordinates", __coords)
# Update widget values
core.event.trigger("update", [widget.module.id], redraw_only=True)
# Wait __interval seconds before checking for default route changes again
time.sleep(__interval)
class Module(core.module.Module):
@core.decorators.every(minutes=60)
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.public_ip))
super().__init__(config, theme, core.widget.Widget(self.publicip))
self.__thread = None
# 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 publicip(self, widget):
return self._format.format(
ip = widget.get("public_ip", "-"),
country_name = widget.get("country_name", "-"),
country_code = widget.get("country_code", "-"),
city_name = widget.get("city_name", "-"),
coordinates = widget.get("coordinates", "-")
)
def __click_update(self, event):
util.location.reset()
def public_ip(self, widget):
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:
__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:
pass
if self.__thread is not None and self.__thread.is_alive():
return
self.__thread = threading.Thread(target=update_publicip_information, args=(self,))
self.__thread.start()
def state(self, widget):
return widget.get("state", None)
# vim: tabstop=7 expandtab shiftwidth=4 softtabstop=4
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4