[modules/cpu] Add initial version of CPU utilization module
Re-enable the CPU utilization module as proof-of-concept for the new core engine. see #23
This commit is contained in:
parent
8855f1155b
commit
aacc56a4e2
9 changed files with 85 additions and 10 deletions
|
@ -55,10 +55,12 @@ class Engine(object):
|
||||||
while self.running():
|
while self.running():
|
||||||
widgets = []
|
widgets = []
|
||||||
for module in self._modules:
|
for module in self._modules:
|
||||||
widgets += module.widgets()
|
module_widgets = module.widgets()
|
||||||
self._output.draw(widgets)
|
widgets += module_widgets if isinstance(module_widgets, list) else [module_widgets]
|
||||||
|
self._output.draw(widgets=widgets, engine=self)
|
||||||
self._output.flush()
|
self._output.flush()
|
||||||
time.sleep(1)
|
if self.running():
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
self._output.stop()
|
self._output.stop()
|
||||||
|
|
||||||
|
|
18
bumblebee/modules/cpu.py
Normal file
18
bumblebee/modules/cpu.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# pylint: disable=C0111,R0903
|
||||||
|
|
||||||
|
"""Displays CPU utilization across all CPUs."""
|
||||||
|
|
||||||
|
import psutil
|
||||||
|
import bumblebee.engine
|
||||||
|
|
||||||
|
class Module(bumblebee.engine.Module):
|
||||||
|
def __init__(self, engine):
|
||||||
|
super(Module, self).__init__(engine)
|
||||||
|
self._utilization = psutil.cpu_percent(percpu=False)
|
||||||
|
|
||||||
|
def widgets(self):
|
||||||
|
self._utilization = psutil.cpu_percent(percpu=False)
|
||||||
|
|
||||||
|
return bumblebee.output.Widget(full_text="{:05.02f}%".format(self._utilization))
|
||||||
|
|
||||||
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -9,6 +9,6 @@ class Module(bumblebee.engine.Module):
|
||||||
super(Module, self).__init__(engine)
|
super(Module, self).__init__(engine)
|
||||||
|
|
||||||
def widgets(self):
|
def widgets(self):
|
||||||
return []
|
return bumblebee.output.Widget(full_text="test")
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
|
@ -5,6 +5,15 @@
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
class Widget(object):
|
||||||
|
"""Represents a single visible block in the status bar"""
|
||||||
|
def __init__(self, full_text):
|
||||||
|
self._full_text = full_text
|
||||||
|
|
||||||
|
def full_text(self):
|
||||||
|
"""Retrieve the full text to display in the widget"""
|
||||||
|
return self._full_text
|
||||||
|
|
||||||
class I3BarOutput(object):
|
class I3BarOutput(object):
|
||||||
"""Manage output according to the i3bar protocol"""
|
"""Manage output according to the i3bar protocol"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -18,14 +27,14 @@ class I3BarOutput(object):
|
||||||
"""Finish i3bar protocol"""
|
"""Finish i3bar protocol"""
|
||||||
sys.stdout.write("]\n")
|
sys.stdout.write("]\n")
|
||||||
|
|
||||||
def draw(self, widgets):
|
def draw(self, widgets, engine=None):
|
||||||
"""Draw a number of widgets"""
|
"""Draw a number of widgets"""
|
||||||
if not isinstance(widgets, list):
|
if not isinstance(widgets, list):
|
||||||
widgets = [widgets]
|
widgets = [widgets]
|
||||||
result = []
|
result = []
|
||||||
for widget in widgets:
|
for widget in widgets:
|
||||||
result.append({
|
result.append({
|
||||||
u"full_text": widget.text()
|
u"full_text": widget.full_text()
|
||||||
})
|
})
|
||||||
sys.stdout.write(json.dumps(result))
|
sys.stdout.write(json.dumps(result))
|
||||||
|
|
||||||
|
|
0
tests/modules/__init__.py
Normal file
0
tests/modules/__init__.py
Normal file
16
tests/modules/test_cpu.py
Normal file
16
tests/modules/test_cpu.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# pylint: disable=C0103,C0111
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from bumblebee.modules.cpu import Module
|
||||||
|
from tests.util import assertWidgetAttributes
|
||||||
|
|
||||||
|
class TestCPUModule(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.module = Module(None)
|
||||||
|
|
||||||
|
def test_widgets(self):
|
||||||
|
widget = self.module.widgets()
|
||||||
|
assertWidgetAttributes(self, widget)
|
||||||
|
|
||||||
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,13 +1,17 @@
|
||||||
# pylint: disable=C0103,C0111
|
# pylint: disable=C0103,C0111
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from bumblebee.error import ModuleLoadError
|
from bumblebee.error import ModuleLoadError
|
||||||
from bumblebee.engine import Engine
|
from bumblebee.engine import Engine
|
||||||
from bumblebee.config import Config
|
from bumblebee.config import Config
|
||||||
|
|
||||||
|
from tests.util import MockOutput
|
||||||
|
|
||||||
class TestEngine(unittest.TestCase):
|
class TestEngine(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.engine = Engine(Config())
|
self.engine = Engine(config=Config(), output=MockOutput())
|
||||||
|
self.singleWidgetModule = [{"module": "test"}]
|
||||||
self.testModule = "test"
|
self.testModule = "test"
|
||||||
self.invalidModule = "no-such-module"
|
self.invalidModule = "no-such-module"
|
||||||
self.testModuleSpec = "bumblebee.modules.{}".format(self.testModule)
|
self.testModuleSpec = "bumblebee.modules.{}".format(self.testModule)
|
||||||
|
@ -41,4 +45,11 @@ class TestEngine(unittest.TestCase):
|
||||||
[self.testModuleSpec for module in modules]
|
[self.testModuleSpec for module in modules]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_run(self):
|
||||||
|
self.engine.load_modules(self.singleWidgetModule)
|
||||||
|
try:
|
||||||
|
self.engine.run()
|
||||||
|
except Exception as e:
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
|
@ -32,14 +32,14 @@ class TestI3BarOutput(unittest.TestCase):
|
||||||
def test_draw_single_widget(self, stdout):
|
def test_draw_single_widget(self, stdout):
|
||||||
self.output.draw(self.someWidget)
|
self.output.draw(self.someWidget)
|
||||||
result = json.loads(stdout.getvalue())[0]
|
result = json.loads(stdout.getvalue())[0]
|
||||||
self.assertEquals(result["full_text"], self.someWidget.text())
|
self.assertEquals(result["full_text"], self.someWidget.full_text())
|
||||||
|
|
||||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||||
def test_draw_multiple_widgets(self, stdout):
|
def test_draw_multiple_widgets(self, stdout):
|
||||||
self.output.draw([self.someWidget, self.someWidget])
|
self.output.draw([self.someWidget, self.someWidget])
|
||||||
result = json.loads(stdout.getvalue())
|
result = json.loads(stdout.getvalue())
|
||||||
for res in result:
|
for res in result:
|
||||||
self.assertEquals(res["full_text"], self.someWidget.text())
|
self.assertEquals(res["full_text"], self.someWidget.full_text())
|
||||||
|
|
||||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||||
def test_flush(self, stdout):
|
def test_flush(self, stdout):
|
||||||
|
|
|
@ -1,10 +1,29 @@
|
||||||
# pylint: disable=C0103,C0111
|
# pylint: disable=C0103,C0111
|
||||||
|
|
||||||
|
from bumblebee.output import Widget
|
||||||
|
|
||||||
|
def assertWidgetAttributes(test, widget):
|
||||||
|
test.assertTrue(isinstance(widget, Widget))
|
||||||
|
test.assertTrue(hasattr(widget, "full_text"))
|
||||||
|
|
||||||
|
class MockOutput(object):
|
||||||
|
def start(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def draw(self, widgets, engine):
|
||||||
|
engine.stop()
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
pass
|
||||||
|
|
||||||
class MockWidget(object):
|
class MockWidget(object):
|
||||||
def __init__(self, text):
|
def __init__(self, text):
|
||||||
self._text = text
|
self._text = text
|
||||||
|
|
||||||
def text(self):
|
def full_text(self):
|
||||||
return self._text
|
return self._text
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
Loading…
Reference in a new issue