diff --git a/beets/autotag/match.py b/beets/autotag/match.py index d95dc7a08..8baaf0108 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -380,8 +380,11 @@ def tag_album(items, search_artist=None, search_album=None, The `AlbumMatch` objects are generated by searching the metadata backends. By default, the metadata of the items is used for the - search. This can be customized by setting the parameters. The - `mapping` field of the album has the matched `items` as keys. + search. This can be customized by setting the parameters. + `search_ids` is a list of MusicBrainz release IDs: if specified, + it will restrict the candidates to those IDs, ignoring + `search_artist` and `search album`. The `mapping` field of the + album has the matched `items` as keys. The recommendation is calculated from the match quality of the candidates. @@ -451,7 +454,8 @@ def tag_item(item, search_artist=None, search_title=None, `(candidates, recommendation)` pair where `candidates` is a list of TrackMatch objects. `search_artist` and `search_title` may be used to override the current metadata for the purposes of the MusicBrainz - title; likewise `search_ids`. + title. `search_ids` may be used for restricting the search to a list + of MusicBrainz IDs. """ # Holds candidates found so far: keys are MBIDs; values are # (distance, TrackInfo) pairs. @@ -474,7 +478,7 @@ def tag_item(item, search_artist=None, search_title=None, return sorted(candidates.itervalues()), rec # If we're searching by ID, don't proceed. - if search_ids != []: + if search_ids: if candidates: return sorted(candidates.itervalues()), rec else: diff --git a/beets/config_default.yaml b/beets/config_default.yaml index 545fa9638..3fdfaf836 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -22,6 +22,7 @@ import: flat: no group_albums: no pretend: false + musicbrainz_ids: [] clutter: ["Thumbs.DB", ".DS_Store"] ignore: [".*", "*~", "System Volume Information"] diff --git a/beets/importer.py b/beets/importer.py index 28a32ec7e..519eecc7e 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -582,9 +582,7 @@ class ImportTask(BaseImportTask): """Retrieve and store candidates for this album. """ # Use a MusicBrainz id directly if provided by the importer -m option. - mb_ids = [] - if config['import']['musicbrainz_ids'].exists(): - mb_ids = config['import']['musicbrainz_ids'].get() + mb_ids = config['import']['musicbrainz_ids'].as_str_seq() artist, album, candidates, recommendation = \ autotag.tag_album(self.items, search_ids=mb_ids) @@ -827,9 +825,7 @@ class SingletonImportTask(ImportTask): def lookup_candidates(self): # Use a MusicBrainz id directly if provided by the importer -m option. - mb_ids = [] - if config['import']['musicbrainz_ids'].exists(): - mb_ids = config['import']['musicbrainz_ids'].get() + mb_ids = config['import']['musicbrainz_ids'].as_str_seq() candidates, recommendation = autotag.tag_item(self.item, search_ids=mb_ids) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 74a6da0ed..c68dcf10f 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -734,7 +734,7 @@ class TerminalImportSession(importer.ImportSession): search_id = manual_id(False) if search_id: _, _, candidates, rec = autotag.tag_album( - task.items, search_ids=[search_id] + task.items, search_ids=search_id.split(' ') ) elif choice in extra_ops.keys(): # Allow extra ops to automatically set the post-choice. @@ -786,8 +786,8 @@ class TerminalImportSession(importer.ImportSession): # Ask for a track ID. search_id = manual_id(True) if search_id: - candidates, rec = autotag.tag_item(task.item, - search_ids=[search_id]) + candidates, rec = autotag.tag_item( + task.item, search_ids=search_id.split(' ')) elif choice in extra_ops.keys(): # Allow extra ops to automatically set the post-choice. post_choice = extra_ops[choice](self, task) diff --git a/docs/guides/tagger.rst b/docs/guides/tagger.rst index 4a4c56184..95975c038 100644 --- a/docs/guides/tagger.rst +++ b/docs/guides/tagger.rst @@ -160,10 +160,10 @@ When beets needs your input about a match, it says something like this:: Beirut - Lon Gisland (Similarity: 94.4%) * Scenic World (Second Version) -> Scenic World - [A]pply, More candidates, Skip, Use as-is, as Tracks, Enter search, or aBort? + [A]pply, More candidates, Skip, Use as-is, as Tracks, Enter search, enter Id, or aBort? When beets asks you this question, it wants you to enter one of the capital -letters: A, M, S, U, T, G, E, or B. That is, you can choose one of the +letters: A, M, S, U, T, G, E, I or B. That is, you can choose one of the following: * *A*: Apply the suggested changes shown and move on. @@ -190,6 +190,11 @@ following: option if beets hasn't found any good options because the album is mistagged or untagged. +* *I*: Enter a MusicBrainz id to use as search in the database. Use this option + to specify a MusicBrainz entity (release or recording) directly, by pasting + its ID or the full URL. You can also specify several IDs by separating them + by a space. + * *B*: Cancel this import task altogether. No further albums will be tagged; beets shuts down immediately. The next time you attempt to import the same directory, though, beets will ask you if you want to resume tagging where you diff --git a/docs/reference/cli.rst b/docs/reference/cli.rst index c072c0c0f..25b3fcbc1 100644 --- a/docs/reference/cli.rst +++ b/docs/reference/cli.rst @@ -132,6 +132,11 @@ Optional command flags: option. If set, beets will just print a list of files that it would otherwise import. +* If you already have a MusicBrainz ID that matches the items to be imported, + you can instruct beets to restrict the search to that ID instead of searching + for other candidates by using the ``--musicbrainzid MB_ID`` option. Multiple + IDs can be specified by simply repeating the option several times. + .. _rarfile: https://pypi.python.org/pypi/rarfile/2.2 .. only:: html