def find_all_albums(self) -> None: """Find all albums for the chosen artist.""" limit, offset, page = (100, 0, 1) resp_0 = addict.Dict( musicbrainzngs.browse_release_groups(artist=self.artist_id, release_type=['album'], limit=limit)) total_releases = resp_0['release-group-count'] response_releases = len(resp_0['release-group-list']) with click.progressbar( length=total_releases, label= f'Searching Musicbrainz for all albums from {self.artist}', ) as bar: release_group_ids = addict.Dict( (i.id, i.title) for i in resp_0['release-group-list'] if i.type == 'Album') bar.update(response_releases) while response_releases > 0: # Get next page offset += limit page += 1 resp_1 = addict.Dict( musicbrainzngs.browse_release_groups( artist=self.artist_id, release_type=['album'], limit=limit, offset=offset, )) response_releases = len(resp_1['release-group-list']) release_group_ids = addict.Dict( **release_group_ids, **addict.Dict((i.id, i.title) for i in resp_1['release-group-list'] if i.type == 'Album'), ) bar.update(response_releases) self.release_group_ids = release_group_ids click.echo(f'Found {len(release_group_ids)} albums for {self.artist}.') del (resp_0, resp_1) return self
def browse_release_groups(artist_id=None, release_types=None, limit=None, offset=None): """Get all release groups linked to an artist. You need to provide artist's MusicBrainz ID. """ if release_types is None: release_types = [] key = cache.gen_key(artist_id, limit, offset, *release_types) release_groups = cache.get(key) if not release_groups: try: api_resp = musicbrainzngs.browse_release_groups( artist=artist_id, release_type=release_types, limit=limit, offset=offset) release_groups = api_resp.get('release-group-count'), api_resp.get( 'release-group-list') except ResponseError as e: if e.cause.code == 404: return None else: raise InternalServerError(e.cause.msg) cache.set(key=key, val=release_groups, time=DEFAULT_CACHE_EXPIRATION) return release_groups
def get_albums(self, artist_id, limit=50, offset=0): result = musicbrainzngs.browse_release_groups(artist=artist_id, includes=[], release_type=["album"], limit=limit, offset=offset) return result
def _missing_albums(self, lib, query): """Print a listing of albums missing from each artist in the library matching query. """ total = self.config['total'].get() albums = lib.albums(query) # build dict mapping artist to list of their albums in library albums_by_artist = defaultdict(list) for alb in albums: artist = (alb['albumartist'], alb['mb_albumartistid']) albums_by_artist[artist].append(alb) total_missing = 0 # build dict mapping artist to list of all albums for artist, albums in albums_by_artist.items(): if artist[1] is None or artist[1] == "": albs_no_mbid = [u"'" + a['album'] + u"'" for a in albums] self._log.info( u"No musicbrainz ID for artist '{}' found in album(s) {}; " "skipping", artist[0], u", ".join(albs_no_mbid) ) continue try: resp = musicbrainzngs.browse_release_groups(artist=artist[1]) release_groups = resp['release-group-list'] except MusicBrainzError as err: self._log.info( u"Couldn't fetch info for artist '{}' ({}) - '{}'", artist[0], artist[1], err ) continue missing = [] present = [] for rg in release_groups: missing.append(rg) for alb in albums: if alb['mb_releasegroupid'] == rg['id']: missing.remove(rg) present.append(rg) break total_missing += len(missing) if total: continue missing_titles = {rg['title'] for rg in missing} for release_title in missing_titles: print_(u"{} - {}".format(artist[0], release_title)) if total: print(total_missing)
def api_get_releases(id): try: mbz.set_useragent("Artistics", "v1.0", "*****@*****.**") result = mbz.browse_release_groups(artist=id) except mbz.WebServiceError as exc: result = None if "release-group-list" in result: return result["release-group-list"] return None
def get_albums_with_artist_id(mb_id: str) -> List[Dict]: try: _metadata = mb.browse_release_groups( artist=mb_id)["release-group-list"] except Exception as e: print(f"Unable to retrieve MB metadata for {mb_id}") traceback.print_tb(e.__traceback__) raise else: return _metadata
def getReleasesByArtist(mbid): initializeConnection() results = mb.browse_release_groups(artist=mbid, release_type='album') for result in results['release-group-list']: print result # messing around # artist = Artist.objects.first() # for result in searchForArtistByName('haim'): # print unicode(result)
def _missing_albums(self, lib, query): """Print a listing of albums missing from each artist in the library matching query. """ total = self.config['total'].get() albums = lib.albums(query) # build dict mapping artist to list of their albums in library albums_by_artist = defaultdict(list) for alb in albums: artist = (alb['albumartist'], alb['mb_albumartistid']) albums_by_artist[artist].append(alb) total_missing = 0 # build dict mapping artist to list of all albums for artist, albums in albums_by_artist.items(): if artist[1] is None or artist[1] == "": albs_no_mbid = [u"'" + a['album'] + u"'" for a in albums] self._log.info( u"No musicbrainz ID for artist '{}' found in album(s) {}; " "skipping", artist[0], u", ".join(albs_no_mbid)) continue try: resp = musicbrainzngs.browse_release_groups(artist=artist[1]) release_groups = resp['release-group-list'] except MusicBrainzError as err: self._log.info( u"Couldn't fetch info for artist '{}' ({}) - '{}'", artist[0], artist[1], err) continue missing = [] present = [] for rg in release_groups: missing.append(rg) for alb in albums: if alb['mb_releasegroupid'] == rg['id']: missing.remove(rg) present.append(rg) break total_missing += len(missing) if total: continue missing_titles = {rg['title'] for rg in missing} for release_title in missing_titles: print_(u"{} - {}".format(artist[0], release_title)) if total: print(total_missing)
def getReleaseGroupInfo(self, artist_id, r_type, offset, limit): """ Helper function used to get the information and count of the releases groups. We use this basically because we want to handle our custom pagination if limit is higher than the limit set by mbz_max_limit :param artist_id: This is the MBID for the artist :param r_type: This is release type :param offset: where we start counting for our pagination :param limit: where to stop counting :return release_group_list: The list of the release-groups found :return release_count: The number of release-groups returned """ mbz_max_limit = 100 #TODO put in config if limit > mbz_max_limit: #Here we get the first chunk below mbz_max_limit release_group = musicbrainzngs.browse_release_groups( artist_id, release_type=r_type, offset=offset, limit=limit) release_group_list = release_group['release-group-list'] release_group_count = release_group['release-group-count'] #Here we get the rest of the info if offset + mbz_max_limit < release_group_count: release_group_list_complement = musicbrainzngs.browse_release_groups( artist_id, release_type=r_type, offset=offset + mbz_max_limit, limit=limit - mbz_max_limit) #Here we merge the two list chunks release_group_list += release_group_list_complement[ 'release-group-list'] else: release_group = musicbrainzngs.browse_release_groups( artist_id, release_type=r_type, offset=offset, limit=limit) release_group_list = release_group['release-group-list'] release_group_count = release_group['release-group-count'] return release_group_list, release_group_count
def browse_release_groups(self, artist_id=None, release_types=[], limit=None, offset=None): """Get all release groups linked to an artist. You need to provide artist's MusicBrainz ID. """ key = generate_cache_key(str(artist_id), type='browse_release_groups', source='api', params=[limit, offset] + release_types) release_groups = cache.get(key) if not release_groups: try: api_resp = browse_release_groups(artist=artist_id, release_type=release_types, limit=limit, offset=offset) release_groups = api_resp.get('release-group-count'), api_resp.get('release-group-list') except ResponseError as e: raise APIError(code=e.cause.code, desc=e.cause.msg) cache.set(key, release_groups, DEFAULT_CACHE_EXPIRATION) return release_groups
def test_browse_release_group(self): artist = "47f67b22-affe-4fe1-9d25-853d69bc0ee3" musicbrainzngs.browse_release_groups(artist=artist) self.assertEqual("http://musicbrainz.org/ws/2/release-group/?artist=47f67b22-affe-4fe1-9d25-853d69bc0ee3", self.opener.get_url()) release = "438042ef-7ccc-4d03-9391-4f66427b2055" musicbrainzngs.browse_release_groups(release=release) self.assertEqual("http://musicbrainz.org/ws/2/release-group/?release=438042ef-7ccc-4d03-9391-4f66427b2055", self.opener.get_url()) release = "438042ef-7ccc-4d03-9391-4f66427b2055" rel_type = "ep" musicbrainzngs.browse_release_groups(release=release, release_type=rel_type) self.assertEqual("http://musicbrainz.org/ws/2/release-group/?release=438042ef-7ccc-4d03-9391-4f66427b2055&type=ep", self.opener.get_url())
def getMBID(): for artists in lib.albums(): if len(artists['mb_albumartistid']) == 0: pass else: artistList.append(artists['mb_albumartistid']) # localList.append(artists['mb_albumid']) localList.append(artists['album']) for albums in set(artistList): # online album db brainzList.update(mb.browse_release_groups(artist=albums)) for info in brainzList['release-group-list']: mbList.append(info['title']) # def compare(): for mbid in mbList: if mbid in localList: pass else: print mbid
def browse_release_groups(artist_id=None, release_types=None, limit=None, offset=None): """Get all release groups linked to an artist. You need to provide artist's MusicBrainz ID. """ if release_types is None: release_types = [] key = cache.gen_key(artist_id, limit, offset, *release_types) release_groups = cache.get(key) if not release_groups: try: api_resp = musicbrainzngs.browse_release_groups(artist=artist_id, release_type=release_types, limit=limit, offset=offset) release_groups = api_resp.get('release-group-count'), api_resp.get('release-group-list') except ResponseError as e: if e.cause.code == 404: return None else: raise InternalServerError(e.cause.msg) cache.set(key=key, val=release_groups, time=DEFAULT_CACHE_EXPIRATION) return release_groups
def test_browse_release_group(self): artist = "47f67b22-affe-4fe1-9d25-853d69bc0ee3" musicbrainzngs.browse_release_groups(artist=artist) self.assertEqual( "http://musicbrainz.org/ws/2/release-group/?artist=47f67b22-affe-4fe1-9d25-853d69bc0ee3", self.opener.get_url()) release = "438042ef-7ccc-4d03-9391-4f66427b2055" musicbrainzngs.browse_release_groups(release=release) self.assertEqual( "http://musicbrainz.org/ws/2/release-group/?release=438042ef-7ccc-4d03-9391-4f66427b2055", self.opener.get_url()) release = "438042ef-7ccc-4d03-9391-4f66427b2055" rel_type = "ep" musicbrainzngs.browse_release_groups(release=release, release_type=rel_type) self.assertEqual( "http://musicbrainz.org/ws/2/release-group/?release=438042ef-7ccc-4d03-9391-4f66427b2055&type=ep", self.opener.get_url())
def getArtist(artistid, extrasonly=False): with mb_lock: artist_dict = {} artist = None try: limit = 200 artist = musicbrainzngs.get_artist_by_id(artistid)['artist'] newRgs = None artist['release-group-list'] = [] while newRgs == None or len(newRgs) >= limit: newRgs = musicbrainzngs.browse_release_groups(artistid,release_type="album",offset=len(artist['release-group-list']),limit=limit)['release-group-list'] artist['release-group-list'] += newRgs except musicbrainzngs.WebServiceError as e: logger.warn('Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (artistid, str(e))) time.sleep(5) except Exception,e: pass if not artist: return False #if 'disambiguation' in artist: # uniquename = unicode(artist['sort-name'] + " (" + artist['disambiguation'] + ")") #else: # uniquename = unicode(artist['sort-name']) artist_dict['artist_name'] = unicode(artist['name']) # Not using the following values anywhere yet so we don't need to grab them. # Was causing an exception to be raised if they didn't exist. # #artist_dict['artist_sortname'] = unicode(artist['sort-name']) #artist_dict['artist_uniquename'] = uniquename #artist_dict['artist_type'] = unicode(artist['type']) #artist_dict['artist_begindate'] = None #artist_dict['artist_enddate'] = None #if 'life-span' in artist: # if 'begin' in artist['life-span']: # artist_dict['artist_begindate'] = unicode(artist['life-span']['begin']) # if 'end' in artist['life-span']: # artist_dict['artist_enddate'] = unicode(artist['life-span']['end']) releasegroups = [] if not extrasonly: for rg in artist['release-group-list']: if "secondary-type-list" in rg.keys(): #only add releases without a secondary type continue releasegroups.append({ 'title': unicode(rg['title']), 'id': unicode(rg['id']), 'url': u"http://musicbrainz.org/release-group/" + rg['id'], 'type': unicode(rg['type']) }) # See if we need to grab extras. Artist specific extras take precedence over global option # Global options are set when adding a new artist myDB = db.DBConnection() try: db_artist = myDB.action('SELECT IncludeExtras, Extras from artists WHERE ArtistID=?', [artistid]).fetchone() includeExtras = db_artist['IncludeExtras'] except IndexError: includeExtras = False if includeExtras: # Need to convert extras string from something like '2,5.6' to ['ep','live','remix'] (append new extras to end) if db_artist['Extras']: extras = map(int, db_artist['Extras'].split(',')) else: extras = [] extras_list = ["single", "ep", "compilation", "soundtrack", "live", "remix", "spokenword", "audiobook", "other", "dj-mix", "mixtape/street", "broadcast", "interview", "demo"] includes = [] i = 1 for extra in extras_list: if i in extras: includes.append(extra) i += 1 for include in includes: mb_extras_list = [] try: limit = 200 newRgs = None while newRgs == None or len(newRgs) >= limit: newRgs = musicbrainzngs.browse_release_groups(artistid,release_type=include,offset=len(mb_extras_list),limit=limit)['release-group-list'] mb_extras_list += newRgs except musicbrainzngs.WebServiceError as e: logger.warn('Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (artistid, str(e))) time.sleep(5) for rg in mb_extras_list: rg_type = rg['type'] if rg_type == 'Album' and 'secondary-type-list' in rg: secondary_type = rg['secondary-type-list'][0] if secondary_type != rg_type: rg_type = secondary_type releasegroups.append({ 'title': unicode(rg['title']), 'id': unicode(rg['id']), 'url': u"http://musicbrainz.org/release-group/" + rg['id'], 'type': unicode(rg_type) }) artist_dict['releasegroups'] = releasegroups return artist_dict
def getArtist(artistid, extrasonly=False): artist_dict = {} artist = None try: limit = 100 with mb_lock: artist = musicbrainzngs.get_artist_by_id(artistid)['artist'] newRgs = None artist['release-group-list'] = [] while newRgs is None or len(newRgs) >= limit: with mb_lock: newRgs = musicbrainzngs.browse_release_groups( artistid, release_type="album", offset=len(artist['release-group-list']), limit=limit) newRgs = newRgs['release-group-list'] artist['release-group-list'] += newRgs except musicbrainzngs.WebServiceError as e: logger.warn('Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (artistid, str(e))) mb_lock.snooze(5) except Exception as e: pass if not artist: return False artist_dict['artist_name'] = unicode(artist['name']) releasegroups = [] if not extrasonly: for rg in artist['release-group-list']: if "secondary-type-list" in rg.keys(): #only add releases without a secondary type continue releasegroups.append({ 'title': unicode(rg['title']), 'id': unicode(rg['id']), 'url': u"http://musicbrainz.org/release-group/" + rg['id'], 'type': unicode(rg['type']) }) # See if we need to grab extras. Artist specific extras take precedence over global option # Global options are set when adding a new artist myDB = db.DBConnection() try: db_artist = myDB.action('SELECT IncludeExtras, Extras from artists WHERE ArtistID=?', [artistid]).fetchone() includeExtras = db_artist['IncludeExtras'] except IndexError: includeExtras = False if includeExtras: # Need to convert extras string from something like '2,5.6' to ['ep','live','remix'] (append new extras to end) if db_artist['Extras']: extras = map(int, db_artist['Extras'].split(',')) else: extras = [] extras_list = headphones.POSSIBLE_EXTRAS includes = [] i = 1 for extra in extras_list: if i in extras: includes.append(extra) i += 1 for include in includes: mb_extras_list = [] try: limit = 100 newRgs = None while newRgs is None or len(newRgs) >= limit: with mb_lock: newRgs = musicbrainzngs.browse_release_groups( artistid, release_type=include, offset=len(mb_extras_list), limit=limit) newRgs = newRgs['release-group-list'] mb_extras_list += newRgs except musicbrainzngs.WebServiceError as e: logger.warn('Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (artistid, str(e))) mb_lock.snooze(5) for rg in mb_extras_list: rg_type = rg['type'] if rg_type == 'Album' and 'secondary-type-list' in rg: secondary_type = rg['secondary-type-list'][0] if secondary_type != rg_type: rg_type = secondary_type releasegroups.append({ 'title': unicode(rg['title']), 'id': unicode(rg['id']), 'url': u"http://musicbrainz.org/release-group/" + rg['id'], 'type': unicode(rg_type) }) artist_dict['releasegroups'] = releasegroups return artist_dict
def getArtist(artistid, extrasonly=False): artist_dict = {} artist = None try: limit = 100 with mb_lock: artist = musicbrainzngs.get_artist_by_id(artistid)['artist'] newRgs = None artist['release-group-list'] = [] while newRgs is None or len(newRgs) >= limit: with mb_lock: newRgs = musicbrainzngs.browse_release_groups( artistid, release_type="album", offset=len(artist['release-group-list']), limit=limit) newRgs = newRgs['release-group-list'] artist['release-group-list'] += newRgs except musicbrainzngs.WebServiceError as e: logger.warn( 'Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (artistid, str(e))) mb_lock.snooze(5) except Exception as e: pass if not artist: return False artist_dict['artist_name'] = unicode(artist['name']) releasegroups = [] if not extrasonly: for rg in artist['release-group-list']: if "secondary-type-list" in rg.keys( ): #only add releases without a secondary type continue releasegroups.append({ 'title': unicode(rg['title']), 'id': unicode(rg['id']), 'url': u"http://musicbrainz.org/release-group/" + rg['id'], 'type': unicode(rg['type']) }) # See if we need to grab extras. Artist specific extras take precedence over global option # Global options are set when adding a new artist myDB = db.DBConnection() try: db_artist = myDB.action( 'SELECT IncludeExtras, Extras from artists WHERE ArtistID=?', [artistid]).fetchone() includeExtras = db_artist['IncludeExtras'] except IndexError: includeExtras = False if includeExtras: # Need to convert extras string from something like '2,5.6' to ['ep','live','remix'] (append new extras to end) if db_artist['Extras']: extras = map(int, db_artist['Extras'].split(',')) else: extras = [] extras_list = headphones.POSSIBLE_EXTRAS includes = [] i = 1 for extra in extras_list: if i in extras: includes.append(extra) i += 1 for include in includes: mb_extras_list = [] try: limit = 100 newRgs = None while newRgs is None or len(newRgs) >= limit: with mb_lock: newRgs = musicbrainzngs.browse_release_groups( artistid, release_type=include, offset=len(mb_extras_list), limit=limit) newRgs = newRgs['release-group-list'] mb_extras_list += newRgs except musicbrainzngs.WebServiceError as e: logger.warn( 'Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (artistid, str(e))) mb_lock.snooze(5) for rg in mb_extras_list: rg_type = rg['type'] if rg_type == 'Album' and 'secondary-type-list' in rg: secondary_type = rg['secondary-type-list'][0] if secondary_type != rg_type: rg_type = secondary_type releasegroups.append({ 'title': unicode(rg['title']), 'id': unicode(rg['id']), 'url': u"http://musicbrainz.org/release-group/" + rg['id'], 'type': unicode(rg_type) }) artist_dict['releasegroups'] = releasegroups return artist_dict
def get_release_group_album_type(self, artist_id, limit=None, offset=None): return musicbrainzngs.browse_release_groups(artist_id, None, ['album'], [], limit, offset)
def get_release_groups_for_artist(artist_id): with musicbrainz_lock: return musicbrainzngs.browse_release_groups(artist=artist_id, release_type=musicbrainzngs.VALID_RELEASE_TYPES)[ 'release-group-list']
def get_release_groups_for_artist(artist_id): with musicbrainz_lock: return musicbrainzngs.browse_release_groups( artist=artist_id, release_type=musicbrainzngs.VALID_RELEASE_TYPES )['release-group-list']