Exemple #1
0
def get_releases_for_recording(recording_id):
    # Because there may be more than 25 releases for a recording, we should use
    # the browse methods

    # the browse release API endpoint doesn't let you retrieve tags for linked releases.
    # Because of this, we only gather IDs here, and return them.
    # we get artist, releasegroup, and tag information in `get_metadata_for_releases`

    offset = 0
    all_releases = []

    releases = mb.browse_releases(recording=recording_id, offset=0)
    total_releases = releases["release-count"]
    all_releases += releases["release-list"]
    offset += len(releases["release-list"])
    while len(all_releases) < total_releases:
        releases = mb.browse_releases(recording=recording_id, offset=offset)
        all_releases += releases["release-list"]
        offset += len(releases["release-list"])

    release_ids = []

    for r in all_releases:
        release_ids.append(r["id"])

    return release_ids
    def test_browse_release(self):
        artist = "47f67b22-affe-4fe1-9d25-853d69bc0ee3"
        musicbrainzngs.browse_releases(artist=artist)
        self.assertEqual(
            "http://musicbrainz.org/ws/2/release/?artist=47f67b22-affe-4fe1-9d25-853d69bc0ee3",
            self.opener.get_url())
        musicbrainzngs.browse_releases(track_artist=artist)
        self.assertEqual(
            "http://musicbrainz.org/ws/2/release/?track_artist=47f67b22-affe-4fe1-9d25-853d69bc0ee3",
            self.opener.get_url())

        label = "713c4a95-6616-442b-9cf6-14e1ddfd5946"
        musicbrainzngs.browse_releases(label=label)
        self.assertEqual(
            "http://musicbrainz.org/ws/2/release/?label=713c4a95-6616-442b-9cf6-14e1ddfd5946",
            self.opener.get_url())

        recording = "7484fcfd-1968-4401-a44d-d1edcc580518"
        musicbrainzngs.browse_releases(recording=recording)
        self.assertEqual(
            "http://musicbrainz.org/ws/2/release/?recording=7484fcfd-1968-4401-a44d-d1edcc580518",
            self.opener.get_url())

        release_group = "1c1b54f7-e56a-3ce8-b62c-e45c378e7f76"
        musicbrainzngs.browse_releases(release_group=release_group)
        self.assertEqual(
            "http://musicbrainz.org/ws/2/release/?release-group=1c1b54f7-e56a-3ce8-b62c-e45c378e7f76",
            self.opener.get_url())
def get_artist_releases(artist_mbid):
    limit = 100
    offset = 0
    releases = []
    release_groups = []
    page = 1

    result = mbz.browse_releases(artist=artist_mbid,
                                 limit=limit,
                                 offset=offset,
                                 includes=['release-groups', 'artist-credits'],
                                 release_status=['official'])

    releases += result['release-list']

    if 'release-count' in result:
        count = result['release-count']

        while len(releases) < count:
            offset += limit
            page += 1

            result = mbz.browse_releases(
                artist=artist_mbid,
                limit=limit,
                offset=offset,
                includes=['release-groups', 'artist-credits'],
                release_status=['official'])
            releases += result['release-list']

    for release in releases:
        if release not in release_groups:
            release_groups.append(release['release-group'])

    return {'status': 200, 'releases': release_groups}
Exemple #4
0
def get_all_releases_from_artist(s_artist_id):
    limit = 100
    offset = 0
    page = 1
    # d_search_parameters = dict(artist=s_artist_id, release_type=["album"])
    d_search_parameters = dict(artist=s_artist_id, limit=limit)

    first_page = musicbrainzngs.browse_releases(**d_search_parameters)
    page_releases = first_page['release-list']

    yield from ({
        "title": albums["title"],
        "date": albums["date"]
    } for albums in page_releases)

    while len(page_releases) >= limit:
        offset += limit
        page += 1
        print("fetching page number %d.." % page)
        next_page = musicbrainzngs.browse_releases(offset=offset,
                                                   **d_search_parameters)
        page_releases = next_page['release-list']
        yield from ({
            "title": albums["title"],
            "date": albums["date"]
        } for albums in page_releases
                    if "date" in albums and "title" in albums)
def get_releases_for_release_group(release_group_id, includes=RELEASE_INCLUDES):
    with musicbrainz_lock:
        logger.debug('Fetching release for rgid {}'.format(release_group_id))
        search_results = musicbrainzngs.browse_releases(release_group=release_group_id,
                                                        release_type='album', includes=includes)['release-list']

        return [album_info(release) for release in search_results]
Exemple #6
0
    def _parse_recordings(recordings):
        _recording = None
        _results = []

        for recording in recordings:
            if MusicEntityGenerator._validate_score(_recording, recording):
                _recording = recording

                recording_releases = musicbrainzngs.browse_releases(
                    recording=recording['id'],
                    includes=['labels', 'release-groups']
                )

                # Find all valid releases (Official releases)
                for rel in recording_releases['release-list']:
                    if MusicEntityGenerator._valid_release(rel):
                        _results.append((rel, rel['label-info-list']))

                # Clean up recording data
                if 'release-list' in recording:
                    recording.pop('release-list')
            else:
                break

        return _recording, _results
def get_artist_tracks_from_musicbrianz_api(artist):
    search_results = mb.search_artists(artist)
    result = search_results['artist-list'][0]

    genre = Artist.get_genre_from_musicbrainz_tag_list(result['tag-list'])

    for album_dict in mb.browse_releases(result['id'],
                                         includes=['recordings'
                                                   ])['release-list']:
        album = Album.objects.create(name=album_dict['title'],
                                     artist=artist,
                                     slug=slugify(album_dict['title']))

        for track_dict in album_dict['medium-list'][0]['track-list']:
            track = Track.objects.create(album=album,
                                         name=track_dict['recording']['title'],
                                         track_number=track_dict['position'],
                                         slug=slugify(
                                             track_dict['recording']['title']))

            Artist.objects.create(track=track,
                                  artist=artist,
                                  genre=genre,
                                  slug=slugify(artist))

    return Artist.objects.filter(artist=artist)
def album_record_label(
        release_group_musicbrainz_id) -> 'record_label_musicbrainz_id':
    """Extracts the record label associated with an album.
       Taken the releases belonging to the release-group, the first valid record label is considered

    Returns:
        str -- record label musicbrainz id
    """
    if release_group_musicbrainz_id is not None:
        releases = mz.browse_releases(
            release_group=release_group_musicbrainz_id['value'],
            includes=['labels'])

        for r in releases['release-list']:
            label_list = r['label-info-list']
            if len(label_list) > 0:
                for l in label_list:
                    try:
                        if l['label']['name'] != '[no label]':
                            return {'value': l['label']['id']}
                    except KeyError:
                        continue

            logging.getLogger('root.features').warning(
                f"Release {r['id']} has no associated record label")
            return None
Exemple #9
0
def get_release_list(artist_str):
    """ Gets a release list from musicbrains API. """
    username = '******'
    password = '******'

    musicbrainzngs.set_useragent(username, password)
    artist_list = musicbrainzngs.search_artists(
        artist=artist_str)['artist-list']
    artist = sorted(artist_list,
                    reverse=True,
                    key=lambda artist: int(artist['ext:score']))[0]
    artist_id = artist['id']

    limit = 100
    offset = 0
    release_list = []
    release_count = 1

    while offset < release_count:
        print 'Requesting tracks {0} - {1}'.format(str(offset),
                                                   str(offset + limit))
        result = musicbrainzngs.browse_releases(artist=artist_id,
                                                release_status=['official'],
                                                release_type=['album'],
                                                includes=['recordings'],
                                                limit=limit,
                                                offset=offset)
        release_count = result['release-count']
        release_list += result['release-list']
        offset += limit

    return release_list
Exemple #10
0
def artist_recorded_label(
        artist_musicbrainz_id) -> 'record_label_musicbrainz_id':
    """Harvest the list of record lables the artist has published records with

    Arguments:
        artist_musicbrainz_id {str} -- 

    Returns:
        list -- Record lables ids
    """
    releases = mz.browse_releases(artist=artist_musicbrainz_id['value'],
                                  includes=['labels'])
    labels = set()
    for r in releases['release-list']:
        label_list = r['label-info-list']
        for l in label_list:
            try:
                if l['label']['name'] != '[no label]':
                    labels.add(l['label']['id'])
            except KeyError:
                continue

    labels = list(labels)
    if len(labels) > 0:
        return [{'value': l} for l in labels]
    else:
        logging.getLogger('root.features').warning(
            f"I was not able to find any label for which artist {artist_musicbrainz_id['value']} has recorded"
        )
        return None
Exemple #11
0
    def get_artist_tracks_from_musicbrainz(cls, artist):
        """
        Create Album, Track, and Solo records for artists we find in the MusicBrainzNGS API

        :param artist: an artist's name as a string to search for
        :return: Queryset of Solos
        """
        search_results = mb.search_artists(artist)
        best_result = search_results['artist-list'][0]
        instrument = Solo.get_instrument_from_musicbrainz_tags(
            best_result['tag-list'])

        for album_dict in mb.browse_releases(best_result['id'],
                                             includes=['recordings'
                                                       ])['release-list']:
            album = Album.objects.create(name=album_dict['title'],
                                         artist=artist,
                                         slug=slugify(album_dict['title']))

            for track_dict in album_dict['medium-list'][0]['track-list']:
                track = Track.objects.create(
                    album=album,
                    name=track_dict['recording']['title'],
                    track_number=track_dict['position'],
                    slug=slugify(track_dict['recording']['title']))

                Solo.objects.create(track=track,
                                    artist=artist,
                                    instrument=instrument,
                                    slug=slugify(artist))

        return Solo.objects.filter(artist=artist)
Exemple #12
0
def get_artist_tracks_from_musicbrainz(artist):
    """
    Create Album, Track, and Solo records for artists we find in the MusicBrainzNGS API

    :param artist: an artist's name as a string to search for
    :return: Queryset of Solos
    """
    search_results = mb.search_artists(artist)
    best_result = search_results['artist-list'][0]

    if 'jazz' not in [d['name'] for d in best_result['tag-list']]:
        return Solo.objects.none()

    instrument = Solo.get_instrument_from_musicbrainz_tags(best_result['tag-list'])

    for album_dict in mb.browse_releases(best_result['id'], includes=['recordings'])['release-list']:

        album = Album.objects.create(name=album_dict['title'], artist=artist, slug=slugify(album_dict['title']))

        for track_dict in album_dict['medium-list'][0]['track-list']:
            track = Track.objects.create(album=album, name=track_dict['recording']['title'],
                                         track_number=track_dict['position'],
                                         slug=slugify(track_dict['recording']['title']))

            Solo.objects.create(track=track, artist=artist, instrument=instrument, slug=slugify(artist))

    return Solo.objects.filter(artist=artist)
Exemple #13
0
def browse_releases(artist_id=None,
                    release_group=None,
                    release_types=None,
                    limit=None,
                    offset=None,
                    includes=None):
    """Get all the releases by a certain artist and/or a release group.
    You need to provide an artist's MusicBrainz ID or the Release Group's MusicBrainz ID
    """
    if release_types is None:
        release_types = []
    key = cache.gen_key(artist_id, release_group, limit, offset,
                        *release_types, *includes)
    releases = cache.get(key)
    if not releases:
        try:
            api_resp = musicbrainzngs.browse_releases(
                artist=artist_id,
                release_type=release_types,
                limit=limit,
                offset=offset,
                release_group=release_group,
                includes=includes)
            releases = api_resp.get('release-list')
        except ResponseError as e:
            if e.cause.code == 404:
                return None
            else:
                raise InternalServerError(e.cause.msg)
        cache.set(key=key, val=releases, time=DEFAULT_CACHE_EXPIRATION)
    return releases
    def test_browse_release(self):
        artist = "47f67b22-affe-4fe1-9d25-853d69bc0ee3"
        musicbrainzngs.browse_releases(artist=artist)
        self.assertEqual("http://musicbrainz.org/ws/2/release/?artist=47f67b22-affe-4fe1-9d25-853d69bc0ee3", self.opener.get_url())
        musicbrainzngs.browse_releases(track_artist=artist)
        self.assertEqual("http://musicbrainz.org/ws/2/release/?track_artist=47f67b22-affe-4fe1-9d25-853d69bc0ee3", self.opener.get_url())

        label = "713c4a95-6616-442b-9cf6-14e1ddfd5946"
        musicbrainzngs.browse_releases(label=label)
        self.assertEqual("http://musicbrainz.org/ws/2/release/?label=713c4a95-6616-442b-9cf6-14e1ddfd5946", self.opener.get_url())

        recording = "7484fcfd-1968-4401-a44d-d1edcc580518"
        musicbrainzngs.browse_releases(recording=recording)
        self.assertEqual("http://musicbrainz.org/ws/2/release/?recording=7484fcfd-1968-4401-a44d-d1edcc580518", self.opener.get_url())

        release_group = "1c1b54f7-e56a-3ce8-b62c-e45c378e7f76"
        musicbrainzngs.browse_releases(release_group=release_group)
        self.assertEqual("http://musicbrainz.org/ws/2/release/?release-group=1c1b54f7-e56a-3ce8-b62c-e45c378e7f76", self.opener.get_url())
Exemple #15
0
 def get_tracks_with_album_id(mb_id: str) -> List[Dict]:
     try:
         _metadata = mb.browse_releases(release_group=mb_id)["release-list"]
     except Exception as e:
         print(f"Unable to retrieve MB metadata for {mb_id}")
         traceback.print_tb(e.__traceback__)
         raise
     else:
         return _metadata
Exemple #16
0
    def find_all_tracks(self) -> None:
        """Find all tracks from all albums.
        """
        self.all_albums = list()
        total_albums = len(self.release_group_ids)
        self.total_track_count = 0

        with click.progressbar(
                length=total_albums,
                label=(
                    'Searching Musicbrainz for all tracks in all albums for '
                    f'{self.artist}'),
        ) as bar:
            for _id, alb in self.release_group_ids.items():
                resp_0 = addict.Dict(
                    musicbrainzngs.browse_releases(
                        release_group=_id,
                        release_type=['album'],
                        includes=['recordings'],
                        limit=100,
                    ))

                album_track_count = [
                    i['medium-list'][0]['track-count']
                    for i in resp_0['release-list']
                ]

                self.total_track_count += max(album_track_count)

                max_track_pos = album_track_count.index(max(album_track_count))

                album_tracks = resp_0['release-list'][max_track_pos]

                try:
                    album_year = resp_0['release-list'][
                        max_track_pos].date.split('-')[0]
                except TypeError:
                    album_year = 'Missing'

                album_tracks = addict.Dict((
                    alb + f' [{album_year}]',
                    [
                        i.recording.title for i in resp_0['release-list']
                        [max_track_pos]['medium-list'][0]['track-list']
                    ],
                ))

                self.all_albums.append(album_tracks)

                bar.update(1)

        # pprint(self.all_albums)
        click.echo(f'Found {self.total_track_count} tracks across'
                   f' {len(self.release_group_ids)} albums for {self.artist}')
        del resp_0
        return self
Exemple #17
0
def get_releases_for_release_group(release_group_id,
                                   includes=RELEASE_INCLUDES):
    with musicbrainz_lock:
        logger.debug('Fetching release for rgid {}'.format(release_group_id))
        search_results = musicbrainzngs.browse_releases(
            release_group=release_group_id,
            release_type='album',
            includes=includes)['release-list']

        return [album_info(release) for release in search_results]
Exemple #18
0
def get_label_releases(label_id, offset, limit):
    """Get up to `limit` releases for label `label_id` starting from
    offset `offset`."""
    releases = musicbrainzngs.browse_releases(
        label=label_id,
        release_status=['official'],
        release_type=['album', 'single', 'ep'],
        includes=['release-groups'],
        limit=limit,
        offset=offset)
    return releases
Exemple #19
0
 def handle(self, **options):
     musicbrainzngs.set_useragent(settings.MB_APP, settings.MB_VERSION, settings.MB_CONTACT)
     if options['changed']:
         artists = Artist.objects.exclude(lastfm_mbid=F('mbid'))
     else:
         artists = Artist.objects\
             .filter(lastfm_playcount__gt=settings.LASTFM_MIN_PLAY_COUNT, mbid__gt='')\
             .order_by('lastfm_playcount')
     for artist in artists:
         print 'ARTIST: ', artist.title
         if artist.updated and not (now() - artist.updated).days:
             print 'updated recently'
             continue
         if options['changed']:
             # deleting old releases and albums
             artist.max_year = 0
             for old_release in artist.releases.all():
                 old_release.delete()
             for old_album in artist.albums.all():
                 old_album.delete()
             artist.save()
         # getting new releases
         for release_type in settings.MB_RELEASE_TYPES:
             limit = 100
             offset = 0
             parsed = 0
             cont = True
             while cont:
                 releases = musicbrainzngs.browse_releases(artist=artist.mbid,
                                                           release_type=[release_type],
                                                           release_status=settings.MB_RELEASE_STATUSES,
                                                           limit=limit,
                                                           offset=offset)
                 for release in releases['release-list']:
                     parsed += 1
                     album, created = Release.objects.get_or_create(mbid=release.get('id'), artist=artist)
                     if created:
                         print 'NEW: ', release.get('id'), release.get('title')
                         album.date = release.get('date')
                         if album.date:
                             album.year = release.get('date').split('-')[0]
                         album.title = release.get('title')
                         album.country = release.get('country')
                         album.type = release_type
                         album.save()
                 if parsed < releases['release-count']:
                     offset += limit
                 else:
                     cont = False
         artist.updated = now()
         artist.save()
     print 'FINISHED'
Exemple #20
0
def get_artist_releases(artist_mbid):
    limit = 100
    offset = 0
    releases = []
    release_groups = []
    page = 1

    result = mbz.browse_releases(
        artist=artist_mbid,
        limit=limit,
        offset=offset,
        includes=["release-groups", "artist-credits"],
        release_status=["official"],
    )

    releases += result["release-list"]

    if "release-count" in result:
        count = result["release-count"]

        while len(releases) < count:
            offset += limit
            page += 1

            result = mbz.browse_releases(
                artist=artist_mbid,
                limit=limit,
                offset=offset,
                includes=["release-groups", "artist-credits"],
                release_status=["official"],
            )
            releases += result["release-list"]

    for release in releases:
        if release not in release_groups:
            release_groups.append(release["release-group"])

    return {"status": 200, "releases": release_groups}
def MBID_releases_iterator(mbid):
    """
    Returns a dictionary with all releases in the form {title:mbid} for a given artist MBID
    """
    releases = {}
    rel = m.browse_releases(mbid)['release-list']
    # print rel
    no_rel = len(rel)
    for i in xrange(no_rel):
        title = rel[i]['title']
        mbid_title = rel[i]['id']
        releases[title] = mbid_title
    # print releases
    return releases
Exemple #22
0
def get_all_artist_songs(artist):
    '''Get a list of songs for a given artist'''
    artist_id = get_artist_id(artist)
    offset = 0
    songs = []
    result_len = BROWSE_LIMIT

    while result_len == BROWSE_LIMIT:
        result = mb.browse_releases(artist=artist_id,
                                    release_type=['single'],
                                    limit=BROWSE_LIMIT,
                                    offset=offset)['release-list']
        result_len = len(result)
        offset += result_len
        songs.extend([s['title'] for s in result])

    return list(set(songs))
    def getReleaseCount(self, release_group_id):
        """
        Helper function used to get the count of releases for a release-group by it's ID
        :param release_group_id: This is the id of the release-group
        :return release_count: The number of releases for that release-group
        """

        try:
            release_group_releases = musicbrainzngs.browse_releases(
                release_group=release_group_id)
            count = release_group_releases['release-count']
        except:
            raise serializers.ValidationError({
                "Too much music":
                "Seems like everybody wants to know how many albums blink 182 released, \
                    At least they are not looking for Britney. Give us a second a try again"
            })

        return count
Exemple #24
0
	def getArtistAlbums(self, artist_mbid):

		if artist_mbid in self.artist_cache:
			return self.artist_cache[artist_mbid]

		data = musicbrainzngs.browse_releases(artist=artist_mbid, includes=['release-groups', 'recordings'])
		ret = []
		for rel in data['release-list']:
			if rel['status'] != 'Official':
				continue
			if rel['release-group']['type'] != 'Album':
				continue
			format = rel['medium-list'][0]['format']
			if not((format == 'CD') | (format == 'Digital')):
				continue
			ret.append(rel)

		self.artist_cache[artist_mbid] = ret
		return ret
Exemple #25
0
def import_releases(artist, mb_id):
    releases = mb.browse_releases(artist=mb_id, release_type='album')
    for release in releases['release-list']:
        title = release['title']
        try:
            date = convert_time(release['date'])
        except:
            date = None
        try:
            mb_id = release['id']
        except:
            mb_id = '0'

        result = models.Album.objects.filter(musicbrainz_id=mb_id)
        if len(result) > 0:
            return

        album = models.Album(artist=artist, name=title,
                musicbrainz_id=mb_id)
        album.save()
def artist_self_releasing_records(
        artist_musicbrainz_id) -> 'artist_self_releasing_records':
    """Tell if the artist have self released records (i.e. without label) or not

    Arguments:
        artist_musicbrainz_id {str} -- 

    Returns:
        bool --
    """
    releases = mz.browse_releases(artist=artist_musicbrainz_id['value'],
                                  includes=['labels'])
    for r in releases['release-list']:
        label_list = r['label-info-list']
        for l in label_list:
            try:
                if l['label']['name'] == '[no label]':
                    return {'value': True}
            except KeyError:
                continue
Exemple #27
0
 def first_release_date(self, group_id):
     """Return the first release date in the release group, or None."""
     dates = []
     limit = 25
     offset = 0
     while True:
         try:
             response = mb_client.browse_releases(release_group=group_id,
                                                  limit=limit,
                                                  offset=offset)
             releases = response['release-list']
             dates.extend([r['date'] for r in releases if 'date' in r])
             if len(releases) < limit:
                 break
             else:
                 offset += limit
         except mb_client.ResponseError as e:
             raise MusicBrainzError from e
     if dates:
         return min(dates)
     else:
         return None
Exemple #28
0
 def get_releases(cls, mbid, rtypes=None):
     """
     @param: Artist mbid
     """
     limit = 100
     rtypes = ['album'] if not rtypes else rtypes
     result = musicbrainzngs.browse_releases(artist=mbid,
                                             release_type=rtypes,
                                             limit=limit)
     page_releases = result['release-list']
     albums = []
     known_titles = []
     for release in page_releases:
         if release.get('status', '') == 'Official':
             mbid = release.get('id', '')
             date = release.get('date', '')
             date = date.split('-')[0]
             title = release.get('title', '')
             if title and not title in known_titles:
                 known_titles.append(title)
                 albums.append({'title': title, 'mbid': mbid, 'date': date})
     return albums
Exemple #29
0
def music_get_artist_albums(artist_id: str, locale: str):
    releases = musicbrainzngs.browse_releases(artist_id,
                                              limit=100)["release-list"]
    artist = musicbrainzngs.get_artist_by_id(artist_id)["artist"]
    artist_name: str = artist["name"]

    doc: Document = minidom.Document()
    feed: Element = create_feed(doc, artist_id, artist_name, request.endpoint)

    for release in releases:
        id: str = release["id"]
        title: str = release["title"]
        entry: Element = create_entry(
            doc, title, id,
            f"/v3.2/{locale}/music/artist/{artist_id}/albums/{id}")
        feed.appendChild(entry)

        # Add front cover
        image_elem: Element = doc.createElement("image")
        image_id_elem: Element = create_id(doc, id)
        image_elem.appendChild(image_id_elem)
        entry.appendChild(image_elem)

        # Create primaryArtist element
        primary_artist_elem: Element = doc.createElement("primaryArtist")

        artist_id_element: Element = doc.createElement("id")
        set_element_value(artist_id_element, artist_id)
        primary_artist_elem.appendChild(artist_id_element)

        artist_name_element: Element = doc.createElement("name")
        set_element_value(artist_name_element, artist_name)
        primary_artist_elem.appendChild(artist_name_element)
        entry.appendChild(primary_artist_elem)

    #doc.appendChild(feed)
    xml_str = doc.toprettyxml(indent="\t")
    return Response(xml_str, mimetype=MIME_XML)
Exemple #30
0
def get_release_list(artist_str):
    """ Gets a release list from musicbrains API. """
    username = '******'
    password = '******'
    
    musicbrainzngs.set_useragent(username, password)
    artist_list = musicbrainzngs.search_artists(artist=artist_str)['artist-list']
    artist = sorted(artist_list, reverse=True, key=lambda artist:int(artist['ext:score']))[0]
    artist_id = artist['id']

    limit = 100
    offset = 0
    release_list = []
    release_count = 1

    while offset < release_count:
        print 'Requesting tracks {0} - {1}'.format(str(offset), str(offset+limit))
        result = musicbrainzngs.browse_releases(artist=artist_id, release_status=['official'], release_type=['album'], includes=['recordings'], limit=limit, offset=offset)
        release_count = result['release-count']
        release_list += result['release-list']
        offset += limit
    
    return release_list
def _artist_credit_fallback_alias(artist_credit, release={}):
    """Given an artist credit block, attempt to find an alias for the artist with the user's preferred locale
    from all the artist-credits for the artist.
    Optionally, we may have data for a release already, so we can try it first.

    Returns an alias for the artist, or the original artist, if not found.
    """

    artist = artist_credit["artist"]
    artist_name = artist['name']
    credit_name = artist_credit.get('name')

    release_lang = release.get('text-representation', {}).get('language')

    # Comparing by ISO639-3, which musicbrainz seems to use for release languages (but not for aliases!)
    release_lang = ISO_639_1_TO_3.get(release_lang, release_lang)
    preferred_langs = [
        ISO_639_1_TO_3.get(x, x) for x in config['import']['languages']
    ]

    # If the associated release matches the primary config locale, and has an additional credit name, use it.
    if release_lang and (release_lang == preferred_langs[0]) and credit_name:
        return credit_name

    # Use the canonical artist name as fallback
    artist_name = artist['name']

    # Lookup additional data on how the artist is credited on their releases
    # This could perhaps be cached somehow, if repeated api calls are a problem...
    # (Even just a cache of the last artist would make a difference in this case)
    try:
        res = musicbrainzngs.browse_releases(artist=artist['id'],
                                             includes='artist-credits')
    except musicbrainzngs.ResponseError:
        return artist_name

    releases = res['release-list']

    # Look through artist releases to find an artist-credits matching the users
    # preferred languages
    name_candidates = {}
    for release in releases:
        release_lang = release.get('text-representation', {}).get('language')
        release_lang = ISO_639_1_TO_3.get(release_lang, release_lang)

        # Skip releases without a language
        if release_lang is None:
            continue

        if release_lang in preferred_langs:
            # Get artist-credit name matching artist-id
            credit_name = None
            for credit in release['artist-credit']:
                # Skip over credits like x, ft., and, etc
                if (isinstance(credit, six.string_types)):
                    continue
                if credit['artist']['id'] == artist['id']:
                    # Differing credit name is under credit['name'] otherwise, will just give the usual artist
                    # details, without this additional tag
                    credit_name = credit.get('name')
                    break

            if credit_name is None:
                continue

            name_candidates.setdefault(release_lang, []).append(credit_name)

    # Choose from found credit-names based on preferred languages
    for lang in preferred_langs:
        names = name_candidates.get(lang)
        if names:
            # Just return the first name matching a locale
            # alternatively, we could perhaps pick one based on the newest release, for example
            return names[0]

    # Nothing valid found, fallback to what we had already
    return artist_name
Exemple #32
0
# print(artist["country"])
# print(artist["begin-area"])
# print(artist["type"])
# print(artist["sort-name"])





label = "71247f6b-fd24-4a56-89a2-23512f006f0c"
limit = 100
offset = 0
releases = []
page = 1
print("fetching page number %d.." % page)
result = musicbrainzngs.browse_releases(label=label, includes=["labels"],
                release_type=["album"], limit=limit)


page_releases = result['release-list']
print(page_releases)

releases += page_releases

# release-count is only available starting with musicbrainzngs 0.5
if "release-count" in result:
        count = result['release-count']
        print("")
while len(page_releases) >= limit:
    offset += limit
    page += 1
    print("fetching page number %d.." % page)
                # get genres for artist (not more than 3)
                try:
                    # sort tags by count
                    newlist = sorted(artist['tag-list'],
                                     key=lambda k: int(k['count']),
                                     reverse=True)
                    genre_list = [k['name'] for k in newlist]
                    genre = '#'.join(
                        genre_list if len(genre_list) < 4 else genre_list[:3])
                except KeyError:
                    print("SKIIIIIP : ARTIST HAS NO GENRE TAGS")
                    continue

                # get albums
                # length of all releases from this artist
                album_query = brainz.browse_releases(artist=artist["id"])
                album_query_len = album_query['release-count']
                # initialize temp variables
                saved_releases = []
                release_offset = release_start // release_limitsize * release_limitsize
                # same as above, brainz.search has limit of 100
                while release_offset < album_query_len:
                    for release_index, release in enumerate(
                            brainz.browse_releases(
                                artist=artist['id'],
                                offset=release_offset + release_start,
                                limit=release_limitsize)['release-list']):
                        # calculate current position for progress debug
                        current_artist = artist_offset + artist_index + start_artist % artist_limitsize
                        current_release = release_offset + release_index + release_start % release_limitsize
                        print(
Exemple #34
0
def getAlbumArtistNames(album,artist, apihandle, song=None):
  '''
  Given a supposed album and artist, determine the real ones
  '''
  def searchWhatAlbums(args):
    if len(args)==0:
      return []
    whatResponse = apihandle.request(action='browse',searchstr=args[0])
    if whatResponse['status']=='success':
      args.pop(0)
      return searchWhatAlbums(args)+[x for x in whatResponse['response']['results'] if 'artist' in x and 'groupName' in x]
    return []
  mbAlbums = []
  parens = re.compile('[\(\[].*[\)\]]')
  if song is not None:
    includes = ['recordings']
    artists = set(re.split(' &|and|ft\.?|featuring|feat\.? ',artist))
    if len(artists) > 1:
      artists.add(artist)
    for ar in artists:
      mbAlbums += [dict(list(x.items())+[("artist-credit-phrase", releases['artist-credit-phrase'])]) for releases in mb.search_recordings(query=song, limit=int(50*mbMultiplier), artistname=mbquote(ar), release=mbquote(album))['recording-list'] for x in releases['release-list']]
      mbAlbums += mb.search_releases(artist=mbquote(ar),query=mbquote(album),limit=int(25*mbMultiplier))['release-list']
      lastfmres = [x['mbid'] for x in lookup('lastfm','songsearch',{'artist':ar, 'song':song})['results']['trackmatches']['track'] if 'mbid' in x and len(x['mbid'])>0]
      if len(lastfmres)>0:
        for lastfmRecId in set(lastfmres):
          try:
            lastfmAlbum = mb.get_recording_by_id(id=lastfmRecId,includes=['releases','artist-credits'])
            for alb in lastfmAlbum['recording'].pop('release-list'):
              alb['medium-list'] = [{}]
              alb['medium-list'][0]['track-list'] = []
              alb['medium-list'][0]['track-list'].append(lastfmAlbum)
              alb['artist-credit-phrase'] = lastfmAlbum['recording']['artist-credit-phrase']
              mbAlbums.append(alb)
          except Exception as e:
            print(e)
  else:
    includes = []
    mbArtists = mb.search_artists(query=mbquote(artist),limit=int(40*mbMultiplier))['artist-list']
    mbAlbums += mb.search_releases(artist=mbquote(artist),query=mbquote(album),limit=int(50*mbMultiplier))['release-list']
    for mbArtist in mbArtists:
      if Levenshtein.ratio(artist.lower(),mbArtist['name'].lower()) > 0.75:
        mbAlbums+=[ dict(list(x.items())+[('artist-credit-phrase',mbArtist['name'])]) for x in mb.browse_releases(artist=mbArtist['id'],includes=includes,limit=25)['release-list']]
  if (len(album)<7 and ('/' in album or ' & ' in album) and 's' in album.lower() and 't' in album.lower()) or ('self' in album.lower() and 'titled' in album.lower()):
    mbAlbums += mb.search_releases(artist=mbquote(artist),query=mbquote(artist),limit=int(25*mbMultiplier))['release-list']
  temp = []
  for x in mbAlbums[:]:
    if x["id"] in temp and not ('medium-list' in x and len(x['medium-list'])>0 and all('track-list' in z and len(z['track-list'])>0 for z in x['medium-list'])):
      mbAlbums.remove(x)
    else:
      temp.append(x['id'])
  print("Done searching musicbrainz for album suggestions, have "+str(len(mbAlbums))+" to rank")
  
  ranks = {}
  for x in mbAlbums:
    ranks[x['id']] = Levenshtein.ratio(album.lower(),x['title'].lower())
    if song is not None:
      x['song'] = {}
      temp = ([(y['recording']['title'] if 'recording' in y else y['title'],
          int(float(
            y['recording']['length'] if 'recording' in y and 'length' in y['recording'] 
            else (y['track_or_recording_length'] if 'track_or_recording_length' in x 
            else y['length'] if 'length' in x else 0)
          )/1000.))
        for tracklist in x['medium-list']
        for y in tracklist['track-list']]
        if 'medium-list' in x and len(x['medium-list'])>0 and all('track-list' in z and len(z['track-list'])>0 for z in x['medium-list'])
        else getSongs(
          {"artist":x['artist-credit-phrase'], 
          "groupName":x['title']}))
      x['song']['name'], x['song']['duration'] = (max(temp, 
        key=lambda y: Levenshtein.ratio(y[0].lower(),song.lower())) if len(temp)>0 else ("",-1))
      if ranks[x['id']] < Levenshtein.ratio(x['song']['name'].lower(),song.lower()):
        ranks[x['id']] /= 6
        ranks[x['id']] +=  (Levenshtein.ratio(x['song']['name'].lower(),song.lower())
          + Levenshtein.ratio(parens.sub('',x['song']['name'].lower()),parens.sub('',song.lower())) )*5/12
      else:
        ranks[x['id']] /= 3
        ranks[x['id']] +=  (Levenshtein.ratio(x['song']['name'].lower(),song.lower())
          + Levenshtein.ratio(parens.sub('',x['song']['name'].lower()),parens.sub('',song.lower())) )/3
    ranks[x['id']] += Levenshtein.ratio(artist.lower(),x['artist-credit-phrase'].lower())*7/6
  if len(ranks) == 0:
    return None
  mbAlbumId, mbAlbumRank = max(ranks.items(),key=(lambda x:x[1]))
  mbAlbum = [x for x in mbAlbums if x['id']==mbAlbumId][0]
  print("For the artist and album derived from the provided dir ("+artist+" and "+album+" respectively),\nthe following artist and album was matched on musicbrains:")
  print("Artist: "+mbAlbum['artist-credit-phrase'])
  print("Album: "+mbAlbum['title'])
  whatAlbums = searchWhatAlbums([mbAlbum['title']+' '+mbAlbum['artist-credit-phrase'], artist+' '+album])
  if len(whatAlbums) == 0:
    whatAlbums = searchWhatAlbums([artist,album,mbAlbum['title'],mbAlbum['artist-credit-phrase']])
    if len(whatAlbums) == 0:
      return None
  whatAlbums = sorted(whatAlbums, key=(lambda x:
      Levenshtein.ratio(x['groupName'],mbAlbum['title'])
      +Levenshtein.ratio(x['groupName'].lower(),album.lower())*3/8
      +Levenshtein.ratio(x['artist'],mbAlbum['artist-credit-phrase'])
      +Levenshtein.ratio(x['artist'].lower(),artist.lower())*5/8),
    reverse=True)#[:min(10,len(whatAlbums))]
  whatAlbum = whatAlbums[0]
  whatAlbum['artist-credit-phrase'] = mbAlbum['artist-credit-phrase']
  if song is not None:
    whatAlbum['song'] = mbAlbum['song']
  print("For the album and artist found on musicbrainz, the following torrent group was found on what:")
  print("Artist: "+whatAlbum['artist'])
  print("Album: "+whatAlbum['groupName'])
  return whatAlbum
Exemple #35
0
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 getMusicbrainzArtistMetadata(artist):
    artist_md.musicbrainz_id = artist['id']
    if 'country' in artist:
        if artist['country'] == 'US':
            artist_md.is_american = True
            artist_md.is_german = False
            artist_md.is_other_country = False
        elif artist['country'] == 'DE':
            artist_md.is_german = True
            artist_md.is_american = False
            artist_md.is_other_country = False
        else:
            artist_md.is_other_country = True
            artist_md.is_american = False
            artist_md.is_german = False
        artist_md.country = artist['country']
    else:
        pass  # TODO: get country
    if 'area' in artist and 'iso-3166-1-code-list' in artist['area']:
        artist_md.area = artist['area']['iso-3166-1-code-list']
    else:
        pass  # TODO: get country
    if 'type' in artist:
        if artist['type'] != "Person":
            artist_md.is_group = True
            artist_md.is_male = False
            artist_md.is_female = False
        else:
            artist_md.is_group = False
    if 'gender' in artist:
        if artist['gender'] == 'Male':
            artist_md.is_male = True
            artist_md.is_female = False
            artist_md.is_group = False
        elif artist['gender'] == 'Female':
            artist_md.is_male = False
            artist_md.is_female = True
            artist_md.is_group = False

    if 'life-span' in artist:
        if 'begin' in artist['life-span']:
            if 'end' in artist['life-span']:
                artist_md.life_span = utils.getActivity(start=artist['life-span']['begin'],
                                                        end=artist['life-span']['end'])
            else:
                try:
                    artist_md.life_span = utils.getActivity(start=artist['life-span']['begin'])
                except ValueError:
                    print colored("| Date error...", 'red')
                    artist_md.error = True

    '''
    musicbrainz uses a rating based on 5 (0 = bad, 5= good) but I want a float between 0 and 100
    '''
    if 'rating' in artist:
        artist_md.buffer['popularity'].append(float(artist['rating']['rating']) * 20)
    artist_md.buffer['recording_count'].append(artist['recording-count'])
    artist_md.buffer['release_count'].append(artist['release-count'])
    artist_md.buffer['work_count'].append(artist['work-count'])
    if 'tag-list' in artist:
        for tag in artist['tag-list']:
            artist_md.addTag(tag['name'])  # TODO: 'count' instead of weight

    releases = musicbrainzngs.browse_releases(artist['id'], includes=['labels'], limit=50)
    for release in releases['release-list']:
        if 'text-representation' in release and 'language' in release['text-representation']:
            artist_md.addLanguage(release['text-representation']['language'])
        if 'label-info-list' in release:
            for label in release['label-info-list']:
                if 'label' in label:
                    artist_md.addLabel({'name': label['label']['name'], 'release_count': None}, parent_label=None,
                                       sublabels=None)  # TODO: get missing data
Exemple #37
0
def getMusicbrainzArtistMetadata(artist):
    artist_md.musicbrainz_id = artist['id']
    if 'country' in artist:
        if artist['country'] == 'US':
            artist_md.is_american = True
            artist_md.is_german = False
            artist_md.is_other_country = False
        elif artist['country'] == 'DE':
            artist_md.is_german = True
            artist_md.is_american = False
            artist_md.is_other_country = False
        else:
            artist_md.is_other_country = True
            artist_md.is_american = False
            artist_md.is_german = False
        artist_md.country = artist['country']
    else:
        pass  # TODO: get country
    if 'area' in artist and 'iso-3166-1-code-list' in artist['area']:
        artist_md.area = artist['area']['iso-3166-1-code-list']
    else:
        pass  # TODO: get country
    if 'type' in artist:
        if artist['type'] != "Person":
            artist_md.is_group = True
            artist_md.is_male = False
            artist_md.is_female = False
        else:
            artist_md.is_group = False
    if 'gender' in artist:
        if artist['gender'] == 'Male':
            artist_md.is_male = True
            artist_md.is_female = False
            artist_md.is_group = False
        elif artist['gender'] == 'Female':
            artist_md.is_male = False
            artist_md.is_female = True
            artist_md.is_group = False

    if 'life-span' in artist:
        if 'begin' in artist['life-span']:
            if 'end' in artist['life-span']:
                artist_md.life_span = utils.getActivity(
                    start=artist['life-span']['begin'],
                    end=artist['life-span']['end'])
            else:
                try:
                    artist_md.life_span = utils.getActivity(
                        start=artist['life-span']['begin'])
                except ValueError:
                    print colored("| Date error...", 'red')
                    artist_md.error = True
    '''
    musicbrainz uses a rating based on 5 (0 = bad, 5= good) but I want a float between 0 and 100
    '''
    if 'rating' in artist:
        artist_md.buffer['popularity'].append(
            float(artist['rating']['rating']) * 20)
    artist_md.buffer['recording_count'].append(artist['recording-count'])
    artist_md.buffer['release_count'].append(artist['release-count'])
    artist_md.buffer['work_count'].append(artist['work-count'])
    if 'tag-list' in artist:
        for tag in artist['tag-list']:
            artist_md.addTag(tag['name'])  # TODO: 'count' instead of weight

    releases = musicbrainzngs.browse_releases(artist['id'],
                                              includes=['labels'],
                                              limit=50)
    for release in releases['release-list']:
        if 'text-representation' in release and 'language' in release[
                'text-representation']:
            artist_md.addLanguage(release['text-representation']['language'])
        if 'label-info-list' in release:
            for label in release['label-info-list']:
                if 'label' in label:
                    artist_md.addLabel(
                        {
                            'name': label['label']['name'],
                            'release_count': None
                        },
                        parent_label=None,
                        sublabels=None)  # TODO: get missing data
Exemple #38
0
 def count_release(self, release_group_id):
     result = musicbrainzngs.browse_releases(release_group=release_group_id)
     return result['release-count']
Exemple #39
0
    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()
        fmt = config['format_album'].get()

        release_status = self.config['release_status'].get()
        release_type = self.config['release_type'].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_releases(
                        artist=artist[1],
                        release_status=release_status,
                        release_type=release_type,
                        includes=[
                            "artist-credits",
                            "labels",
                            "recordings",
                            "isrcs",
                            "release-groups",
                            "media",
                            "discids",
                            "area-rels",
                            "artist-rels",
                            "label-rels",
                            "place-rels",
                            "event-rels",
                            "recording-rels",
                            "release-rels",
                            "release-group-rels",
                            "series-rels",
                            "url-rels",
                            "work-rels",
                            "instrument-rels"
                        ]
                    )
                release_groups = resp['release-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.get("release-group", {}).get("id"):
                        missing.remove(rg)
                        present.append(rg)
                        break

            total_missing += len(missing)
            if total:
                continue

            for r in missing:
                #self._log.info(u"{}\n\n", r)
                item = _album_item(r)
                print_(format(item, fmt))

        if total:
            print(total_missing)
def populate_db(mbdb, options, irank_db):
	if options.threshold:
		artists = irank_db.execute('select artist from songs where artist <> "" group by artist having count(path) > ? order by count(path)', [options.threshold])
	else:
		artists = irank_db.execute('select artist from songs where artist <> "" group by artist')
	
	if options.target:
		assert options.max_age, "--max-age must be provided when using --target"
		min_date = TODAY - datetime.timedelta(days=options.max_age)
		logging.debug("min_date: %r" % (min_date,))
		# we're not doing all artists, just the `n` oldest
		artists = list(artists)
		logging.debug("total artists: %d", len(artists))
		def age(artist):
			checked = list(mbdb.execute('select checked from artists where name = ?', [artist]))
			if not checked: return EPOCH
			date = checked[0][0]
			if date == 'now':
				# oops...
				return to_date('2015-02-01')
			return to_date(date)
		artists_with_age = [(artist, age(artist[0])) for artist in artists]
		artists_with_age = sorted(artists_with_age, key=lambda pair:pair[1])
		if options.min_age:
			max_date = TODAY - datetime.timedelta(days=options.min_age)
			logging.debug("max_date: %r", max_date)
			artists_with_age = list(itertools.takewhile(lambda pair: pair[1] < max_date, artists_with_age))
			logging.debug(
				"there are %d artists which were checked more than %d days ago" %
				(len(artists_with_age), options.min_age))

		selection = list(itertools.takewhile(lambda pair: pair[1] < min_date, artists_with_age))
		logging.debug(
			"there are %d artists which were checked more than %d days ago" %
			(len(selection), options.max_age))

		if len(selection) > options.target:
			logging.warn(
				"processing %d artists which were checked more than %d days ago" %
				(len(selection), options.max_age))
		else:
			selection = artists_with_age[:options.target]
		artists = [pair[0] for pair in selection]
		# logging.debug('%r', selection)
		logging.debug("Processing %d artists", len(artists))

	now = format_date(TODAY)
	for (artist,) in artists:
		logging.debug("getting ID for artist %s", artist)
		results = mb.search_artists(artist=artist, strict=False, limit=10)['artist-list']
		if len(results) == 0:
			err("WARN: no such artist: %s" % artist)
			continue
		if len(results) > 1:
			logging.info("multiple artists: %s", ' / '.join(list(map(lambda artist: artist['name'], results))))
		result = results[0]
		artist_id = result['id']
		mbdb.execute('insert or replace into artists (name, id, checked) values (?,?,?)', (artist, artist_id, now))
		
		# OK, id saved to the DB now.
		offset=0
		limit=100
		releases = {}
		while True:
			logging.info("getting releases[%d:%d] for artist %s [%s]", offset, offset+limit, artist, artist_id)
			recordings = mb.browse_releases(artist=artist_id, release_type=['album', 'ep'], includes=['url-rels'], offset=offset, limit=limit)['release-list']
			# recordings = sorted(recordings, key=lambda rec: rec.get('date', ''))
			logging.info("got %d recordings", len(recordings))
			for title, recordings in itertools.groupby(recordings, lambda x: x['title']):
				recordings = list(recordings)
				dates = list(map(lambda rec: rec.get('date', ''), recordings))
				# err(repr((title, dates)))
				longest_timestamp = len(max(dates))
				if not longest_timestamp:
					continue
				earliest_date = min(filter(lambda date: len(date) == longest_timestamp, dates))
				if title in releases and releases[title] <= earliest_date:
					continue
				releases[title] = earliest_date
			if len(recordings) < limit: break # we got less than `limit`, so there aren't any more
			offset += len(recordings)

		for title, date in sorted(releases.items(), key=lambda pair:pair[1]):
			date = format_date(to_date(date))
			mbdb.execute('insert or replace into releases (artist_id, title, artist, date) VALUES (?,?,?,?)', (artist_id, title, artist, date))
			# err("%s - %s (released %s)" % (artist, title, date))
		mbdb.execute('update artists set checked=? where name=? and id=?', (now, artist, artist_id))
		mbdb.commit()
Exemple #41
0
def get_new_releases(rgid, includeExtras=False, forcefull=False):
    myDB = db.DBConnection()
    results = []

    release_status = "official"
    if includeExtras and not headphones.CONFIG.OFFICIAL_RELEASES_ONLY:
        release_status = []

    try:
        limit = 100
        newResults = None
        while newResults is None or len(newResults) >= limit:
            with mb_lock:
                newResults = musicbrainzngs.browse_releases(
                    release_group=rgid,
                    includes=["artist-credits", "labels", "recordings", "release-groups", "media"],
                    release_status=release_status,
                    limit=limit,
                    offset=len(results),
                )
            if "release-list" not in newResults:
                break  # may want to raise an exception here instead ?
            newResults = newResults["release-list"]
            results += newResults

    except musicbrainzngs.WebServiceError as e:
        logger.warn(
            'Attempt to retrieve information from MusicBrainz for release group "%s" failed (%s)' % (rgid, str(e))
        )
        mb_lock.snooze(5)
        return False

    if not results or len(results) == 0:
        return False

    # Clean all references to releases in dB that are no longer referenced in musicbrainz
    release_list = []
    force_repackage1 = 0
    if len(results) != 0:
        for release_mark in results:
            release_list.append(unicode(release_mark["id"]))
            release_title = release_mark["title"]
        remove_missing_releases = myDB.action("SELECT ReleaseID FROM allalbums WHERE AlbumID=?", [rgid])
        if remove_missing_releases:
            for items in remove_missing_releases:
                if items["ReleaseID"] not in release_list and items["ReleaseID"] != rgid:
                    # Remove all from albums/tracks that aren't in release
                    myDB.action("DELETE FROM albums WHERE ReleaseID=?", [items["ReleaseID"]])
                    myDB.action("DELETE FROM tracks WHERE ReleaseID=?", [items["ReleaseID"]])
                    myDB.action("DELETE FROM allalbums WHERE ReleaseID=?", [items["ReleaseID"]])
                    myDB.action("DELETE FROM alltracks WHERE ReleaseID=?", [items["ReleaseID"]])
                    logger.info("Removing all references to release %s to reflect MusicBrainz" % items["ReleaseID"])
                    force_repackage1 = 1
    else:
        logger.info(
            "There was either an error pulling data from MusicBrainz or there might not be any releases for this category"
        )

    num_new_releases = 0

    for releasedata in results:

        release = {}
        rel_id_check = releasedata["id"]
        album_checker = myDB.action("SELECT * from allalbums WHERE ReleaseID=?", [rel_id_check]).fetchone()
        if not album_checker or forcefull:
            # DELETE all references to this release since we're updating it anyway.
            myDB.action("DELETE from allalbums WHERE ReleaseID=?", [rel_id_check])
            myDB.action("DELETE from alltracks WHERE ReleaseID=?", [rel_id_check])
            release["AlbumTitle"] = unicode(releasedata["title"])
            release["AlbumID"] = unicode(rgid)
            release["AlbumASIN"] = unicode(releasedata["asin"]) if "asin" in releasedata else None
            release["ReleaseDate"] = unicode(releasedata["date"]) if "date" in releasedata else None
            release["ReleaseID"] = releasedata["id"]
            if "release-group" not in releasedata:
                raise Exception("No release group associated with release id " + releasedata["id"] + " album id" + rgid)
            release["Type"] = unicode(releasedata["release-group"]["type"])

            if release["Type"] == "Album" and "secondary-type-list" in releasedata["release-group"]:
                secondary_type = unicode(releasedata["release-group"]["secondary-type-list"][0])
                if secondary_type != release["Type"]:
                    release["Type"] = secondary_type

            # making the assumption that the most important artist will be first in the list
            if "artist-credit" in releasedata:
                release["ArtistID"] = unicode(releasedata["artist-credit"][0]["artist"]["id"])
                release["ArtistName"] = unicode(releasedata["artist-credit-phrase"])
            else:
                logger.warn("Release " + releasedata["id"] + " has no Artists associated.")
                return False

            release["ReleaseCountry"] = unicode(releasedata["country"]) if "country" in releasedata else u"Unknown"
            # assuming that the list will contain media and that the format will be consistent
            try:
                additional_medium = ""
                for position in releasedata["medium-list"]:
                    if position["format"] == releasedata["medium-list"][0]["format"]:
                        medium_count = int(position["position"])
                    else:
                        additional_medium = additional_medium + " + " + position["format"]
                if medium_count == 1:
                    disc_number = ""
                else:
                    disc_number = str(medium_count) + "x"
                packaged_medium = disc_number + releasedata["medium-list"][0]["format"] + additional_medium
                release["ReleaseFormat"] = unicode(packaged_medium)
            except:
                release["ReleaseFormat"] = u"Unknown"

            release["Tracks"] = getTracksFromRelease(releasedata)

            # What we're doing here now is first updating the allalbums & alltracks table to the most
            # current info, then moving the appropriate release into the album table and its associated
            # tracks into the tracks table
            controlValueDict = {"ReleaseID": release["ReleaseID"]}

            newValueDict = {
                "ArtistID": release["ArtistID"],
                "ArtistName": release["ArtistName"],
                "AlbumTitle": release["AlbumTitle"],
                "AlbumID": release["AlbumID"],
                "AlbumASIN": release["AlbumASIN"],
                "ReleaseDate": release["ReleaseDate"],
                "Type": release["Type"],
                "ReleaseCountry": release["ReleaseCountry"],
                "ReleaseFormat": release["ReleaseFormat"],
            }

            myDB.upsert("allalbums", newValueDict, controlValueDict)

            for track in release["Tracks"]:

                cleanname = helpers.clean_name(
                    release["ArtistName"] + " " + release["AlbumTitle"] + " " + track["title"]
                )

                controlValueDict = {"TrackID": track["id"], "ReleaseID": release["ReleaseID"]}

                newValueDict = {
                    "ArtistID": release["ArtistID"],
                    "ArtistName": release["ArtistName"],
                    "AlbumTitle": release["AlbumTitle"],
                    "AlbumID": release["AlbumID"],
                    "AlbumASIN": release["AlbumASIN"],
                    "TrackTitle": track["title"],
                    "TrackDuration": track["duration"],
                    "TrackNumber": track["number"],
                    "CleanName": cleanname,
                }

                match = myDB.action(
                    "SELECT Location, BitRate, Format from have WHERE CleanName=?", [cleanname]
                ).fetchone()

                if not match:
                    match = myDB.action(
                        "SELECT Location, BitRate, Format from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?",
                        [release["ArtistName"], release["AlbumTitle"], track["title"]],
                    ).fetchone()
                    # if not match:
                    # match = myDB.action('SELECT Location, BitRate, Format from have WHERE TrackID=?', [track['id']]).fetchone()
                if match:
                    newValueDict["Location"] = match["Location"]
                    newValueDict["BitRate"] = match["BitRate"]
                    newValueDict["Format"] = match["Format"]
                    # myDB.action('UPDATE have SET Matched="True" WHERE Location=?', [match['Location']])
                    myDB.action("UPDATE have SET Matched=? WHERE Location=?", (release["AlbumID"], match["Location"]))

                myDB.upsert("alltracks", newValueDict, controlValueDict)
            num_new_releases = num_new_releases + 1
            if album_checker:
                logger.info(
                    "[%s] Existing release %s (%s) updated"
                    % (release["ArtistName"], release["AlbumTitle"], rel_id_check)
                )
            else:
                logger.info(
                    "[%s] New release %s (%s) added" % (release["ArtistName"], release["AlbumTitle"], rel_id_check)
                )
        if force_repackage1 == 1:
            num_new_releases = -1
            logger.info(
                "[%s] Forcing repackage of %s, since dB releases have been removed"
                % (release["ArtistName"], release_title)
            )
        else:
            num_new_releases = num_new_releases

    return num_new_releases
Exemple #42
0
    def get_artist_info(mbid):
        result = musicbrainzngs.get_artist_by_id(mbid, ['url-rels', 'tags'])
        releases = musicbrainzngs.browse_releases(artist=mbid, limit=100)

        result['artist']['release-list'] = releases['release-list']
        return result
Exemple #43
0
async def _releases(artist_id, offset=0):
    return mbz.browse_releases(artist=artist_id,
                               release_type=['album', 'single'],
                               includes='recordings',
                               offset=offset,
                               limit=100)
Exemple #44
0
def get_new_releases(rgid,includeExtras=False,forcefull=False):

    myDB = db.DBConnection()
    results = []
    try:
        limit = 100
        newResults = None
        while newResults == None or len(newResults) >= limit:
            newResults = musicbrainzngs.browse_releases(release_group=rgid,includes=['artist-credits','labels','recordings','release-groups','media'],limit=limit,offset=len(results))
            if 'release-list' not in newResults:
                break #may want to raise an exception here instead ?
            newResults = newResults['release-list']
            results += newResults

    except musicbrainzngs.WebServiceError as e:
        logger.warn('Attempt to retrieve information from MusicBrainz for release group "%s" failed (%s)' % (rgid, str(e)))
        time.sleep(5)
        return False

    if not results or len(results) == 0:
        return False

    #Clean all references to releases in dB that are no longer referenced in musicbrainz
    release_list = []
    force_repackage1 = 0
    if len(results) != 0:
        for release_mark in results:
            release_list.append(unicode(release_mark['id']))
            release_title = release_mark['title']
        remove_missing_releases = myDB.action("SELECT ReleaseID FROM allalbums WHERE AlbumID=?", [rgid])
        if remove_missing_releases:
            for items in remove_missing_releases:
                if items['ReleaseID'] not in release_list and items['ReleaseID'] != rgid:
                    # Remove all from albums/tracks that aren't in release
                    myDB.action("DELETE FROM albums WHERE ReleaseID=?", [items['ReleaseID']])
                    myDB.action("DELETE FROM tracks WHERE ReleaseID=?", [items['ReleaseID']])
                    myDB.action("DELETE FROM allalbums WHERE ReleaseID=?", [items['ReleaseID']])
                    myDB.action("DELETE FROM alltracks WHERE ReleaseID=?", [items['ReleaseID']])
                    logger.info("Removing all references to release %s to reflect MusicBrainz" % items['ReleaseID'])
                    force_repackage1 = 1
    else:
        logger.info("There was either an error pulling data from MusicBrainz or there might not be any releases for this category")

    num_new_releases = 0

    for releasedata in results:
        #releasedata.get will return None if it doesn't have a status
        #all official releases should have the Official status included
        if not includeExtras and releasedata.get('status') != 'Official':
            continue

        release = {}
        rel_id_check = releasedata['id']
        artistid = unicode(releasedata['artist-credit'][0]['artist']['id'])

        album_checker = myDB.action('SELECT * from allalbums WHERE ReleaseID=?', [rel_id_check]).fetchone()
        if not album_checker or forcefull:
            #DELETE all references to this release since we're updating it anyway.
            myDB.action('DELETE from allalbums WHERE ReleaseID=?', [rel_id_check])
            myDB.action('DELETE from alltracks WHERE ReleaseID=?', [rel_id_check])
            release['AlbumTitle'] = unicode(releasedata['title'])
            release['AlbumID'] = unicode(rgid)
            release['AlbumASIN'] = unicode(releasedata['asin']) if 'asin' in releasedata else None
            release['ReleaseDate'] = unicode(releasedata['date']) if 'date' in releasedata else None
            release['ReleaseID'] = releasedata['id']
            if 'release-group' not in releasedata:
                raise Exception('No release group associated with release id ' + releasedata['id'] + ' album id' + rgid)
            release['Type'] = unicode(releasedata['release-group']['type'])

            if release['Type'] == 'Album' and 'secondary-type-list' in releasedata['release-group']:
                secondary_type = unicode(releasedata['release-group']['secondary-type-list'][0])
                if secondary_type != release['Type']:
                    release['Type'] = secondary_type

            #making the assumption that the most important artist will be first in the list
            if 'artist-credit' in releasedata:
                release['ArtistID'] = unicode(releasedata['artist-credit'][0]['artist']['id'])
                release['ArtistName'] = unicode(releasedata['artist-credit-phrase'])
            else:
                logger.warn('Release ' + releasedata['id'] + ' has no Artists associated.')
                return False


            release['ReleaseCountry'] = unicode(releasedata['country']) if 'country' in releasedata else u'Unknown'
            #assuming that the list will contain media and that the format will be consistent
            try:
                additional_medium=''
                for position in releasedata['medium-list']:
                    if position['format'] == releasedata['medium-list'][0]['format']:
                        medium_count = int(position['position'])
                    else:
                        additional_medium = additional_medium+' + '+position['format']
                if medium_count == 1:
                    disc_number = ''
                else:
                    disc_number = str(medium_count)+'x'
                packaged_medium = disc_number+releasedata['medium-list'][0]['format']+additional_medium
                release['ReleaseFormat'] = unicode(packaged_medium)
            except:
                release['ReleaseFormat'] = u'Unknown'

            release['Tracks'] = getTracksFromRelease(releasedata)

        # What we're doing here now is first updating the allalbums & alltracks table to the most
        # current info, then moving the appropriate release into the album table and its associated
        # tracks into the tracks table
            controlValueDict = {"ReleaseID" : release['ReleaseID']}

            newValueDict = {"ArtistID":         release['ArtistID'],
                            "ArtistName":       release['ArtistName'],
                            "AlbumTitle":       release['AlbumTitle'],
                            "AlbumID":          release['AlbumID'],
                            "AlbumASIN":        release['AlbumASIN'],
                            "ReleaseDate":      release['ReleaseDate'],
                            "Type":             release['Type'],
                            "ReleaseCountry":   release['ReleaseCountry'],
                            "ReleaseFormat":    release['ReleaseFormat']
                        }

            myDB.upsert("allalbums", newValueDict, controlValueDict)

            for track in release['Tracks']:

                cleanname = helpers.cleanName(release['ArtistName'] + ' ' + release['AlbumTitle'] + ' ' + track['title'])

                controlValueDict = {"TrackID":      track['id'],
                                    "ReleaseID":    release['ReleaseID']}

                newValueDict = {"ArtistID":         release['ArtistID'],
                                "ArtistName":       release['ArtistName'],
                                "AlbumTitle":       release['AlbumTitle'],
                                "AlbumID":          release['AlbumID'],
                                "AlbumASIN":        release['AlbumASIN'],
                                "TrackTitle":       track['title'],
                                "TrackDuration":    track['duration'],
                                "TrackNumber":      track['number'],
                                "CleanName":        cleanname
                            }

                match = myDB.action('SELECT Location, BitRate, Format from have WHERE CleanName=?', [cleanname]).fetchone()

                if not match:
                    match = myDB.action('SELECT Location, BitRate, Format from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [release['ArtistName'], release['AlbumTitle'], track['title']]).fetchone()
                #if not match:
                    #match = myDB.action('SELECT Location, BitRate, Format from have WHERE TrackID=?', [track['id']]).fetchone()
                if match:
                    newValueDict['Location'] = match['Location']
                    newValueDict['BitRate'] = match['BitRate']
                    newValueDict['Format'] = match['Format']
                    #myDB.action('UPDATE have SET Matched="True" WHERE Location=?', [match['Location']])
                    myDB.action('UPDATE have SET Matched=? WHERE Location=?', (release['AlbumID'], match['Location']))

                myDB.upsert("alltracks", newValueDict, controlValueDict)
            num_new_releases = num_new_releases + 1
            #print releasedata['title']
            #print num_new_releases
            if album_checker:
                logger.info('[%s] Existing release %s (%s) updated' % (release['ArtistName'], release['AlbumTitle'], rel_id_check))
            else:
                logger.info('[%s] New release %s (%s) added' % (release['ArtistName'], release['AlbumTitle'], rel_id_check))
    if force_repackage1 == 1:
        num_new_releases = -1
        logger.info('[%s] Forcing repackage of %s, since dB releases have been removed' % (release['ArtistName'], release_title))
    else:
        num_new_releases = num_new_releases

    return num_new_releases
Exemple #45
0
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()