diff --git a/bumblebee/modules/disk.py b/bumblebee/modules/disk.py new file mode 100644 index 0000000..586909f --- /dev/null +++ b/bumblebee/modules/disk.py @@ -0,0 +1,50 @@ +# pylint: disable=C0111,R0903 + +"""Shows free diskspace, total diskspace and the percentage of free disk space. + +Parameters: + * disk.warning: Warning threshold in % of disk space (defaults to 80%) + * disk.critical: Critical threshold in % of disk space (defaults ot 90%) + * disk.path: Path to calculate disk usage from (defaults to /) +""" + +import os + +import bumblebee.input +import bumblebee.output +import bumblebee.engine + +class Module(bumblebee.engine.Module): + def __init__(self, engine, config): + super(Module, self).__init__(engine, config, + bumblebee.output.Widget(full_text=self.diskspace) + ) + self._path = self.parameter("path", "/") + self._perc = 0 + + engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE, + cmd="nautilus {}".format(self._path)) + + def diskspace(self): + st = os.statvfs(self._path) + size = st.f_frsize*st.f_blocks + used = size - st.f_frsize*st.f_bavail + self._perc = 100.0*used/size + + return "{} {}/{} ({:05.02f}%)".format(self._path, + bumblebee.util.bytefmt(used), + bumblebee.util.bytefmt(size), self._perc + ) + + def update(self, widgets): + pass + + def state(self, widget): + pass + def warning(self, widget): + return self._perc > self._config.parameter("warning", 80) + + def critical(self, widget): + return self._perc > self._config.parameter("critical", 90) + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/bumblebee/util.py b/bumblebee/util.py index 24e2cb1..f35ce89 100644 --- a/bumblebee/util.py +++ b/bumblebee/util.py @@ -18,6 +18,13 @@ def execute(cmd, wait=True): return out.decode("utf-8") return None +def bytefmt(num): + for unit in [ "", "Ki", "Mi", "Gi" ]: + if num < 1024.0: + return "{:.2f}{}B".format(num, unit) + num /= 1024.0 + return "{:05.2f%}{}GiB".format(num) + def durationfmt(duration): minutes, seconds = divmod(duration, 60) hours, minutes = divmod(minutes, 60) diff --git a/tests/modules/test_disk.py b/tests/modules/test_disk.py new file mode 100644 index 0000000..3ee74b0 --- /dev/null +++ b/tests/modules/test_disk.py @@ -0,0 +1,36 @@ +# pylint: disable=C0103,C0111 + +import json +import unittest +import mock + +import bumblebee.input +from bumblebee.input import I3BarInput +from bumblebee.modules.disk import Module +from tests.util import MockEngine, MockConfig, assertPopen + +class TestDiskModule(unittest.TestCase): + def setUp(self): + self.engine = MockEngine() + self.engine.input = I3BarInput() + self.engine.input.need_event = True + self.config = MockConfig() + self.config.set("disk.path", "somepath") + self.module = Module(engine=self.engine, config={"config": self.config}) + + @mock.patch("select.select") + @mock.patch("subprocess.Popen") + @mock.patch("sys.stdin") + def test_leftclick(self, mock_input, mock_output, mock_select): + mock_input.readline.return_value = json.dumps({ + "name": self.module.id, + "button": bumblebee.input.LEFT_MOUSE, + "instance": None + }) + mock_select.return_value = (1,2,3) + self.engine.input.start() + self.engine.input.stop() + mock_input.readline.assert_any_call() + assertPopen(mock_output, "nautilus {}".format(self.module.parameter("path"))) + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4