gtk: Add a TagDeviceList

This will be used to make a tree of tag / device / run objects for
viewing. I sort the tags so that newer ones appear towards the top of
the list.

Signed-off-by: Anna Schumaker <anna@nowheycreamery.com>
This commit is contained in:
Anna Schumaker 2023-11-03 16:38:28 -04:00
parent 6c8e155a44
commit ce2c36a0dd
2 changed files with 128 additions and 0 deletions

View File

@ -193,3 +193,77 @@ class TestDateDeviceList(unittest.TestCase):
with self.assertRaises(IndexError):
self.assertIsNone(tree[5])
class TestTagDeviceList(unittest.TestCase):
"""Test case for our TagDeviceList GObject."""
def setUp(self):
"""Set up common variables."""
self.tag = xfstestsdb.gtk.tree.TagDeviceList(name="mytag")
def test_init(self):
"""Test creating a TagDeviceList instance."""
self.assertIsInstance(self.tag, GObject.GObject)
self.assertIsInstance(self.tag, Gio.ListModel)
self.assertEqual(self.tag.name, "mytag")
self.assertEqual(str(self.tag), "mytag")
def test_lt(self):
"""Test comparing TagDeviceList instances."""
tag_a = xfstestsdb.gtk.tree.TagDeviceList(name="a")
tag_b = xfstestsdb.gtk.tree.TagDeviceList(name="b")
now = datetime.datetime.now()
then = now - datetime.timedelta(seconds=42)
tag_a.add_run(1, "/dev/vda1", now)
tag_b.add_run(2, "/dev/vda2", then)
self.assertTrue(tag_a < tag_b)
self.assertFalse(tag_b < tag_a)
self.assertFalse(tag_a < tag_a)
tag_a.add_run(2, "/dev/vda2", then)
self.assertTrue(tag_b < tag_a)
def test_get_item_type(self):
"""Test the get_item_type() function."""
self.assertEqual(self.tag.get_item_type(),
xfstestsdb.gtk.tree.DeviceRunsList.__gtype__)
def test_get_n_items(self):
"""Test the get_n_items() function."""
self.assertEqual(self.tag.get_n_items(), 0)
self.assertEqual(self.tag.n_items, 0)
self.tag.add_run(1, "/dev/vda1", datetime.datetime.now())
self.assertEqual(self.tag.get_n_items(), 1)
self.assertEqual(self.tag.n_items, 1)
def test_get_item(self):
"""Test the get_item() function."""
now = datetime.datetime.now()
then = now - datetime.timedelta(seconds=42)
self.tag.add_run(1, "/dev/vda2", now)
self.assertIsInstance(self.tag[0], xfstestsdb.gtk.tree.DeviceRunsList)
self.assertEqual(self.tag[0].name, "/dev/vda2")
self.assertEqual(self.tag[0][0].runid, 1)
self.assertEqual(self.tag[0][0].timestamp, now)
self.assertEqual(self.tag[0][0].ftime, "%c")
self.tag.add_run(2, "/dev/vda1", then)
self.assertEqual(self.tag[0].name, "/dev/vda1")
self.assertEqual(self.tag[1].name, "/dev/vda2")
def test_get_earliest_run(self):
"""Test the get_earliest_run() function."""
self.assertIsNone(self.tag.get_earliest_run())
now = datetime.datetime.now()
self.tag.add_run(1, "/dev/vda1", now)
self.assertEqual(self.tag.get_earliest_run().runid, 1)
then = now - datetime.timedelta(seconds=42)
self.tag.add_run(2, "/dev/vda2", then)
self.assertEqual(self.tag.get_earliest_run().runid, 2)

View File

@ -126,3 +126,57 @@ class DateDeviceList(GObject.GObject, Gio.ListModel):
min = datetime.datetime.combine(date, datetime.time())
max = min + datetime.timedelta(days=1)
return (min, max)
class TagDeviceList(GObject.GObject, Gio.ListModel):
"""Contains a single tag with multiple devices and runs."""
name = GObject.Property(type=str)
n_items = GObject.Property(type=int)
def __init__(self, name: str) -> None:
"""Initialize our TagDeviceList."""
super().__init__(name=name)
self.__devices = []
def __lt__(self, rhs: typing.Self) -> bool:
"""Compare two TagDeviceList objects."""
lhs_run = self.get_earliest_run()
rhs_run = rhs.get_earliest_run()
if lhs_run.runid == rhs_run.runid:
return self.name > rhs.name
return lhs_run > rhs_run
def __str__(self) -> str:
"""Get the name of this tag."""
return self.name
def do_get_item_type(self) -> GObject.GType:
"""Get the type of objects in the list."""
return DeviceRunsList.__gtype__
def do_get_n_items(self) -> int:
"""Get the number of devices added to this tag."""
return self.n_items
def do_get_item(self, n: int) -> DeviceRunsList:
"""Get the device at the nth position."""
return self.__devices[n]
def add_run(self, runid: int, device: str,
timestamp: datetime.datetime) -> None:
"""Add a run to the Tag's list."""
pos = bisect.bisect_left(self.__devices, device, key=str)
if pos < len(self.__devices) and self.__devices[pos].name == device:
dev = self.__devices[pos]
else:
dev = DeviceRunsList(device)
self.__devices.insert(pos, dev)
dev.add_run(runid, timestamp, "%c")
self.n_items = len(self.__devices)
def get_earliest_run(self) -> XfstestsRun | None:
"""Get the earliest run added to the tag."""
runs = [d.get_earliest_run() for d in self.__devices]
return min(runs, default=None)