Commits

Adrian Sampson committed 67f0ea7 Merge

Merge pull request #98 from mrmachine/low-rec-triggers

Add `low_rec_triggers` setting.

  • Participants
  • Parent commits 3aa9e2a, 0ac4743

Comments (0)

Files changed (4)

File beets/autotag/match.py

 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 not results:
         # No candidates: no recommendation.
     else:
         min_dist = results[0].distance
         if min_dist < config['match']['strong_rec_thresh'].as_number():
-            # Partial matches get downgraded to "medium".
-            if isinstance(results[0], hooks.AlbumMatch) and \
-                    (results[0].extra_items or results[0].extra_tracks):
-                rec = recommendation.medium
-            else:
-                # Strong recommendation level.
-                rec = recommendation.strong
+            # Strong recommendation level.
+            rec = recommendation.strong
         elif min_dist <= config['match']['medium_rec_thresh'].as_number():
             # Medium recommendation level.
             rec = recommendation.medium
             # Only a single candidate.
             rec = recommendation.low
         elif results[1].distance - min_dist >= \
-                    config['match']['rec_gap_thresh'].as_number():
+                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
     return rec
 
 def _add_candidate(items, results, info):

File beets/config_default.yaml

     strong_rec_thresh: 0.04
     medium_rec_thresh: 0.25
     rec_gap_thresh: 0.25
+    max_rec:
+        partial: low
+        tracklength: medium
+        tracknumber: medium

File docs/changelog.rst

   is when considering a candidate.
 * :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.
 * :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
 * Some changes to the way candidates are recommended for selection, thanks to
   Tai Lee:
 
-  * Partial album matches are never "strong" recommendations.
+  * 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

File docs/reference/config.rst

 that match but not automatically confirm it. Otherwise, you'll see a list of
 options to choose from.
 
+.. _max_rec:
+
+max_rec
+~~~~~~~
+
+You can define a maximum recommendation for albums with missing/extra tracks or
+differing track lengths/numbers::
+
+    match:
+        max_rec:
+            partial: low
+            tracklength: medium
+            tracknumber: medium
+
+If a recommendation is higher than the configured maximum and the condition is
+met, the recommendation will be downgraded. The maximum for each condition can
+be one of ``none``, ``low``, ``medium`` or ``strong``.
+
 .. _path-format-config:
 
 Path Format Configuration