コード例 #1
0
    def calc_distance(track_info, track_name, artist_name):
        dist = hooks.Distance()

        dist.add_string('track_title', track_name, track_info.title)

        if track_info.artist:
            dist.add_string('track_artist', artist_name, track_info.artist)

        return dist.distance
コード例 #2
0
def distance(items, album_info, mapping):
    """Determines how "significant" an album metadata change would be.
    Returns a Distance object. `album_info` is an AlbumInfo object
    reflecting the album to be compared. `items` is a sequence of all
    Item objects that will be matched (order is not important).
    `mapping` is a dictionary mapping Items to TrackInfo objects; the
    keys are a subset of `items` and the values are a subset of
    `album_info.tracks`.
    """
    likelies, consensus = current_metadata(items)

    dist = hooks.Distance()

    # Artist, if not various.
    if not album_info.va:
        dist.add_string('artist', likelies['artist'], album_info.artist)

    # Album.
    dist.add_string('album', likelies['album'], album_info.album)

    # Current or preferred media.
    if album_info.media:
        # Preferred media options.
        patterns = config['match']['preferred']['media'].as_str_seq()
        options = [re.compile(r'(\d+x)?(%s)' % pat, re.I) for pat in patterns]
        if options:
            dist.add_priority('media', album_info.media, options)
        # Current media.
        elif likelies['media']:
            dist.add_equality('media', album_info.media, likelies['media'])

    # Mediums.
    if likelies['disctotal'] and album_info.mediums:
        dist.add_number('mediums', likelies['disctotal'], album_info.mediums)

    # Prefer earliest release.
    if album_info.year and config['match']['preferred']['original_year']:
        # Assume 1889 (earliest first gramophone discs) if we don't know the
        # original year.
        original = album_info.original_year or 1889
        diff = abs(album_info.year - original)
        diff_max = abs(datetime.date.today().year - original)
        dist.add_ratio('year', diff, diff_max)
    # Year.
    elif likelies['year'] and album_info.year:
        if likelies['year'] in (album_info.year, album_info.original_year):
            # No penalty for matching release or original year.
            dist.add('year', 0.0)
        elif album_info.original_year:
            # Prefer matchest closest to the release year.
            diff = abs(likelies['year'] - album_info.year)
            diff_max = abs(datetime.date.today().year -
                           album_info.original_year)
            dist.add_ratio('year', diff, diff_max)
        else:
            # Full penalty when there is no original year.
            dist.add('year', 1.0)

    # Preferred countries.
    patterns = config['match']['preferred']['countries'].as_str_seq()
    options = [re.compile(pat, re.I) for pat in patterns]
    if album_info.country and options:
        dist.add_priority('country', album_info.country, options)
    # Country.
    elif likelies['country'] and album_info.country:
        dist.add_string('country', likelies['country'], album_info.country)

    # Label.
    if likelies['label'] and album_info.label:
        dist.add_string('label', likelies['label'], album_info.label)

    # Catalog number.
    if likelies['catalognum'] and album_info.catalognum:
        dist.add_string('catalognum', likelies['catalognum'],
                        album_info.catalognum)

    # Disambiguation.
    if likelies['albumdisambig'] and album_info.albumdisambig:
        dist.add_string('albumdisambig', likelies['albumdisambig'],
                        album_info.albumdisambig)

    # Album ID.
    if likelies['mb_albumid']:
        dist.add_equality('album_id', likelies['mb_albumid'],
                          album_info.album_id)

    # Tracks.
    dist.tracks = {}
    for item, track in mapping.items():
        dist.tracks[track] = track_distance(item, track, album_info.va)
        dist.add('tracks', dist.tracks[track].distance)

    # Track totals
    medium_totals = {}
    for track in album_info.tracks:
        if track.medium_total and track.medium not in medium_totals:
            medium_totals[track.medium] = track.medium_total
    medium_all_total = sum(medium_totals.values())

    # If we have a consensus, and it's the same as the all-disc total,
    # short-circuit the logic and take the simple approach.
    if consensus and likelies['tracktotal'] and likelies['tracktotal'] == medium_all_total:
        pass
    else:
        # The imported track may have tags for per disc numbering or not,
        # so check for both.
        def item_disc(i):
            return i.disc or 0

        items_by_disc = sorted(mapping.keys(), key=item_disc)
        grouped_items = groupby(items_by_disc, item_disc)
        for disc, disc_items in grouped_items:
            medium_total = medium_totals.get(disc, 0)
            tracktotals = set(i.tracktotal for i in disc_items if i.tracktotal)
            for tracktotal in tracktotals:
                if tracktotal != medium_all_total and medium_total:
                    dist.add_number('tracktotal', medium_total, tracktotal)

    # Missing tracks.
    for i in range(len(album_info.tracks) - len(mapping)):
        dist.add('missing_tracks', 1.0)

    # Unmatched tracks.
    for i in range(len(items) - len(mapping)):
        dist.add('unmatched_tracks', 1.0)

    # Plugins.
    dist.update(plugins.album_distance(items, album_info, mapping))

    return dist
コード例 #3
0
    def track_distance(self, session, info):
        dist = hooks.Distance()
        if self.config['filter_on_import'] and not self._has_work_id(info.track_id):
            dist.add('work_id', 1)

        return dist