Exemple #1
0
def main(argv):
    # load plugins

    from morituri.configure import configure
    pluginsdir = configure.pluginsdir
    homepluginsdir = os.path.join(os.path.expanduser('~'),
        '.morituri', 'plugins')

    distributions, errors = pkg_resources.working_set.find_plugins(
        pkg_resources.Environment([pluginsdir, homepluginsdir]))
    if errors:
        log.warning('errors finding plugins: %r', errors)
    log.debug('mapping distributions %r', distributions)
    map(pkg_resources.working_set.add, distributions)

    # validate dependencies
    from morituri.common import deps
    h = deps.DepsHandler()
    h.validate()

    # set user agent
    import musicbrainzngs
    musicbrainzngs.set_useragent("morituri", configure.version,
        'https://thomas.apestaart.org/morituri/trac')


    c = Rip()
    try:
        ret = c.parse(argv)
    except SystemError, e:
        sys.stderr.write('rip: error: %s\n' % e.args)
        return 255
Exemple #2
0
def main(argv):
    # load plugins

    from morituri.configure import configure
    pluginsdir = configure.pluginsdir
    homepluginsdir = os.path.join(os.path.expanduser('~'), '.morituri',
                                  'plugins')

    distributions, errors = pkg_resources.working_set.find_plugins(
        pkg_resources.Environment([pluginsdir, homepluginsdir]))
    if errors:
        log.warning('errors finding plugins: %r', errors)
    log.debug('mapping distributions %r', distributions)
    map(pkg_resources.working_set.add, distributions)

    # validate dependencies
    from morituri.common import deps
    h = deps.DepsHandler()
    h.validate()

    # set user agent
    from morituri.extern.musicbrainzngs import musicbrainz
    musicbrainz.set_useragent("morituri", configure.version,
                              'https://thomas.apestaart.org/morituri/trac')

    c = Rip()
    try:
        ret = c.parse(argv)
    except SystemError, e:
        sys.stderr.write('rip: error: %s\n' % e.args)
        return 255
Exemple #3
0
def _getMetadata(release):
    """
    @type  release: L{musicbrainz2.model.Release}

    @rtype: L{DiscMetadata} or None
    """
    log.debug('program', 'getMetadata for release id %r',
        release.getId())
    if not release.getId():
        log.warning('program', 'No id for release %r', release)
        return None

    assert release.id, 'Release does not have an id'

    metadata = DiscMetadata()

    isSingleArtist = release.isSingleArtistRelease()
    metadata.various = not isSingleArtist
    metadata.title = release.title
    # getUniqueName gets disambiguating names like Muse (UK rock band)
    metadata.artist = release.artist.name
    metadata.sortName = release.artist.sortName
    metadata.release = release.getEarliestReleaseDate()

    metadata.mbid = urlparse.urlparse(release.id)[2].split("/")[-1]
    metadata.mbidArtist = urlparse.urlparse(
        release.artist.id)[2].split("/")[-1]
    metadata.url = release.getId()

    tainted = False
    duration = 0

    for t in release.tracks:
        track = TrackMetadata()

        if isSingleArtist or t.artist == None:
            track.artist = metadata.artist
            track.sortName = metadata.sortName
            track.mbidArtist = metadata.mbidArtist
        else:
            # various artists discs can have tracks with no artist
            track.artist = t.artist and t.artist.name or release.artist.name
            track.sortName = t.artist.sortName
            track.mbidArtist = urlparse.urlparse(t.artist.id)[2].split("/")[-1]

        track.title = t.title
        track.mbid = urlparse.urlparse(t.id)[2].split("/")[-1]

        track.duration = t.duration
        if not track.duration:
            log.warning('getMetadata',
                'track %r (%r) does not have duration' % (
                    track.title, track.mbid))
            tainted = True
        else:
            duration += t.duration

        metadata.tracks.append(track)

    if not tainted:
        metadata.duration = duration
    else:
        metadata.duration = 0

    return metadata
Exemple #4
0
def _getMetadata(releaseShort, release, discid, country=None):
    """
    @type  release: C{dict}
    @param release: a release dict as returned in the value for key release
                    from get_release_by_id

    @rtype: L{DiscMetadata} or None
    """
    log.debug('program', 'getMetadata for release id %r', release['id'])
    if not release['id']:
        log.warning('program', 'No id for release %r', release)
        return None

    assert release['id'], 'Release does not have an id'

    if 'country' in release and country and release['country'] != country:
        log.warning('program', '%r was not released in %r', release, country)
        return None

    discMD = DiscMetadata()

    discMD.releaseType = releaseShort.get('release-group', {}).get('type')
    discCredit = _Credit(release['artist-credit'])

    # FIXME: is there a better way to check for VA ?
    discMD.various = False
    if discCredit[0]['artist']['id'] == VA_ID:
        discMD.various = True

    if len(discCredit) > 1:
        log.debug('mbngs', 'artist-credit more than 1: %r', discCredit)

    albumArtistName = discCredit.getName()

    # getUniqueName gets disambiguating names like Muse (UK rock band)
    discMD.artist = albumArtistName
    discMD.sortName = discCredit.getSortName()
    # FIXME: is format str ?
    if not 'date' in release:
        log.warning('mbngs', 'Release %r does not have date', release)
    else:
        discMD.release = release['date']

    discMD.mbid = release['id']
    discMD.mbidArtist = discCredit.getIds()
    discMD.url = 'https://musicbrainz.org/release/' + release['id']

    discMD.barcode = release.get('barcode', None)
    lil = release.get('label-info-list', [{}])
    if lil:
        discMD.catalogNumber = lil[0].get('catalog-number')
    tainted = False
    duration = 0

    # only show discs from medium-list->disc-list with matching discid
    for medium in release['medium-list']:
        for disc in medium['disc-list']:
            if disc['id'] == discid:
                title = release['title']
                discMD.releaseTitle = title
                if 'disambiguation' in release:
                    title += " (%s)" % release['disambiguation']
                count = len(release['medium-list'])
                if count > 1:
                    title += ' (Disc %d of %d)' % (int(
                        medium['position']), count)
                if 'title' in medium:
                    title += ": %s" % medium['title']
                discMD.title = title
                for t in medium['track-list']:
                    track = TrackMetadata()
                    trackCredit = _Credit(t['recording']['artist-credit'])
                    if len(trackCredit) > 1:
                        log.debug('mbngs', 'artist-credit more than 1: %r',
                                  trackCredit)

                    # FIXME: leftover comment, need an example
                    # various artists discs can have tracks with no artist
                    track.artist = trackCredit.getName()
                    track.sortName = trackCredit.getSortName()
                    track.mbidArtist = trackCredit.getIds()

                    track.title = t['recording']['title']
                    track.mbid = t['recording']['id']

                    # FIXME: unit of duration ?
                    track.duration = int(t['recording'].get('length', 0))
                    if not track.duration:
                        log.warning(
                            'getMetadata',
                            'track %r (%r) does not have duration' %
                            (track.title, track.mbid))
                        tainted = True
                    else:
                        duration += track.duration

                    discMD.tracks.append(track)

                if not tainted:
                    discMD.duration = duration
                else:
                    discMD.duration = 0

    return discMD
def _getMetadata(release, discid):
    """
    @type  release: C{dict}
    @param release: a release dict as returned in the value for key release
                    from get_release_by_id

    @rtype: L{DiscMetadata} or None
    """
    log.debug('program', 'getMetadata for release id %r',
        release['id'])
    if not release['id']:
        log.warning('program', 'No id for release %r', release)
        return None

    assert release['id'], 'Release does not have an id'

    metadata = DiscMetadata()

    credit = release['artist-credit']

    artist = credit[0]['artist']

    if len(credit) > 1:
        log.debug('musicbrainzngs', 'artist-credit more than 1: %r', credit)

    for i, c in enumerate(credit):
        if isinstance(c, dict):
            credit[i] = c.get(
                'name', c['artist'].get('name', None))

    albumArtistName = "".join(credit)

    # FIXME: is there a better way to check for VA
    metadata.various = False
    if artist['id'] == VA_ID:
        metadata.various = True

    # getUniqueName gets disambiguating names like Muse (UK rock band)
    metadata.artist = albumArtistName
    metadata.sortName = artist['sort-name']
    # FIXME: is format str ?
    if not 'date' in release:
        log.warning('musicbrainzngs', 'Release %r does not have date', release)
    else:
        metadata.release = release['date']

    metadata.mbid = release['id']
    metadata.mbidArtist = artist['id']
    metadata.url = 'http://musicbrainz.org/release/' + release['id']

    tainted = False
    duration = 0

    # only show discs from medium-list->disc-list with matching discid
    for medium in release['medium-list']:
        for disc in medium['disc-list']:
            if disc['id'] == discid:
                title = release['title']
                metadata.releaseTitle = title
                if 'disambiguation' in release:
                    title += " (%s)" % release['disambiguation']
                count = len(release['medium-list'])
                if count > 1:
                    title += ' (Disc %d of %d)' % (
                        int(medium['position']), count)
                if 'title' in medium:
                    title += ": %s" % medium['title']
                metadata.title = title
                for t in medium['track-list']:
                    track = TrackMetadata()
                    credit = t['recording']['artist-credit']
                    if len(credit) > 1:
                        log.debug('musicbrainzngs',
                            'artist-credit more than 1: %r', credit)
                        # credit is of the form [dict, str, dict, ... ]
                    for i, c in enumerate(credit):
                        if isinstance(c, dict):
                            credit[i] = c.get(
                                'name', c['artist'].get('name', None))


                    trackArtistName = "".join(credit)

                    if not artist:
                        track.artist = metadata.artist
                        track.sortName = metadata.sortName
                        track.mbidArtist = metadata.mbidArtist
                    else:
                        # various artists discs can have tracks with no artist
                        track.artist = trackArtistName
                        track.sortName = artist['sort-name']
                        track.mbidArtist = artist['id']

                    track.title = t['recording']['title']
                    track.mbid = t['recording']['id']

                    # FIXME: unit of duration ?
                    track.duration = int(t['recording'].get('length', 0))
                    if not track.duration:
                        log.warning('getMetadata',
                            'track %r (%r) does not have duration' % (
                                track.title, track.mbid))
                        tainted = True
                    else:
                        duration += track.duration

                    metadata.tracks.append(track)

                if not tainted:
                    metadata.duration = duration
                else:
                    metadata.duration = 0

    return metadata
Exemple #6
0
def _getMetadata(releaseShort, release, discid, country=None):
    """
    @type  release: C{dict}
    @param release: a release dict as returned in the value for key release
                    from get_release_by_id

    @rtype: L{DiscMetadata} or None
    """
    log.debug('program', 'getMetadata for release id %r',
        release['id'])
    if not release['id']:
        log.warning('program', 'No id for release %r', release)
        return None

    assert release['id'], 'Release does not have an id'

    if 'country' in release and country and release['country'] != country:
        log.warning('program', '%r was not released in %r', release, country)
        return None

    discMD = DiscMetadata()

    discMD.releaseType = releaseShort.get('release-group', {}).get('type')
    discCredit = _Credit(release['artist-credit'])

    # FIXME: is there a better way to check for VA ?
    discMD.various = False
    if discCredit[0]['artist']['id'] == VA_ID:
        discMD.various = True


    if len(discCredit) > 1:
        log.debug('mbngs', 'artist-credit more than 1: %r', discCredit)

    albumArtistName = discCredit.getName()

    # getUniqueName gets disambiguating names like Muse (UK rock band)
    discMD.artist = albumArtistName
    discMD.sortName = discCredit.getSortName()
    # FIXME: is format str ?
    if not 'date' in release:
        log.warning('mbngs', 'Release %r does not have date', release)
    else:
        discMD.release = release['date']

    discMD.mbid = release['id']
    discMD.mbidArtist = discCredit.getIds()
    discMD.url = 'https://musicbrainz.org/release/' + release['id']

    discMD.barcode = release.get('barcode', None)
    lil = release.get('label-info-list', [{}])
    if lil:
        discMD.catalogNumber = lil[0].get('catalog-number')
    tainted = False
    duration = 0

    # only show discs from medium-list->disc-list with matching discid
    for medium in release['medium-list']:
        for disc in medium['disc-list']:
            if disc['id'] == discid:
                title = release['title']
                discMD.releaseTitle = title
                if 'disambiguation' in release:
                    title += " (%s)" % release['disambiguation']
                count = len(release['medium-list'])
                if count > 1:
                    title += ' (Disc %d of %d)' % (
                        int(medium['position']), count)
                if 'title' in medium:
                    title += ": %s" % medium['title']
                discMD.title = title
                for t in medium['track-list']:
                    track = TrackMetadata()
                    trackCredit = _Credit(t['recording']['artist-credit'])
                    if len(trackCredit) > 1:
                        log.debug('mbngs',
                            'artist-credit more than 1: %r', trackCredit)

                    # FIXME: leftover comment, need an example
                    # various artists discs can have tracks with no artist
                    track.artist = trackCredit.getName()
                    track.sortName = trackCredit.getSortName()
                    track.mbidArtist = trackCredit.getIds()

                    track.title = t['recording']['title']
                    track.mbid = t['recording']['id']

                    # FIXME: unit of duration ?
                    track.duration = int(t['recording'].get('length', 0))
                    if not track.duration:
                        log.warning('getMetadata',
                            'track %r (%r) does not have duration' % (
                                track.title, track.mbid))
                        tainted = True
                    else:
                        duration += track.duration

                    discMD.tracks.append(track)

                if not tainted:
                    discMD.duration = duration
                else:
                    discMD.duration = 0

    return discMD
Exemple #7
0
def _getMetadata(releaseShort, release, discid, country=None):
    """
    @type  release: C{dict}
    @param release: a release dict as returned in the value for key release
                    from get_release_by_id

    @rtype: L{DiscMetadata} or None
    """
    log.debug("program", "getMetadata for release id %r", release["id"])
    if not release["id"]:
        log.warning("program", "No id for release %r", release)
        return None

    assert release["id"], "Release does not have an id"

    if "country" in release and country and release["country"] != country:
        log.warning("program", "%r was not released in %r", release, country)
        return None

    discMD = DiscMetadata()

    discMD.releaseType = releaseShort.get("release-group", {}).get("type")
    discCredit = _Credit(release["artist-credit"])

    # FIXME: is there a better way to check for VA ?
    discMD.various = False
    if discCredit[0]["artist"]["id"] == VA_ID:
        discMD.various = True

    if len(discCredit) > 1:
        log.debug("mbngs", "artist-credit more than 1: %r", discCredit)

    albumArtistName = discCredit.getName()

    # getUniqueName gets disambiguating names like Muse (UK rock band)
    discMD.artist = albumArtistName
    discMD.sortName = discCredit.getSortName()
    # FIXME: is format str ?
    if not "date" in release:
        log.warning("mbngs", "Release %r does not have date", release)
    else:
        discMD.release = release["date"]

    discMD.mbid = release["id"]
    discMD.mbidArtist = discCredit.getIds()
    discMD.url = "https://musicbrainz.org/release/" + release["id"]

    discMD.barcode = release.get("barcode", None)
    lil = release.get("label-info-list", [{}])
    if lil:
        discMD.catalogNumber = lil[0].get("catalog-number")
    tainted = False
    duration = 0

    # only show discs from medium-list->disc-list with matching discid
    for medium in release["medium-list"]:
        for disc in medium["disc-list"]:
            if disc["id"] == discid:
                title = release["title"]
                discMD.releaseTitle = title
                if "disambiguation" in release:
                    title += " (%s)" % release["disambiguation"]
                count = len(release["medium-list"])
                if count > 1:
                    title += " (Disc %d of %d)" % (int(medium["position"]), count)
                if "title" in medium:
                    title += ": %s" % medium["title"]
                discMD.title = title
                for t in medium["track-list"]:
                    track = TrackMetadata()
                    trackCredit = _Credit(t["recording"]["artist-credit"])
                    if len(trackCredit) > 1:
                        log.debug("mbngs", "artist-credit more than 1: %r", trackCredit)

                    # FIXME: leftover comment, need an example
                    # various artists discs can have tracks with no artist
                    track.artist = trackCredit.getName()
                    track.sortName = trackCredit.getSortName()
                    track.mbidArtist = trackCredit.getIds()

                    track.title = t["recording"]["title"]
                    track.mbid = t["recording"]["id"]

                    # FIXME: unit of duration ?
                    track.duration = int(t["recording"].get("length", 0))
                    if not track.duration:
                        log.warning("getMetadata", "track %r (%r) does not have duration" % (track.title, track.mbid))
                        tainted = True
                    else:
                        duration += track.duration

                    discMD.tracks.append(track)

                if not tainted:
                    discMD.duration = duration
                else:
                    discMD.duration = 0

    return discMD
Exemple #8
0
def _getMetadata(release):
    """
    @type  release: L{musicbrainz2.model.Release}

    @rtype: L{DiscMetadata} or None
    """
    log.debug('program', 'getMetadata for release id %r',
        release.getId())
    if not release.getId():
        log.warning('program', 'No id for release %r', release)
        return None

    assert release.id, 'Release does not have an id'

    metadata = DiscMetadata()

    isSingleArtist = release.isSingleArtistRelease()
    metadata.various = not isSingleArtist
    metadata.title = release.title
    # getUniqueName gets disambiguating names like Muse (UK rock band)
    metadata.artist = release.artist.name
    metadata.sortName = release.artist.sortName
    metadata.release = release.getEarliestReleaseDate()

    metadata.mbid = urlparse.urlparse(release.id)[2].split("/")[-1]
    metadata.mbidArtist = urlparse.urlparse(release.artist.id)[2].split("/")[-1]
    metadata.url = release.getId()

    tainted = False
    duration = 0

    for t in release.tracks:
        track = TrackMetadata()

        if isSingleArtist or t.artist == None:
            track.artist = metadata.artist
            track.sortName = metadata.sortName
            track.mbidArtist = metadata.mbidArtist
        else:
            # various artists discs can have tracks with no artist
            track.artist = t.artist and t.artist.name or release.artist.name
            track.sortName = t.artist.sortName
            track.mbidArtist = urlparse.urlparse(t.artist.id)[2].split("/")[-1]

        track.title = t.title
        track.mbid = urlparse.urlparse(t.id)[2].split("/")[-1]

        track.duration = t.duration
        if not track.duration:
            log.warning('getMetadata',
                'track %r (%r) does not have duration' % (
                    track.title, track.mbid))
            tainted = True
        else:
            duration += t.duration

        metadata.tracks.append(track)

    if not tainted:
        metadata.duration = duration
    else:
        metadata.duration = 0

    return metadata
def _getMetadata(release, discid):
    """
    @type  release: C{dict}
    @param release: a release dict as returned in the value for key release
                    from get_release_by_id

    @rtype: L{DiscMetadata} or None
    """
    log.debug('program', 'getMetadata for release id %r', release['id'])
    if not release['id']:
        log.warning('program', 'No id for release %r', release)
        return None

    assert release['id'], 'Release does not have an id'

    metadata = DiscMetadata()

    credit = release['artist-credit']

    artist = credit[0]['artist']

    if len(credit) > 1:
        log.debug('musicbrainzngs', 'artist-credit more than 1: %r', credit)

    for i, c in enumerate(credit):
        if isinstance(c, dict):
            credit[i] = c.get('name', c['artist'].get('name', None))

    albumArtistName = "".join(credit)

    # FIXME: is there a better way to check for VA
    metadata.various = False
    if artist['id'] == VA_ID:
        metadata.various = True

    # getUniqueName gets disambiguating names like Muse (UK rock band)
    metadata.artist = albumArtistName
    metadata.sortName = artist['sort-name']
    # FIXME: is format str ?
    if not 'date' in release:
        log.warning('musicbrainzngs', 'Release %r does not have date', release)
    else:
        metadata.release = release['date']

    metadata.mbid = release['id']
    metadata.mbidArtist = artist['id']
    metadata.url = 'http://musicbrainz.org/release/' + release['id']

    tainted = False
    duration = 0

    # only show discs from medium-list->disc-list with matching discid
    for medium in release['medium-list']:
        for disc in medium['disc-list']:
            if disc['id'] == discid:
                title = release['title']
                metadata.releaseTitle = title
                if 'disambiguation' in release:
                    title += " (%s)" % release['disambiguation']
                count = len(release['medium-list'])
                if count > 1:
                    title += ' (Disc %d of %d)' % (int(
                        medium['position']), count)
                if 'title' in medium:
                    title += ": %s" % medium['title']
                metadata.title = title
                for t in medium['track-list']:
                    track = TrackMetadata()
                    credit = t['recording']['artist-credit']
                    if len(credit) > 1:
                        log.debug('musicbrainzngs',
                                  'artist-credit more than 1: %r', credit)
                        # credit is of the form [dict, str, dict, ... ]
                    for i, c in enumerate(credit):
                        if isinstance(c, dict):
                            credit[i] = c.get('name',
                                              c['artist'].get('name', None))

                    trackArtistName = "".join(credit)

                    if not artist:
                        track.artist = metadata.artist
                        track.sortName = metadata.sortName
                        track.mbidArtist = metadata.mbidArtist
                    else:
                        # various artists discs can have tracks with no artist
                        track.artist = trackArtistName
                        track.sortName = artist['sort-name']
                        track.mbidArtist = artist['id']

                    track.title = t['recording']['title']
                    track.mbid = t['recording']['id']

                    # FIXME: unit of duration ?
                    track.duration = int(t['recording'].get('length', 0))
                    if not track.duration:
                        log.warning(
                            'getMetadata',
                            'track %r (%r) does not have duration' %
                            (track.title, track.mbid))
                        tainted = True
                    else:
                        duration += track.duration

                    metadata.tracks.append(track)

                if not tainted:
                    metadata.duration = duration
                else:
                    metadata.duration = 0

    return metadata
def _getMetadata(releaseShort, release, discid):
    """
    @type  release: C{dict}
    @param release: a release dict as returned in the value for key release
                    from get_release_by_id

    @rtype: L{DiscMetadata} or None
    """
    log.debug("program", "getMetadata for release id %r", release["id"])
    if not release["id"]:
        log.warning("program", "No id for release %r", release)
        return None

    assert release["id"], "Release does not have an id"

    metadata = DiscMetadata()

    metadata.releaseType = releaseShort.get("release-group", {}).get("type")
    credit = release["artist-credit"]

    artist = credit[0]["artist"]

    if len(credit) > 1:
        log.debug("musicbrainzngs", "artist-credit more than 1: %r", credit)

    for i, c in enumerate(credit):
        if isinstance(c, dict):
            credit[i] = c.get("name", c["artist"].get("name", None))

    albumArtistName = "".join(credit)

    # FIXME: is there a better way to check for VA
    metadata.various = False
    if artist["id"] == VA_ID:
        metadata.various = True

    # getUniqueName gets disambiguating names like Muse (UK rock band)
    metadata.artist = albumArtistName
    metadata.sortName = artist["sort-name"]
    # FIXME: is format str ?
    if not "date" in release:
        log.warning("musicbrainzngs", "Release %r does not have date", release)
    else:
        metadata.release = release["date"]

    metadata.mbid = release["id"]
    metadata.mbidArtist = artist["id"]
    metadata.url = "http://musicbrainz.org/release/" + release["id"]

    metadata.barcode = release.get("barcode", None)
    lil = release.get("label-info-list", [{}])
    if lil:
        metadata.catalogNumber = lil[0].get("catalog-number")
    tainted = False
    duration = 0

    # only show discs from medium-list->disc-list with matching discid
    for medium in release["medium-list"]:
        for disc in medium["disc-list"]:
            if disc["id"] == discid:
                title = release["title"]
                metadata.releaseTitle = title
                if "disambiguation" in release:
                    title += " (%s)" % release["disambiguation"]
                count = len(release["medium-list"])
                if count > 1:
                    title += " (Disc %d of %d)" % (int(medium["position"]), count)
                if "title" in medium:
                    title += ": %s" % medium["title"]
                metadata.title = title
                for t in medium["track-list"]:
                    track = TrackMetadata()
                    credit = t["recording"]["artist-credit"]
                    if len(credit) > 1:
                        log.debug("musicbrainzngs", "artist-credit more than 1: %r", credit)
                        # credit is of the form [dict, str, dict, ... ]
                    for i, c in enumerate(credit):
                        if isinstance(c, dict):
                            credit[i] = c.get("name", c["artist"].get("name", None))

                    trackArtistName = "".join(credit)

                    if not artist:
                        track.artist = metadata.artist
                        track.sortName = metadata.sortName
                        track.mbidArtist = metadata.mbidArtist
                    else:
                        # various artists discs can have tracks with no artist
                        track.artist = trackArtistName
                        track.sortName = artist["sort-name"]
                        track.mbidArtist = artist["id"]

                    track.title = t["recording"]["title"]
                    track.mbid = t["recording"]["id"]

                    # FIXME: unit of duration ?
                    track.duration = int(t["recording"].get("length", 0))
                    if not track.duration:
                        log.warning("getMetadata", "track %r (%r) does not have duration" % (track.title, track.mbid))
                        tainted = True
                    else:
                        duration += track.duration

                    metadata.tracks.append(track)

                if not tainted:
                    metadata.duration = duration
                else:
                    metadata.duration = 0

    return metadata