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 * Public IP address
* Country Name * Country Name
* Country Code * Country Code
* City Name * City Name
* Geographic Coordinates\ * 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 Left mouse click on the widget forces immediate update
Any change to the default route will cause the widget to update
Requirements:
* netifaces
Parameters: Parameters:
publicip.format: Format string (defaults to {ip} ({country_code})) * publicip.format: Format string (defaults to {ip} ({country_code}))
* Available format strings - ip, country_name, country_code, city_name, coordinates
Available format strings:
ip
country_name
country_code
city_name
coordinates
Examples: Examples:
bumblebee-status -m publicip -p publicip.format="{ip} ({country_code})" * 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="{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="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.module
import core.widget import core.widget
import core.decorators
import core.input import core.input
import core.decorators
import util.format import util.format
import util.location 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): class Module(core.module.Module):
@core.decorators.every(minutes=60) @core.decorators.every(minutes=60)
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.publicip))
self.__thread = None
# Immediate update (override default) when left click on widget # Immediate update (override default) when left click on widget
core.input.register(self, button=core.input.LEFT_MOUSE, cmd=self.__click_update) 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>) # By default show: <ip> (<2 letter country code>)
self._format = self.parameter("format", "{ip} ({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): def __click_update(self, event):
util.location.reset() 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): def update(self):
try: if self.__thread is not None and self.__thread.is_alive():
__info = util.location.location_info() return
self.__ip = __info["public_ip"] self.__thread = threading.Thread(target=update_publicip_information, args=(self,))
self.__country_name = __info["country"] self.__thread.start()
self.__country_code = __info["country_code"]
self.__city_name = __info["city_name"] def state(self, widget):
__lat = __info["latitude"] return widget.get("state", None)
__lon = __info["longitude"]
__lat = "{:.2f}".format(__lat)
__lon = "{:.2f}".format(__lon)
__output = __lat + "°N" + "," + " " + __lon + "°E"
self.__coordinates = __output
except Exception:
pass
# vim: tabstop=7 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4