mirror of
https://github.com/beetbox/beets.git
synced 2026-01-02 05:52:50 +01:00
further refactoring: abstract source from matching logic
--HG-- rename : beets/autotag/model.py => beets/autotag/hooks.py
This commit is contained in:
parent
ee78391f4f
commit
064a0432f1
4 changed files with 34 additions and 20 deletions
|
|
@ -18,15 +18,16 @@ import os
|
|||
|
||||
from beets import library, mediafile
|
||||
from beets.util import sorted_walk
|
||||
from . import mb
|
||||
|
||||
# Parts of external interface.
|
||||
from .model import AlbumInfo, TrackInfo
|
||||
from .hooks import AlbumInfo, TrackInfo
|
||||
from .match import tag_item, tag_album
|
||||
from .match import RECOMMEND_STRONG, RECOMMEND_MEDIUM, RECOMMEND_NONE
|
||||
from .match import STRONG_REC_THRESH, MEDIUM_REC_THRESH, REC_GAP_THRESH
|
||||
|
||||
|
||||
# Main interface.
|
||||
# Additional utilities for the main interface.
|
||||
|
||||
def albums_in_dir(path):
|
||||
"""Recursively searches the given directory and returns an iterable
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@
|
|||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""Classes used by metadata sources and the matching logic."""
|
||||
"""Glue between metadata sources and the matching logic."""
|
||||
|
||||
from . import mb
|
||||
|
||||
# Classes used to represent candidate options.
|
||||
|
||||
class AlbumInfo(object):
|
||||
"""Describes a canonical release that may be used to match a release
|
||||
|
|
@ -68,3 +72,18 @@ class TrackInfo(object):
|
|||
self.artist = artist
|
||||
self.artist_id = artist
|
||||
self.length = length
|
||||
|
||||
|
||||
# Aggregation of sources.
|
||||
|
||||
def _album_for_id(album_id):
|
||||
return mb.album_for_id(album_id)
|
||||
|
||||
def _match_album(artist, album, tracks):
|
||||
return mb.match_album(artist, album, tracks)
|
||||
|
||||
def _track_for_id(track_id):
|
||||
return mb.track_for_id(track_id)
|
||||
|
||||
def _match_track(artist, title):
|
||||
return mb.match_track(artist, title)
|
||||
|
|
@ -20,9 +20,9 @@ import re
|
|||
from munkres import Munkres
|
||||
from unidecode import unidecode
|
||||
|
||||
from beets.autotag import mb
|
||||
from beets import plugins
|
||||
from beets.util import levenshtein, plurality
|
||||
from beets.autotag import hooks
|
||||
|
||||
# Distance parameters.
|
||||
# Text distance weights: proportions on the normalized intuitive edit
|
||||
|
|
@ -64,12 +64,6 @@ SD_REPLACE = [
|
|||
(r'&', 'and'),
|
||||
]
|
||||
|
||||
# Try 5 releases. In the future, this should be more dynamic: let the
|
||||
# probability of continuing to the next release be inversely
|
||||
# proportional to how good our current best is and how long we've
|
||||
# already taken.
|
||||
MAX_CANDIDATES = 5
|
||||
|
||||
# Recommendation constants.
|
||||
RECOMMEND_STRONG = 'RECOMMEND_STRONG'
|
||||
RECOMMEND_MEDIUM = 'RECOMMEND_MEDIUM'
|
||||
|
|
@ -304,7 +298,7 @@ def match_by_id(items):
|
|||
if bool(reduce(lambda x,y: x if x==y else (), albumids)):
|
||||
albumid = albumids[0]
|
||||
log.debug('Searching for discovered album ID: ' + albumid)
|
||||
return mb.album_for_id(albumid)
|
||||
return hooks._album_for_id(albumid)
|
||||
else:
|
||||
log.debug('No album ID consensus.')
|
||||
return None
|
||||
|
|
@ -398,7 +392,7 @@ def tag_album(items, timid=False, search_artist=None, search_album=None,
|
|||
# Try to find album indicated by MusicBrainz IDs.
|
||||
if search_id:
|
||||
log.debug('Searching for album ID: ' + search_id)
|
||||
id_info = mb.album_for_id(search_id)
|
||||
id_info = hooks._album_for_id(search_id)
|
||||
else:
|
||||
id_info = match_by_id(items)
|
||||
if id_info:
|
||||
|
|
@ -428,8 +422,8 @@ def tag_album(items, timid=False, search_artist=None, search_album=None,
|
|||
|
||||
# Get candidate metadata from search.
|
||||
if search_artist and search_album:
|
||||
candidates = mb.match_album(search_artist, search_album,
|
||||
len(items), MAX_CANDIDATES)
|
||||
candidates = hooks._match_album(search_artist, search_album,
|
||||
len(items))
|
||||
candidates = list(candidates)
|
||||
else:
|
||||
candidates = []
|
||||
|
|
@ -439,8 +433,7 @@ def tag_album(items, timid=False, search_artist=None, search_album=None,
|
|||
(search_artist.lower() in VA_ARTISTS) or \
|
||||
any(item.comp for item in items)):
|
||||
log.debug(u'Possibly Various Artists; adding matches.')
|
||||
candidates.extend(mb.match_album(None, search_album, len(items),
|
||||
MAX_CANDIDATES))
|
||||
candidates.extend(hooks._match_album(None, search_album, len(items)))
|
||||
|
||||
# Get candidates from plugins.
|
||||
candidates.extend(plugins.candidates(items))
|
||||
|
|
@ -471,7 +464,7 @@ def tag_item(item, timid=False, search_artist=None, search_title=None,
|
|||
trackid = search_id or item.mb_trackid
|
||||
if trackid:
|
||||
log.debug('Searching for track ID: ' + trackid)
|
||||
track_info = mb.track_for_id(trackid)
|
||||
track_info = hooks._track_for_id(trackid)
|
||||
if track_info:
|
||||
dist = track_distance(item, track_info, incl_artist=True)
|
||||
candidates.append((dist, track_info))
|
||||
|
|
@ -494,7 +487,7 @@ def tag_item(item, timid=False, search_artist=None, search_title=None,
|
|||
log.debug(u'Item search terms: %s - %s' % (search_artist, search_title))
|
||||
|
||||
# Candidate metadata from search.
|
||||
for track_info in mb.match_track(search_artist, search_title):
|
||||
for track_info in hooks._match_track(search_artist, search_title):
|
||||
dist = track_distance(item, track_info, incl_artist=True)
|
||||
candidates.append((dist, track_info))
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@ from musicbrainz2.model import Release
|
|||
from threading import Lock
|
||||
from musicbrainz2.model import VARIOUS_ARTISTS_ID
|
||||
|
||||
SEARCH_LIMIT = 10
|
||||
SEARCH_LIMIT = 5
|
||||
VARIOUS_ARTISTS_ID = VARIOUS_ARTISTS_ID.rsplit('/', 1)[1]
|
||||
|
||||
|
||||
class ServerBusyError(Exception): pass
|
||||
class BadResponseError(Exception): pass
|
||||
|
||||
|
|
@ -298,7 +299,7 @@ def match_album(artist, album, tracks=None, limit=SEARCH_LIMIT):
|
|||
criteria['tracks'] = str(tracks)
|
||||
|
||||
# Search for the release.
|
||||
return find_releases(criteria)
|
||||
return find_releases(criteria, limit)
|
||||
|
||||
def match_track(artist, title):
|
||||
"""Searches for a single track and returns an iterable of track
|
||||
|
|
|
|||
Loading…
Reference in a new issue