""" Displays information about the public IP address associated with the default route: * Public IP address * Country Name * Country Code * City Name * 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 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}" contributed by `tfwiii `_ - many thanks! """ import re import threading import netifaces import time import core.module import core.widget 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.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) # By default show: (<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 update(self): 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=8 expandtab shiftwidth=4 softtabstop=4