def test_browse_recording(self): artist = "47f67b22-affe-4fe1-9d25-853d69bc0ee3" musicbrainzngs.browse_recordings(artist=artist) self.assertEqual("http://musicbrainz.org/ws/2/recording/?artist=47f67b22-affe-4fe1-9d25-853d69bc0ee3", self.opener.get_url()) release = "438042ef-7ccc-4d03-9391-4f66427b2055" musicbrainzngs.browse_recordings(release=release) self.assertEqual("http://musicbrainz.org/ws/2/recording/?release=438042ef-7ccc-4d03-9391-4f66427b2055", self.opener.get_url())
def get_all_recordings(artist, includes=['artist-credits']): ''' Gets all recordings by an artist with default artist credits Parameters ---------- artist : str This should be a musicbrainz id str representing the artist includes : [str] list of include parameters matching the parameters at https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Libraries_to_use_the_Web_Service Returns ------- recs : [{...}] a list of dicts, where each dict is a recording done by (at least) the artist Postconditions -------------- the return value does not contain any duplicate recording titles ''' recs = list() # return value titles = set() # set of already seen titles to remove duplicates recordings = mb.browse_recordings(artist, limit=100, includes=includes) recs += recordings['recording-list'] count = recordings['recording-count'] - 100 # already grabbed offset = 100 print('Downloading {}...'.format(artist)) while count >= 0: recordings = mb.browse_recordings(artist, limit=100, includes=includes, offset=offset) # have we already seen a recording of this name? for record in recordings['recording-list']: if not (record['title'] in titles): recs.append(record) # update already seen titles titles.update( [record['title'] for record in recordings['recording-list']]) count -= 100 offset += 100 return recs
def get_lyrics(artist_id): """ Browses all pages of artist's recordings by increasing the offset by the limit For each recording the song name is added to a list ('recordings') """ print("Collecting lyrics ...") offset = 0 limit = 100 recordings_browse = musicbrainzngs.browse_recordings( artist=artist_id, limit=limit, offset=offset ) # Gets all recordings linked to artist - returns dict with keys ['recording-list', 'recording-count'] num_recordings = recordings_browse['recording-count'] # 1746 for Beyonce recordings = [None] * num_recordings for page_num in range(num_recordings // 100): recordings_browse = musicbrainzngs.browse_recordings( artist=artist_id, limit=limit, offset=offset ) # Gets all recordings linked to artist - returns dict with keys ['recording-list', 'recording-count'] for position in range(limit): song_name = recordings_browse['recording-list'][position]['title'] index = (page_num * 100) + position recordings[index] = song_name offset += limit recordings_browse = musicbrainzngs.browse_recordings( artist=artist_id, limit=limit, offset=offset ) # Gets all recordings linked to artist - returns dict with keys ['recording-list', 'recording-count'] max_index = num_recordings - ((num_recordings // 100) * 100) for position in range(max_index): song_name = recordings_browse['recording-list'][position]['title'] index = ((num_recordings // 100) * 100) + position recordings[index] = song_name recordings = list( dict.fromkeys(recordings) ) # removes duplicates by converting 'recordings' list to a dictionary then back to a list return recordings
def loadDiscographieFromServer(self, theID, turn = 1, threshold = 5): # skipp the unknown if theID == '125ec42a-7229-4250-afc5-e057484327fe': return() if self.v: print("Trying to load discographie from server:", theID) respond = [] try: # fetch songs from sevrer offs = 0 while offs != -1: resp = musicbrainzngs.browse_recordings(theID, includes = ["artist-credits"], offset = offs, limit = 100) # save fetched songs to DB, so we have them for s in resp['recording-list']: # save the songs songID = s['id'] #self.saveSong(songID, theID) # save related artists: artists = {} for art in s['artist-credit']: if isinstance(art, str): # skip things like 'feat' and '&' continue a = art['artist'] artists[a['name']] = a['id'] # also save the names, so we have them already self.saveArtist(a['id'],a['name']) # save the song and the artists related to it: respond.append(self.storeSongData(songID, theID, artists)) # write data to db, as we now have many new songs of this artist self.db.commit() if (resp['recording-count'] - len(resp['recording-list']) > offs ): offs = len(resp['recording-list']) + offs else: offs = -1 self.db.commit() # save artist as done: except: print("Problem reaching the server") if turn < threshold: print("Lets try again in 5 seconds") sleep(5) turn = turn + 1 self.loadDiscographieFromServer(theID, turn) else: print("We tried to often, skipping Artist") print(theID) return(respond)
def MBID_recording_iterator(mbid): """ Returns a dictionary with all releases in the form {title:mbid} for a given artist MBID """ recordings = {} recording_list = m.browse_recordings(release = mbid)['recording-list'] no_rec = len(recording_list) for i in xrange(no_rec): title = recording_list[i]['title'] mbid_title = recording_list[i]['id'] recordings[title] = mbid_title # print recordings return recordings
def fetch_all_recordings(artist_id): # When you want to fetch a list of entities greater than 25, you have to use one of the browse # functions. Not only can you specify a limit as high as 100, but you can also specify an offset # to get the complete list in multiple requests. offset = 0 limit = 100 recordings = [] page = 1 result = musicbrainz.browse_recordings(artist=artist_id, limit=limit) page_recs = result['recording-list'] recordings += page_recs if "release-count" in result: count = result['release-count'] while len(page_recs) >= limit: offset += limit page += 1 result = musicbrainz.browse_recordings(artist=artist_id, limit=limit, offset=offset) page_recs = result['recording-list'] recordings += page_recs return recordings
def api_get_recordings(id): try: mbz.set_useragent("Artistics", "v1.0", "*****@*****.**") result = mbz.browse_recordings(artist=id, limit=1000) except mbz.WebServiceError as exc: result = {} if "recording-list" in result: return [ recording(recordings["title"], recordings["length"] if "length" in recordings else None) for recordings in result["recording-list"] ] return None
def _get_album(self): random_country = random.choice(self._country_field) musicbrainzngs.set_useragent( PROJECTNAME, "1.a", CONTACT ) try: results = musicbrainzngs.search_releases(query="", limit=10, offset=None, strict=False, country=random_country, mediums="CD", type="Album") offset = random.randint(0, results["release-count"] - 100) result = musicbrainzngs.search_releases(query="", limit=100, offset=offset, strict=False, country=random_country, mediums="CD", type="Album", reid="1ec09df8-aef8-48f1-91a9-92a982bf0dfe") except: return None releases = result["release-list"] releases_with_tracks = [x for x in releases if "medium-track-count" in x and x["medium-track-count"] > 4] while True: release = random.choice(releases_with_tracks) release_id = release["id"] try: tracks = musicbrainzngs.browse_recordings(release=release_id) self._success = True except: return None try: release_length = sum([int(int(x["length"]) / 1000) for x in tracks["recording-list"]]) break except: pass self._data = { "title": release["title"], "id": release_id, "country": countries[random_country][0], "releaseyear": None, "artist": release["artist-credit"][0]["name"], "tracks": tracks["recording-count"], "duration": release_length } if "date" in release: self._data["releaseyear"] = int(release["date"][:4])
def fetch_recording_list_module(artist_id, record_count): """ fetch the recording list from the musicbrainz python module :param artist_id: musicbrainz id :param record_count: count of recordings want to return :return: an array of recordings found in the module """ _offset = _OFFSET _recordings = [] try: # set the musicbrainz api user agent mb.set_useragent('jw-tech-test', '1', contact='*****@*****.**') while _offset < int(record_count): _ret = mb.browse_recordings(artist_id, limit=_LIMIT, offset=_offset) _rec_json = _ret["recording-list"] for r in _rec_json: s = r["title"].upper() if (check_brackets_in_arr(s, _recordings) and check_cases_in_arr(s, _recordings)): _recordings.append(s) _offset += 100 return _recordings except mb.UsageError as e: print("No access to musicbrainz API") except mb.ResponseError as e: print(f"No artist found with id {artist_id}") except Exception as e: print(f"Unexpected error: {sys.info()}") raise e
def album_info(release): """Takes a MusicBrainz release result dictionary and returns a beets AlbumInfo object containing the interesting data about that release. """ # Get artist name using join phrases. artist_name, artist_sort_name, artist_credit_name = \ _flatten_artist_credit(release['artist-credit']) ntracks = sum(len(m['track-list']) for m in release['medium-list']) # The MusicBrainz API omits 'artist-relation-list' and 'work-relation-list' # when the release has more than 500 tracks. So we use browse_recordings # on chunks of tracks to recover the same information in this case. if ntracks > BROWSE_MAXTRACKS: log.debug(u'Album {} has too many tracks', release['id']) recording_list = [] for i in range(0, ntracks, BROWSE_CHUNKSIZE): log.debug(u'Retrieving tracks starting at {}', i) recording_list.extend( musicbrainzngs.browse_recordings(release=release['id'], limit=BROWSE_CHUNKSIZE, includes=BROWSE_INCLUDES, offset=i)['recording-list']) track_map = {r['id']: r for r in recording_list} for medium in release['medium-list']: for recording in medium['track-list']: recording_info = track_map[recording['recording']['id']] recording['recording'] = recording_info # Basic info. track_infos = [] index = 0 for medium in release['medium-list']: disctitle = medium.get('title') format = medium.get('format') if format in config['match']['ignored_media'].as_str_seq(): continue all_tracks = medium['track-list'] if ('data-track-list' in medium and not config['match']['ignore_data_tracks']): all_tracks += medium['data-track-list'] track_count = len(all_tracks) if 'pregap' in medium: all_tracks.insert(0, medium['pregap']) for track in all_tracks: if ('title' in track['recording'] and track['recording']['title'] in SKIPPED_TRACKS): continue if ('video' in track['recording'] and track['recording']['video'] == 'true' and config['match']['ignore_video_tracks']): continue # Basic information from the recording. index += 1 ti = track_info( track['recording'], index, int(medium['position']), int(track['position']), track_count, ) ti.release_track_id = track['id'] ti.disctitle = disctitle ti.media = format ti.track_alt = track['number'] # Prefer track data, where present, over recording data. if track.get('title'): ti.title = track['title'] if track.get('artist-credit'): # Get the artist names. ti.artist, ti.artist_sort, ti.artist_credit = \ _flatten_artist_credit(track['artist-credit']) ti.artist_id = track['artist-credit'][0]['artist']['id'] if track.get('length'): ti.length = int(track['length']) / (1000.0) track_infos.append(ti) info = beets.autotag.hooks.AlbumInfo( album=release['title'], album_id=release['id'], artist=artist_name, artist_id=release['artist-credit'][0]['artist']['id'], tracks=track_infos, mediums=len(release['medium-list']), artist_sort=artist_sort_name, artist_credit=artist_credit_name, data_source=u'MusicBrainz', data_url=album_url(release['id']), ) info.va = info.artist_id == VARIOUS_ARTISTS_ID if info.va: info.artist = config['va_name'].as_str() info.asin = release.get('asin') info.releasegroup_id = release['release-group']['id'] info.albumstatus = release.get('status') # Get the disambiguation strings at the release and release group level. if release['release-group'].get('disambiguation'): info.releasegroupdisambig = \ release['release-group'].get('disambiguation') if release.get('disambiguation'): info.albumdisambig = release.get('disambiguation') # Get the "classic" Release type. This data comes from a legacy API # feature before MusicBrainz supported multiple release types. if 'type' in release['release-group']: reltype = release['release-group']['type'] if reltype: info.albumtype = reltype.lower() # Log the new-style "primary" and "secondary" release types. # Eventually, we'd like to actually store this data, but we just log # it for now to help understand the differences. if 'primary-type' in release['release-group']: rel_primarytype = release['release-group']['primary-type'] if rel_primarytype: log.debug('primary MB release type: ' + rel_primarytype.lower()) if 'secondary-type-list' in release['release-group']: if release['release-group']['secondary-type-list']: log.debug('secondary MB release type(s): ' + ', '.join([ secondarytype.lower() for secondarytype in release['release-group']['secondary-type-list'] ])) # Release events. info.country, release_date = _preferred_release_event(release) release_group_date = release['release-group'].get('first-release-date') if not release_date: # Fall back if release-specific date is not available. release_date = release_group_date _set_date_str(info, release_date, False) _set_date_str(info, release_group_date, True) # Label name. if release.get('label-info-list'): label_info = release['label-info-list'][0] if label_info.get('label'): label = label_info['label']['name'] if label != '[no label]': info.label = label info.catalognum = label_info.get('catalog-number') # Text representation data. if release.get('text-representation'): rep = release['text-representation'] info.script = rep.get('script') info.language = rep.get('language') # Media (format). if release['medium-list']: first_medium = release['medium-list'][0] info.media = first_medium.get('format') genres = release.get('genre-list') if config['musicbrainz']['genres'] and genres: info.genre = ';'.join(g['name'] for g in genres) extra_albumdatas = plugins.send('mb_album_extract', data=release) for extra_albumdata in extra_albumdatas: info.update(extra_albumdata) info.decode() return info
# find the ID from the extracted json mbid = data['artists'][0]['id'] # the lyrics site has a limit of a 100 results, the below loops through the pages to return all the songs limit = 100 offset = 0 recordings = [] page = 0 # create a list to hold the track names list = [] # use the function from the musicbrainz library to retrieve the track listings # and loop through the pages based on the recording count result = musicbrainzngs.browse_recordings(artist=mbid, limit=limit) for recordinglist in result['recording-list']: list.append(recordinglist['title']) page_recordings = result['recording-list'] recordings += page_recordings if "recording-count" in result: count = result['recording-count'] while len(page_recordings) >= limit: offset += limit page += 1 result = musicbrainzngs.browse_recordings(artist=mbid, limit=limit, offset=offset) page_recordings = result['recording-list'] recordings += page_recordings
import musicbrainzngs import requests def sources(recordingid): res = requests.get('http://185.97.32.250:8468/mbid:{}'.format(recordingid)) #import pdb;pdb.set_trace() if not b'None' in res.content: return res.content.decode('utf-8') musicbrainzngs.set_useragent("mb.py", "0", contact="*****@*****.**") res = musicbrainzngs.search_artists("Ablaze") for artist in res['artist-list']: print(artist['name'], artist['id']) #import pdb;pdb.set_trace() res = musicbrainzngs.browse_releases(artist='d2c0d69e-e3ca-45a4-a540-6ce42c617599', limit=100) for release in res['release-list']: print(release['title']) recordings = musicbrainzngs.browse_recordings(release=release['id']) for rec in recordings['recording-list']: # import pdb;pdb.set_trace() print("\t\t",rec['title'],'\t', end='') print(sources(rec['id'])) #import pdb;pdb.set_trace()
def run_app(name): response = musicbrainzngs.browse_recordings(artist=get_artist_id(name)) titles = [] for val in response['recording-list']: titles.append(val.get('title').replace("'", '')) return titles
def get_albums(artist_id): """ Browses all releases of a given artist id, where release type is 'album' For each release, if not alreay in the dictionary then the title and date are added to one dictionary, whilst title and release id are added to another. For each release (album), its recordings (songs) are compared to those in words_dict2 (found previously by browsing the artist's recordings) - where songs match their word counnt is found from words_dict2 and thus the average number of words in each album is calculated. A bar chart of each album's year of release and the average number of words is plotted. """ limit = 100 offset = 0 releases_browse = musicbrainzngs.browse_releases( release_type=['album'], artist=artist_id, limit=limit, offset=offset ) # Gets all recordings linked to artist - returns dict with keys ['recording-list', 'recording-count'] num_releases = releases_browse['release-count'] albums = [None] * num_releases for page_num in range(num_releases // 100): releases_browse = musicbrainzngs.browse_releases( release_type=['album'], artist=artist_id, limit=limit, offset=offset ) # Gets all recordings linked to artist - returns dict with keys ['recording-list', 'recording-count'] for position in range(limit): # 0 to 99 album_info = releases_browse['release-list'][position] index = (page_num * 100) + position albums[index] = album_info offset += limit releases_browse = musicbrainzngs.browse_releases( release_type=['album'], artist=artist_id, limit=limit, offset=offset ) # Gets all recordings linked to artist - returns dict with keys ['recording-list', 'recording-count'] max_index = num_releases - ((num_releases // 100) * 100) for position in range(max_index): # 0 to 99 album_info = releases_browse['release-list'][position] index = ((num_releases // 100) * 100) + position albums[index] = album_info #albums = list(dict.fromkeys(albums)) album_id = {} album_dates = {} for album in albums: if album['title'] not in album_id.keys( ) and album['title'] not in album_dates.keys(): try: album_date = datetime.datetime.strptime( str(album['date'])[:4], '%Y').date() album_dates.update({album['title']: album_date.year}) album_id.update({album['title']: album['id']}) except KeyError: pass album_songs = {} for album_name, release_id in album_id.items(): album_words = 0 album_num_songs = 0 recordings = musicbrainzngs.browse_recordings( release=release_id, limit=100, offset=0 ) # Gets all recordings linked to artist - returns dict with keys ['recording-list', 'recording-count'] for recording in recordings['recording-list']: title = recording['title'] for key, value in words_dict2.items(): if key == title: album_num_songs += 1 album_words += value if album_num_songs != 0: album_av = album_words / album_num_songs else: album_av = 0 album_songs.update({album_name: album_av}) album_name, av_words = zip( *album_songs.items()) # unpack a list of pairs into two tuples album_name, album_date = zip( *album_dates.items()) # unpack a list of pairs into two tuples plt.bar([str(date) for date in album_date], height=av_words) plt.axhline(average, linewidth=1, color='m', linestyle='--', label="Average over all songs") plt.xlabel("Year", fontsize=12) plt.ylabel("Average number of words", fontsize=12) plt.title( "Graph of average number of words in album \n alongside year of release \n for {}" .format(artist_name)) plt.xticks(rotation=90) plt.legend() plt.show()