From 01f6b58c4d55aba703302a35e0580b64213725d2 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Wed, 13 Jun 2018 07:59:34 +0200 Subject: [PATCH 01/28] Added ping.1m+.py --- ping.1m+.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 ping.1m+.py diff --git a/ping.1m+.py b/ping.1m+.py new file mode 100755 index 0000000..f8e92ec --- /dev/null +++ b/ping.1m+.py @@ -0,0 +1,74 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" Simulates httping for `argos `""" + +import sys #for redirecting print to stderr +import datetime #for the whole ms → s and vice versa stuff +import requests #for the central HTTP HEAD request +import statistics #for median and stdev + +__author__ = "Tobias Schmidl" +__copyright__ = "Copyright 2018, Tobias Schmidl" +__license__ = "MIT" +__version__ = "0.0.1" +__maintainer__ = "Tobias Schmidl" + +# in seconds +max_ping = datetime.timedelta(milliseconds = 1000) +targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org" ] + +max_ping_in_ms = max_ping.total_seconds() * 1000 + +class Themes: + purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] + red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] +# shellcheck disable=SC2034 + original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] + +# Configuration + selected_colors = red_green + + def colorize(response_time): + # panda's "cut" functon would be an alternative here, but this would be overkill, to include numpy just for this + if response_time < max_ping_in_ms / 5: + return Themes.selected_colors[5] + elif response_time >= max_ping_in_ms / 5 and response_time < 2 * max_ping_in_ms / 5: + return Themes.selected_colors[4] + elif response_time >= 2 * max_ping_in_ms / 5 and response_time < 3 * max_ping_in_ms / 5: + return Themes.selected_colors[3] + elif response_time >= 3 * max_ping_in_ms / 5 and response_time < 4 * max_ping_in_ms / 5: + return Themes.selected_colors[2] + elif response_time >= 4 * max_ping_in_ms / 5 and response_time < max_ping_in_ms: + return Themes.selected_colors[1] + else: + return Themes.selected_colors[0] + +def httping(targets): + responses = {} + for target in targets: + try: + responses[target] = requests.head(target, timeout = max_ping.total_seconds()).elapsed.total_seconds() * 1000 + except requests.exceptions.RequestException as ex: + print(str(ex), file=sys.stderr) + responses[target] = None + response_times = [value for key, value in responses.items() if isinstance(value, float)] + if len(response_times) > 1: + return responses, statistics.median(response_times), statistics.stdev(response_times) + elif len(response_times) > 0: + return responses, response_times[0], 0 + else: + return responses, None, None + +if __name__ == "__main__": + response_times, median, stddev = httping(targets) + if isinstance(median, float) and median != max_ping_in_ms: + print("⦿ " + str(round(median,2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) + else: + print("☠ | color=" + Themes.selected_colors[0]); + print("---") + for target, response_time in response_times.items(): + if isinstance(response_time, float): + print(target + ": " + str(round(response_time, 2)) + " | color=" + Themes.colorize(response_time)) + else: + print(target + ": ☠ | color=" + Themes.selected_colors[0]) From 21f99d3c03427572bb4f2ff4fe056668d8c5f9fb Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Wed, 13 Jun 2018 08:46:34 +0200 Subject: [PATCH 02/28] Added metadata for bitbar --- ping.1m+.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ping.1m+.py b/ping.1m+.py index f8e92ec..2d96472 100755 --- a/ping.1m+.py +++ b/ping.1m+.py @@ -2,6 +2,14 @@ # -*- coding: utf-8 -*- """ Simulates httping for `argos `""" +# httping +# v1.0 +# Tobias Schmidl +# schtobia +# Short description of what your plugin does. +# +# python,requests +# https://github.com/schtobia/argos-httping/blob/master/ping.1m+.py import sys #for redirecting print to stderr import datetime #for the whole ms → s and vice versa stuff @@ -14,19 +22,17 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -# in seconds -max_ping = datetime.timedelta(milliseconds = 1000) -targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org" ] +max_ping = datetime.timedelta(milliseconds = 1000) # in seconds +targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] max_ping_in_ms = max_ping.total_seconds() * 1000 class Themes: + # Themes are from http://colorbrewer2.org/ purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] -# shellcheck disable=SC2034 original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] -# Configuration selected_colors = red_green def colorize(response_time): From a7a2eaab9670fb968289cd01f4a3cb9936f89d99 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Wed, 13 Jun 2018 08:47:42 +0200 Subject: [PATCH 03/28] Added requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8f94722 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +requests>=2.5.0 From 51d6d25aa98aae3ebd293650095bfa3ab890b99f Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Wed, 13 Jun 2018 08:48:50 +0200 Subject: [PATCH 04/28] moved ping.1m+.py --> httping.py --- ping.1m+.py => httping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename ping.1m+.py => httping.py (98%) diff --git a/ping.1m+.py b/httping.py similarity index 98% rename from ping.1m+.py rename to httping.py index 2d96472..2e4baa6 100755 --- a/ping.1m+.py +++ b/httping.py @@ -9,7 +9,7 @@ # Short description of what your plugin does. # # python,requests -# https://github.com/schtobia/argos-httping/blob/master/ping.1m+.py +# https://github.com/schtobia/argos-httping/blob/master/httping.py import sys #for redirecting print to stderr import datetime #for the whole ms → s and vice versa stuff From 9a4c15f5339d3175349f44fc5c5e1254dadf6339 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Wed, 13 Jun 2018 15:54:17 +0200 Subject: [PATCH 05/28] Replace the if switch with a lambda and a for loop --- httping.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/httping.py b/httping.py index 2e4baa6..976f9f2 100755 --- a/httping.py +++ b/httping.py @@ -26,29 +26,22 @@ max_ping = datetime.timedelta(milliseconds = 1000) # in seconds targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] max_ping_in_ms = max_ping.total_seconds() * 1000 +in_bin = lambda x, bin: x >= bin[0] and x <= bin[1] class Themes: # Themes are from http://colorbrewer2.org/ purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] - selected_colors = red_green + generate_bins = lambda min_val, max_val, step_width = 2: [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] + bins = generate_bins(0, int(max_ping_in_ms), int(max_ping_in_ms / (len(selected_colors) - 1))) def colorize(response_time): - # panda's "cut" functon would be an alternative here, but this would be overkill, to include numpy just for this - if response_time < max_ping_in_ms / 5: - return Themes.selected_colors[5] - elif response_time >= max_ping_in_ms / 5 and response_time < 2 * max_ping_in_ms / 5: - return Themes.selected_colors[4] - elif response_time >= 2 * max_ping_in_ms / 5 and response_time < 3 * max_ping_in_ms / 5: - return Themes.selected_colors[3] - elif response_time >= 3 * max_ping_in_ms / 5 and response_time < 4 * max_ping_in_ms / 5: - return Themes.selected_colors[2] - elif response_time >= 4 * max_ping_in_ms / 5 and response_time < max_ping_in_ms: - return Themes.selected_colors[1] - else: - return Themes.selected_colors[0] + for index, bin in enumerate(Themes.bins): + if in_bin(response_time, bin): + return Themes.selected_colors[len(Themes.selected_colors) - 1 - index] + return Themes.selected_colors[0] def httping(targets): responses = {} @@ -59,6 +52,7 @@ def httping(targets): print(str(ex), file=sys.stderr) responses[target] = None response_times = [value for key, value in responses.items() if isinstance(value, float)] + if len(response_times) > 1: return responses, statistics.median(response_times), statistics.stdev(response_times) elif len(response_times) > 0: From 3fa40d33715c39dca9caabb781788e89faa50dde Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Thu, 13 Jun 2019 04:17:07 +0200 Subject: [PATCH 06/28] Added yapf config, applied yapf --- .gitignore | 2 ++ .style.yapf | 30 ++++++++++++++++++++++++++++++ httping.py | 30 +++++++++++++++++------------- 3 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 .style.yapf diff --git a/.gitignore b/.gitignore index 894a44c..e0e3af3 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,5 @@ venv.bak/ # mypy .mypy_cache/ +/tags +/tags.* diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 0000000..5312d3a --- /dev/null +++ b/.style.yapf @@ -0,0 +1,30 @@ +[style] + +# The column limit. +column_limit=120 + +# Split before the '.' if we need to split a longer expression: +# +# foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) +# +# would reformat to something like: +# +# foo = ('This is a really long string: {}, {}, {}, {}' +# .format(a, b, c, d)) +split_before_dot=False + +# Set to True to split list comprehensions and generators that have +# non-trivial expressions and multiple clauses before each of these +# clauses. For example: +# +# result = [ +# a_long_var + 100 for a_long_var in xrange(1000) +# if a_long_var % 10] +# +# would reformat to something like: +# +# result = [ +# a_long_var + 100 +# for a_long_var in xrange(1000) +# if a_long_var % 10] +split_complex_comprehension=True diff --git a/httping.py b/httping.py index 976f9f2..3bea580 100755 --- a/httping.py +++ b/httping.py @@ -1,6 +1,5 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- - """ Simulates httping for `argos `""" # httping # v1.0 @@ -11,10 +10,11 @@ # python,requests # https://github.com/schtobia/argos-httping/blob/master/httping.py -import sys #for redirecting print to stderr -import datetime #for the whole ms → s and vice versa stuff -import requests #for the central HTTP HEAD request -import statistics #for median and stdev +import datetime # for the whole ms → s and vice versa stuff +import statistics # for median and stdev +import sys # for redirecting print to stderr + +import requests # for the central HTTP HEAD request __author__ = "Tobias Schmidl" __copyright__ = "Copyright 2018, Tobias Schmidl" @@ -22,19 +22,21 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -max_ping = datetime.timedelta(milliseconds = 1000) # in seconds +max_ping = datetime.timedelta(milliseconds=1000) # in seconds targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] max_ping_in_ms = max_ping.total_seconds() * 1000 in_bin = lambda x, bin: x >= bin[0] and x <= bin[1] + class Themes: # Themes are from http://colorbrewer2.org/ - purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] - red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] - original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] + purple_green = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] + red_green = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] + original = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] selected_colors = red_green - generate_bins = lambda min_val, max_val, step_width = 2: [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] + generate_bins = lambda min_val, max_val, step_width=2: [[x, x + step_width - 1] for x in range( + min_val, max_val, step_width)] bins = generate_bins(0, int(max_ping_in_ms), int(max_ping_in_ms / (len(selected_colors) - 1))) def colorize(response_time): @@ -43,11 +45,12 @@ class Themes: return Themes.selected_colors[len(Themes.selected_colors) - 1 - index] return Themes.selected_colors[0] + def httping(targets): responses = {} for target in targets: try: - responses[target] = requests.head(target, timeout = max_ping.total_seconds()).elapsed.total_seconds() * 1000 + responses[target] = requests.head(target, timeout=max_ping.total_seconds()).elapsed.total_seconds() * 1000 except requests.exceptions.RequestException as ex: print(str(ex), file=sys.stderr) responses[target] = None @@ -60,12 +63,13 @@ def httping(targets): else: return responses, None, None + if __name__ == "__main__": response_times, median, stddev = httping(targets) if isinstance(median, float) and median != max_ping_in_ms: - print("⦿ " + str(round(median,2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) + print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) else: - print("☠ | color=" + Themes.selected_colors[0]); + print("☠ | color=" + Themes.selected_colors[0]) print("---") for target, response_time in response_times.items(): if isinstance(response_time, float): From 1278ad984c15ea1135a15ef205772bab133bfcf2 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Thu, 13 Jun 2019 05:21:32 +0200 Subject: [PATCH 07/28] incorporated some of the findings of pylint --- httping.py | 64 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/httping.py b/httping.py index 3bea580..f462d79 100755 --- a/httping.py +++ b/httping.py @@ -22,35 +22,52 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -max_ping = datetime.timedelta(milliseconds=1000) # in seconds -targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] +MAX_PING = datetime.timedelta(milliseconds=1000) # in seconds +TARGETS = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] -max_ping_in_ms = max_ping.total_seconds() * 1000 -in_bin = lambda x, bin: x >= bin[0] and x <= bin[1] +MAX_PING_IN_MS = MAX_PING.total_seconds() * 1000 + + +def in_bucket(element, bucket): + """ Returns True if element is in bucket """ + return bucket[0] <= element <= bucket[1] + + +def generate_buckets(min_val, max_val, step_width=2): + """ Generates a list of partitioned lists between min_val and max_val.""" + return [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] class Themes: + """Maintains a list of themes and generates buckets between 0 and MAX_PING_IN_MS based on the selected theme.""" # Themes are from http://colorbrewer2.org/ purple_green = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] red_green = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] original = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] - selected_colors = red_green - generate_bins = lambda min_val, max_val, step_width=2: [[x, x + step_width - 1] for x in range( - min_val, max_val, step_width)] - bins = generate_bins(0, int(max_ping_in_ms), int(max_ping_in_ms / (len(selected_colors) - 1))) + selected_colors = None + buckets = None - def colorize(response_time): - for index, bin in enumerate(Themes.bins): - if in_bin(response_time, bin): - return Themes.selected_colors[len(Themes.selected_colors) - 1 - index] - return Themes.selected_colors[0] + def __init__(self, selected_colors): + self.selected_colors = selected_colors + self.buckets = generate_buckets(0, int(MAX_PING_IN_MS), int(MAX_PING_IN_MS / (len(selected_colors) - 1))) + + def colorize(self, input_text): + """Colorized the current input according to the selected theme.""" + for index, current_bucket in enumerate(self.buckets): + if in_bucket(input_text, current_bucket): + return self.selected_colors[len(self.selected_colors) - 1 - index] + return self.selected_colors[0] + + +CURRENT_THEME = Themes(Themes.red_green) def httping(targets): + """Pings the supplied targets and returns a mean and a std deviation over all target responses.""" responses = {} for target in targets: try: - responses[target] = requests.head(target, timeout=max_ping.total_seconds()).elapsed.total_seconds() * 1000 + responses[target] = requests.head(target, timeout=MAX_PING.total_seconds()).elapsed.total_seconds() * 1000 except requests.exceptions.RequestException as ex: print(str(ex), file=sys.stderr) responses[target] = None @@ -58,21 +75,22 @@ def httping(targets): if len(response_times) > 1: return responses, statistics.median(response_times), statistics.stdev(response_times) - elif len(response_times) > 0: + elif response_times: return responses, response_times[0], 0 else: return responses, None, None if __name__ == "__main__": - response_times, median, stddev = httping(targets) - if isinstance(median, float) and median != max_ping_in_ms: - print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) + responses, median, stddev = httping(TARGETS) + if isinstance(median, float) and median != MAX_PING_IN_MS: + print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + CURRENT_THEME.colorize(median)) else: - print("☠ | color=" + Themes.selected_colors[0]) + print("☠ | color=" + CURRENT_THEME.selected_colors[0]) print("---") - for target, response_time in response_times.items(): - if isinstance(response_time, float): - print(target + ": " + str(round(response_time, 2)) + " | color=" + Themes.colorize(response_time)) + for current_host, current_response in responses.items(): + if isinstance(current_response, float): + print(current_host + ": " + str(round(current_response, 2)) + " | color=" + + CURRENT_THEME.colorize(current_response)) else: - print(target + ": ☠ | color=" + Themes.selected_colors[0]) + print(current_host + ": ☠ | color=" + CURRENT_THEME.selected_colors[0]) From 9a096252c43918f01b998f0846fc27a49757009d Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Thu, 13 Jun 2019 05:45:09 +0200 Subject: [PATCH 08/28] added first draft --- httping.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/httping.py b/httping.py index f462d79..618b830 100755 --- a/httping.py +++ b/httping.py @@ -15,6 +15,8 @@ import statistics # for median and stdev import sys # for redirecting print to stderr import requests # for the central HTTP HEAD request +from typing import (List) +from __future__ import annotations __author__ = "Tobias Schmidl" __copyright__ = "Copyright 2018, Tobias Schmidl" @@ -22,10 +24,10 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -MAX_PING = datetime.timedelta(milliseconds=1000) # in seconds -TARGETS = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] +MAX_PING: int = datetime.timedelta(milliseconds=1000) # in seconds +TARGETS: List[str] = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] -MAX_PING_IN_MS = MAX_PING.total_seconds() * 1000 +MAX_PING_IN_MS: int = MAX_PING.total_seconds() * 1000 def in_bucket(element, bucket): From 1dd63d542e202ba2041e40d83860c1da30af9799 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Fri, 19 Jul 2019 06:54:40 +0200 Subject: [PATCH 09/28] Extended type annotations --- httping.py | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/httping.py b/httping.py index 618b830..80f5164 100755 --- a/httping.py +++ b/httping.py @@ -1,5 +1,6 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- + """ Simulates httping for `argos `""" # httping # v1.0 @@ -10,13 +11,14 @@ # python,requests # https://github.com/schtobia/argos-httping/blob/master/httping.py +from __future__ import annotations + import datetime # for the whole ms → s and vice versa stuff import statistics # for median and stdev import sys # for redirecting print to stderr +from typing import Generic, List, Sequence, TypeVar, Optional, Tuple, Dict, Union import requests # for the central HTTP HEAD request -from typing import (List) -from __future__ import annotations __author__ = "Tobias Schmidl" __copyright__ = "Copyright 2018, Tobias Schmidl" @@ -24,30 +26,34 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -MAX_PING: int = datetime.timedelta(milliseconds=1000) # in seconds +MAX_PING: datetime.timedelta = datetime.timedelta(milliseconds=1000) # in seconds TARGETS: List[str] = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] -MAX_PING_IN_MS: int = MAX_PING.total_seconds() * 1000 +T = TypeVar('T') +Bucket = Tuple[int, int] +BucketList = List[Bucket] + +MAX_PING_IN_MS: int = int(MAX_PING.total_seconds() * 1000) -def in_bucket(element, bucket): +def in_bucket(element: int, bucket: Bucket) -> bool: """ Returns True if element is in bucket """ return bucket[0] <= element <= bucket[1] -def generate_buckets(min_val, max_val, step_width=2): +def generate_buckets(min_val: int, max_val: int, step_width: int = 2) -> BucketList: """ Generates a list of partitioned lists between min_val and max_val.""" - return [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] + return [(x, x + step_width - 1) for x in range(min_val, max_val, step_width)] class Themes: """Maintains a list of themes and generates buckets between 0 and MAX_PING_IN_MS based on the selected theme.""" # Themes are from http://colorbrewer2.org/ - purple_green = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] - red_green = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] - original = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] - selected_colors = None - buckets = None + purple_green: List[str] = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] + red_green: List[str] = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] + original: List[str] = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] + selected_colors: List[str] = [] + buckets: BucketList = [] def __init__(self, selected_colors): self.selected_colors = selected_colors @@ -61,12 +67,12 @@ class Themes: return self.selected_colors[0] -CURRENT_THEME = Themes(Themes.red_green) +CURRENT_THEME: Themes = Themes(Themes.red_green) -def httping(targets): +def httping(targets: List[str]) -> Tuple[Dict[str, Optional[float]], Optional[float], Optional[float]]: """Pings the supplied targets and returns a mean and a std deviation over all target responses.""" - responses = {} + responses : Dict[str, Optional[float]] = {} for target in targets: try: responses[target] = requests.head(target, timeout=MAX_PING.total_seconds()).elapsed.total_seconds() * 1000 @@ -86,7 +92,7 @@ def httping(targets): if __name__ == "__main__": responses, median, stddev = httping(TARGETS) if isinstance(median, float) and median != MAX_PING_IN_MS: - print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + CURRENT_THEME.colorize(median)) + print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + CURRENT_THEME.colorize(median)) # type: ignore else: print("☠ | color=" + CURRENT_THEME.selected_colors[0]) print("---") From fde2556e47b8f3990f1e82cbfb8d7d688df37646 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Fri, 19 Jul 2019 06:54:59 +0200 Subject: [PATCH 10/28] added pylama.ini, extended style.yapf --- .style.yapf | 5 ++++- pylama.ini | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 pylama.ini diff --git a/.style.yapf b/.style.yapf index 5312d3a..b34c3f4 100644 --- a/.style.yapf +++ b/.style.yapf @@ -1,5 +1,8 @@ [style] +# Insert a blank line before a module docstring. +blank_line_before_module_docstring=True + # The column limit. column_limit=120 @@ -11,7 +14,7 @@ column_limit=120 # # foo = ('This is a really long string: {}, {}, {}, {}' # .format(a, b, c, d)) -split_before_dot=False +split_before_dot=True # Set to True to split list comprehensions and generators that have # non-trivial expressions and multiple clauses before each of these diff --git a/pylama.ini b/pylama.ini new file mode 100644 index 0000000..5f09266 --- /dev/null +++ b/pylama.ini @@ -0,0 +1,15 @@ +[pylama] +format = pylint +linters = mccabe,pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,isort,mypy +ignore = D203 +skip=.env/* + +[pylama:pycodestyle] +max_line_length = 120 + +[pylama:pep8] +max_line_length = 120 + +[pylama:pylint] +max_line_length = 120 + From e1d2ed99902a640a5408c5c7a9f4f92749767294 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Fri, 19 Jul 2019 06:58:24 +0200 Subject: [PATCH 11/28] fixup! Extended type annotations --- httping.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/httping.py b/httping.py index 80f5164..8b81fd5 100755 --- a/httping.py +++ b/httping.py @@ -72,7 +72,7 @@ CURRENT_THEME: Themes = Themes(Themes.red_green) def httping(targets: List[str]) -> Tuple[Dict[str, Optional[float]], Optional[float], Optional[float]]: """Pings the supplied targets and returns a mean and a std deviation over all target responses.""" - responses : Dict[str, Optional[float]] = {} + responses: Dict[str, Optional[float]] = {} for target in targets: try: responses[target] = requests.head(target, timeout=MAX_PING.total_seconds()).elapsed.total_seconds() * 1000 @@ -92,7 +92,8 @@ def httping(targets: List[str]) -> Tuple[Dict[str, Optional[float]], Optional[fl if __name__ == "__main__": responses, median, stddev = httping(TARGETS) if isinstance(median, float) and median != MAX_PING_IN_MS: - print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + CURRENT_THEME.colorize(median)) # type: ignore + print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + + CURRENT_THEME.colorize(median)) # type: ignore else: print("☠ | color=" + CURRENT_THEME.selected_colors[0]) print("---") From 3a8c260b8cbb1785839a2098ed7bd439e361d92c Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:03 +0200 Subject: [PATCH 12/28] Added ping.1m+.py --- ping.1m+.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 ping.1m+.py diff --git a/ping.1m+.py b/ping.1m+.py new file mode 100755 index 0000000..f8e92ec --- /dev/null +++ b/ping.1m+.py @@ -0,0 +1,74 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" Simulates httping for `argos `""" + +import sys #for redirecting print to stderr +import datetime #for the whole ms → s and vice versa stuff +import requests #for the central HTTP HEAD request +import statistics #for median and stdev + +__author__ = "Tobias Schmidl" +__copyright__ = "Copyright 2018, Tobias Schmidl" +__license__ = "MIT" +__version__ = "0.0.1" +__maintainer__ = "Tobias Schmidl" + +# in seconds +max_ping = datetime.timedelta(milliseconds = 1000) +targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org" ] + +max_ping_in_ms = max_ping.total_seconds() * 1000 + +class Themes: + purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] + red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] +# shellcheck disable=SC2034 + original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] + +# Configuration + selected_colors = red_green + + def colorize(response_time): + # panda's "cut" functon would be an alternative here, but this would be overkill, to include numpy just for this + if response_time < max_ping_in_ms / 5: + return Themes.selected_colors[5] + elif response_time >= max_ping_in_ms / 5 and response_time < 2 * max_ping_in_ms / 5: + return Themes.selected_colors[4] + elif response_time >= 2 * max_ping_in_ms / 5 and response_time < 3 * max_ping_in_ms / 5: + return Themes.selected_colors[3] + elif response_time >= 3 * max_ping_in_ms / 5 and response_time < 4 * max_ping_in_ms / 5: + return Themes.selected_colors[2] + elif response_time >= 4 * max_ping_in_ms / 5 and response_time < max_ping_in_ms: + return Themes.selected_colors[1] + else: + return Themes.selected_colors[0] + +def httping(targets): + responses = {} + for target in targets: + try: + responses[target] = requests.head(target, timeout = max_ping.total_seconds()).elapsed.total_seconds() * 1000 + except requests.exceptions.RequestException as ex: + print(str(ex), file=sys.stderr) + responses[target] = None + response_times = [value for key, value in responses.items() if isinstance(value, float)] + if len(response_times) > 1: + return responses, statistics.median(response_times), statistics.stdev(response_times) + elif len(response_times) > 0: + return responses, response_times[0], 0 + else: + return responses, None, None + +if __name__ == "__main__": + response_times, median, stddev = httping(targets) + if isinstance(median, float) and median != max_ping_in_ms: + print("⦿ " + str(round(median,2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) + else: + print("☠ | color=" + Themes.selected_colors[0]); + print("---") + for target, response_time in response_times.items(): + if isinstance(response_time, float): + print(target + ": " + str(round(response_time, 2)) + " | color=" + Themes.colorize(response_time)) + else: + print(target + ": ☠ | color=" + Themes.selected_colors[0]) From 34a9fd6d40537d20b9d2d56a1dabaa403d835803 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:06 +0200 Subject: [PATCH 13/28] Added metadata for bitbar --- ping.1m+.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ping.1m+.py b/ping.1m+.py index f8e92ec..2d96472 100755 --- a/ping.1m+.py +++ b/ping.1m+.py @@ -2,6 +2,14 @@ # -*- coding: utf-8 -*- """ Simulates httping for `argos `""" +# httping +# v1.0 +# Tobias Schmidl +# schtobia +# Short description of what your plugin does. +# +# python,requests +# https://github.com/schtobia/argos-httping/blob/master/ping.1m+.py import sys #for redirecting print to stderr import datetime #for the whole ms → s and vice versa stuff @@ -14,19 +22,17 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -# in seconds -max_ping = datetime.timedelta(milliseconds = 1000) -targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org" ] +max_ping = datetime.timedelta(milliseconds = 1000) # in seconds +targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] max_ping_in_ms = max_ping.total_seconds() * 1000 class Themes: + # Themes are from http://colorbrewer2.org/ purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] -# shellcheck disable=SC2034 original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] -# Configuration selected_colors = red_green def colorize(response_time): From 5a91c8c9411e1eef014ebd22f04954f0de0cd44a Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:08 +0200 Subject: [PATCH 14/28] Added requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8f94722 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +requests>=2.5.0 From d0cede777192037bd21739f7045c53756ce48f31 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:11 +0200 Subject: [PATCH 15/28] moved ping.1m+.py --> httping.py --- ping.1m+.py => httping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename ping.1m+.py => httping.py (98%) diff --git a/ping.1m+.py b/httping.py similarity index 98% rename from ping.1m+.py rename to httping.py index 2d96472..2e4baa6 100755 --- a/ping.1m+.py +++ b/httping.py @@ -9,7 +9,7 @@ # Short description of what your plugin does. # # python,requests -# https://github.com/schtobia/argos-httping/blob/master/ping.1m+.py +# https://github.com/schtobia/argos-httping/blob/master/httping.py import sys #for redirecting print to stderr import datetime #for the whole ms → s and vice versa stuff From 98fb0be057ce3b61050e684a296a377b6e0a025a Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:13 +0200 Subject: [PATCH 16/28] Replace the if switch with a lambda and a for loop --- httping.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/httping.py b/httping.py index 2e4baa6..976f9f2 100755 --- a/httping.py +++ b/httping.py @@ -26,29 +26,22 @@ max_ping = datetime.timedelta(milliseconds = 1000) # in seconds targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] max_ping_in_ms = max_ping.total_seconds() * 1000 +in_bin = lambda x, bin: x >= bin[0] and x <= bin[1] class Themes: # Themes are from http://colorbrewer2.org/ purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] - selected_colors = red_green + generate_bins = lambda min_val, max_val, step_width = 2: [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] + bins = generate_bins(0, int(max_ping_in_ms), int(max_ping_in_ms / (len(selected_colors) - 1))) def colorize(response_time): - # panda's "cut" functon would be an alternative here, but this would be overkill, to include numpy just for this - if response_time < max_ping_in_ms / 5: - return Themes.selected_colors[5] - elif response_time >= max_ping_in_ms / 5 and response_time < 2 * max_ping_in_ms / 5: - return Themes.selected_colors[4] - elif response_time >= 2 * max_ping_in_ms / 5 and response_time < 3 * max_ping_in_ms / 5: - return Themes.selected_colors[3] - elif response_time >= 3 * max_ping_in_ms / 5 and response_time < 4 * max_ping_in_ms / 5: - return Themes.selected_colors[2] - elif response_time >= 4 * max_ping_in_ms / 5 and response_time < max_ping_in_ms: - return Themes.selected_colors[1] - else: - return Themes.selected_colors[0] + for index, bin in enumerate(Themes.bins): + if in_bin(response_time, bin): + return Themes.selected_colors[len(Themes.selected_colors) - 1 - index] + return Themes.selected_colors[0] def httping(targets): responses = {} @@ -59,6 +52,7 @@ def httping(targets): print(str(ex), file=sys.stderr) responses[target] = None response_times = [value for key, value in responses.items() if isinstance(value, float)] + if len(response_times) > 1: return responses, statistics.median(response_times), statistics.stdev(response_times) elif len(response_times) > 0: From cd2bd2771151da7c4fad8377a075afbbef73ed18 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:15 +0200 Subject: [PATCH 17/28] Added yapf config, applied yapf --- .gitignore | 2 ++ .style.yapf | 30 ++++++++++++++++++++++++++++++ httping.py | 30 +++++++++++++++++------------- 3 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 .style.yapf diff --git a/.gitignore b/.gitignore index 894a44c..e0e3af3 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,5 @@ venv.bak/ # mypy .mypy_cache/ +/tags +/tags.* diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 0000000..5312d3a --- /dev/null +++ b/.style.yapf @@ -0,0 +1,30 @@ +[style] + +# The column limit. +column_limit=120 + +# Split before the '.' if we need to split a longer expression: +# +# foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) +# +# would reformat to something like: +# +# foo = ('This is a really long string: {}, {}, {}, {}' +# .format(a, b, c, d)) +split_before_dot=False + +# Set to True to split list comprehensions and generators that have +# non-trivial expressions and multiple clauses before each of these +# clauses. For example: +# +# result = [ +# a_long_var + 100 for a_long_var in xrange(1000) +# if a_long_var % 10] +# +# would reformat to something like: +# +# result = [ +# a_long_var + 100 +# for a_long_var in xrange(1000) +# if a_long_var % 10] +split_complex_comprehension=True diff --git a/httping.py b/httping.py index 976f9f2..3bea580 100755 --- a/httping.py +++ b/httping.py @@ -1,6 +1,5 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- - """ Simulates httping for `argos `""" # httping # v1.0 @@ -11,10 +10,11 @@ # python,requests # https://github.com/schtobia/argos-httping/blob/master/httping.py -import sys #for redirecting print to stderr -import datetime #for the whole ms → s and vice versa stuff -import requests #for the central HTTP HEAD request -import statistics #for median and stdev +import datetime # for the whole ms → s and vice versa stuff +import statistics # for median and stdev +import sys # for redirecting print to stderr + +import requests # for the central HTTP HEAD request __author__ = "Tobias Schmidl" __copyright__ = "Copyright 2018, Tobias Schmidl" @@ -22,19 +22,21 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -max_ping = datetime.timedelta(milliseconds = 1000) # in seconds +max_ping = datetime.timedelta(milliseconds=1000) # in seconds targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] max_ping_in_ms = max_ping.total_seconds() * 1000 in_bin = lambda x, bin: x >= bin[0] and x <= bin[1] + class Themes: # Themes are from http://colorbrewer2.org/ - purple_green = ["#762a83", "#9970ab","#c2a5cf","#a6dba0","#5aae61","#1b7837"] - red_green = ["#d73027", "#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"] - original = ["#acacac","#ff0101","#cc673b","#ce8458","#6bbb15","#0ed812"] + purple_green = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] + red_green = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] + original = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] selected_colors = red_green - generate_bins = lambda min_val, max_val, step_width = 2: [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] + generate_bins = lambda min_val, max_val, step_width=2: [[x, x + step_width - 1] for x in range( + min_val, max_val, step_width)] bins = generate_bins(0, int(max_ping_in_ms), int(max_ping_in_ms / (len(selected_colors) - 1))) def colorize(response_time): @@ -43,11 +45,12 @@ class Themes: return Themes.selected_colors[len(Themes.selected_colors) - 1 - index] return Themes.selected_colors[0] + def httping(targets): responses = {} for target in targets: try: - responses[target] = requests.head(target, timeout = max_ping.total_seconds()).elapsed.total_seconds() * 1000 + responses[target] = requests.head(target, timeout=max_ping.total_seconds()).elapsed.total_seconds() * 1000 except requests.exceptions.RequestException as ex: print(str(ex), file=sys.stderr) responses[target] = None @@ -60,12 +63,13 @@ def httping(targets): else: return responses, None, None + if __name__ == "__main__": response_times, median, stddev = httping(targets) if isinstance(median, float) and median != max_ping_in_ms: - print("⦿ " + str(round(median,2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) + print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) else: - print("☠ | color=" + Themes.selected_colors[0]); + print("☠ | color=" + Themes.selected_colors[0]) print("---") for target, response_time in response_times.items(): if isinstance(response_time, float): From 17ecea90fabf755de784c9d051ea6142e6d16b51 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:17 +0200 Subject: [PATCH 18/28] incorporated some of the findings of pylint --- httping.py | 64 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/httping.py b/httping.py index 3bea580..f462d79 100755 --- a/httping.py +++ b/httping.py @@ -22,35 +22,52 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -max_ping = datetime.timedelta(milliseconds=1000) # in seconds -targets = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] +MAX_PING = datetime.timedelta(milliseconds=1000) # in seconds +TARGETS = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] -max_ping_in_ms = max_ping.total_seconds() * 1000 -in_bin = lambda x, bin: x >= bin[0] and x <= bin[1] +MAX_PING_IN_MS = MAX_PING.total_seconds() * 1000 + + +def in_bucket(element, bucket): + """ Returns True if element is in bucket """ + return bucket[0] <= element <= bucket[1] + + +def generate_buckets(min_val, max_val, step_width=2): + """ Generates a list of partitioned lists between min_val and max_val.""" + return [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] class Themes: + """Maintains a list of themes and generates buckets between 0 and MAX_PING_IN_MS based on the selected theme.""" # Themes are from http://colorbrewer2.org/ purple_green = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] red_green = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] original = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] - selected_colors = red_green - generate_bins = lambda min_val, max_val, step_width=2: [[x, x + step_width - 1] for x in range( - min_val, max_val, step_width)] - bins = generate_bins(0, int(max_ping_in_ms), int(max_ping_in_ms / (len(selected_colors) - 1))) + selected_colors = None + buckets = None - def colorize(response_time): - for index, bin in enumerate(Themes.bins): - if in_bin(response_time, bin): - return Themes.selected_colors[len(Themes.selected_colors) - 1 - index] - return Themes.selected_colors[0] + def __init__(self, selected_colors): + self.selected_colors = selected_colors + self.buckets = generate_buckets(0, int(MAX_PING_IN_MS), int(MAX_PING_IN_MS / (len(selected_colors) - 1))) + + def colorize(self, input_text): + """Colorized the current input according to the selected theme.""" + for index, current_bucket in enumerate(self.buckets): + if in_bucket(input_text, current_bucket): + return self.selected_colors[len(self.selected_colors) - 1 - index] + return self.selected_colors[0] + + +CURRENT_THEME = Themes(Themes.red_green) def httping(targets): + """Pings the supplied targets and returns a mean and a std deviation over all target responses.""" responses = {} for target in targets: try: - responses[target] = requests.head(target, timeout=max_ping.total_seconds()).elapsed.total_seconds() * 1000 + responses[target] = requests.head(target, timeout=MAX_PING.total_seconds()).elapsed.total_seconds() * 1000 except requests.exceptions.RequestException as ex: print(str(ex), file=sys.stderr) responses[target] = None @@ -58,21 +75,22 @@ def httping(targets): if len(response_times) > 1: return responses, statistics.median(response_times), statistics.stdev(response_times) - elif len(response_times) > 0: + elif response_times: return responses, response_times[0], 0 else: return responses, None, None if __name__ == "__main__": - response_times, median, stddev = httping(targets) - if isinstance(median, float) and median != max_ping_in_ms: - print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + Themes.colorize(median)) + responses, median, stddev = httping(TARGETS) + if isinstance(median, float) and median != MAX_PING_IN_MS: + print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + CURRENT_THEME.colorize(median)) else: - print("☠ | color=" + Themes.selected_colors[0]) + print("☠ | color=" + CURRENT_THEME.selected_colors[0]) print("---") - for target, response_time in response_times.items(): - if isinstance(response_time, float): - print(target + ": " + str(round(response_time, 2)) + " | color=" + Themes.colorize(response_time)) + for current_host, current_response in responses.items(): + if isinstance(current_response, float): + print(current_host + ": " + str(round(current_response, 2)) + " | color=" + + CURRENT_THEME.colorize(current_response)) else: - print(target + ": ☠ | color=" + Themes.selected_colors[0]) + print(current_host + ": ☠ | color=" + CURRENT_THEME.selected_colors[0]) From bdb0fd33cc1c434abae5f33a8f61ff53f86f5fde Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:19 +0200 Subject: [PATCH 19/28] Used pylama.ini from other project --- .style.yapf | 5 ++++- httping.py | 11 +++++++---- pylama.ini | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 pylama.ini diff --git a/.style.yapf b/.style.yapf index 5312d3a..b34c3f4 100644 --- a/.style.yapf +++ b/.style.yapf @@ -1,5 +1,8 @@ [style] +# Insert a blank line before a module docstring. +blank_line_before_module_docstring=True + # The column limit. column_limit=120 @@ -11,7 +14,7 @@ column_limit=120 # # foo = ('This is a really long string: {}, {}, {}, {}' # .format(a, b, c, d)) -split_before_dot=False +split_before_dot=True # Set to True to split list comprehensions and generators that have # non-trivial expressions and multiple clauses before each of these diff --git a/httping.py b/httping.py index f462d79..a8d255d 100755 --- a/httping.py +++ b/httping.py @@ -1,6 +1,7 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- -""" Simulates httping for `argos `""" + +"""Simulates httping for `argos `.""" # httping # v1.0 # Tobias Schmidl @@ -29,17 +30,18 @@ MAX_PING_IN_MS = MAX_PING.total_seconds() * 1000 def in_bucket(element, bucket): - """ Returns True if element is in bucket """ + """Return True if element is in bucket.""" return bucket[0] <= element <= bucket[1] def generate_buckets(min_val, max_val, step_width=2): - """ Generates a list of partitioned lists between min_val and max_val.""" + """Generate a list of partitioned lists between min_val and max_val.""" return [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] class Themes: - """Maintains a list of themes and generates buckets between 0 and MAX_PING_IN_MS based on the selected theme.""" + """Maintain a list of themes and generates buckets between 0 and MAX_PING_IN_MS based on the selected theme.""" + # Themes are from http://colorbrewer2.org/ purple_green = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] red_green = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] @@ -48,6 +50,7 @@ class Themes: buckets = None def __init__(self, selected_colors): + """Initialize class with a selected theme.""" self.selected_colors = selected_colors self.buckets = generate_buckets(0, int(MAX_PING_IN_MS), int(MAX_PING_IN_MS / (len(selected_colors) - 1))) diff --git a/pylama.ini b/pylama.ini new file mode 100644 index 0000000..b7f11e2 --- /dev/null +++ b/pylama.ini @@ -0,0 +1,15 @@ +[pylama] +format = pylint +linters = mccabe,pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,isort +ignore = D203 +skip=.env/* + +[pylama:pycodestyle] +max_line_length = 120 + +[pylama:pep8] +max_line_length = 120 + +[pylama:pylint] +max_line_length = 120 + From fbcfafdac3d3c6efef38e3d14c9a29b0237bf9b1 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:22 +0200 Subject: [PATCH 20/28] added first draft --- httping.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/httping.py b/httping.py index a8d255d..eca53cc 100755 --- a/httping.py +++ b/httping.py @@ -16,6 +16,8 @@ import statistics # for median and stdev import sys # for redirecting print to stderr import requests # for the central HTTP HEAD request +from typing import (List) +from __future__ import annotations __author__ = "Tobias Schmidl" __copyright__ = "Copyright 2018, Tobias Schmidl" @@ -23,10 +25,10 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -MAX_PING = datetime.timedelta(milliseconds=1000) # in seconds -TARGETS = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] +MAX_PING: int = datetime.timedelta(milliseconds=1000) # in seconds +TARGETS: List[str] = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] -MAX_PING_IN_MS = MAX_PING.total_seconds() * 1000 +MAX_PING_IN_MS: int = MAX_PING.total_seconds() * 1000 def in_bucket(element, bucket): From 26010092b987ecfcd77c9d966915c3a01e4681fe Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:24 +0200 Subject: [PATCH 21/28] Extended type annotations --- httping.py | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/httping.py b/httping.py index eca53cc..40555cd 100755 --- a/httping.py +++ b/httping.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- """Simulates httping for `argos `.""" + # httping # v1.0 # Tobias Schmidl @@ -11,13 +12,14 @@ # python,requests # https://github.com/schtobia/argos-httping/blob/master/httping.py +from __future__ import annotations + import datetime # for the whole ms → s and vice versa stuff import statistics # for median and stdev import sys # for redirecting print to stderr +from typing import Generic, List, Sequence, TypeVar, Optional, Tuple, Dict, Union import requests # for the central HTTP HEAD request -from typing import (List) -from __future__ import annotations __author__ = "Tobias Schmidl" __copyright__ = "Copyright 2018, Tobias Schmidl" @@ -25,31 +27,35 @@ __license__ = "MIT" __version__ = "0.0.1" __maintainer__ = "Tobias Schmidl" -MAX_PING: int = datetime.timedelta(milliseconds=1000) # in seconds +MAX_PING: datetime.timedelta = datetime.timedelta(milliseconds=1000) # in seconds TARGETS: List[str] = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] -MAX_PING_IN_MS: int = MAX_PING.total_seconds() * 1000 +T = TypeVar('T') +Bucket = Tuple[int, int] +BucketList = List[Bucket] + +MAX_PING_IN_MS: int = int(MAX_PING.total_seconds() * 1000) -def in_bucket(element, bucket): +def in_bucket(element: int, bucket: Bucket) -> bool: """Return True if element is in bucket.""" return bucket[0] <= element <= bucket[1] -def generate_buckets(min_val, max_val, step_width=2): +def generate_buckets(min_val: int, max_val: int, step_width: int = 2) -> BucketList: """Generate a list of partitioned lists between min_val and max_val.""" - return [[x, x + step_width - 1] for x in range(min_val, max_val, step_width)] + return [(x, x + step_width - 1) for x in range(min_val, max_val, step_width)] class Themes: """Maintain a list of themes and generates buckets between 0 and MAX_PING_IN_MS based on the selected theme.""" # Themes are from http://colorbrewer2.org/ - purple_green = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] - red_green = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] - original = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] - selected_colors = None - buckets = None + purple_green: List[str] = ["#762a83", "#9970ab", "#c2a5cf", "#a6dba0", "#5aae61", "#1b7837"] + red_green: List[str] = ["#d73027", "#fc8d59", "#fee08b", "#d9ef8b", "#91cf60", "#1a9850"] + original: List[str] = ["#acacac", "#ff0101", "#cc673b", "#ce8458", "#6bbb15", "#0ed812"] + selected_colors: List[str] = [] + buckets: BucketList = [] def __init__(self, selected_colors): """Initialize class with a selected theme.""" @@ -64,12 +70,12 @@ class Themes: return self.selected_colors[0] -CURRENT_THEME = Themes(Themes.red_green) +CURRENT_THEME: Themes = Themes(Themes.red_green) -def httping(targets): +def httping(targets: List[str]) -> Tuple[Dict[str, Optional[float]], Optional[float], Optional[float]]: """Pings the supplied targets and returns a mean and a std deviation over all target responses.""" - responses = {} + responses: Dict[str, Optional[float]] = {} for target in targets: try: responses[target] = requests.head(target, timeout=MAX_PING.total_seconds()).elapsed.total_seconds() * 1000 @@ -89,7 +95,8 @@ def httping(targets): if __name__ == "__main__": responses, median, stddev = httping(TARGETS) if isinstance(median, float) and median != MAX_PING_IN_MS: - print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + CURRENT_THEME.colorize(median)) + print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + + CURRENT_THEME.colorize(median)) # type: ignore else: print("☠ | color=" + CURRENT_THEME.selected_colors[0]) print("---") From 07fd54dfcaf0c5f8d6e497d6c70586ec0be97a73 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:26 +0200 Subject: [PATCH 22/28] added pylama.ini, extended style.yapf --- pylama.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pylama.ini b/pylama.ini index b7f11e2..5f3e097 100644 --- a/pylama.ini +++ b/pylama.ini @@ -1,6 +1,6 @@ [pylama] format = pylint -linters = mccabe,pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,isort +linters = mccabe,pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,isort,mypy ignore = D203 skip=.env/* @@ -12,4 +12,3 @@ max_line_length = 120 [pylama:pylint] max_line_length = 120 - From a95fc1ace0e63f4c9ce2a12e2c000a309c63e90f Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:28 +0200 Subject: [PATCH 23/28] fixed a few pylint warnings --- httping.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/httping.py b/httping.py index 40555cd..147d757 100755 --- a/httping.py +++ b/httping.py @@ -17,7 +17,7 @@ from __future__ import annotations import datetime # for the whole ms → s and vice versa stuff import statistics # for median and stdev import sys # for redirecting print to stderr -from typing import Generic, List, Sequence, TypeVar, Optional, Tuple, Dict, Union +from typing import Dict, List, Optional, Tuple import requests # for the central HTTP HEAD request @@ -30,7 +30,6 @@ __maintainer__ = "Tobias Schmidl" MAX_PING: datetime.timedelta = datetime.timedelta(milliseconds=1000) # in seconds TARGETS: List[str] = ["https://www.google.de", "https://www.bing.com", "https://www.wikipedia.org"] -T = TypeVar('T') Bucket = Tuple[int, int] BucketList = List[Bucket] From 9bfa8f62fc6afdd0c87f1fb4ee9a18b096d42560 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 21 Sep 2020 08:10:31 +0200 Subject: [PATCH 24/28] Panel space is valuable! --- httping.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/httping.py b/httping.py index 147d757..8028f62 100755 --- a/httping.py +++ b/httping.py @@ -94,8 +94,7 @@ def httping(targets: List[str]) -> Tuple[Dict[str, Optional[float]], Optional[fl if __name__ == "__main__": responses, median, stddev = httping(TARGETS) if isinstance(median, float) and median != MAX_PING_IN_MS: - print("⦿ " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + - CURRENT_THEME.colorize(median)) # type: ignore + print("⦿ | color=" + CURRENT_THEME.colorize(median)) # type: ignore else: print("☠ | color=" + CURRENT_THEME.selected_colors[0]) print("---") @@ -105,3 +104,6 @@ if __name__ == "__main__": CURRENT_THEME.colorize(current_response)) else: print(current_host + ": ☠ | color=" + CURRENT_THEME.selected_colors[0]) + print("---") + print("Average: " + str(round(median, 2)) + "±" + str(round(stddev, 2)) + " | color=" + + CURRENT_THEME.colorize(median)) From f67825e76ceec29c38efa1ce444567e634c6c80b Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Fri, 12 Feb 2021 06:58:50 +0100 Subject: [PATCH 25/28] moved scaffolding files to .pscaffold --- .gitignore | 107 +------------------------------------------------ .gitlab-ci.yml | 22 ++++++++++ .gitmodules | 3 ++ .pscaffold | 1 + .style.yapf | 34 +--------------- pylama.ini | 15 +------ 6 files changed, 29 insertions(+), 153 deletions(-) mode change 100644 => 120000 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .gitmodules create mode 160000 .pscaffold mode change 100644 => 120000 .style.yapf mode change 100644 => 120000 pylama.ini diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e0e3af3..0000000 --- a/.gitignore +++ /dev/null @@ -1,106 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -/tags -/tags.* diff --git a/.gitignore b/.gitignore new file mode 120000 index 0000000..c803af3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.pscaffold/.gitignore \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..3a1d417 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,22 @@ +image: python:alpine + +test:pylama: + stage: test + only: + - master + - develop + before_script: + - if test -r requirements.txt; then pip install -r requirements.txt; fi + script: + if test -x "$(which pylama)"; then pylama *.py; fi + +test:pytest: + stage: test + only: + - master + - develop + before_script: + - if test -r requirements.txt; then pip install -r requirements.txt; fi + script: + if test -x "$(which pytest)"; then pytest .; fi + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..09ac888 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".pscaffold"] + path = .pscaffold + url = ../pscaffold.git diff --git a/.pscaffold b/.pscaffold new file mode 160000 index 0000000..c853254 --- /dev/null +++ b/.pscaffold @@ -0,0 +1 @@ +Subproject commit c8532548825b9f01601e096e8286ee011dbfac8e diff --git a/.style.yapf b/.style.yapf deleted file mode 100644 index b34c3f4..0000000 --- a/.style.yapf +++ /dev/null @@ -1,33 +0,0 @@ -[style] - -# Insert a blank line before a module docstring. -blank_line_before_module_docstring=True - -# The column limit. -column_limit=120 - -# Split before the '.' if we need to split a longer expression: -# -# foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) -# -# would reformat to something like: -# -# foo = ('This is a really long string: {}, {}, {}, {}' -# .format(a, b, c, d)) -split_before_dot=True - -# Set to True to split list comprehensions and generators that have -# non-trivial expressions and multiple clauses before each of these -# clauses. For example: -# -# result = [ -# a_long_var + 100 for a_long_var in xrange(1000) -# if a_long_var % 10] -# -# would reformat to something like: -# -# result = [ -# a_long_var + 100 -# for a_long_var in xrange(1000) -# if a_long_var % 10] -split_complex_comprehension=True diff --git a/.style.yapf b/.style.yapf new file mode 120000 index 0000000..e4269e9 --- /dev/null +++ b/.style.yapf @@ -0,0 +1 @@ +.pscaffold/.style.yapf \ No newline at end of file diff --git a/pylama.ini b/pylama.ini deleted file mode 100644 index 5f3e097..0000000 --- a/pylama.ini +++ /dev/null @@ -1,14 +0,0 @@ -[pylama] -format = pylint -linters = mccabe,pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,isort,mypy -ignore = D203 -skip=.env/* - -[pylama:pycodestyle] -max_line_length = 120 - -[pylama:pep8] -max_line_length = 120 - -[pylama:pylint] -max_line_length = 120 diff --git a/pylama.ini b/pylama.ini new file mode 120000 index 0000000..9ad5e0b --- /dev/null +++ b/pylama.ini @@ -0,0 +1 @@ +.pscaffold/pylama.ini \ No newline at end of file From 074cfbf84632d54346aa5a0a6c5906d1f7087b1d Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Mon, 1 Mar 2021 10:26:01 +0100 Subject: [PATCH 26/28] updated scaffold --- .gitlab-ci.yml | 2 +- .pscaffold | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3a1d417..0f33f75 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: python:alpine +image: python test:pylama: stage: test diff --git a/.pscaffold b/.pscaffold index c853254..bc09b49 160000 --- a/.pscaffold +++ b/.pscaffold @@ -1 +1 @@ -Subproject commit c8532548825b9f01601e096e8286ee011dbfac8e +Subproject commit bc09b49a828808ea9c0b42f80af0b06f90e207cc From 935d2e534dfeab19f8c3f59a29fd7ed1604990b6 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Tue, 27 Apr 2021 15:08:22 +0200 Subject: [PATCH 27/28] made the entries clickable --- httping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httping.py b/httping.py index 8028f62..e588c8d 100755 --- a/httping.py +++ b/httping.py @@ -101,7 +101,7 @@ if __name__ == "__main__": for current_host, current_response in responses.items(): if isinstance(current_response, float): print(current_host + ": " + str(round(current_response, 2)) + " | color=" + - CURRENT_THEME.colorize(current_response)) + CURRENT_THEME.colorize(current_response) + " | bash=\"httping -K " + current_host + "\"") else: print(current_host + ": ☠ | color=" + CURRENT_THEME.selected_colors[0]) print("---") From f9663a175a8a725a96bba739deb6ede5cabf5f30 Mon Sep 17 00:00:00 2001 From: Tobias Schmidl Date: Wed, 28 Apr 2021 08:26:42 +0000 Subject: [PATCH 28/28] Update metadata --- httping.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/httping.py b/httping.py index e588c8d..e4e5553 100755 --- a/httping.py +++ b/httping.py @@ -7,10 +7,10 @@ # v1.0 # Tobias Schmidl # schtobia -# Short description of what your plugin does. +# Simulates httping. # # python,requests -# https://github.com/schtobia/argos-httping/blob/master/httping.py +# https://gitlab.com/schtobia/argos-httping/blob/master/httping.py from __future__ import annotations @@ -22,9 +22,9 @@ from typing import Dict, List, Optional, Tuple import requests # for the central HTTP HEAD request __author__ = "Tobias Schmidl" -__copyright__ = "Copyright 2018, Tobias Schmidl" +__copyright__ = "Copyright 2021, Tobias Schmidl" __license__ = "MIT" -__version__ = "0.0.1" +__version__ = "1.0" __maintainer__ = "Tobias Schmidl" MAX_PING: datetime.timedelta = datetime.timedelta(milliseconds=1000) # in seconds