def __init__(self, aliases=False, releases=(), vaReleases=(), artistRelations=False, releaseRelations=False, trackRelations=False, urlRelations=False, tags=False, ratings=False, releaseGroups=False): assert not isinstance(releases, basestring) assert not isinstance(vaReleases, basestring) assert len(releases) == 0 or len(vaReleases) == 0 self._includes = { 'aliases': aliases, 'artist-rels': artistRelations, 'release-groups': releaseGroups, 'release-rels': releaseRelations, 'track-rels': trackRelations, 'url-rels': urlRelations, 'tags': tags, 'ratings': ratings, } for elem in releases: self._includes['sa-' + mbutils.extractFragment(elem)] = True for elem in vaReleases: self._includes['va-' + mbutils.extractFragment(elem)] = True
def __init__(self, title=None, discId=None, releaseTypes=None, artistName=None, artistId=None, limit=None, offset=None, query=None, trackCount=None): """Constructor. If C{discId} or C{artistId} are set, only releases matching those IDs are returned. The C{releaseTypes} parameter allows to limit the types of the releases returned. You can set it to C{(Release.TYPE_ALBUM, Release.TYPE_OFFICIAL)}, for example, to only get officially released albums. Note that those values are connected using the I{AND} operator. MusicBrainz' support is currently very limited, so C{Release.TYPE_LIVE} and C{Release.TYPE_COMPILATION} exclude each other (see U{the documentation on release attributes <http://wiki.musicbrainz.org/AlbumAttribute>} for more information and all valid values). If both the C{artistName} and the C{artistId} parameter are given, the server will ignore C{artistName}. The C{query} parameter may contain a query in U{Lucene syntax <http://lucene.apache.org/java/docs/queryparsersyntax.html>}. Note that C{query} may not be used together with the other parameters except for C{limit} and C{offset}. @param title: a unicode string containing the release's title @param discId: a unicode string containing the DiscID @param releaseTypes: a sequence of release type URIs @param artistName: a unicode string containing the artist's name @param artistId: a unicode string containing the artist's ID @param limit: the maximum number of releases to return @param offset: start results at this zero-based offset @param query: a string containing a query in Lucene syntax @param trackCount: the number of tracks in the release @see: the constants in L{musicbrainz2.model.Release} """ if releaseTypes is None or len(releaseTypes) == 0: releaseTypesStr = None else: tmp = [ mbutils.extractFragment(x) for x in releaseTypes ] releaseTypesStr = ' '.join(tmp) self._params = [ ('title', title), ('discid', discId), ('releasetypes', releaseTypesStr), ('artist', artistName), ('artistid', mbutils.extractUuid(artistId)), ('limit', limit), ('offset', offset), ('query', query), ('count', trackCount), ] if not _paramsValid(self._params): raise ValueError('invalid combination of parameters')
def getArtist(artistid): with mb_lock: artist_dict = {} #Get all official release groups inc = ws.ArtistIncludes(releases=(m.Release.TYPE_OFFICIAL, m.Release.TYPE_ALBUM), releaseGroups=True) attempt = 0 while attempt < 5: try: artist = q.getArtistById(artistid, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve information from MusicBrainz failed: %s' % e) attempt += 1 time.sleep(1) time.sleep(1) artist_dict['artist_name'] = artist.name artist_dict['artist_sortname'] = artist.sortName artist_dict['artist_uniquename'] = artist.getUniqueName() artist_dict['artist_type'] = u.extractFragment(artist.type) artist_dict['artist_begindate'] = artist.beginDate artist_dict['artist_endDate'] = artist.endDate releasegroups = [] for rg in artist.getReleaseGroups(): releasegroups.append({ 'title': rg.title, 'id': u.extractUuid(rg.id), 'url': rg.id, 'type': u.getReleaseTypeName(rg.type) }) artist_dict['releasegroups'] = releasegroups return artist_dict
def getArtist(artistid, extrasonly=False): with mb_lock: artist_dict = {} #Get all official release groups inc = ws.ArtistIncludes(releases=(m.Release.TYPE_OFFICIAL, m.Release.TYPE_ALBUM), releaseGroups=True) artist = None attempt = 0 while attempt < 5: try: artist = q.getArtistById(artistid, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve artist information from MusicBrainz failed for artistid: %s. Sleeping 5 seconds' % artistid) attempt += 1 time.sleep(5) if not artist: return False time.sleep(1) artist_dict['artist_name'] = artist.name artist_dict['artist_sortname'] = artist.sortName artist_dict['artist_uniquename'] = artist.getUniqueName() artist_dict['artist_type'] = u.extractFragment(artist.type) artist_dict['artist_begindate'] = artist.beginDate artist_dict['artist_enddate'] = artist.endDate releasegroups = [] if not extrasonly: for rg in artist.getReleaseGroups(): releasegroups.append({ 'title': rg.title, 'id': u.extractUuid(rg.id), 'url': rg.id, 'type': u.getReleaseTypeName(rg.type) }) # See if we need to grab extras myDB = db.DBConnection() try: includeExtras = myDB.select('SELECT IncludeExtras from artists WHERE ArtistID=?', [artistid])[0][0] except IndexError: includeExtras = False if includeExtras or headphones.INCLUDE_EXTRAS: includes = [m.Release.TYPE_COMPILATION, m.Release.TYPE_REMIX, m.Release.TYPE_SINGLE, m.Release.TYPE_LIVE, m.Release.TYPE_EP] for include in includes: inc = ws.ArtistIncludes(releases=(m.Release.TYPE_OFFICIAL, include), releaseGroups=True) artist = None attempt = 0 while attempt < 5: try: artist = q.getArtistById(artistid, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve artist information from MusicBrainz failed for artistid: %s. Sleeping 5 seconds' % artistid) attempt += 1 time.sleep(5) if not artist: continue for rg in artist.getReleaseGroups(): releasegroups.append({ 'title': rg.title, 'id': u.extractUuid(rg.id), 'url': rg.id, 'type': u.getReleaseTypeName(rg.type) })
def getReleaseGroup(rgid): """ Returns the best release out of any given release group """ with mb_lock: releaselist = [] inc = ws.ReleaseGroupIncludes(releases=True) releaseGroup = None attempt = 0 while attempt < 5: try: releaseGroup = q.getReleaseGroupById(rgid, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve information from MusicBrainz for release group "%s" failed. Sleeping 5 seconds' % rgid) attempt += 1 time.sleep(5) if not releaseGroup: return False time.sleep(1) # I think for now we have to make separate queries for each release, in order # to get more detailed release info (ASIN, track count, etc.) for release in releaseGroup.releases: inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True) releaseResult = None attempt = 0 while attempt < 5: try: releaseResult = q.getReleaseById(release.id, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve release information for %s from MusicBrainz failed: %s. Sleeping 5 seconds' % (releaseResult.title, e)) attempt += 1 time.sleep(5) if not releaseResult: continue if releaseResult.title.lower() != releaseGroup.title.lower(): continue time.sleep(1) formats = { '2xVinyl': '2', 'Vinyl': '2', 'CD': '0', 'Cassette': '3', '2xCD': '1', 'Digital Media': '0' } country = { 'US': '0', 'GB': '1', 'JP': '1', } try: format = int(replace_all(u.extractFragment(releaseResult.releaseEvents[0].format), formats)) except: format = 3 try: country = int(replace_all(releaseResult.releaseEvents[0].country, country)) except: country = 2 release_dict = { 'hasasin': bool(releaseResult.asin), 'asin': releaseResult.asin, 'trackscount': len(releaseResult.getTracks()), 'releaseid': u.extractUuid(releaseResult.id), 'releasedate': releaseResult.getEarliestReleaseDate(), 'format': format, 'country': country } tracks = [] i = 1 for track in releaseResult.tracks: tracks.append({ 'number': i, 'title': track.title, 'id': u.extractUuid(track.id), 'url': track.id, 'duration': track.duration }) i += 1 release_dict['tracks'] = tracks releaselist.append(release_dict)
def getRelease(releaseid): """ Deep release search to get track info """ with mb_lock: release = {} inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True, releaseGroup=True, artist=True) results = None attempt = 0 while attempt < 5: try: results = q.getReleaseById(releaseid, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve information from MusicBrainz for release "%s" failed: %s. SLeeping 5 seconds' % (releaseid, e)) attempt += 1 time.sleep(5) if not results: return False time.sleep(1) release['title'] = results.title release['id'] = u.extractUuid(results.id) release['asin'] = results.asin release['date'] = results.getEarliestReleaseDate() rg = results.getReleaseGroup() if rg: release['rgid'] = u.extractUuid(rg.id) release['rg_title'] = rg.title release['rg_type'] = u.extractFragment(rg.type) else: logger.warn("Release " + releaseid + "had no ReleaseGroup associated") #so we can start with a releaseID from anywhere and get the artist info #it looks like MB api v1 only returns 1 artist object - 2.0 returns more... release['artist_name'] = results.artist.name release['artist_id'] = u.extractUuid(results.artist.id) tracks = [] i = 1 for track in results.tracks: tracks.append({ 'number': i, 'title': track.title, 'id': u.extractUuid(track.id), 'url': track.id, 'duration': track.duration }) i += 1 release['tracks'] = tracks return release
for item in releaselist: item['trackscount_delta'] = abs(average_tracks - item['trackscount']) a = multikeysort(releaselist, ['-hasasin', 'country', 'format', 'trackscount_delta']) release_dict = {'releaseid' :a[0]['releaseid'], 'releasedate' : releaselist[0]['releasedate'], 'trackcount' : a[0]['trackscount'], 'tracks' : a[0]['tracks'], 'asin' : a[0]['asin'], 'releaselist' : releaselist, 'artist_name' : releaseGroup.artist.name, 'artist_id' : u.extractUuid(releaseGroup.artist.id), 'title' : releaseGroup.title, 'type' : u.extractFragment(releaseGroup.type) } return release_dict def getRelease(releaseid): """ Deep release search to get track info """ with mb_lock: release = {} inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True, releaseGroup=True, artist=True) results = None attempt = 0
def getReleaseGroup(rgid): """ Returns a dictionary of the best stuff from a release group """ with mb_lock: releaselist = [] inc = ws.ReleaseGroupIncludes(releases=True, artist=True) releaseGroup = None attempt = 0 while attempt < 5: try: releaseGroup = q.getReleaseGroupById(rgid, inc) break except WebServiceError, e: logger.warn( 'Attempt to retrieve information from MusicBrainz for release group "%s" failed. Sleeping 5 seconds' % rgid) attempt += 1 time.sleep(5) if not releaseGroup: return False time.sleep(1) # I think for now we have to make separate queries for each release, in order # to get more detailed release info (ASIN, track count, etc.) for release in releaseGroup.releases: inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True) releaseResult = None attempt = 0 while attempt < 5: try: releaseResult = q.getReleaseById(release.id, inc) break except WebServiceError, e: logger.warn( 'Attempt to retrieve release information for %s from MusicBrainz failed: %s. Sleeping 5 seconds' % (releaseResult.title, e)) attempt += 1 time.sleep(5) if not releaseResult: continue # Release filter for non-official live albums types = releaseResult.getTypes() if any('Live' in type for type in types): if not any('Official' in type for type in types): logger.debug('%s is not an official live album. Skipping' % releaseResult.name) continue time.sleep(1) formats = { '2xVinyl': '2', 'Vinyl': '2', 'CD': '0', 'Cassette': '3', '2xCD': '1', 'Digital Media': '0' } country = { 'US': '0', 'GB': '1', 'JP': '2', } try: format = int( replace_all( u.extractFragment( releaseResult.releaseEvents[0].format), formats)) except: format = 3 try: country = int( replace_all(releaseResult.releaseEvents[0].country, country)) except: country = 3 release_dict = { 'hasasin': bool(releaseResult.asin), 'asin': releaseResult.asin, 'trackscount': len(releaseResult.getTracks()), 'releaseid': u.extractUuid(releaseResult.id), 'releasedate': releaseResult.getEarliestReleaseDate(), 'format': format, 'country': country } tracks = [] i = 1 for track in releaseResult.tracks: tracks.append({ 'number': i, 'title': track.title, 'id': u.extractUuid(track.id), 'url': track.id, 'duration': track.duration }) i += 1 release_dict['tracks'] = tracks releaselist.append(release_dict)
def getRelease(releaseid): """ Deep release search to get track info """ with mb_lock: release = {} inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True, releaseGroup=True, artist=True) results = None attempt = 0 while attempt < 5: try: results = q.getReleaseById(releaseid, inc) break except WebServiceError, e: logger.warn( 'Attempt to retrieve information from MusicBrainz for release "%s" failed: %s. SLeeping 5 seconds' % (releaseid, e)) attempt += 1 time.sleep(5) if not results: return False time.sleep(1) release['title'] = results.title release['id'] = u.extractUuid(results.id) release['asin'] = results.asin release['date'] = results.getEarliestReleaseDate() rg = results.getReleaseGroup() if rg: release['rgid'] = u.extractUuid(rg.id) release['rg_title'] = rg.title release['rg_type'] = u.extractFragment(rg.type) else: logger.warn("Release " + releaseid + "had no ReleaseGroup associated") #so we can start with a releaseID from anywhere and get the artist info #it looks like MB api v1 only returns 1 artist object - 2.0 returns more... release['artist_name'] = results.artist.name release['artist_id'] = u.extractUuid(results.artist.id) tracks = [] i = 1 for track in results.tracks: tracks.append({ 'number': i, 'title': track.title, 'id': u.extractUuid(track.id), 'url': track.id, 'duration': track.duration }) i += 1 release['tracks'] = tracks return release
def getArtist(artistid, extrasonly=False): with mb_lock: artist_dict = {} #Get all official release groups inc = ws.ArtistIncludes(releases=(m.Release.TYPE_OFFICIAL, m.Release.TYPE_ALBUM), releaseGroups=True) artist = None attempt = 0 while attempt < 5: try: artist = q.getArtistById(artistid, inc) break except WebServiceError, e: logger.warn( 'Attempt to retrieve artist information from MusicBrainz failed for artistid: %s. Sleeping 5 seconds' % artistid) attempt += 1 time.sleep(5) if not artist: return False time.sleep(1) artist_dict['artist_name'] = artist.name artist_dict['artist_sortname'] = artist.sortName artist_dict['artist_uniquename'] = artist.getUniqueName() artist_dict['artist_type'] = u.extractFragment(artist.type) artist_dict['artist_begindate'] = artist.beginDate artist_dict['artist_enddate'] = artist.endDate releasegroups = [] if not extrasonly: for rg in artist.getReleaseGroups(): releasegroups.append({ 'title': rg.title, 'id': u.extractUuid(rg.id), 'url': rg.id, 'type': u.getReleaseTypeName(rg.type) }) # See if we need to grab extras myDB = db.DBConnection() try: includeExtras = myDB.select( 'SELECT IncludeExtras from artists WHERE ArtistID=?', [artistid])[0][0] except IndexError: includeExtras = False if includeExtras or headphones.INCLUDE_EXTRAS: includes = [ m.Release.TYPE_COMPILATION, m.Release.TYPE_REMIX, m.Release.TYPE_SINGLE, m.Release.TYPE_LIVE, m.Release.TYPE_EP, m.Release.TYPE_SOUNDTRACK ] for include in includes: inc = ws.ArtistIncludes(releases=(m.Release.TYPE_OFFICIAL, include), releaseGroups=True) artist = None attempt = 0 while attempt < 5: try: artist = q.getArtistById(artistid, inc) break except WebServiceError, e: logger.warn( 'Attempt to retrieve artist information from MusicBrainz failed for artistid: %s. Sleeping 5 seconds' % artistid) attempt += 1 time.sleep(5) if not artist: continue for rg in artist.getReleaseGroups(): releasegroups.append({ 'title': rg.title, 'id': u.extractUuid(rg.id), 'url': rg.id, 'type': u.getReleaseTypeName(rg.type) })
a = multikeysort( releaselist, ['-hasasin', 'country', 'format', 'trackscount_delta']) release_dict = { 'releaseid': a[0]['releaseid'], 'releasedate': releaselist[0]['releasedate'], 'trackcount': a[0]['trackscount'], 'tracks': a[0]['tracks'], 'asin': a[0]['asin'], 'releaselist': releaselist, 'artist_name': releaseGroup.artist.name, 'artist_id': u.extractUuid(releaseGroup.artist.id), 'title': releaseGroup.title, 'type': u.extractFragment(releaseGroup.type) } return release_dict def getRelease(releaseid): """ Deep release search to get track info """ with mb_lock: release = {} inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True,
def getReleaseGroup(rgid): """ Returns a dictionary of the best stuff from a release group """ with mb_lock: releaselist = [] inc = ws.ReleaseGroupIncludes(releases=True, artist=True) releaseGroup = None attempt = 0 while attempt < 5: try: releaseGroup = q.getReleaseGroupById(rgid, inc) break except WebServiceError, e: logger.warn( 'Attempt to retrieve information from MusicBrainz for release group "%s" failed. Sleeping 5 seconds' % rgid ) attempt += 1 time.sleep(5) if not releaseGroup: return False time.sleep(1) # I think for now we have to make separate queries for each release, in order # to get more detailed release info (ASIN, track count, etc.) for release in releaseGroup.releases: inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True) releaseResult = None attempt = 0 while attempt < 5: try: releaseResult = q.getReleaseById(release.id, inc) break except WebServiceError, e: logger.warn( "Attempt to retrieve release information for %s from MusicBrainz failed: %s. Sleeping 5 seconds" % (releaseResult.title, e) ) attempt += 1 time.sleep(5) if not releaseResult: continue # Release filter for non-official live albums types = releaseResult.getTypes() if any("Live" in type for type in types): if not any("Official" in type for type in types): logger.debug("%s is not an official live album. Skipping" % releaseResult.name) continue time.sleep(1) formats = {"2xVinyl": "2", "Vinyl": "2", "CD": "0", "Cassette": "3", "2xCD": "1", "Digital Media": "0"} country = {"US": "0", "GB": "1", "JP": "2"} try: format = int(replace_all(u.extractFragment(releaseResult.releaseEvents[0].format), formats)) except: format = 3 try: country = int(replace_all(releaseResult.releaseEvents[0].country, country)) except: country = 3 release_dict = { "hasasin": bool(releaseResult.asin), "asin": releaseResult.asin, "trackscount": len(releaseResult.getTracks()), "releaseid": u.extractUuid(releaseResult.id), "releasedate": releaseResult.getEarliestReleaseDate(), "format": format, "country": country, } tracks = [] i = 1 for track in releaseResult.tracks: tracks.append( { "number": i, "title": track.title, "id": u.extractUuid(track.id), "url": track.id, "duration": track.duration, } ) i += 1 release_dict["tracks"] = tracks releaselist.append(release_dict)
for item in releaselist: item["trackscount_delta"] = abs(average_tracks - item["trackscount"]) a = multikeysort(releaselist, ["-hasasin", "country", "format", "trackscount_delta"]) release_dict = { "releaseid": a[0]["releaseid"], "releasedate": releaselist[0]["releasedate"], "trackcount": a[0]["trackscount"], "tracks": a[0]["tracks"], "asin": a[0]["asin"], "releaselist": releaselist, "artist_name": releaseGroup.artist.name, "artist_id": u.extractUuid(releaseGroup.artist.id), "title": releaseGroup.title, "type": u.extractFragment(releaseGroup.type), } return release_dict def getRelease(releaseid): """ Deep release search to get track info """ with mb_lock: release = {} inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True, releaseGroup=True, artist=True) results = None
def getReleaseGroup(rgid): """ Returns a dictionary of the best stuff from a release group """ with mb_lock: releaselist = [] inc = ws.ReleaseGroupIncludes(releases=True, artist=True) releaseGroup = None attempt = 0 q, sleepytime = startmb() while attempt < 5: try: releaseGroup = q.getReleaseGroupById(rgid, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve information from MusicBrainz for release group "%s" failed (%s)' % (rgid, str(e))) attempt += 1 time.sleep(5) if not releaseGroup: return False time.sleep(sleepytime) # I think for now we have to make separate queries for each release, in order # to get more detailed release info (ASIN, track count, etc.) for release in releaseGroup.releases: inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True) releaseResult = None attempt = 0 while attempt < 5: try: releaseResult = q.getReleaseById(release.id, inc) break except WebServiceError, e: logger.warn('Attempt to retrieve release information for %s from MusicBrainz failed (%s)' % (releaseResult.title, str(e))) attempt += 1 time.sleep(5) if not releaseResult: continue # Release filter for non-official live albums types = releaseResult.getTypes() if any('Live' in type for type in types): if not any('Official' in type for type in types): logger.debug('%s is not an official live album. Skipping' % releaseResult.name) continue time.sleep(sleepytime) formats = { '2xVinyl': '2', 'Vinyl': '2', 'CD': '0', 'Cassette': '3', '2xCD': '1', 'Digital Media': '0' } country = { 'US': '0', 'GB': '1', 'JP': '2', } try: format = int(replace_all(u.extractFragment(releaseResult.releaseEvents[0].format), formats)) except: format = 3 try: country = int(replace_all(releaseResult.releaseEvents[0].country, country)) except: country = 3 release_dict = { 'hasasin': bool(releaseResult.asin), 'asin': releaseResult.asin, 'trackscount': len(releaseResult.getTracks()), 'releaseid': u.extractUuid(releaseResult.id), 'releasedate': releaseResult.getEarliestReleaseDate(), 'format': format, 'country': country } tracks = [] i = 1 for track in releaseResult.tracks: tracks.append({ 'number': i, 'title': track.title, 'id': u.extractUuid(track.id), 'url': track.id, 'duration': track.duration }) i += 1 release_dict['tracks'] = tracks releaselist.append(release_dict)