This commit is contained in:
Adrian Sampson 2010-09-27 15:32:06 -07:00
commit d453f5911d
6 changed files with 26 additions and 15 deletions

1
NEWS
View file

@ -30,6 +30,7 @@
* Fixed bug that completely broke non-autotagged imports ("import -A").
* Fixed bug that logged the wrong paths when using "import -l".
* Fixed autotagging for the creatively-named band !!!.
* Fixed normalization of relative paths.
* Efficiency tweak should reduce the number of MusicBrainz queries per
autotagged album.
* A new "-v" command line switch enables debugging output.

View file

@ -55,8 +55,8 @@ RECOMMEND_STRONG = 'RECOMMEND_STRONG'
RECOMMEND_MEDIUM = 'RECOMMEND_MEDIUM'
RECOMMEND_NONE = 'RECOMMEND_NONE'
# Thresholds for recommendations.
STRONG_REC_THRESH = 0.03
MEDIUM_REC_THRESH = 0.2
STRONG_REC_THRESH = 0.04
MEDIUM_REC_THRESH = 0.25
REC_GAP_THRESH = 0.25
# Parameters for string distance function.
@ -66,16 +66,15 @@ SD_END_WORDS = ['the', 'a', 'an']
SD_PATTERNS = [
(r'^the ', 0.1),
(r'[\[\(]?(ep|single)[\]\)]?', 0.0),
(r'[\[\(]?(featuring|feat|ft)[\. :]', 0.3),
(r'[\[\(]?(featuring|feat|ft)[\. :].+', 0.1),
(r'\(.*?\)', 0.3),
(r'\[.*?\]', 0.3),
(r'(, )?(pt\.|part) .+', 0.2),
]
# Autotagging exceptions.
class AutotagError(Exception):
pass
class InsufficientMetadataError(AutotagError):
pass
# Global logger.
log = logging.getLogger('beets')
@ -197,7 +196,9 @@ def string_dist(str1, str2):
# the current case), recalculate the distances for the
# modified strings.
case_dist = _string_dist_basic(case_str1, case_str2)
case_delta = max(0, base_dist - case_dist)
case_delta = max(0.0, base_dist - case_dist)
if case_delta == 0.0:
continue
# Shift our baseline strings down (to avoid rematching the
# same part of the string) and add a scaled distance
@ -468,6 +469,7 @@ def tag_album(items, search_artist=None, search_album=None):
"""
# Get current metadata.
cur_artist, cur_album = current_metadata(items)
log.debug('Tagging %s - %s' % (cur_artist, cur_album))
# The output result tuples (keyed by MB album ID).
out_tuples = {}
@ -482,20 +484,22 @@ def tag_album(items, search_artist=None, search_album=None):
# matches.
rec = recommendation(out_tuples)
if rec == RECOMMEND_STRONG:
log.debug('ID match for %s - %s.' % (cur_artist, cur_album))
log.debug('ID match.')
return cur_artist, cur_album, out_tuples.values(), rec
# Search terms.
if not (search_artist and search_album):
# No explicit search terms -- use current metadata.
search_artist, search_album = cur_artist, cur_album
log.debug('Search terms: %s - %s' % (search_artist, search_album))
# Get candidate metadata from search.
if not search_artist or not search_album:
raise InsufficientMetadataError()
candidates = mb.match_album(search_artist, search_album,
len(items), MAX_CANDIDATES)
candidates = list(candidates)
if search_artist and search_album:
candidates = mb.match_album(search_artist, search_album,
len(items), MAX_CANDIDATES)
candidates = list(candidates)
else:
candidates = []
# Get candidates from plugins.
candidates.extend(plugins.candidates(items))

View file

@ -283,6 +283,8 @@ class Item(object):
"""
if read_path is None:
read_path = self.path
else:
read_path = _normpath(read_path)
f = MediaFile(read_path)
for key in ITEM_KEYS_META:

View file

@ -211,7 +211,7 @@ def choose_match(path, items, cur_artist, cur_album, candidates,
print_("No match found for:", path)
sel = ui.input_options(
"[U]se as-is, Skip, Enter manual search, or aBort?",
('u', 's', 'e'), 'u',
('u', 's', 'e', 'b'), 'u',
'Enter U, S, E, or B:'
)
if sel == 'u':

View file

@ -85,7 +85,7 @@ class LastIdPlugin(BeetsPlugin):
dist, dist_max = 0.0, 0.0
# Track title distance.
dist += autotag._ie_dist(last_data['title'],
dist += autotag.string_dist(last_data['title'],
info['title']) \
* autotag.TRACK_TITLE_WEIGHT
dist_max += autotag.TRACK_TITLE_WEIGHT
@ -108,7 +108,7 @@ class LastIdPlugin(BeetsPlugin):
# Compare artist to MusicBrainz metadata.
dist, dist_max = 0.0, 0.0
dist += autotag._ie_dist(last_artist, info['artist']) \
dist += autotag.string_dist(last_artist, info['artist']) \
* autotag.ARTIST_WEIGHT
dist_max += autotag.ARTIST_WEIGHT

View file

@ -305,6 +305,10 @@ class StringDistanceTest(unittest.TestCase):
autotag.string_dist('(EP)', '(EP)')
autotag.string_dist(', An', '')
def test_heuristic_does_not_harm_distance(self):
dist = autotag.string_dist('Untitled', '[Untitled]')
self.assertEqual(dist, 0.0)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)