4 Commits

Author SHA1 Message Date
5d5526835c playlistdb: micropython does not have bytes.removeprefix()
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 3m23s
Check code formatting / Check-C-Format (push) Successful in 7s
Check code formatting / Check-Python-Flake8 (push) Successful in 9s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 4s
Run unit tests on host / Run-Unit-Tests (push) Successful in 7s
Run pytests / Check-Pytest (push) Successful in 10s
2025-08-28 18:06:54 +02:00
6c98cc0c40 app: Fix bug when a tag that has no playlist is encountered 2025-08-28 18:06:54 +02:00
52b08ab7d9 playlistdb: Allow up to 100k tracks; Add validate method; docstrings
- Increase the formatting of playlist entries to allow up to 100000
  tracks. Also enforce that playlist entries are indexed by integers
  using the validate method.

- Add a validate method to validate the data stored in the
  btreedb. Optionally dump the contents to stdout. For testing, add a
  validate+dump by default when opening the db. This can be removed once
  the playlistdb is validated.
2025-08-28 18:06:51 +02:00
6f02794525 Add playlist database
Add playlist database based on the micropython 'btree' module.
Supported features are:
* Create playlist
* Load playlist
* Store position in playlist

Different playlist modes will be added in a followup for #24.

Implements #23.

The playlist data is stored in the btree database in a hierarchical
schema. The hierarchy levels are separated by the '/' character.
Currently, the schema is as follows: The top level for a playlist is the
'tag' id encoded as a hexadecimal string. Beneath this, the 'playlist'
key contains the elements in the playlist. The exact keys used for the
playlist entries are not specified, they are enumerated in native sort
order to build the playlist. When writing a playlist using the
playlistdb module, the keys are 000, 001, etc. by default.  The
'playlistpos' key is also located under the 'tag' key and stores the key
of the current playlist entry.

For example, a playlist with two entries 'a.mp3' and 'b.mp3' for a tag
with the id '00aa11bb22' would be stored in the following key/value
pairs in the btree db:
- 00aa11bb22/playlist/000: a.mp3
- 00aa11bb22/playlist/001: b.mp3
- 00aa11bb22/playlistpos: 000

Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
2025-08-28 18:06:16 +02:00
2 changed files with 7 additions and 4 deletions

View File

@@ -92,7 +92,8 @@ class BTreeDB(IPlaylistDB):
return self.db[pos]
def _setPlaylistPos(self, tag, pos, flush=True):
self.db[self._keyPlaylistPos(tag)] = pos.removeprefix(self._keyPlaylistStart(tag))
assert pos.startswith(self._keyPlaylistStart(tag))
self.db[self._keyPlaylistPos(tag)] = pos[len(self._keyPlaylistStart(tag)):]
if flush:
self._flush()
@@ -123,7 +124,9 @@ class BTreeDB(IPlaylistDB):
def _getNextTrack(self, tag, pos):
_, end_key = self._keyPlaylistStartEnd(tag)
return next(self.db.keys(pos, end_key))
it = self.db.keys(pos, end_key)
next(it)
return next(it)
def getPlaylistForTag(self, tag: bytes):
"""

View File

@@ -15,7 +15,7 @@ class FakeDB:
def values(self, start_key=None, end_key=None, flags=None):
res = []
for key in sorted(self.contents):
if start_key is not None and start_key >= key:
if start_key is not None and start_key > key:
continue
if end_key is not None and end_key < key:
break
@@ -24,7 +24,7 @@ class FakeDB:
def keys(self, start_key=None, end_key=None, flags=None):
for key in sorted(self.contents):
if start_key is not None and start_key >= key:
if start_key is not None and start_key > key:
continue
if end_key is not None and end_key < key:
break