Skip to content

Commit d960f36

Browse files
committed
mbsync: support other data sources
1 parent 4c5a3bd commit d960f36

File tree

4 files changed

+38
-66
lines changed

4 files changed

+38
-66
lines changed

beetsplug/mbsync.py

+4-28
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,14 @@
1212
# The above copyright notice and this permission notice shall be
1313
# included in all copies or substantial portions of the Software.
1414

15-
"""Update library's tags using MusicBrainz."""
15+
"""Synchronise library metadata with metadata source backends."""
1616

17-
import re
1817
from collections import defaultdict
1918

2019
from beets import autotag, library, ui, util
2120
from beets.autotag import hooks
2221
from beets.plugins import BeetsPlugin, apply_item_changes
2322

24-
MBID_REGEX = r"(\d|\w){8}-(\d|\w){4}-(\d|\w){4}-(\d|\w){4}-(\d|\w){12}"
25-
2623

2724
class MBSyncPlugin(BeetsPlugin):
2825
def __init__(self):
@@ -84,17 +81,7 @@ def singletons(self, lib, query, move, pretend, write):
8481
)
8582
continue
8683

87-
# Do we have a valid MusicBrainz track ID?
88-
if not re.match(MBID_REGEX, item.mb_trackid):
89-
self._log.info(
90-
"Skipping singleton with invalid mb_trackid:" + " {0}",
91-
item_formatted,
92-
)
93-
continue
94-
95-
# Get the MusicBrainz recording info.
96-
track_info = hooks.track_for_mbid(item.mb_trackid)
97-
if not track_info:
84+
if not (track_info := hooks.track_for_id(item.mb_trackid)):
9885
self._log.info(
9986
"Recording ID not found: {0} for track {0}",
10087
item.mb_trackid,
@@ -121,18 +108,7 @@ def albums(self, lib, query, move, pretend, write):
121108
continue
122109

123110
items = list(a.items())
124-
125-
# Do we have a valid MusicBrainz album ID?
126-
if not re.match(MBID_REGEX, a.mb_albumid):
127-
self._log.info(
128-
"Skipping album with invalid mb_albumid: {0}",
129-
album_formatted,
130-
)
131-
continue
132-
133-
# Get the MusicBrainz album information.
134-
album_info = hooks.album_for_mbid(a.mb_albumid)
135-
if not album_info:
111+
if not (album_info := hooks.album_for_id(a.mb_albumid)):
136112
self._log.info(
137113
"Release ID {0} not found for album {1}",
138114
a.mb_albumid,
@@ -179,7 +155,7 @@ def albums(self, lib, query, move, pretend, write):
179155
with lib.transaction():
180156
autotag.apply_metadata(album_info, mapping)
181157
changed = False
182-
# Find any changed item to apply MusicBrainz changes to album.
158+
# Find any changed item to apply changes to album.
183159
any_changed_item = items[0]
184160
for item in items:
185161
item_changed = ui.show_model_changes(item)

docs/changelog.rst

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ New features:
2222
* :doc:`plugins/lyrics`: Rewrite lyrics translation functionality to use Azure
2323
AI Translator API and add relevant instructions to the documentation.
2424
* :doc:`plugins/missing`: Add support for all metadata sources.
25+
* :doc:`plugins/mbsync`: Add support for all metadata sorces.
2526

2627
Bug fixes:
2728

docs/plugins/mbsync.rst

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
MBSync Plugin
22
=============
33

4-
This plugin provides the ``mbsync`` command, which lets you fetch metadata
5-
from MusicBrainz for albums and tracks that already have MusicBrainz IDs. This
6-
is useful for updating tags as they are fixed in the MusicBrainz database, or
7-
when you change your mind about some config options that change how tags are
8-
written to files. If you have a music library that is already nicely tagged by
9-
a program that also uses MusicBrainz like Picard, this can speed up the
10-
initial import if you just import "as-is" and then use ``mbsync`` to get
11-
up-to-date tags that are written to the files according to your beets
4+
This plugin provides the ``mbsync`` command, which lets you synchronize
5+
metadata for albums and tracks that have external data source IDs.
6+
7+
This is useful for syncing your library with online data or when changing
8+
configuration options that affect tag writing. If your music library already
9+
contains correct tags, you can speed up the initial import by importing files
10+
"as-is" and then using ``mbsync`` to write tags according to your beets
1211
configuration.
1312

1413

test/plugins/test_mbsync.py

+26-30
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# The above copyright notice and this permission notice shall be
1313
# included in all copies or substantial portions of the Software.
1414

15-
from unittest.mock import patch
15+
from unittest.mock import Mock, patch
1616

1717
from beets.autotag.hooks import AlbumInfo, TrackInfo
1818
from beets.library import Item
@@ -22,37 +22,36 @@
2222
class MbsyncCliTest(PluginTestCase):
2323
plugin = "mbsync"
2424

25-
@patch("beets.autotag.mb.album_for_id")
26-
@patch("beets.autotag.mb.track_for_id")
27-
def test_update_library(self, track_for_id, album_for_id):
25+
@patch(
26+
"beets.plugins.album_for_id",
27+
Mock(
28+
side_effect=lambda *_: AlbumInfo(
29+
album_id="album id",
30+
album="new album",
31+
tracks=[TrackInfo(track_id="track id", title="new title")],
32+
)
33+
),
34+
)
35+
@patch(
36+
"beets.plugins.track_for_id",
37+
Mock(
38+
side_effect=lambda *_: TrackInfo(
39+
track_id="singleton id", title="new title"
40+
)
41+
),
42+
)
43+
def test_update_library(self):
2844
album_item = Item(
2945
album="old album",
30-
mb_albumid="81ae60d4-5b75-38df-903a-db2cfa51c2c6",
46+
mb_albumid="album id",
3147
mb_trackid="track id",
3248
)
3349
self.lib.add_album([album_item])
3450

35-
singleton = Item(
36-
title="old title", mb_trackid="b8c2cf90-83f9-3b5f-8ccd-31fb866fcf37"
37-
)
51+
singleton = Item(title="old title", mb_trackid="singleton id")
3852
self.lib.add(singleton)
3953

40-
album_for_id.return_value = AlbumInfo(
41-
album_id="album id",
42-
album="new album",
43-
tracks=[
44-
TrackInfo(track_id=album_item.mb_trackid, title="new title")
45-
],
46-
)
47-
track_for_id.return_value = TrackInfo(
48-
track_id=singleton.mb_trackid, title="new title"
49-
)
50-
51-
with capture_log() as logs:
52-
self.run_command("mbsync")
53-
54-
assert "Sending event: albuminfo_received" in logs
55-
assert "Sending event: trackinfo_received" in logs
54+
self.run_command("mbsync")
5655

5756
singleton.load()
5857
assert singleton.title == "new title"
@@ -81,9 +80,6 @@ def test_custom_format(self):
8180

8281
with capture_log("beets.mbsync") as logs:
8382
self.run_command("mbsync", "-f", "'%if{$album,$album,$title}'")
84-
assert set(logs) == {
85-
"mbsync: Skipping album with no mb_albumid: 'no id'",
86-
"mbsync: Skipping album with invalid mb_albumid: 'invalid id'",
87-
"mbsync: Skipping singleton with no mb_trackid: 'no id'",
88-
"mbsync: Skipping singleton with invalid mb_trackid: 'invalid id'",
89-
}
83+
84+
assert "mbsync: Skipping album with no mb_albumid: 'no id'" in logs
85+
assert "mbsync: Skipping singleton with no mb_trackid: 'no id'" in logs

0 commit comments

Comments
 (0)