Example #1
0
def match_by_id(items):
    """If the items are tagged with a MusicBrainz album ID, returns an
    info dict for the corresponding album. Otherwise, returns None.
    """
    # Is there a consensus on the MB album ID?
    albumids = [item.mb_albumid for item in items if item.mb_albumid]
    if not albumids:
        log.debug('No album IDs found.')
        return None
    
    # If all album IDs are equal, look up the album.
    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)
    else:
        log.debug('No album ID consensus.')
        return None
Example #2
0
def _album_for_id(album_id):
    """Get an album corresponding to a MusicBrainz release ID."""
    return mb.album_for_id(album_id)
Example #3
0
def _album_for_id(album_id):
    """Get an album corresponding to a MusicBrainz release ID."""
    try:
        return mb.album_for_id(album_id)
    except mb.MusicBrainzAPIError as exc:
        exc.log(log)
Example #4
0
    if isinstance(path, basestring):
        out = art_in_path(path)
        if out:
            return out

    if album.asin:
        log.debug('Fetching album art for ASIN %s.' % album.asin)
        out = art_for_asin(album.asin)
        if out:
            return out
        return aao_art(album.asin)
    else:
        log.debug('No ASIN available: no art found.')
        return None


# Smoke test.

if __name__ == '__main__':
    aid = sys.argv[1]
    album = album_for_id(aid)
    if not album:
        print 'album not found'
    else:
        fn = art_for_album(album, None)
        if fn:
            print fn
            print len(open(fn).read())/1024
        else:
            print 'no art found'
Example #5
0
    if isinstance(path, basestring):
        out = art_in_path(path)
        if out:
            return out

    if album.asin:
        log.debug('Fetching album art for ASIN %s.' % album.asin)
        out = art_for_asin(album.asin)
        if out:
            return out
        return aao_art(album.asin)
    else:
        log.debug('No ASIN available: no art found.')
        return None


# Smoke test.

if __name__ == '__main__':
    aid = sys.argv[1]
    album = album_for_id(aid)
    if not album:
        print 'album not found'
    else:
        fn = art_for_album(album, None)
        if fn:
            print fn
            print len(open(fn).read()) / 1024
        else:
            print 'no art found'
Example #6
0
def _album_for_id(album_id):
    """Get an album corresponding to a MusicBrainz release ID."""
    try:
        return mb.album_for_id(album_id)
    except mb.MusicBrainzAPIError as exc:
        exc.log(log)
Example #7
0
def tag_album(items, timid=False, search_artist=None, search_album=None,
              search_id=None):
    """Bundles together the functionality used to infer tags for a
    set of items comprised by an album. Returns everything relevant:
        - The current artist.
        - The current album.
        - A list of (distance, items, info) tuples where info is a
          dictionary containing the inferred tags and items is a
          reordered version of the input items list. The candidates are
          sorted by distance (i.e., best match first).
        - A recommendation, one of RECOMMEND_STRONG, RECOMMEND_MEDIUM,
          or RECOMMEND_NONE; indicating that the first candidate is
          very likely, it is somewhat likely, or no conclusion could
          be reached.
    If search_artist and search_album or search_id are provided, then
    they are used as search terms in place of the current metadata.
    May raise an AutotagError if existing metadata is insufficient.
    """
    # Get current metadata.
    cur_artist, cur_album, artist_consensus = current_metadata(items)
    log.debug('Tagging %s - %s' % (cur_artist, cur_album))
    
    # The output result tuples (keyed by MB album ID).
    out_tuples = {}
    
    # 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)
    else:
        id_info = match_by_id(items)
    if id_info:
        validate_candidate(items, out_tuples, id_info)
        rec = recommendation(out_tuples.values())
        log.debug('Album ID match recommendation is ' + str(rec))
        if out_tuples and not timid:
            # If we have a very good MBID match, return immediately.
            # Otherwise, this match will compete against metadata-based
            # matches.
            if rec == RECOMMEND_STRONG:
                log.debug('ID match.')
                return cur_artist, cur_album, out_tuples.values(), rec

    # If searching by ID, don't continue to metadata search.
    if search_id is not None:
        if out_tuples:
            return cur_artist, cur_album, out_tuples.values(), rec
        else:
            return cur_artist, cur_album, [], RECOMMEND_NONE
    
    # Search terms.
    if not (search_artist and search_album):
        # No explicit search terms -- use current metadata.
        search_artist, search_album = cur_artist, cur_album
    log.debug(u'Search terms: %s - %s' % (search_artist, search_album))
    
    # Get candidate metadata from search.
    if search_artist and search_album:
        candidates = mb.match_album(search_artist, search_album,
                                    len(items), MAX_CANDIDATES)
        candidates = list(candidates)
    else:
        candidates = []

    # Possibly add "various artists" search.
    if search_album and ((not artist_consensus) or \
                         (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))

    # Get candidates from plugins.
    candidates.extend(plugins.candidates(items))
    
    # Get the distance to each candidate.
    log.debug(u'Evaluating %i candidates.' % len(candidates))
    for info in candidates:
        validate_candidate(items, out_tuples, info)
    
    # Sort by distance.
    out_tuples = out_tuples.values()
    out_tuples.sort()
    
    rec = recommendation(out_tuples)
    return cur_artist, cur_album, out_tuples, rec
Example #8
0
def _album_for_id(album_id):
    """Get an album corresponding to a MusicBrainz release ID."""
    return mb.album_for_id(album_id)