X-Git-Url: https://diplodocus.org/git/flac-archive/blobdiff_plain/47d39442b35fe1d44133693f95e81c03cab69a9f..4601d7cc2cd896acc9b645aa3708e1aebc8656f6:/fa-rip diff --git a/fa-rip b/fa-rip index 1fe5bbd..be1d5ca 100755 --- a/fa-rip +++ b/fa-rip @@ -82,7 +82,7 @@ it under the same terms as Perl itself. """ -import os, re, sys, tempfile, traceback +import os, re, sys, tempfile, time, traceback from optparse import OptionParser import urllib @@ -148,13 +148,12 @@ def tags_file(fn, trackcount, various, artist=None, album=None, if len(tracks) > 0: trackcount = min(trackcount, len(tracks)) for i in xrange(1, trackcount + 1): - try: + artist = title = '' + if len(tracks) > 0: track = tracks.pop(0) title = track.title - artist = track.artist - except IndexError: - title = '' - artist = '' + if track.artist: + artist = track.artist.name various and c(fp.write, 'ARTIST[%d]=%s\n' % (i, artist.encode('utf-8'))) c(fp.write, 'TITLE[%d]=%s\n' % (i, title.encode('utf-8'))) @@ -167,8 +166,9 @@ def cover_art(i, asin): fp.write(urllib.urlopen(url).read()) fp.close() -def tags(q, releases, trackcount): +def tags(releases, trackcount): results = [] + seen_asins = set() seen_various = False tags_file('candidate-tags-0', trackcount, False) @@ -176,9 +176,8 @@ def tags(q, releases, trackcount): include = musicbrainz2.webservice.ReleaseIncludes(artist=True, tracks=True) i = 0 - for rel_id in releases: + for release in releases: i += 1 - release = q.getReleaseById(rel_id, include) various = not release.isSingleArtistRelease() if various and not seen_various: @@ -189,14 +188,16 @@ def tags(q, releases, trackcount): release.artist.name, release.title, release.getReleaseEventsAsDict(), release.tracks) - - # XXX Not sure if .asin is here after my change above; may need to - # include urlRelations=True. See also: - # for i in release.getRelations(): print i.type - # http://musicbrainz.org/ns/rel-1.0#Wikipedia - # ... - # http://musicbrainz.org/ns/rel-1.0#AmazonAsin - cover_art(str(i), release.asin) + if release.asin: + # See also: + # for i in release.getRelations(): print i.type + # http://musicbrainz.org/ns/rel-1.0#Wikipedia + # ... + # http://musicbrainz.org/ns/rel-1.0#AmazonAsin + asin = release.asin + if asin not in seen_asins: + seen_asins.add(asin) + cover_art(str(i), asin) def rip(device, trackcount, single_file): if device == None: @@ -220,20 +221,37 @@ def make_post_processor(command): c(fp.write, command +' "$@"\n') c(fp.close) -def releases_by_disc(q, disc): - filter = musicbrainz2.webservice.ReleaseFilter(discId=disc.getId()) - # XXX had to change x.getId to x.release.getId on 10.04; is that an API - # change in a newer version (handle both) or is this code I never tested? - return (x.release.getId() for x in q.getReleases(filter)) +def get_releases(filter_, tries=5): + sleep = 1 + query = musicbrainz2.webservice.Query() + while True: + try: + return query.getReleases(filter_) + except musicbrainz2.webservice.WebServiceError, e: + if '503' not in e.msg: + raise + tries -= 1 + sys.stderr.write('getReleases: %s: ' % e) + if tries == 0: + sys.stderr.write('giving up\n') + raise + sleep *= 2 + sys.stderr.write('sleeping %ds before retry...\n' % sleep) + time.sleep(sleep) + +def releases_by_disc(disc_id): + filter_ = musicbrainz2.webservice.ReleaseFilter(discId=disc_id) + return (result.release for result in get_releases(filter_)) def releases_by(q, title, artist=None): - r = q.getReleases(musicbrainz2.webservice.ReleaseFilter(title=title)) - if artist == None: - return r - - artist = re.sub(r'\s+', r'\s+', artist.strip()) - return (x.getId() for x in r if re.match(artist, x.release.artist.name, - re.IGNORECASE) != None) + filter_ = musicbrainz2.webservice.ReleaseFilter(title=title) + results = get_releases(filter_) + releases = (result.release for result in results) + if artist: + pattern = re.sub(r'\s+', r'\s+', artist.strip()) + releases = (x for x in releases + if re.match(pattern, x.artist.name, re.IGNORECASE)) + return releases def main(argv): # Control the exit code for any uncaught exceptions. @@ -241,6 +259,7 @@ def main(argv): parser = OptionParser() parser.disable_interspersed_args() parser.add_option('--artist') + parser.add_option('--discid') parser.add_option('--title') parser.add_option('-d', '--device') parser.add_option('-m', '--no-musicbrainz', @@ -273,20 +292,18 @@ def main(argv): make_post_processor(options.post_processor) - q = musicbrainz2.webservice.Query() if options.title != None: - releases = releases_by(q, options.title, options.artist) + tags(releases_by(q, options.title, options.artist), trackcount) + elif options.discid != None: + tags(releases_by_disc(options.discid), trackcount) else: disc = musicbrainz2.disc.readDisc(device) trackcount = mkcue(disc, trackcount) if options.no_musicbrainz: releases = [] else: - releases = releases_by_disc(q, disc) - - tags(q, releases, trackcount) - - if options.title == None: + releases = releases_by_disc(disc.getId()) + tags(releases, trackcount) rip(device, trackcount, options.single_file) except Exception, error: if isinstance(error, SystemExit):