From 7a4c228c79ff5329d835ffeb17a789504644bf4c Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Thu, 7 Feb 2013 23:35:27 -0800 Subject: [PATCH] style tweaks & doc expansion (#98) --- beets/autotag/match.py | 110 +++++++++++++++++++------------------- docs/changelog.rst | 6 ++- docs/reference/config.rst | 11 +++- 3 files changed, 69 insertions(+), 58 deletions(-) diff --git a/beets/autotag/match.py b/beets/autotag/match.py index 9a69f4ae4..9c6baa576 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -324,64 +324,66 @@ def _recommendation(results): """Given a sorted list of AlbumMatch or TrackMatch objects, return a recommendation based on the results' distances. - If the recommendation is higher than the configured maximum for albums with - missing/extra tracks or differing track lengths/numbers, the recommendation - will be downgraded to the match configured maximum. + If the recommendation is higher than the configured maximum for + certain situations, the recommendation will be downgraded to the + configured maximum. """ if not results: # No candidates: no recommendation. - rec = recommendation.none + return recommendation.none + + # Basic distance thresholding. + min_dist = results[0].distance + if min_dist < config['match']['strong_rec_thresh'].as_number(): + # Strong recommendation level. + rec = recommendation.strong + elif min_dist <= config['match']['medium_rec_thresh'].as_number(): + # Medium recommendation level. + rec = recommendation.medium + elif len(results) == 1: + # Only a single candidate. + rec = recommendation.low + elif results[1].distance - min_dist >= \ + config['match']['rec_gap_thresh'].as_number(): + # Gap between first two candidates is large. + rec = recommendation.low else: - min_dist = results[0].distance - if min_dist < config['match']['strong_rec_thresh'].as_number(): - # Strong recommendation level. - rec = recommendation.strong - elif min_dist <= config['match']['medium_rec_thresh'].as_number(): - # Medium recommendation level. - rec = recommendation.medium - elif len(results) == 1: - # Only a single candidate. - rec = recommendation.low - elif results[1].distance - min_dist >= \ - config['match']['rec_gap_thresh'].as_number(): - # Gap between first two candidates is large. - rec = recommendation.low - else: - # No conclusion. - rec = recommendation.none - # Downgrade recommendation according to configured maximums. - if isinstance(results[0], hooks.AlbumMatch): - # Maximum recommendations. - max_rec = {} - for trigger in ('partial', 'tracklength', 'tracknumber'): - max_rec[trigger] = \ - config['match']['max_rec'][trigger].as_choice({ - 'strong': recommendation.strong, - 'medium': recommendation.medium, - 'low': recommendation.low, - 'none': recommendation.none, - }) - # Partial match. - if rec > max_rec['partial'] and \ - (results[0].extra_items or results[0].extra_tracks): - rec = max_rec['partial'] - downgraded = False - # Check track number and duration for each item. - for item, track_info in results[0].mapping.items(): - # Track length differs. - if rec > max_rec['tracklength'] and item.length and \ - track_info.length and \ - abs(item.length - track_info.length) > \ - TRACK_LENGTH_GRACE: - rec = max_rec['tracklength'] - downgraded = True - # Track number differs. - elif rec > max_rec['tracknumber'] and item.track not in \ - (track_info.index, track_info.medium_index): - rec = max_rec['tracknumber'] - downgraded = True - if downgraded: - break + # No conclusion. + rec = recommendation.none + + # "Downgrades" in certain configured situations. + if isinstance(results[0], hooks.AlbumMatch): + # Load the configured recommendation maxima. + max_rec = {} + for trigger in 'partial', 'tracklength', 'tracknumber': + max_rec[trigger] = \ + config['match']['max_rec'][trigger].as_choice({ + 'strong': recommendation.strong, + 'medium': recommendation.medium, + 'low': recommendation.low, + 'none': recommendation.none, + }) + + # Partial match. + if rec > max_rec['partial'] and \ + (results[0].extra_items or results[0].extra_tracks): + rec = max_rec['partial'] + + # Check track number and duration for each item. + for item, track_info in results[0].mapping.items(): + # Track length differs. + if rec > max_rec['tracklength'] and \ + item.length and track_info.length and \ + abs(item.length - track_info.length) > TRACK_LENGTH_GRACE: + rec = max_rec['tracklength'] + break + + # Track number differs. + elif rec > max_rec['tracknumber'] and item.track not in \ + (track_info.index, track_info.medium_index): + rec = max_rec['tracknumber'] + break + return rec def _add_candidate(items, results, info): diff --git a/docs/changelog.rst b/docs/changelog.rst index b2c35afbd..65fa95177 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,7 +11,8 @@ New configuration options: * :ref:`none_rec_action` lets you skip the prompt, and automatically choose an action, when there is no good candidate. Thanks to Tai Lee. * :ref:`max_rec` lets you define a maximum recommendation for albums with - missing/extra tracks or differing track lengths/numbers. + missing/extra tracks or differing track lengths/numbers. Thanks again to Tai + Lee. * :ref:`clutter` controls which files should be ignored when cleaning up empty directories. Thanks to Steinþór Pálsson. * :doc:`/plugins/lastgenre`: A new configuration option lets you choose to @@ -33,7 +34,8 @@ Other new stuff: * Some changes to the way candidates are recommended for selection, thanks to Tai Lee: - * Partial album matches are downgraded to a "low" recommendation by default. + * According to the new :ref:`max_rec` configuration option, partial album + matches are downgraded to a "low" recommendation by default. * When a match isn't great but is either better than all the others or the only match, it is given a "low" (rather than "medium") recommendation. * There is no prompt default (i.e., input is required) when matches are diff --git a/docs/reference/config.rst b/docs/reference/config.rst index f7a97c121..fc85e2b97 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -351,8 +351,15 @@ options to choose from. max_rec ~~~~~~~ -You can define a maximum recommendation for albums with missing/extra tracks or -differing track lengths/numbers:: +As mentioned above, autotagger matches have *recommendations* that control how +the UI behaves for a certain quality of match. The recommendation for a certain +match is usually based on the distance calculation. But you can also control +the recommendation for certain specific situations by defining *maximum* +recommendations when (a) a match has missing/extra tracks; (b) the track number +for at least one track differs; or (c) the track length for at least one track +differs. + +To define maxima, use keys under ``max_rec:`` in the ``match`` section:: match: max_rec: