explicit searching for VA releases when it seems likely

This commit is contained in:
Adrian Sampson 2011-04-02 20:29:01 -07:00
parent effc338957
commit f256726917
3 changed files with 40 additions and 10 deletions

View file

@ -74,6 +74,9 @@ SD_PATTERNS = [
(r'(, )?(pt\.|part) .+', 0.2),
]
# Artist signals that indicate "various artists".
VA_ARTISTS = (u'', u'various artists', u'va', u'unknown')
# Autotagging exceptions.
class AutotagError(Exception):
pass
@ -230,7 +233,7 @@ def _plurality(objs):
max_freq = freq
res = obj
return res
return res, len(freqs) <= 1
def current_metadata(items):
"""Returns the most likely artist and album for a set of Items.
@ -238,10 +241,11 @@ def current_metadata(items):
"""
keys = 'artist', 'album'
likelies = {}
consensus = {}
for key in keys:
values = [getattr(item, key) for item in items]
likelies[key] = _plurality(values)
return likelies['artist'], likelies['album']
likelies[key], consensus[key] = _plurality(values)
return likelies['artist'], likelies['album'], consensus['artist']
def order_items(items, trackinfo):
"""Orders the items based on how they match some canonical track
@ -325,7 +329,7 @@ def distance(items, info):
"""Determines how "significant" an album metadata change would be.
Returns a float in [0.0,1.0]. The list of items must be ordered.
"""
cur_artist, cur_album = current_metadata(items)
cur_artist, cur_album, _ = current_metadata(items)
cur_artist = cur_artist or ''
cur_album = cur_album or ''
@ -492,7 +496,7 @@ def tag_album(items, search_artist=None, search_album=None):
May raise an AutotagError if existing metadata is insufficient.
"""
# Get current metadata.
cur_artist, cur_album = current_metadata(items)
cur_artist, cur_album, artist_consensus = current_metadata(items)
log.debug('Tagging %s - %s' % (cur_artist, cur_album))
# The output result tuples (keyed by MB album ID).
@ -525,6 +529,14 @@ def tag_album(items, search_artist=None, search_album=None):
else:
candidates = []
# Possibly add "various artists" search.
if search_album and ((not artist_consensus) or \
(search_artist.lower() in VA_ARTISTS) or \
any(item.comp for item in items)):
log.debug('Possibly Various Artists; adding matches.')
candidates.extend(mb.match_album(None, search_album, len(items),
MAX_CANDIDATES))
# Get candidates from plugins.
candidates.extend(plugins.candidates(items))

View file

@ -226,7 +226,12 @@ def match_album(artist, album, tracks=None, limit=SEARCH_LIMIT):
optionally, a number of tracks on the album.
"""
# Build search criteria.
criteria = {'artist': artist, 'release': album}
criteria = {'release': album}
if artist is not None:
criteria['artist'] = artist
else:
# Various Artists search.
criteria['arid'] = VARIOUS_ARTISTS_ID
if tracks is not None:
criteria['tracks'] = str(tracks)

View file

@ -28,26 +28,39 @@ from beets.library import Item
class PluralityTest(unittest.TestCase):
def test_plurality_consensus(self):
objs = [1, 1, 1, 1]
obj = autotag._plurality(objs)
obj, consensus = autotag._plurality(objs)
self.assertEqual(obj, 1)
self.assertTrue(consensus)
def test_plurality_near_consensus(self):
objs = [1, 1, 2, 1]
obj = autotag._plurality(objs)
obj, consensus = autotag._plurality(objs)
self.assertEqual(obj, 1)
self.assertFalse(consensus)
def test_plurality_conflict(self):
objs = [1, 1, 2, 2, 3]
obj = autotag._plurality(objs)
obj, consensus = autotag._plurality(objs)
self.assert_(obj in (1, 2))
self.assertFalse(consensus)
def test_current_metadata_finds_pluralities(self):
items = [Item({'artist': 'The Beetles', 'album': 'The White Album'}),
Item({'artist': 'The Beatles', 'album': 'The White Album'}),
Item({'artist': 'The Beatles', 'album': 'Teh White Album'})]
l_artist, l_album = autotag.current_metadata(items)
l_artist, l_album, artist_consensus = autotag.current_metadata(items)
self.assertEqual(l_artist, 'The Beatles')
self.assertEqual(l_album, 'The White Album')
self.assertFalse(artist_consensus)
def test_current_metadata_artist_consensus(self):
items = [Item({'artist': 'The Beatles', 'album': 'The White Album'}),
Item({'artist': 'The Beatles', 'album': 'The White Album'}),
Item({'artist': 'The Beatles', 'album': 'Teh White Album'})]
l_artist, l_album, artist_consensus = autotag.current_metadata(items)
self.assertEqual(l_artist, 'The Beatles')
self.assertEqual(l_album, 'The White Album')
self.assertTrue(artist_consensus)
class AlbumDistanceTest(unittest.TestCase):
def item(self, title, track, artist='some artist'):