diff --git a/README.md b/README.md index a7c623f..075c1e2 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ other playlists run out of tracks. * Python3 * dateutil * gobject + * liblistenbrainz * musicbrainzngs * mutagen * pyxdg diff --git a/emmental/listenbrainz/__init__.py b/emmental/listenbrainz/__init__.py new file mode 100644 index 0000000..63a0898 --- /dev/null +++ b/emmental/listenbrainz/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2024 (c) Anna Schumaker. +"""Our ListenBrainz custom GObject.""" +from gi.repository import GObject +from . import thread +from . import task + + +class ListenBrainz(GObject.GObject): + """Our main ListenBrainz GObject.""" + + def __init__(self): + """Initialize the ListenBrainz GObject.""" + super().__init__() + self._queue = task.Queue() + self._thread = thread.Thread() + + def stop(self) -> None: + """Stop the ListenBrainz thread.""" + self._thread.stop() diff --git a/emmental/listenbrainz/task.py b/emmental/listenbrainz/task.py new file mode 100644 index 0000000..b4e88bd --- /dev/null +++ b/emmental/listenbrainz/task.py @@ -0,0 +1,6 @@ +# Copyright 2024 (c) Anna Schumaker. +"""Our ListenBrainz operation priority queue.""" + + +class Queue: + """A queue for prioritizing ListenBrainz operations.""" diff --git a/emmental/listenbrainz/thread.py b/emmental/listenbrainz/thread.py new file mode 100644 index 0000000..2e2745d --- /dev/null +++ b/emmental/listenbrainz/thread.py @@ -0,0 +1,7 @@ +# Copyright 2024 (c) Anna Schumaker. +"""Our ListenBrainz client thread.""" +from .. import thread + + +class Thread(thread.Thread): + """Thread for submitting listens to ListenBrainz.""" diff --git a/tests/listenbrainz/test_listenbrainz.py b/tests/listenbrainz/test_listenbrainz.py new file mode 100644 index 0000000..42d6def --- /dev/null +++ b/tests/listenbrainz/test_listenbrainz.py @@ -0,0 +1,30 @@ +# Copyright 2024 (c) Anna Schumaker. +"""Tests our custom ListenBrainz GObject.""" +import emmental.listenbrainz +import unittest +from gi.repository import GObject + + +class TestListenBrainz(unittest.TestCase): + """ListenBrainz GObject test case.""" + + def setUp(self): + """Set up common variables.""" + self.listenbrainz = emmental.listenbrainz.ListenBrainz() + + def tearDown(self): + """Clean up.""" + self.listenbrainz.stop() + + def test_init(self): + """Test that the ListenBrainz GObject was set up properly.""" + self.assertIsInstance(self.listenbrainz, GObject.GObject) + self.assertIsInstance(self.listenbrainz._queue, + emmental.listenbrainz.task.Queue) + self.assertIsInstance(self.listenbrainz._thread, + emmental.listenbrainz.thread.Thread) + + def test_stop(self): + """Test stopping the thread during shutdown.""" + self.listenbrainz.stop() + self.assertFalse(self.listenbrainz._thread.is_alive()) diff --git a/tests/listenbrainz/test_task.py b/tests/listenbrainz/test_task.py new file mode 100644 index 0000000..8bcd106 --- /dev/null +++ b/tests/listenbrainz/test_task.py @@ -0,0 +1,16 @@ +# Copyright 2024 (c) Anna Schumaker. +"""Tests our ListenBrainz priority queue.""" +import emmental.listenbrainz.task +import unittest + + +class TestTaskQueue(unittest.TestCase): + """Test the ListenBrainz queue.""" + + def setUp(self): + """Set up common variables.""" + self.queue = emmental.listenbrainz.task.Queue() + + def test_init(self): + """Test that the queue was set up properly.""" + self.assertIsNotNone(self.queue) diff --git a/tests/listenbrainz/test_thread.py b/tests/listenbrainz/test_thread.py new file mode 100644 index 0000000..446055b --- /dev/null +++ b/tests/listenbrainz/test_thread.py @@ -0,0 +1,20 @@ +# Copyright 2024 (c) Anna Schumaker. +"""Tests our ListenBrainz client thread.""" +import emmental.listenbrainz.thread +import unittest + + +class TestThread(unittest.TestCase): + """ListenBrainz Thread test case.""" + + def setUp(self): + """Set up common variables.""" + self.thread = emmental.listenbrainz.thread.Thread() + + def tearDown(self): + """Clean up.""" + self.thread.stop() + + def test_init(self): + """Test that the ListenBrainz thread was initialized properly.""" + self.assertIsInstance(self.thread, emmental.thread.Thread)