Skip to content

Commit

Permalink
Net widget: make cumulative traffic available
Browse files Browse the repository at this point in the history
This adds the new format fields down_cumulative, up_cumulative, and
total_cumulative (as well as corresponding _suffix fields) to the Net
widget in order to make cumulative traffic numbers available.

It also adds a cumulative_prefix option to allow formatting current
speeds differently from cumulative traffic.
  • Loading branch information
saviola777 authored and tych0 committed Jul 17, 2024
1 parent d5b263c commit ff90e5c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 12 deletions.
47 changes: 41 additions & 6 deletions libqtile/widget/net.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ class Net(base.ThreadPoolText):
"""
Displays interface down and up speed
The following fields are available in the `format` string:
- ``interface``: name of the interface
- ``down``: download speed
- ``down_suffix``: suffix for the download speed
- ``down_cumulative``: cumulative download traffic
- ``down_cumulative_suffix``: suffix for the cumulative download traffic
- ``up``: upload speed
- ``up_suffix``: suffix for the upload speed
- ``up_cumulative``: cumulative upload traffic
- ``up_cumulative_suffix``: suffix for the cumulative upload traffic
- ``total``: total speed
- ``total_suffix``: suffix for the total speed
- ``total_cumulative``: cumulative total traffic
- ``total_cumulative_suffix``: suffix for the cumulative total traffic
Widget requirements: psutil_.
Expand All @@ -53,6 +68,11 @@ class Net(base.ThreadPoolText):
("update_interval", 1, "The update interval."),
("use_bits", False, "Use bits instead of bytes per second?"),
("prefix", None, "Use a specific prefix for the unit of the speed."),
(
"cumulative_prefix",
None,
"Use a specific prefix for the unit of the cumulative traffic.",
),
]

def __init__(self, **config):
Expand Down Expand Up @@ -82,19 +102,19 @@ def __init__(self, **config):
)
self.stats = self.get_stats()

def convert_b(self, num_bytes: float) -> tuple[float, str]:
def convert_b(self, num_bytes: float, prefix: str | None = None) -> tuple[float, str]:
"""Converts the number of bytes to the correct unit"""

num_bytes *= self.byte_multiplier

if self.prefix is None:
if prefix is None:
if num_bytes > 0:
power = int(log(num_bytes) / log(self.factor))
power = min(power, len(self.units) - 1)
else:
power = 0
else:
power = self.allowed_prefixes.index(self.prefix)
power = self.allowed_prefixes.index(prefix)

converted_bytes = num_bytes / self.factor**power
unit = self.units[power]
Expand Down Expand Up @@ -135,19 +155,34 @@ def poll(self):
down = down / self.update_interval
up = up / self.update_interval
total = total / self.update_interval
down, down_suffix = self.convert_b(down)
up, up_suffix = self.convert_b(up)
total, total_suffix = self.convert_b(total)
down, down_suffix = self.convert_b(down, self.prefix)
down_cumulative, down_cumulative_suffix = self.convert_b(
new_stats[intf]["down"], self.cumulative_prefix
)
up, up_suffix = self.convert_b(up, self.prefix)
up_cumulative, up_cumulative_suffix = self.convert_b(
new_stats[intf]["up"], self.cumulative_prefix
)
total, total_suffix = self.convert_b(total, self.prefix)
total_cumulative, total_cumulative_suffix = self.convert_b(
new_stats[intf]["total"], self.cumulative_prefix
)
self.stats[intf] = new_stats[intf]
ret_stat.append(
self.format.format(
interface=intf,
down=down,
down_suffix=down_suffix,
down_cumulative=down_cumulative,
down_cumulative_suffix=down_cumulative_suffix,
up=up,
up_suffix=up_suffix,
up_cumulative=up_cumulative,
up_cumulative_suffix=up_cumulative_suffix,
total=total,
total_suffix=total_suffix,
total_cumulative=total_cumulative,
total_cumulative_suffix=total_cumulative_suffix,
)
)

Expand Down
17 changes: 11 additions & 6 deletions test/widgets/test_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ def build_widget(**kwargs):
# Reload fixes cases where psutil may have been imported previously
reload(net)
widget = net.Net(
format="{interface}: U {up}{up_suffix} D {down}{down_suffix} T {total}{total_suffix}",
format="{interface}: U {up}{up_suffix} {up_cumulative}{up_cumulative_suffix} D "
"{down}{down_suffix} {down_cumulative}{down_cumulative_suffix} T {total}"
"{total_suffix} {total_cumulative}{total_cumulative_suffix}",
**kwargs
)
fakebar = FakeBar([widget], window=fake_window)
Expand All @@ -76,19 +78,22 @@ def build_widget(**kwargs):
def test_net_defaults(patch_net):
"""Default: widget shows `all` interfaces"""
net1 = patch_net()
assert net1.poll() == "all: U 40.0kB D 1.2MB T 1.24MB"
assert net1.poll() == "all: U 40.0kB 80.0kB D 1.2MB 2.4MB T 1.24MB 2.48MB"


def test_net_single_interface(patch_net):
"""Display single named interface"""
net2 = patch_net(interface="wlp58s0")
assert net2.poll() == "wlp58s0: U 40.0kB D 1.2MB T 1.24MB"
assert net2.poll() == "wlp58s0: U 40.0kB 160.0kB D 1.2MB 4.8MB T 1.24MB 4.96MB"


def test_net_list_interface(patch_net):
"""Display multiple named interfaces"""
net2 = patch_net(interface=["wlp58s0", "lo"])
assert net2.poll() == "wlp58s0: U 40.0kB D 1.2MB T 1.24MB lo: U 40.0kB D 1.2MB T 1.24MB"
assert net2.poll() == (
"wlp58s0: U 40.0kB 240.0kB D 1.2MB 7.2MB T 1.24MB 7.44MB lo: U 40.0kB "
"240.0kB D 1.2MB 7.2MB T 1.24MB 7.44MB"
)


def test_net_invalid_interface(patch_net):
Expand All @@ -100,7 +105,7 @@ def test_net_invalid_interface(patch_net):
def test_net_use_bits(patch_net):
"""Display all interfaces in bits rather than bytes"""
net4 = patch_net(use_bits=True)
assert net4.poll() == "all: U 320.0kb D 9.6Mb T 9.92Mb"
assert net4.poll() == "all: U 320.0kb 2.56Mb D 9.6Mb 76.8Mb T 9.92Mb 79.36Mb"


def test_net_convert_zero_b(patch_net):
Expand All @@ -112,7 +117,7 @@ def test_net_convert_zero_b(patch_net):
def test_net_use_prefix(patch_net):
"""Tests `prefix` configurable option"""
net6 = patch_net(prefix="M")
assert net6.poll() == "all: U 0.04MB D 1.2MB T 1.24MB"
assert net6.poll() == "all: U 0.04MB 440.0kB D 1.2MB 13.2MB T 1.24MB 13.64MB"


# Untested: 128-129 - generic exception catching

0 comments on commit ff90e5c

Please sign in to comment.