From 1e078c249be8d4fdc08aaf82581ce38e94ec138d Mon Sep 17 00:00:00 2001 From: Mathis FELARDOS Date: Wed, 11 Jan 2017 02:44:06 +0100 Subject: [PATCH 1/2] external_ip: add external ip module --- docs/conf.py | 1 + i3pystatus/external_ip.py | 80 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 i3pystatus/external_ip.py diff --git a/docs/conf.py b/docs/conf.py index 1921276..c2549e5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,6 +25,7 @@ MOCK_MODULES = [ "lxml.html", "lxml.cssselect", "lxml", "praw", "gi", "gi.repository", "dbus.mainloop.glib", "dbus", + "GeoIP", "pywapi", "basiciw", "i3pystatus.pulseaudio.pulse", "notmuch", diff --git a/i3pystatus/external_ip.py b/i3pystatus/external_ip.py new file mode 100644 index 0000000..ee81c74 --- /dev/null +++ b/i3pystatus/external_ip.py @@ -0,0 +1,80 @@ +from i3pystatus import IntervalModule, formatp + +import GeoIP +import urllib.request + + +class ExternalIP(IntervalModule): + """ + Shows the external IP with the country code/name. + + Requires the PyPI package `GeoIP`. + + .. rubric:: Available formatters + + * {country_name} the full name of the country from the IP (eg. 'United States') + * {country_code} the country code of the country from the IP (eg. 'US') + * {ip} the ip + """ + + settings = ( + "format", + "color", + ("color_down", "color when the http request failed"), + ("color_hide", "color when the user has decide to switch to the hide format"), + ("format_down", "format when the http request failed"), + ("format_hide", "format when the user has decide to switch to the hide format"), + ("ip_website", "http website where the IP is directly available as raw"), + ("timeout", "timeout in seconds when the http request is taking too much time"), + ) + + interval = 15 + format = "{country_name} {country_code} {ip}" + format_hide = "{country_code}" + format_down = "Timeout" + + ip_website = "https://api.ipify.org" + timeout = 5 + color = "#FFFFFF" + color_hide = "#FFFF00" + color_down = "#FF0000" + + on_leftclick = "switch_hide" + on_rightclick = "run" + + def run(self): + try: + request = urllib.request.urlopen(self.ip_website, + timeout=self.timeout) + ip = request.read().decode().strip() + except Exception: + return self.disable() + + gi = GeoIP.GeoIP(GeoIP.GEOIP_STANDARD) + country_code = gi.country_code_by_addr(ip) + country_name = gi.country_name_by_addr(ip) + + if not ip or not country_code: + return self.disable() # fail here in the case of a bad IP + + fdict = { + "country_name": country_name, + "country_code": country_code, + "ip": ip + } + + self.output = { + "full_text": formatp(self.format, **fdict).strip(), + "color": self.color + } + + def disable(self): + self.output = { + "full_text": self.format_down, + "color": self.color_down + } + + def switch_hide(self): + self.format, self.format_hide = self.format_hide, self.format + self.color, self.color_hide = self.color_hide, self.color + self.run() From a7db805db727fbe1c6e9f37152e6c3c2f94d406d Mon Sep 17 00:00:00 2001 From: Mathis FELARDOS Date: Wed, 11 Jan 2017 13:21:32 +0100 Subject: [PATCH 2/2] external_ip: add require internet --- i3pystatus/external_ip.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/i3pystatus/external_ip.py b/i3pystatus/external_ip.py index ee81c74..359fd88 100644 --- a/i3pystatus/external_ip.py +++ b/i3pystatus/external_ip.py @@ -1,4 +1,5 @@ from i3pystatus import IntervalModule, formatp +from i3pystatus.core.util import internet, require import GeoIP import urllib.request @@ -16,6 +17,7 @@ class ExternalIP(IntervalModule): * {country_code} the country code of the country from the IP (eg. 'US') * {ip} the ip """ + interval = 15 settings = ( "format", @@ -28,7 +30,6 @@ class ExternalIP(IntervalModule): ("timeout", "timeout in seconds when the http request is taking too much time"), ) - interval = 15 format = "{country_name} {country_code} {ip}" format_hide = "{country_code}" format_down = "Timeout" @@ -42,19 +43,25 @@ class ExternalIP(IntervalModule): on_leftclick = "switch_hide" on_rightclick = "run" - def run(self): + @require(internet) + def get_external_ip(self): try: request = urllib.request.urlopen(self.ip_website, timeout=self.timeout) - ip = request.read().decode().strip() + return request.read().decode().strip() except Exception: + return None + + def run(self): + ip = self.get_external_ip() + if not ip: return self.disable() gi = GeoIP.GeoIP(GeoIP.GEOIP_STANDARD) country_code = gi.country_code_by_addr(ip) country_name = gi.country_name_by_addr(ip) - if not ip or not country_code: + if not country_code: return self.disable() # fail here in the case of a bad IP fdict = {