From 61fe7f6d3e2f9df32f4a58c46b23cb626689f9a8 Mon Sep 17 00:00:00 2001 From: tfwiii Date: Thu, 6 Oct 2022 13:49:37 +0700 Subject: [PATCH 1/3] Handled fail where core.location does not provide values for latitude and longitude. Added handling for coordinates N, S, E, W. --- bumblebee_status/modules/contrib/publicip.py | 25 ++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/bumblebee_status/modules/contrib/publicip.py b/bumblebee_status/modules/contrib/publicip.py index d79c2a1..ca0cd31 100644 --- a/bumblebee_status/modules/contrib/publicip.py +++ b/bumblebee_status/modules/contrib/publicip.py @@ -116,6 +116,8 @@ class Module(core.module.Module): def update(self): widget = self.widget() + __lat = None + __lon = None try: util.location.reset() @@ -123,10 +125,23 @@ class Module(core.module.Module): # 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" + # Contstruct coordinates string if util.location has provided required info + if __lat and __lon: + __lat = "{:.2f}".format(__info["latitude"]) + __lon = "{:.2f}".format(__info["longitude"]) + if __lat < 0: + __coords = __lat + "°S" + else: + __coords = __lat + "°N" + __coords += "," + if __lon < 0: + __coords += __lon + "°W" + else: + __coords += __lon + "°E" + else: + __lat = "Unknown" + __lon = "Unknown" + __coords = "Unknown" # Set widget values widget.set("public_ip", __info["public_ip"]) @@ -139,6 +154,8 @@ class Module(core.module.Module): core.event.trigger("update", [widget.module.id], redraw_only=True) except Exception as ex: widget.set("public_ip", None) + print("OH NOES!") + print(__info) logging.error(str(ex)) def state(self, widget): From 605b749e2269a722c90ed9e5633c0e4715c41a1f Mon Sep 17 00:00:00 2001 From: tfwiii Date: Thu, 6 Oct 2022 14:21:43 +0700 Subject: [PATCH 2/3] Removed debugging prints --- bumblebee_status/modules/contrib/publicip.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bumblebee_status/modules/contrib/publicip.py b/bumblebee_status/modules/contrib/publicip.py index ca0cd31..7f91271 100644 --- a/bumblebee_status/modules/contrib/publicip.py +++ b/bumblebee_status/modules/contrib/publicip.py @@ -154,8 +154,6 @@ class Module(core.module.Module): core.event.trigger("update", [widget.module.id], redraw_only=True) except Exception as ex: widget.set("public_ip", None) - print("OH NOES!") - print(__info) logging.error(str(ex)) def state(self, widget): From cace02909e8e15a00def57fb0215076031581475 Mon Sep 17 00:00:00 2001 From: tfwiii Date: Sat, 8 Oct 2022 10:42:12 +0700 Subject: [PATCH 3/3] Bug fix improvements to publicip and util.location Fixed publicip bug arising from last PR review Simplified ip change detection code Added pause after location.reset() call to allow completion before query util.location - change order of information providers as default was not returning geo coords --- bumblebee_status/modules/contrib/publicip.py | 78 +++++++++----------- bumblebee_status/util/location.py | 22 +++--- 2 files changed, 45 insertions(+), 55 deletions(-) diff --git a/bumblebee_status/modules/contrib/publicip.py b/bumblebee_status/modules/contrib/publicip.py index 7f91271..9a8f468 100644 --- a/bumblebee_status/modules/contrib/publicip.py +++ b/bumblebee_status/modules/contrib/publicip.py @@ -60,43 +60,34 @@ class Module(core.module.Module): self.__monitor.start() def monitor(self): - default_route = None - interfaces = None + __previous_ips = set() + __current_ips = set() # Initially set to True to force an info update on first pass - information_changed = True + __information_changed = True self.update() while threading.main_thread().is_alive(): - # Look for any changes in the netifaces default route information + __current_ips.clear() + # Look for any changes to IP addresses try: - current_default_route = netifaces.gateways()["default"][2] + for interface in netifaces.interfaces(): + __current_ips.add(netifaces.ifaddresses(interface)[2][0]['addr']) + except: - # error reading out default gw -> assume none exists - current_default_route = None - if current_default_route != default_route: - default_route = current_default_route - information_changed = True + # If not ip address information found clear __current_ips + __current_ips.clear() + + # If a change of any interfaces' IP then flag change + if __current_ips.symmetric_difference(__previous_ips): + __previous_ips = __current_ips.copy() + __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 + # Update if change is flagged + if __information_changed: + __information_changed = False self.update() - + # Throttle the calls to netifaces time.sleep(1) @@ -104,11 +95,11 @@ class Module(core.module.Module): if widget.get("public_ip") is None: return "n/a" 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", "-"), + 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): @@ -116,31 +107,30 @@ class Module(core.module.Module): def update(self): widget = self.widget() - __lat = None - __lon = None try: util.location.reset() + time.sleep(5) # wait for reset to complete before querying results # Fetch fresh location information __info = util.location.location_info() + __raw_lat = __info["latitude"] + __raw_lon = __info["longitude"] # Contstruct coordinates string if util.location has provided required info - if __lat and __lon: - __lat = "{:.2f}".format(__info["latitude"]) - __lon = "{:.2f}".format(__info["longitude"]) + if isinstance(__raw_lat, float) and isinstance(__raw_lon, float): + __lat = float("{:.2f}".format(__raw_lat)) + __lon = float("{:.2f}".format(__raw_lon)) if __lat < 0: - __coords = __lat + "°S" + __coords = str(__lat) + "°S" else: - __coords = __lat + "°N" + __coords = str(__lat) + "°N" __coords += "," if __lon < 0: - __coords += __lon + "°W" + __coords += str(__lon) + "°W" else: - __coords += __lon + "°E" + __coords += str(__lon) + "°E" else: - __lat = "Unknown" - __lon = "Unknown" __coords = "Unknown" # Set widget values diff --git a/bumblebee_status/util/location.py b/bumblebee_status/util/location.py index 9cd3a10..3d9494f 100644 --- a/bumblebee_status/util/location.py +++ b/bumblebee_status/util/location.py @@ -18,17 +18,6 @@ __document = None __data = {} __next = 0 __sources = [ - { - "url": "http://ipapi.co/json", - "mapping": { - "latitude": "latitude", - "longitude": "longitude", - "country_name": "country_name", - "country_code": "country_code", - "city": "city_name", - "ip": "public_ip", - }, - }, { "url": "http://free.ipwhois.io/json/", "mapping": { @@ -51,6 +40,17 @@ __sources = [ "query": "public_ip", }, }, + { + "url": "http://ipapi.co/json", + "mapping": { + "latitude": "latitude", + "longitude": "longitude", + "country_name": "country_name", + "country_code": "country_code", + "city": "city_name", + "ip": "public_ip", + }, + } ]