mirror of
https://github.com/beetbox/beets.git
synced 2026-01-02 05:52:50 +01:00
manual searching for singletons
(Still on a plane.)
This commit is contained in:
parent
69dc998d7c
commit
375e335002
3 changed files with 40 additions and 15 deletions
|
|
@ -482,7 +482,7 @@ def tag_album(items, search_artist=None, search_album=None):
|
|||
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))
|
||||
log.debug(u'Search terms: %s - %s' % (search_artist, search_album))
|
||||
|
||||
# Get candidate metadata from search.
|
||||
if search_artist and search_album:
|
||||
|
|
@ -496,7 +496,7 @@ def tag_album(items, search_artist=None, search_album=None):
|
|||
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.')
|
||||
log.debug(u'Possibly Various Artists; adding matches.')
|
||||
candidates.extend(mb.match_album(None, search_album, len(items),
|
||||
MAX_CANDIDATES))
|
||||
|
||||
|
|
@ -504,7 +504,7 @@ def tag_album(items, search_artist=None, search_album=None):
|
|||
candidates.extend(plugins.candidates(items))
|
||||
|
||||
# Get the distance to each candidate.
|
||||
log.debug('Evaluating %i candidates.' % len(candidates))
|
||||
log.debug(u'Evaluating %i candidates.' % len(candidates))
|
||||
for info in candidates:
|
||||
validate_candidate(items, out_tuples, info)
|
||||
|
||||
|
|
@ -515,10 +515,12 @@ def tag_album(items, search_artist=None, search_album=None):
|
|||
rec = recommendation(out_tuples)
|
||||
return cur_artist, cur_album, out_tuples, rec
|
||||
|
||||
def tag_item(item):
|
||||
def tag_item(item, search_artist=None, search_title=None):
|
||||
"""Attempts to find metadata for a single track. Returns a
|
||||
`(candidates, recommendation)` pair where `candidates` is a list
|
||||
of `(distance, track_info)` pairs.
|
||||
of `(distance, track_info)` pairs. `search_artist` and
|
||||
`search_title` may be used to override the current metadata for
|
||||
the purposes of the MusicBrainz category.
|
||||
"""
|
||||
candidates = []
|
||||
|
||||
|
|
@ -534,9 +536,14 @@ def tag_item(item):
|
|||
if rec == RECOMMEND_STRONG:
|
||||
log.debug('Track ID match.')
|
||||
return candidates, rec
|
||||
|
||||
# Search terms.
|
||||
if not (search_artist and search_title):
|
||||
search_artist, search_title = item.artist, item.title
|
||||
log.debug(u'Item search terms: %s - %s' % (search_artist, search_title))
|
||||
|
||||
# Candidate metadata from search.
|
||||
for track_info in mb.match_track(item.artist, item.title):
|
||||
for track_info in mb.match_track(search_artist, search_title):
|
||||
dist = track_distance(item, track_info, incl_artist=True)
|
||||
candidates.append((dist, track_info))
|
||||
|
||||
|
|
|
|||
|
|
@ -294,11 +294,14 @@ def choose_candidate(candidates, singleton, rec, color,
|
|||
elif sel == 'b':
|
||||
raise importer.ImportAbort()
|
||||
|
||||
def manual_search():
|
||||
"""Input an artist and album for manual search."""
|
||||
def manual_search(singleton):
|
||||
"""Input either an artist and album (for full albums) or artist and
|
||||
track name (for singletons) for manual search.
|
||||
"""
|
||||
artist = raw_input('Artist: ').decode(sys.stdin.encoding)
|
||||
album = raw_input('Album: ').decode(sys.stdin.encoding)
|
||||
return artist.strip(), album.strip()
|
||||
name = raw_input('Track: ' if singleton else 'Album: ') \
|
||||
.decode(sys.stdin.encoding)
|
||||
return artist.strip(), name.strip()
|
||||
|
||||
def choose_match(task, config):
|
||||
"""Given an initial autotagging of items, go through an interactive
|
||||
|
|
@ -332,7 +335,7 @@ def choose_match(task, config):
|
|||
return choice
|
||||
elif choice is importer.action.MANUAL:
|
||||
# Try again with manual search terms.
|
||||
search_artist, search_album = manual_search()
|
||||
search_artist, search_album = manual_search(False)
|
||||
try:
|
||||
_, _, candidates, rec = \
|
||||
autotag.tag_album(items, search_artist, search_album)
|
||||
|
|
@ -341,6 +344,7 @@ def choose_match(task, config):
|
|||
else:
|
||||
# We have a candidate! Finish tagging. Here, choice is
|
||||
# an (info, items) pair as desired.
|
||||
assert not isinstance(choice, importer.action)
|
||||
return choice
|
||||
|
||||
def choose_item(task, config):
|
||||
|
|
@ -362,10 +366,24 @@ def choose_item(task, config):
|
|||
else:
|
||||
return _quiet_fall_back(config)
|
||||
|
||||
else:
|
||||
while True:
|
||||
# Ask for a choice.
|
||||
return choose_candidate(candidates, True, rec, config.color,
|
||||
item=task.items[0])
|
||||
choice = choose_candidate(candidates, True, rec, config.color,
|
||||
item=task.items[0])
|
||||
|
||||
if choice in (importer.action.SKIP, importer.action.ASIS):
|
||||
return choice
|
||||
elif choice == importer.action.TRACKS:
|
||||
assert False # TRACKS is only legal for albums.
|
||||
elif choice == importer.action.MANUAL:
|
||||
# Continue in the loop with a new set of candidates.
|
||||
search_artist, search_title = manual_search(False)
|
||||
candidates, rec = autotag.tag_item(task.items[0], search_artist,
|
||||
search_title)
|
||||
else:
|
||||
# Chose a candidate.
|
||||
assert not isinstance(choice, importer.action)
|
||||
return choice
|
||||
|
||||
# The import command.
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ class InputTest(unittest.TestCase):
|
|||
def test_manual_search_gets_unicode(self):
|
||||
self.io.addinput('\xc3\x82me')
|
||||
self.io.addinput('\xc3\x82me')
|
||||
artist, album = commands.manual_search()
|
||||
artist, album = commands.manual_search(False)
|
||||
self.assertEqual(artist, u'\xc2me')
|
||||
self.assertEqual(album, u'\xc2me')
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue