mirror of
https://github.com/beetbox/beets.git
synced 2026-01-11 10:26:36 +01:00
fix interface to ID matching
As outlined in #299, we broke many places in the code that were expecting _album_for_id and _track_for_id to return a single item rather than a list. I took this opportunity to divide up the interface: there's now one function for MBIDs (returning a single object or None) and one for generic IDs (returning a list).
This commit is contained in:
parent
18bbe9f645
commit
4624f65ce3
5 changed files with 36 additions and 41 deletions
|
|
@ -166,37 +166,37 @@ TrackMatch = namedtuple('TrackMatch', ['distance', 'info'])
|
|||
|
||||
# Aggregation of sources.
|
||||
|
||||
def _album_for_id(album_id):
|
||||
"""Get a list of albums corresponding to a release ID."""
|
||||
candidates = []
|
||||
|
||||
# Candidates from MusicBrainz.
|
||||
def album_for_mbid(release_id):
|
||||
"""Get an AlbumInfo object for a MusicBrainz release ID. Return None
|
||||
if the ID is not found.
|
||||
"""
|
||||
try:
|
||||
candidates.append(mb.album_for_id(album_id))
|
||||
return mb.album_for_id(release_id)
|
||||
except mb.MusicBrainzAPIError as exc:
|
||||
exc.log(log)
|
||||
|
||||
# From plugins.
|
||||
def track_for_mbid(recording_id):
|
||||
"""Get a TrackInfo object for a MusicBrainz recording ID. Return None
|
||||
if the ID is not found.
|
||||
"""
|
||||
try:
|
||||
return mb.track_for_id(recording_id)
|
||||
except mb.MusicBrainzAPIError as exc:
|
||||
exc.log(log)
|
||||
|
||||
def albums_for_id(album_id):
|
||||
"""Get a list of albums for an ID."""
|
||||
candidates = [album_for_mbid(album_id)]
|
||||
candidates.extend(plugins.album_for_id(album_id))
|
||||
|
||||
return filter(None, candidates)
|
||||
|
||||
def _track_for_id(track_id):
|
||||
"""Get an item for a recording ID."""
|
||||
candidates = []
|
||||
|
||||
# From MusicBrainz.
|
||||
try:
|
||||
candidates.append(mb.track_for_id(track_id))
|
||||
except mb.MusicBrainzAPIError as exc:
|
||||
exc.log(log)
|
||||
|
||||
# From plugins.
|
||||
def tracks_for_id(track_id):
|
||||
"""Get a list of tracks for an ID."""
|
||||
candidates = [track_for_mbid(track_id)]
|
||||
candidates.extend(plugins.track_for_id(track_id))
|
||||
|
||||
return filter(None, candidates)
|
||||
|
||||
def _album_candidates(items, artist, album, va_likely):
|
||||
def album_candidates(items, artist, album, va_likely):
|
||||
"""Search for album matches. ``items`` is a list of Item objects
|
||||
that make up the album. ``artist`` and ``album`` are the respective
|
||||
names (strings), which may be derived from the item list or may be
|
||||
|
|
@ -224,7 +224,7 @@ def _album_candidates(items, artist, album, va_likely):
|
|||
|
||||
return out
|
||||
|
||||
def _item_candidates(item, artist, title):
|
||||
def item_candidates(item, artist, title):
|
||||
"""Search for item matches. ``item`` is the Item to be matched.
|
||||
``artist`` and ``title`` are strings and either reflect the item or
|
||||
are specified by the user.
|
||||
|
|
|
|||
|
|
@ -361,9 +361,7 @@ def match_by_id(items):
|
|||
if bool(reduce(lambda x,y: x if x==y else (), albumids)):
|
||||
albumid = albumids[0]
|
||||
log.debug('Searching for discovered album ID: ' + albumid)
|
||||
matches = hooks._album_for_id(albumid)
|
||||
if matches:
|
||||
return matches[0]
|
||||
return hooks.album_for_mbid(albumid)
|
||||
else:
|
||||
log.debug('No album ID consensus.')
|
||||
|
||||
|
|
@ -485,7 +483,7 @@ def tag_album(items, search_artist=None, search_album=None,
|
|||
# Search by explicit ID.
|
||||
if search_id is not None:
|
||||
log.debug('Searching for album ID: ' + search_id)
|
||||
search_cands = hooks._album_for_id(search_id)
|
||||
search_cands = hooks.albums_for_id(search_id)
|
||||
|
||||
# Use existing metadata or text search.
|
||||
else:
|
||||
|
|
@ -516,8 +514,8 @@ def tag_album(items, search_artist=None, search_album=None,
|
|||
log.debug(u'Album might be VA: %s' % str(va_likely))
|
||||
|
||||
# Get the results from the data sources.
|
||||
search_cands = hooks._album_candidates(items, search_artist,
|
||||
search_album, va_likely)
|
||||
search_cands = hooks.album_candidates(items, search_artist,
|
||||
search_album, va_likely)
|
||||
|
||||
log.debug(u'Evaluating %i candidates.' % len(search_cands))
|
||||
for info in search_cands:
|
||||
|
|
@ -544,7 +542,7 @@ def tag_item(item, search_artist=None, search_title=None,
|
|||
trackid = search_id or item.mb_trackid
|
||||
if trackid:
|
||||
log.debug('Searching for track ID: ' + trackid)
|
||||
for track_info in hooks._track_for_id(trackid):
|
||||
for track_info in hooks.tracks_for_id(trackid):
|
||||
dist = track_distance(item, track_info, incl_artist=True)
|
||||
candidates[track_info.track_id] = \
|
||||
hooks.TrackMatch(dist, track_info)
|
||||
|
|
@ -567,7 +565,7 @@ def tag_item(item, search_artist=None, search_title=None,
|
|||
log.debug(u'Item search terms: %s - %s' % (search_artist, search_title))
|
||||
|
||||
# Get and evaluate candidate metadata.
|
||||
for track_info in hooks._item_candidates(item, search_artist, search_title):
|
||||
for track_info in hooks.item_candidates(item, search_artist, search_title):
|
||||
dist = track_distance(item, track_info, incl_artist=True)
|
||||
candidates[track_info.track_id] = hooks.TrackMatch(dist, track_info)
|
||||
|
||||
|
|
|
|||
|
|
@ -127,9 +127,9 @@ class AcoustidPlugin(plugins.BeetsPlugin):
|
|||
def candidates(self, items, artist, album, va_likely):
|
||||
albums = []
|
||||
for relid in _all_releases(items):
|
||||
matches = hooks._album_for_id(relid)
|
||||
if matches:
|
||||
albums.extend(matches)
|
||||
album = hooks.album_for_mbid(relid)
|
||||
if album:
|
||||
albums.append(album)
|
||||
|
||||
log.debug('acoustid album candidates: %i' % len(albums))
|
||||
return albums
|
||||
|
|
@ -141,7 +141,7 @@ class AcoustidPlugin(plugins.BeetsPlugin):
|
|||
recording_ids, _ = _matches[item.path]
|
||||
tracks = []
|
||||
for recording_id in recording_ids:
|
||||
track = hooks._track_for_id(recording_id)
|
||||
track = hooks.track_for_mbid(recording_id)
|
||||
if track:
|
||||
tracks.append(track)
|
||||
log.debug('acoustid item candidates: {0}'.format(len(tracks)))
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ def mbsync_singletons(lib, query, move, pretend, write):
|
|||
s.old_data = dict(s.record)
|
||||
|
||||
# Get the MusicBrainz recording info.
|
||||
track_info = hooks._track_for_id(s.mb_trackid)
|
||||
track_info = hooks.track_for_mbid(s.mb_trackid)
|
||||
if not track_info:
|
||||
log.info(u'Recording ID not found: {0}'.format(s.mb_trackid))
|
||||
continue
|
||||
|
|
@ -97,11 +97,10 @@ def mbsync_albums(lib, query, move, pretend, write):
|
|||
item.old_data = dict(item.record)
|
||||
|
||||
# Get the MusicBrainz album information.
|
||||
matches = hooks._album_for_id(a.mb_albumid)
|
||||
if not matches:
|
||||
album_info = hooks.album_for_mbid(a.mb_albumid)
|
||||
if not album_info:
|
||||
log.info(u'Release ID not found: {0}'.format(a.mb_albumid))
|
||||
continue
|
||||
album_info = matches[0]
|
||||
|
||||
# Construct a track mapping according to MBIDs. This should work
|
||||
# for albums that have missing or extra tracks.
|
||||
|
|
|
|||
|
|
@ -39,9 +39,7 @@ def _missing(album):
|
|||
if len([i for i in album.items()]) < album.tracktotal:
|
||||
# fetch missing items
|
||||
# TODO: Implement caching that without breaking other stuff
|
||||
matches = hooks._album_for_id(album.mb_albumid)
|
||||
if matches:
|
||||
album_info = matches[0]
|
||||
album_info = hooks.album_for_mbid(album.mb_albumid)
|
||||
for track_info in getattr(album_info, 'tracks', []):
|
||||
if track_info.track_id not in item_mbids:
|
||||
item = _item(track_info, album_info, album.id)
|
||||
|
|
|
|||
Loading…
Reference in a new issue