Skip to content

Commit beda6fc

Browse files
authored
Add mbpseudo plugin for pseudo-release proposals (#5888)
## Description Adds the new `mbpseudo` plugin, that proactively searches for pseudo-releases during import and adds them as candidates. Since it also depends on MusicBrainz, there are some special considerations for the default logic (which is now a plugin as well). However, at the very least it expects a list of desired [names of scripts](https://en.wikipedia.org/wiki/ISO_15924) in the configuration, for example: ```yaml mbpseudo: scripts: - Latn ``` It will use that to search for pseudo-releases that match some of the desired scripts, but will only do so if the input tracks match against an official release that is not in one of the desired scripts. ## Standalone Usage This would be the recommended approach, which involves disabling the `musicbrainz` plugin. The `mbpseudo` plugin will manually delegate the initial search to it. Since the data source of official releases will still match MusicBrainz, weights are still relevant: ```yaml mbpseudo: source_weight: 0.0 scripts: - Latn musicbrainz: source_weight: 0.1 ``` A setup like that would ensure that the pseudo-releases have slightly more preference when choosing the final proposal. ## Combined Usage I initially thought it would be important to coexist with the `musicbrainz` plugin when it's enabled, and reuse as much of its data as possible to avoid redundant calls to the MusicBrainz API. I have the impression this is not really important in the end, and maybe things could be simplified if we decide that both plugins shouldn't coexist. As it is right now, using both plugins at the same time would still work, but it'll only avoid redundancy if `musicbrainz` emits its candidates before `mbpseudo`, ~which is why I modified the plugin-loading logic slightly to guarantee ordering. I'm not sure if you think this could be an issue, but I think the `musicbrainz` plugin is also used by other plugins and I can imagine it's good to guarantee the order that is declared in the configuration?~ If the above is fulfilled, the `mbpseudo` plugin will use listeners to intercept data emitted by the `musicbrainz` plugin and check if any of them have pseudo-releases that might be desirable.
2 parents 584329e + c087851 commit beda6fc

File tree

12 files changed

+1983
-8
lines changed

12 files changed

+1983
-8
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* @beetbox/maintainers
33

44
# Specific ownerships:
5-
/beets/metadata_plugins.py @semohr
5+
/beets/metadata_plugins.py @semohr
6+
/beetsplug/mbpseudo.py @asardaes

beets/autotag/match.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import lap
2525
import numpy as np
2626

27-
from beets import config, logging, metadata_plugins
27+
from beets import config, logging, metadata_plugins, plugins
2828
from beets.autotag import AlbumInfo, AlbumMatch, TrackInfo, TrackMatch, hooks
2929
from beets.util import get_most_common_tags
3030

@@ -274,12 +274,17 @@ def tag_album(
274274
log.debug("Searching for album ID: {}", search_id)
275275
if info := metadata_plugins.album_for_id(search_id):
276276
_add_candidate(items, candidates, info)
277+
if opt_candidate := candidates.get(info.album_id):
278+
plugins.send("album_matched", match=opt_candidate)
277279

278280
# Use existing metadata or text search.
279281
else:
280282
# Try search based on current ID.
281283
if info := match_by_id(items):
282284
_add_candidate(items, candidates, info)
285+
for candidate in candidates.values():
286+
plugins.send("album_matched", match=candidate)
287+
283288
rec = _recommendation(list(candidates.values()))
284289
log.debug("Album ID match recommendation is {}", rec)
285290
if candidates and not config["import"]["timid"]:
@@ -313,6 +318,8 @@ def tag_album(
313318
items, search_artist, search_album, va_likely
314319
):
315320
_add_candidate(items, candidates, matched_candidate)
321+
if opt_candidate := candidates.get(matched_candidate.album_id):
322+
plugins.send("album_matched", match=opt_candidate)
316323

317324
log.debug("Evaluating {} candidates.", len(candidates))
318325
# Sort and get the recommendation.

beets/plugins.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
"album_imported",
7373
"album_removed",
7474
"albuminfo_received",
75+
"album_matched",
7576
"before_choose_candidate",
7677
"before_item_moved",
7778
"cli_exit",

0 commit comments

Comments
 (0)