Added secondary check for potential changes in public IP and a small bug fix arising from reliance on util.location

Added a second check for indications of possible change of public IP address since netifaces does not properly handle all Linux routing tables (ref: http://linux-ip.net/html/routing-tables.html) which can lead to changes being missed if only looking at defauilt route. Consequently an additional check for changes to the network interface names/numbers was added to further help in identifying potentially notable changes. Note that netifaces is no longer being maintained so the underlying issue with its handling of gateways is unlikely to be resolved (https://github.com/al45tair/netifaces). An alternative would be to use direct calls to the OS like 'ip route list table all' (note the difference to 'ip route list all') but this might lead to unpredicatble results between distributions/flavours so probably best to stick with a library for now. all') but this might lead to unpredicatble results between distributions/flavours so probably best to stick with a library for now.

Introduced time.sleep(2) following calls to util.location.reset() since it can take util.location a while to update following a call to .reset() which can cause calls to .location_info() to return unpredicatable/unuseful results.
This commit is contained in:
tfwiii 2022-08-30 02:01:25 +07:00
parent 82e55ec517
commit 7ee9645437

View file

@ -6,8 +6,8 @@ Displays information about the public IP address associated with the default rou
* City Name * City Name
* Geographic Coordinates * Geographic Coordinates
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 Any change to the default route will cause the widget to update.
Requirements: Requirements:
* netifaces * netifaces
@ -21,7 +21,7 @@ Examples:
* 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! contributed by `tfwiii <https://github.com/tfwiii>` - many thanks!
""" """
import re import re
@ -57,9 +57,15 @@ class Module(core.module.Module):
self.__monitor.start() self.__monitor.start()
def monitor(self): def monitor(self):
current_default_route = None
default_route = None default_route = None
interfaces = None
# Initially set to True to force an info update on first pass
information_changed = True
self.update()
while threading.main_thread().is_alive(): while threading.main_thread().is_alive():
# Look for any changes in the netifaces default route information
try: try:
current_default_route = netifaces.gateways()["default"][2] current_default_route = netifaces.gateways()["default"][2]
except: except:
@ -67,11 +73,32 @@ class Module(core.module.Module):
current_default_route = None current_default_route = None
if current_default_route != default_route: if current_default_route != default_route:
default_route = current_default_route default_route = current_default_route
information_changed = True
# netifaces does not check ALL routing tables which might lead to false negatives
# (ref: http://linux-ip.net/html/routing-tables.html) so additionally... look for
# any changes in the netifaces interfaces information which might also be an inticator
# of a change of route/external IP
if not information_changed: # Only check if no routing table change found
try:
current_interfaces = netifaces.interfaces()
except:
# error reading interfaces information -> assume none exists
current_interfaces = None
if current_interfaces != interfaces:
interfaces = current_interfaces
information_changed = True
# Update either routing or interface information has changed
if information_changed:
information_changed = False
self.update() self.update()
# Throttle the calls to netifaces
time.sleep(1) time.sleep(1)
def publicip(self, widget): def publicip(self, widget):
if widget.get("public_ip") == None: if widget.get("public_ip") is None:
return "n/a" return "n/a"
return self._format.format( return self._format.format(
ip=widget.get("public_ip", "-"), ip=widget.get("public_ip", "-"),
@ -83,12 +110,17 @@ class Module(core.module.Module):
def __click_update(self, event): def __click_update(self, event):
util.location.reset() util.location.reset()
# pause to allow reset time to complete
time.sleep(2)
def update(self): def update(self):
widget = self.widget() widget = self.widget()
try: try:
util.location.reset() util.location.reset()
# pause to allow reset time to complete
time.sleep(2)
# Fetch fresh location information # Fetch fresh location information
__info = util.location.location_info() __info = util.location.location_info()
@ -106,11 +138,12 @@ class Module(core.module.Module):
# Update widget values # Update widget values
core.event.trigger("update", [widget.module.id], redraw_only=True) core.event.trigger("update", [widget.module.id], redraw_only=True)
except: except Exception as ex:
widget.set("public_ip", None) widget.set("public_ip", None)
print(ex)
def state(self, widget): def state(self, widget):
return widget.get("state", None) return widget.get("state", None)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4