This release is far too long in coming, but it's a good one. There is the usual torrent of new features and a ridiculously long line of fixes, but there are also some crucial maintenance changes. We officially support Python 3.7 and 3.8, and some performance optimizations can (anecdotally) make listing your library more than three times faster than in the previous version.
The new core features are:
- A new
config-aunique
configuration option allows setting default options for theaunique
template function. - The
albumdisambig
field no longer includes the MusicBrainz release group disambiguation comment. A newreleasegroupdisambig
field has been added. #3024 - The
modify
command now allows resetting fixed attributes. For example,beet modify -a artist:beatles artpath!
resetsartpath
attribute from matching albums back to the default value. #2497 - A new importer option,
ignore_data_tracks
, lets you skip audio tracks contained in data files. #3021
There are some new plugins:
- The
playlist
can query the beets library using M3U playlists. Thanks to @Holzhaus and @Xenopathic. #123 #3145 - The
loadext
allows loading of SQLite extensions, primarily for use with the ICU SQLite extension for internationalization. #3160 #3226 - The
subsonicupdate
can automatically update your Subsonic library. Thanks to @maffo999. #3001
And many improvements to existing plugins:
lastgenre
: Added option-A
to match individual tracks and singletons. #3220 #3219play
: The plugin can now emit a UTF-8 BOM, fixing some issues with foobar2000 and Winamp. Thanks to @mz2212. #2944gmusic
:- Add a new option to automatically upload to Google Play Music library on track import. Thanks to @shuaiscott.
- Add new options for Google Play Music authentication. Thanks to @thetarkus. #3002
replaygain
:albumpeak
on large collections is calculated as the average, not the maximum. #3008 #3009chroma
:- Now optionally has a bias toward looking up more relevant releases according to the
preferred
configuration options. Thanks to @Archer4499. #3017 - Fingerprint values are now properly stored as strings, which prevents strange repeated output when running
beet write
. Thanks to @Holzhaus. #3097 #2942
- Now optionally has a bias toward looking up more relevant releases according to the
convert
: The plugin now has anid3v23
option that allows you to override the globalid3v23
option. Thanks to @Holzhaus. #3104spotify
:ipfs
: The plugin now supports anocopy
option which passes that flag to ipfs. Thanks to @wildthyme.discogs
: The plugin now has rate limiting for the Discogs API. #3081mpdstats
,mpdupdate
: These plugins now use theMPD_PORT
environment variable if no port is specified in the configuration file. #3223bpd
:- MPD protocol commands
consume
andsingle
are now supported along with updated semantics forrepeat
andprevious
and new fields forstatus
. The bpd server now understands and ignores some additional commands. #3200 #800 - MPD protocol command
idle
is now supported, allowing the MPD version to be bumped to 0.14. #3205 #800 - MPD protocol command
decoders
is now supported. #3222 - The plugin now uses the main beets logging system. The special-purpose
--debug
flag has been removed. Thanks to @arcresu. #3196
- MPD protocol commands
mbsync
: The plugin no longer queries MusicBrainz when either themb_albumid
ormb_trackid
field is invalid. See also the discussion on Google Groups Thanks to @arogl.export
: The plugin now also exportspath
field if the user explicitly specifies it with-i
parameter. This only works when exporting library fields. #3084acousticbrainz
: The plugin now declares types for all its fields, which enables easier querying and avoids a problem where very small numbers would be stored as strings. Thanks to @rain0r. #2790 #3238
Some improvements have been focused on improving beets' performance:
- Querying the library is now faster:
- We only convert fields that need to be displayed. Thanks to @pprkut. #3089
- We now compile templates once and reuse them instead of recompiling them to print out each matching object. Thanks to @SimonPersson. #3258
- Querying the library for items is now faster, for all queries that do not need to access album level properties. This was implemented by lazily fetching the album only when needed. Thanks to @SimonPersson. #3260
absubmit
,badfiles
: Analysis now works in parallel (on Python 3 only). Thanks to @bemeurer. #2442 #3003mpdstats
: Use thecurrentsong
MPD command instead ofplaylist
to get the current song, improving performance when the playlist is long. Thanks to @ray66. #3207 #2752
Several improvements are related to usability:
- The disambiguation string for identifying albums in the importer now shows the catalog number. Thanks to @8h2a. #2951
- Added whitespace padding to missing tracks dialog to improve readability. Thanks to @jams2. #2962
- The
move
command now lists the number of items already in-place. Thanks to @RollingStar. #3117 - Modify selection can now be applied early without selecting every item. #3083
- Beets now emits more useful messages during startup if SQLite returns an error. The SQLite error message is now attached to the beets message. #3005
- Fixed a confusing typo when the
convert
plugin copies the art covers. #3063
Many fixes have been focused on issues where beets would previously crash:
- Avoid a crash when archive extraction fails during import. #3041
- Missing album art file during an update no longer causes a fatal exception (instead, an error is logged and the missing file path is removed from the library). #3030
- When updating the database, beets no longer tries to move album art twice. #3189
- Fix an unhandled exception when pruning empty directories. #1996 #3209
fetchart
: Added network connection error handling to backends so that beets won't crash if a request fails. Thanks to @Holzhaus. #1579badfiles
: Avoid a crash when the underlying tool emits undecodable output. #3165beatport
: Avoid a crash when the server produces an error. #3184bpd
: Fix crashes in the bpd server during exception handling. #3200bpd
: Fix a crash triggered when certain clients tried to list the albums belonging to a particular artist. #3007 #3215replaygain
: Avoid a crash when thebs1770gain
tool emits malformed XML. #2983 #3247
There are many fixes related to compatibility with our dependencies including addressing changes interfaces:
- On Python 2, pin the
jellyfish
requirement to version 0.6.0 for compatibility. - Fix compatibility with Python 3.7 and its change to a name in the
re
module. #2978 - Fix several uses of deprecated standard-library features on Python 3.7. Thanks to @arcresu. #3197
- Fix compatibility with pre-release versions of Python 3.8. #3201 #3202
web
: Fix an error when using more recent versions of Flask with CORS enabled. Thanks to @rveachkc. #2979: #2980- Avoid some deprecation warnings with certain versions of the MusicBrainz library. Thanks to @zhelezov. #2826 #3092
- Restore iTunes Store album art source, and remove the dependency on
python-itunes
, which had gone unmaintained and was not Python-3-compatible. Thanks to @ocelma for creatingpython-itunes
in the first place. Thanks to @nathdwek. #2371 #2551 #2718 lastgenre
,edit
: Avoid a deprecation warnings from thePyYAML
library by switching to the safe loader. Thanks to @translit and @sbraz. #3192 #3225- Fix a problem when resizing images with
PIL
/pillow
on Python 3. Thanks to @architek. #2504 #3029
And there are many other fixes:
- R128 normalization tags are now properly deleted from files when the values are missing. Thanks to @autrimpo. #2757
- Display the artist credit when matching albums if the
artist_credit
configuration option is set. #2953 - With the
from_scratch
configuration option set, only writable fields are cleared. Beets now no longer ignores the format your music is saved in. #2972 - The
%aunique
template function now works correctly with the-f/--format
option. #3043 - Fixed the ordering of items when manually selecting changes while updating tags Thanks to @TaizoSimpson. #3501
- The
%title
template function now works correctly with apostrophes. Thanks to @GuilhermeHideki. #3033 lastgenre
: It's now possible to set theprefer_specific
option without also settingcanonical
. #2973fetchart
: The plugin now respects theignore
andignore_hidden
settings. #1632hook
: Fix byte string interpolation in hook commands. #2967 #3167the
: Log a message when something has changed, not when it hasn't. Thanks to @arcresu. #3195lastgenre
: Theforce
config option now actually works. #2704 #3054- Resizing image files with ImageMagick now avoids problems on systems where there is a
convert
command that is not ImageMagick's by using themagick
executable when it is available. Thanks to @ababyduck. #2093 #3236
There is one new thing for plugin developers to know about:
- In addition to prefix-based field queries, plugins can now define named queries that are not associated with any specific field. For example, the new
playlist
supports queries likeplaylist:name
although there is no field namedplaylist
. Seeextend-query
for details.
And some messages for packagers:
- Note the changes to the dependencies on
jellyfish
andmunkres
. - The optional
python-itunes
dependency has been removed. - Python versions 3.7 and 3.8 are now supported.