Releases: linuxserver/docker-beets
nightly-76a39eb8-ls277
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-76a39eb8-ls277/index.html
LinuxServer Changes:
Full Changelog: nightly-42f5512e-ls276...nightly-76a39eb8-ls277
Remote Changes:
fix: Improve DBAccessError messages for permission/directory issues (#6579)
Good day!
Thank you for maintaining beets!
Summary of Changes
This PR improves the error messages in DBAccessError to help users
diagnose database permission issues more easily:
-
Updated
DBAccessErrordocstring — Now mentions directory
missing and file permissions as potential causes (not just file
deletion). -
Split error handling — The combined
if ... in (...)check is
replaced with separateif/elifbranches, each providing a distinct,
actionable message:
unable to open database file→ "Check that the parent directory
exists and is writable."attempt to write a readonly database→ "Check file permissions: the
database file or its directory may not be writable."
Issue
- Fixes beetbox/beets#1676
Verification
- Python syntax check passes (
python3 -m py_compile) - Diff is minimal: 14 insertions, 7 deletions across 1 file
- Only
beets/dbcore/db.pychanged
Testing
Manual verification:
from beets.dbcore.db import DBAccessError
try:
raise DBAccessError("attempt to write a readonly database")
except DBAccessError as e:
print(str(e))
# -> 'attempt to write a readonly database. Check file permissions: the database file or its directory may not be writable.'Thank you for reviewing this PR!
Warmly,
RoomWithRoof
nightly-20b0dd33-ls277
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-20b0dd33-ls277/index.html
LinuxServer Changes:
No changes
Remote Changes:
lyrics: handle apostrophes in musixmatch slug (#6590)
REPLACEMENTS runs before unidecode in the musixmatch backend, so
curly apostrophes (U+2018, U+2019) survived as raw bytes in the
percent-encoded URL and titles like "If They're Shooting at You"
produced a lookup that returned nothing. A new entry in REPLACEMENTS
maps both codepoints to a dash. The shared slug() helper avoids the
bug because it calls unidecode first.
Fixes #4759.
nightly-f24ffeb4-ls276
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-f24ffeb4-ls276/index.html
LinuxServer Changes:
No changes
Remote Changes:
Reduce smartplaylist complexity (#6568)
Refactor smartplaylist plugin internals
This PR incrementally cleans up smartplaylist.py with no behaviour
changes, splitting a monolithic update_playlists method into focused,
testable units.
Key changes
get_item_uri— extracts URI resolution logic (prefix,
dest_regen,relative_to,urlencode,uri_format) out of the
update loop into a dedicated method. Config options are now lazily
cached as@cached_propertyfields on the plugin instance.get_playlist_items— isolates item/album query resolution into a
static/class method returning a deduplicatedIterator[Item]. A helper
get_queriesnormalises single vs. compound query inputs.write_playlist— extracts file I/O and#EXTM3Uheader writing
into its own method.PlaylistItem.get_comment— moves per-entry comment formatting
(including#EXTINFgeneration) onto thePlaylistItemdataclass.- Output format validation — moved to plugin init using
confuse.Choice, replacing a manual runtime string check. The CLI
--outputoption now usestype="choice"accordingly. pretendconfig default — added to the config schema so
update_playlistscan read it directly, removing thepretend
parameter from its signature.defaultdict— replaces manualm3u/m3u_urisdict
initialisation in the update loop.
Test impact
TestGetItemURI replaces two large integration-style test methods
(test_playlist_update_uri_format, test_playlist_update_dest_regen)
with a focused parametrised class using real Item fixtures instead of
MagicMock. The multi-query ordering and deduplication tests are
replaced by a single test_get_playlist_items using real library items.
Before
$ complexipy beetsplug/smartplaylist.py
🧠 Total Cognitive Complexity: 117
After
$ complexipy beetsplug/smartplaylist.py
🧠 Total Cognitive Complexity: 59
nightly-d2a9e836-ls276
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-d2a9e836-ls276/index.html
LinuxServer Changes:
No changes
Remote Changes:
Fix concurrent plugin execution (#6585)
Fix lambda closure bug in concurrent plugin method execution
Fixes a classic Python closure-over-loop-variable bug in
_yield_from_plugins, where all ThreadPoolExecutor futures ended up
calling the last plugin's method instead of their respective plugin.
Root cause
The inline lambda captured plugin by reference. By the time the
executor ran the futures, the loop had finished and all lambdas resolved
getattr(plugin, method_name) to the final loop value.
Fix
Extracts a named materialize(method, *args, **kwargs) helper. The
plugin method is now passed as an argument to executor.submit, so
each future holds its own reference — no closure over the loop variable.
Testing
A regression test (test_albums_for_ids_calls_each_plugin_once) was
added first to reproduce the bug, then xfail removed once fixed. The
test uses a DelayedStartExecutor to force all submissions to complete
before any worker starts, reliably triggering the original race.
Fixes: #6583
nightly-9ce4f11b-ls276
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-9ce4f11b-ls276/index.html
LinuxServer Changes:
No changes
Remote Changes:
Correct MusicBrainz extra_tags default documentation (#6586)
The MusicBrainz plugin currently defaults extra_tags to an empty list.
Album search criteria are built from the release title plus either the
artist name or the MusicBrainz Various Artists ID; track count is only
added when tracks is configured in musicbrainz.extra_tags.
This updates the extra_tags documentation to match the current plugin
behavior.
Refs #6073.
Validation
- Checked
MusicBrainzPlugin.get_album_criteriaand
MusicBrainzAPI.searchagainst the documented behavior. - Parsed the edited RST block and ran
git diff --check.
nightly-42f5512e-ls276
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-42f5512e-ls276/index.html
LinuxServer Changes:
Full Changelog: nightly-8a82a92a-ls275...nightly-42f5512e-ls276
Remote Changes:
zero: treat images and art as aliases in keep_fields (#6581)
Fixes #3532
When images is listed in keep_fields, embedded album art was still
being removed because the zero plugin didn't recognize art as an alias
for images. Both field names map to the same underlying data in
mediafile, so specifying either one in keep_fields should protect
embedded art.
This PR adds aliasing logic in the keep_fields block. If either
images or art appears in keep_fields, the other is automatically
added to the keep set.
2.10.0-ls327
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/2.10.0-ls327/index.html
LinuxServer Changes:
Full Changelog: 2.10.0-ls326...2.10.0-ls327
Remote Changes:
Updating PIP version of beets to 2.10.0
nightly-8a82a92a-ls275
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-8a82a92a-ls275/index.html
LinuxServer Changes:
Full Changelog: nightly-8a82a92a-ls274...nightly-8a82a92a-ls275
Remote Changes:
library: add subtitle (id3 TIT3) field (#5696)
Adds support for a subtitle field, corresponding to the TIT3 id3 tag.
Requires beetbox/mediafile#82
nightly-baffb341-ls274
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-baffb341-ls274/index.html
LinuxServer Changes:
No changes
Remote Changes:
Fix labeler config (#6574)
Fix labeler regex patterns to use OR matching
Consolidates duplicate label-matching rules in .github/labeler.yaml.
Each plugin label previously used two separate regex patterns — one
matching "<name> plugin" and one matching "<name>:" — which the
labeler config ANDs together, requiring both patterns to match
simultaneously.
Each pair is replaced with a single regex using a non-capturing group,
e.g. /convert(?: plugin|:)/i, so either suffix correctly triggers the
label.
Note I tested this issue under the following pr:
beetbox/beets#6573. See the changes timeline.
nightly-a35bb419-ls274
CI Report:
https://ci-tests.linuxserver.io/linuxserver/beets/nightly-a35bb419-ls274/index.html
LinuxServer Changes:
Full Changelog: nightly-7edf27bf-ls273...nightly-a35bb419-ls274
Remote Changes:
Regression: #6547 main needs default (#6571)
Fix regression error from #6547.
Default value None is needed for main function, was removed
accidentally.