diff --git a/beets/autotag/match.py b/beets/autotag/match.py index 435e6fb03..bc6a506f6 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -17,6 +17,7 @@ releases and tracks. """ import logging import re +import copy from munkres import Munkres from unidecode import unidecode @@ -31,6 +32,8 @@ ARTIST_WEIGHT = 3.0 ALBUM_WEIGHT = 3.0 # The weight of the entire distance calculated for a given track. TRACK_WEIGHT = 1.0 +# The weight of a missing track. +MISSING_WEIGHT = 0.3 # These distances are components of the track distance (that is, they # compete against each other but not ARTIST_WEIGHT and ALBUM_WEIGHT; # the overall TRACK_WEIGHT does that). @@ -161,7 +164,7 @@ def current_metadata(items): likelies = {} consensus = {} for key in keys: - values = [getattr(item, key) for item in items] + values = [getattr(item, key) for item in items if item] likelies[key], freq = plurality(values) consensus[key] = (freq == len(values)) return likelies['artist'], likelies['album'], consensus['artist'] @@ -269,12 +272,25 @@ def distance(items, album_info): # Track distances. for i, (item, track_info) in enumerate(zip(items, album_info.tracks)): - dist += track_distance(item, track_info, i+1, album_info.va) * \ - TRACK_WEIGHT - dist_max += TRACK_WEIGHT + if item: + dist += track_distance(item, track_info, i+1, album_info.va) * \ + TRACK_WEIGHT + dist_max += TRACK_WEIGHT + else: + dist += MISSING_WEIGHT + dist_max += MISSING_WEIGHT # Plugin distances. - plugin_d, plugin_dm = plugins.album_distance(items, album_info) + # In order not to break compatibility, send purged lists + purged_items, purged_tracks = [], [] + for i, t in zip(items, album_info.tracks): + if i: + purged_items.append(i) + purged_tracks.append(t) + purged_album_info = copy.copy(album_info) + purged_album_info.tracks = purged_tracks + + plugin_d, plugin_dm = plugins.album_distance(purged_items, purged_album_info) dist += plugin_d dist_max += plugin_dm diff --git a/test/test_autotag.py b/test/test_autotag.py index e2f71d94a..0b5ccc535 100644 --- a/test/test_autotag.py +++ b/test/test_autotag.py @@ -94,6 +94,21 @@ class AlbumDistanceTest(unittest.TestCase): ) self.assertEqual(match.distance(items, info), 0) + def test_incomplete_album(self): + items = [] + items.append(self.item('one', 1)) + items.append(self.item('three', 3)) + info = AlbumInfo( + artist = 'some artist', + album = 'some album', + tracks = self.trackinfo(), + va = False, + album_id = None, artist_id = None, + ) + self.assertNotEqual(match.distance(items, info), 0) + # Make sure the distance is not too great + self.assertTrue(match.distance(items, info) < 0.2) + def test_global_artists_differ(self): items = [] items.append(self.item('one', 1))