diff --git a/bumblebee/modules/network_traffic.py b/bumblebee/modules/network_traffic.py new file mode 100644 index 0000000..0d2067a --- /dev/null +++ b/bumblebee/modules/network_traffic.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Displays network traffic + * No extra configuration needed +""" + +import psutil +import netifaces + +import bumblebee.input +import bumblebee.output +import bumblebee.engine +import bumblebee.util + +WIDGET_NAME = 'network_traffic' + +class Module(bumblebee.engine.Module): + """Bumblebee main module """ + + def __init__(self, engine, config): + super(Module, self).__init__(engine, config) + + try: + self._bandwidth = BandwidthInfo() + + self._download_tx = self._bandwidth.bytes_recv() + self._upload_tx = self._bandwidth.bytes_sent() + except Exception: + """ We do not want do explode anything """ + pass + + @classmethod + def state(cls, widget): + """Return the widget state""" + + if widget.name == '{}.rx'.format(WIDGET_NAME): + return 'rx' + elif widget.name == '{}.tx'.format(WIDGET_NAME): + return 'tx' + + return None + + def update(self, widgets): + try: + download_tx = self._bandwidth.bytes_recv() + upload_tx = self._bandwidth.bytes_sent() + + download_rate = (download_tx - self._download_tx) + upload_rate = (upload_tx - self._upload_tx) + + self.update_widgets(widgets, download_rate, upload_rate) + + self._download_tx, self._upload_tx = download_tx, upload_tx + except Exception: + """ We do not want do explode anything """ + pass + + @classmethod + def update_widgets(cls, widgets, download_rate, upload_rate): + """Update tx/rx widgets with new rates""" + del widgets[:] + + widgets.extend(( + TrafficWidget(text=download_rate, direction='tx'), + TrafficWidget(text=upload_rate, direction='rx') + )) + + +class BandwidthInfo(object): + """Get received/sent bytes from network adapter""" + + def bytes_recv(self): + """Return received bytes""" + return self.bandwidth().bytes_recv + + def bytes_sent(self): + """Return sent bytes""" + return self.bandwidth().bytes_sent + + def bandwidth(self): + """Return bandwidth information""" + io_counters = self.io_counters() + return io_counters[self.default_network_adapter()] + + @classmethod + def default_network_adapter(cls): + """Return default active network adapter""" + gateway = netifaces.gateways()['default'] + + if not gateway: + raise 'No default gateway found' + + return gateway[netifaces.AF_INET][1] + + @classmethod + def io_counters(cls): + """Return IO counters""" + return psutil.net_io_counters(pernic=True) + +class TrafficWidget(object): + """Create a traffic widget with humanized bytes string with proper icon (up/down)""" + def __new__(cls, text, direction): + widget = bumblebee.output.Widget(name='{0}.{1}'.format(WIDGET_NAME, direction)) + widget.set('theme.minwidth', '0000000KiB/s') + widget.full_text(cls.humanize(text)) + + return widget + + @staticmethod + def humanize(text): + """Return humanized bytes""" + humanized_byte_format = bumblebee.util.bytefmt(text) + return '{0}/s'.format(humanized_byte_format) diff --git a/themes/icons/ascii.json b/themes/icons/ascii.json index 6358442..9f345b5 100644 --- a/themes/icons/ascii.json +++ b/themes/icons/ascii.json @@ -92,6 +92,10 @@ "rx": { "prefix": "down"}, "tx": { "prefix": "up"} }, + "network_traffic": { + "rx": { "prefix": "down" }, + "tx": { "prefix": "up" } + }, "mpd": { "playing": { "prefix": ">" }, "paused": { "prefix": "||" }, diff --git a/themes/icons/awesome-fonts.json b/themes/icons/awesome-fonts.json index ff97533..933c0fa 100644 --- a/themes/icons/awesome-fonts.json +++ b/themes/icons/awesome-fonts.json @@ -148,6 +148,10 @@ "rx": { "prefix": "" }, "tx": { "prefix": "" } }, + "network_traffic": { + "rx": { "prefix": "" }, + "tx": { "prefix": "" } + }, "mpd": { "playing": { "prefix": "" }, "paused": { "prefix": "" }, diff --git a/themes/icons/ionicons.json b/themes/icons/ionicons.json index f2f8fc1..bd9ee4b 100644 --- a/themes/icons/ionicons.json +++ b/themes/icons/ionicons.json @@ -129,6 +129,10 @@ "rx": { "prefix": "\uf365" }, "tx": { "prefix": "\uf35f" } }, + "network_traffic": { + "rx": { "prefix": "\uf365" }, + "tx": { "prefix": "\uf35f" } + }, "mpd": { "playing": { "prefix": "\uf488" }, "paused": { "prefix": "\uf210" },