fixed net_speed to properly use speedtest-cli/modularize-2

added some nice unicode formatting down and up symbols for download and upload speed.
This commit is contained in:
Gareth Dunstone 2016-09-14 10:24:17 +10:00
parent 03df1a644a
commit 338ad21ccb

View File

@ -1,5 +1,5 @@
from i3pystatus import IntervalModule from i3pystatus import IntervalModule
import speedtest_cli import speedtest
import requests import requests
import time import time
import os import os
@ -12,23 +12,56 @@ from io import StringIO
class NetSpeed(IntervalModule): class NetSpeed(IntervalModule):
""" """
Attempts to provide an estimation of internet speeds. Attempts to provide an estimation of internet speeds.
Requires: speedtest_cli Requires: speedtest-cli/modularize-2
""" """
settings = ( settings = (
("url", "Target URL to download a file from. Uses speedtest_cli to "
"find the 'best' server if none is supplied."),
("units", "Valid values are B, b, bytes, or bits"), ("units", "Valid values are B, b, bytes, or bits"),
"format" "format"
) )
color = "#FFFFFF" color = "#FFFFFF"
interval = 300 interval = 300
url = None
units = 'bits' units = 'bits'
format = "{speed} ({hosting_provider})" format = "{speed_down:.2f}{down_units}{speed_up:.2f}{up_units} ({hosting_provider})"
def form_b(self, n: float)->tuple:
"""
formates a bps as bps/kbps/mbps/gbps etc
handles whether its meant to be in bytes
:param n: input float
:rtype tuple:
:return: tuple of float-number of mbps etc, str-units
"""
unit = 'bps'
kilo = 1000
mega = 1000000
giga = 1000000000
bps = 0
if self.units == 'bytes' or self.units == 'B':
unit = 'Bps'
kilo = 8000
mega = 8000000
giga = 8000000000
if n < kilo:
bps = float(n)
if n >= kilo and n < mega:
unit = "K" + unit
bps = float(n / 1024.0)
if n >= mega and n < giga:
unit = "M" + unit
bps = float(n / (1024.0 * 1024.0))
if n >= giga:
unit = "G" + unit
bps = float(n / (1024.0 * 1024.0 * 1024.0))
return bps, unit
def run(self): def run(self):
# since speedtest_cli likes to print crap, we need to squelch it # since speedtest_cli likes to print crap, we need to squelch it
@contextlib.contextmanager @contextlib.contextmanager
def nostdout(): def nostdout():
@ -37,72 +70,43 @@ class NetSpeed(IntervalModule):
yield yield
sys.stdout = save_stdout sys.stdout = save_stdout
if not self.url: cdict = {
"speed_up": 0.0,
"speed_down": 0.0,
"down_units": "",
"up_units": "",
"hosting_provider": 'null'
}
st = None
with nostdout(): with nostdout():
try: try:
config = speedtest_cli.getConfig() # this is now the canonical way to use speedtest_cli as a module.
servers = speedtest_cli.closestServers(config['client']) st = speedtest.Speedtest()
best = speedtest_cli.getBestServer(servers) except speedtest.ConfigRetrievalError:
# 1500x1500 is about 4.3MB, which seems like a reasonable place to # log('Cannot retrieve speedtest configuration')
# start, i guess... self.output = {}
url = '%s/random1500x1500.jpg' % os.path.dirname(best['url']) if st:
except KeyError: try:
url = None # get the servers
st.get_servers()
st.get_best_server()
if not url: except speedtest.ServersRetrievalError:
cdict = { # log this somehow
"speed": 0, # log('Cannot retrieve speedtest server list')
"hosting_provider": 'null', pass
} results = st.results
else:
with open('/dev/null', 'wb') as devnull:
start = time.time()
req = requests.get(url, stream=True)
devnull.write(req.content)
end = time.time()
total_length = int(req.headers.get('content-length'))
devnull.close()
# chop off the float after the 4th decimal point down, up = st.download(), st.upload()
# note: not rounding, simply cutting speed_down, down_units = self.form_b(down)
# note: dl_time is in seconds speed_up, up_units = self.form_b(up)
dl_time = float(end - start)
if self.units == 'bits' or self.units == 'b':
unit = 'bps'
kilo = 1000
mega = 1000000
giga = 1000000000
factor = 8
elif self.units == 'bytes' or self.units == 'B':
unit = 'Bps'
kilo = 8000
mega = 8000000
giga = 8000000000
factor = 1
if total_length < kilo:
bps = float(total_length / dl_time)
if total_length >= kilo and total_length < mega:
unit = "K" + unit
bps = float((total_length / 1024.0) / dl_time)
if total_length >= mega and total_length < giga:
unit = "M" + unit
bps = float((total_length / (1024.0 * 1024.0)) / dl_time)
if total_length >= giga:
unit = "G" + unit
bps = float((total_length / (1024.0 * 1024.0 * 1024.0)) / dl_time)
bps = "%.2f" % (bps * factor)
speed = "%s %s" % (bps, unit)
hosting_provider = '.'.join(urlparse(url).hostname.split('.')[-2:])
cdict = { cdict = {
"speed": speed, "speed_down": speed_down,
"hosting_provider": hosting_provider, "speed_up": speed_up,
"up_units": up_units,
"down_units": down_units,
"hosting_provider": results.server.get("sponsor", "Unknown Provider")
} }
self.output = { self.output = {