def getReleases(self, artistResult): q = Query() offset = 0 limit = 100 releaseResults = set() while True: try: f = ReleaseFilter(artistId=artistResult.getKey( MusicbrainzSource._sourceName), offset=offset, limit=limit) results = q.getReleases(f) except WebServiceError, e: raise SourceError count = len(results) results = filter(lambda res: res.getScore() == 100, results) for r in results: rr = ReleaseResult( title=r.getRelease().getTitle(), date=r.getRelease().getEarliestReleaseDate(), tracksCount=r.getRelease().getTracksCount()) rr.setKey(MusicbrainzSource._sourceName, r.getRelease().getId()) releaseResults.add(rr) if count < limit: break offset += count
def populate_album_set(self): """ Find and create models for all albums released by this artist. Only albums with an Amazon ASIN are imported, to try and stop the database getting clogged up with b-sides, remixes, and bonus material. """ # We can't do anything without the MusicBrainz and Last.fm libraries. try: ReleaseFilter except NameError: return False # Find any official album release held by MusicBrainz for this artist. filter = ReleaseFilter(artistName=self.name, releaseTypes=(Release.TYPE_ALBUM, Release.TYPE_OFFICIAL)) query = Query() releases = query.getReleases(filter) for release in releases: album = release.release # Only import albums with an Amazon ASIN. That allows for some # quality-control as Music Brainz lists every B-side and bonus # material you can think of. if album.asin: # First try and find an already-existing album with this ASIN # As an ASIN is unique it means we'll find it even if the fields # have been changed since creation. try: db_album = Album.objects.get(asin=album.asin) except Album.DoesNotExist: db_album = Album(artist=self, title=album.title, asin=album.asin, mbid=album.id.rsplit("/", 1)[1]) # MusicBrainz stores releases dates for as many countries as # it can. I'm only interested in Britain though, so look # for that first. As a fallback, us the world wide release # date (XE) or the US release date. release_dates = dict( (r.country, r.date) for r in album.releaseEvents) if release_dates: # GB = United Kingdom, XE = world, US = United States. for country in ('GB', 'XE', 'US'): if release_dates.has_key(country): db_album.released_in = country # The release date can be in the format "2010", # "2010-02", or "2010-02-18", so make up the # missing month and/or day so a proper release # date object can be created. release_date = release_dates[country] date_list = map(int, release_date.split('-')) try: db_album.release_date = datetime.date( *date_list + [1] * (3 - len(date_list))) except ValueError: pass # Date couldn't be parsed. break db_album.save()
def __init__(self, username, password, server='https://musicbrainz.org'): self.user_agent = 'zeroinch-bot/1.0 ( %s/user/%s )' % (server, username) self.ws = WebService(userAgent=self.user_agent, host=re.sub(r'^http://', '', server), username=username, password=password) self.q = Query(self.ws)
def find_artist_and_title(puid): q = Query() try: f = TrackFilter(puid=sys.argv[1]) results = q.getTracks(f) except WebServiceError, e: print 'Error:', e sys.exit(1)
def lookup_puid(self, _puid): q = Query() f = TrackFilter(puid=_puid) try: r = q.getTracks(f) track = r[0].track return track except: print 'MusicBrainz::lookup_puid: Error finding track metadata.' # raise AssertionError('MusicBrainz::lookup_puid: Error finding track metadata.') return None
def find_releases(puid): """Given a track's puid, return a list of (track-no, track, release) for each release that the song appeared on on.""" query = Query() trackfilter = TrackFilter(puid=puid) results = query.getTracks(trackfilter) out = [] for result in results: track = result.track rels = track.getReleases() assert len(rels) == 1 rel = rels[0] out.append((rel.getTracksOffset()+1, track, rel)) return out
def get_musicbrainz_id(self): """ Retrieve the MusicBrainz id for this artist and save it on the model. """ # Make sure the useful bits of the musicbrainz2 package have been # imported. try: Query, ArtistFilter except NameError: return False # Query MusicBrainz. artist_filter = ArtistFilter(name=self.name) query = Query() try: artist = query.getArtists(artist_filter)[0].artist self.mbid = artist.id.rsplit("/", 1)[1] self.save() except (IndexError, AttributeError): return False
def getArtists(self, name, date=None, disambiguation=None): q = Query() if disambiguation: disPattern = re.compile(disambiguation, re.I) else: disPattern = None offset = 0 limit = 100 artistResults = set() while True: try: f = ArtistFilter(name=name, offset=offset, limit=limit) results = q.getArtists(f) except WebServiceError, e: raise SourceError results = filter(lambda res: res.getScore() == 100, results) # use filtered count because resulsts are score-ordered count = len(results) results = filter( lambda res: (not date or res.getArtist().getBeginDate() == date) and (not disPattern or disPattern.search(res.getArtist( ).getDisambiguation())), results) for r in results: ar = ArtistResult(name=r.getArtist().getName(), date=r.getArtist().getBeginDate(), disambiguation=disambiguation) # use original disambiguation cause it'll be used in # artist's comparation ar.setKey(MusicbrainzSource._sourceName, r.getArtist().getId()) artistResults.add(ar) if count < limit: break offset += count
import logging from musicbrainz2.webservice import Query, ArtistFilter, WebServiceError, ReleaseFilter, ArtistIncludes, ReleaseIncludes import musicbrainz2.model as m from time import sleep import codecs logging.basicConfig() logger = logging.getLogger() logger.setLevel(logging.ERROR) sys.stdout = codecs.getwriter('utf8')(sys.stdout) # workaround for pipes if len(sys.argv) < 2: print "Usage:", os.path.basename(sys.argv[0]), "'artist name' [offset]" sys.exit(1) q = Query() try: # Search for all artists matching the given name. Limit the results # to the 5 best matches. The offset parameter could be used to page # through the results. # f = ArtistFilter(name=sys.argv[1], limit=10) artistResults = q.getArtists(f) except WebServiceError, e: print 'Error:', e sys.exit(1) if len(sys.argv) > 2: artistResults = [artistResults[int(sys.argv[2])]] else:
def submit_isrcs(self, tracks2isrcs): q = Query(self.ws) q.submitISRCs(tracks2isrcs)
def get_release(self, gid): q = Query(self.ws) inc = ReleaseIncludes(tracks=True, isrcs=True) return q.getReleaseById(gid, include=inc)
for arg in sys.argv[1:]: if os.path.isdir(arg): for root, dirs, files2 in walk(arg): files.extend([os.path.join(root, file) for file in files2]) elif os.path.isfile(arg): files.append(arg) toSubmit = {} for file in files: file = file.decode(encoding) fileId = tp.addFile(file, 0) print ("Adding %s (%s)" % (file, fileId)).encode('ascii', 'ignore') ws = WebService(host=server, username=username, password=password) q = Query(ws, clientId='puid_submit.py-%s' % (__version__,)) analyzed = {} while tp.getNumFiles(): ret, type, fileId, status = tp.getNotification() if not ret: continue print ret,type,fileId,status tr = tp.getTrack(fileId) tr.lock() fileName = tr.getFileName() mdata = tr.getLocalMetadata() tr.unlock()
def __init__(self, releaseId): #self.ignoreMissing(True) super(MusicBrainz2AlbumInfo, self).__init__() if isinstance(releaseId, basestring): self.__releaseId = releaseId query = Query() include = ReleaseIncludes(artist=True, tracks=True, releaseEvents=True) release = query.getReleaseById(releaseId, include) elif isinstance(releaseId, Release): release = releaseId self.__releaseId = release.id else: raise Exception( "incorrect type parameter for MusicBrainz2AlbumInfo %s" % releaseId) self.title = release.title # XXX: musicbrainz doesn't have genre info. what to do? #self.genre = 'Musicbrainz' self.artist = release.artist.name date = release.getEarliestReleaseDate() if not date: self.year = 0 else: self.year = int(date[0:4]) self.genre = '' tracks = [] number = 0 self.isVarious = False for track in release.tracks: number += 1 # XXX: get rid of the overcomplicated validation scheme that makes # for these ugly hacks class MBTrackInfo(TrackInfo): '''Represent musicbrainz track information.''' def getPlayLength(self): 'getter' return self.__playLength def setPlayLength(self, playLength): 'setter' self.__playLength = playLength def __init__(self): super(MBTrackInfo, self).__init__() playLength = property(getPlayLength, setPlayLength) track_info = MBTrackInfo() del track_info.validateProps[ track_info.validateProps.index('playLength')] track_info.number = number if track.duration: track_info.playLength = track.duration / 1000.0 else: # XXX: make sure we don't use namebinder relying on track length track_info.playLength = 0 if track.artist: track_info.artist = track.artist.name self.isVarious = True else: track_info.artist = release.artist.name track_info.title = track.title tracks.append(track_info) self.tracks = tracks