mirror of
https://github.com/beetbox/beets.git
synced 2025-12-10 10:32:34 +01:00
merge
This commit is contained in:
commit
d453f5911d
6 changed files with 26 additions and 15 deletions
1
NEWS
1
NEWS
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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':
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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__)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue