Example #1
0
def getSpotifyMetadata(track, search_artist=True):
    artist_id = None
    possible_tracks = []
    recordings = spotify.search(q='artist:' + track[0] + ' track:' + track[1], type='track')
    for recording in recordings['tracks']['items']:  # keys in recordings: items,next,href,limit,offset,total,previous
        for artist in recording['artists']:
            '''
            Spotify may return different versions of the same song, e.g. a Radio Edit, or the same song released on another label
            '''
            if utils.is_similar(artist['name'].lower(), track[0]) and (
                    utils.checkTrackNamingConvention(recording['name'].lower(),
                                                     track[1], normalize=True)):
                if artist_id is None:
                    artist_id = artist['id']
                possible_tracks.append(recording)
    getSpotifyTrackMetadata(possible_tracks)
    if search_artist:
        if artist_id is None:
            artists = spotify.search(q='artist:' + track[0], type='artist')
            for artist in artists['artists']['items']:
                # TODO: multiple artists with same name => let user choose
                if utils.is_similar(artist['name'].lower(), track[0]):
                    getSpotifyArtistMetadata(artist)
                    break
        else:
            getSpotifyArtistMetadata(spotify.artist(artist_id))
Example #2
0
def getSpotifyMetadata(track, search_artist=True):
    artist_id = None
    possible_tracks = []
    recordings = spotify.search(q='artist:' + track[0] + ' track:' + track[1],
                                type='track')
    for recording in recordings['tracks'][
            'items']:  # keys in recordings: items,next,href,limit,offset,total,previous
        for artist in recording['artists']:
            '''
            Spotify may return different versions of the same song, e.g. a Radio Edit, or the same song released on another label
            '''
            if utils.is_similar(
                    artist['name'].lower(),
                    track[0]) and (utils.checkTrackNamingConvention(
                        recording['name'].lower(), track[1], normalize=True)):
                if artist_id is None:
                    artist_id = artist['id']
                possible_tracks.append(recording)
    getSpotifyTrackMetadata(possible_tracks)
    if search_artist:
        if artist_id is None:
            artists = spotify.search(q='artist:' + track[0], type='artist')
            for artist in artists['artists']['items']:
                # TODO: multiple artists with same name => let user choose
                if utils.is_similar(artist['name'].lower(), track[0]):
                    getSpotifyArtistMetadata(artist)
                    break
        else:
            getSpotifyArtistMetadata(spotify.artist(artist_id))
Example #3
0
def getEchonestMetadata(track, search_artist=True):
    artist_id = None
    possible_artists = []
    possible_tracks = []

    try:
        '''
        Get all recordings from echonest with the corresponding artist and track-title
        '''
        recordings = echonest_song.search(artist=track[0], title=track[1])
        for recording in recordings:
            '''
            check if echonest found the correct title or if it returned just similar written tracks
            '''
            if utils.is_similar(recording.title, track[1], normalize=True) and utils.is_similar(
                    recording.artist_name.lower(),
                    track[0]):
                if artist_id is None:
                    artist_id = recording.artist_id
                '''
                there may exist multiple entities for one song at echonest, so I collect all the matching songs
                '''
                possible_tracks.append(recording)
        '''
        if we found more than one track, get the mean metadata for all of them
        '''
        if len(possible_tracks) > 0:
            getEchonestTrackMetadata(possible_tracks)

        if search_artist:
            if artist_id is None:
                '''
                if echonest couldn't find a corresponding match for the given artist and track, there are chances it will still find
                only the artist by it's name
                '''
                artists = echonest_artist.search(name=track[0])
                for artist in artists:
                    if utils.is_similar(artist.name, track[0], normalize=True):
                        possible_artists.append(artist)
                if len(possible_artists) > 1:
                    pass  # TODO let user choose
                elif len(possible_artists) == 1:
                    getEchonestArtistMetadata(possible_artists[0])
            else:
                getEchonestArtistMetadata(echonest_artist.Artist(artist_id))
    except socket.timeout:
        track_md.error = True
        print colored("| Socket timeout...", 'red')
Example #4
0
def getEchonestMetadata(track, search_artist=True):
    artist_id = None
    possible_artists = []
    possible_tracks = []

    try:
        '''
        Get all recordings from echonest with the corresponding artist and track-title
        '''
        recordings = echonest_song.search(artist=track[0], title=track[1])
        for recording in recordings:
            '''
            check if echonest found the correct title or if it returned just similar written tracks
            '''
            if utils.is_similar(recording.title, track[1],
                                normalize=True) and utils.is_similar(
                                    recording.artist_name.lower(), track[0]):
                if artist_id is None:
                    artist_id = recording.artist_id
                '''
                there may exist multiple entities for one song at echonest, so I collect all the matching songs
                '''
                possible_tracks.append(recording)
        '''
        if we found more than one track, get the mean metadata for all of them
        '''
        if len(possible_tracks) > 0:
            getEchonestTrackMetadata(possible_tracks)

        if search_artist:
            if artist_id is None:
                '''
                if echonest couldn't find a corresponding match for the given artist and track, there are chances it will still find
                only the artist by it's name
                '''
                artists = echonest_artist.search(name=track[0])
                for artist in artists:
                    if utils.is_similar(artist.name, track[0], normalize=True):
                        possible_artists.append(artist)
                if len(possible_artists) > 1:
                    pass  # TODO let user choose
                elif len(possible_artists) == 1:
                    getEchonestArtistMetadata(possible_artists[0])
            else:
                getEchonestArtistMetadata(echonest_artist.Artist(artist_id))
    except socket.timeout:
        track_md.error = True
        print colored("| Socket timeout...", 'red')
Example #5
0
def getDiscogsMetadata(track, search_artist=True):
    # artists = discogs.search(track[1], type='release', artist=track[0])

    # TODO: discogs offers a really really REALLY weird search functionality. You never get what you expect to get (if you get anything at all...)
    # The best, most performant and according to discogs 'correct' way to query the data is the call above this comment, but... well, it does not work, so I try to get the best results with
    # this call:
    try:
        releases = discogs.search(u"{0}+{1}".format(track[0], track[1]),
                                  type="release")
        processed_artist = False
        checked_releases = 0
        for release in releases:
            '''
            problem: For artists with the same name discogs generates a suffix with the index, e.g. '# TODO: discogs offers a really really REALLY weird search functionality. You never get what you expect to get (if you get anything at all...) Adele', 'Adele (2)', 'Adele (3)',...
            and they don't provide the normal name of the artist in the artist-object.
            The solution is to filter out the suffix using regular expression in order to compare the name from the artist-object with the
            given track artist
            '''
            checked_releases += 1
            if checked_releases > DISCOGS_RELEASES_LIMIT:
                break
            for artist in release.artists:
                name = re.search("^(.*?)(\s\(\d\))?$", artist.name)
                if name:
                    if utils.is_similar(name.group(1).lower(), track[0]):
                        if search_artist and not processed_artist:
                            getDiscogsArtistMetadata(artist)
                            processed_artist = True
                        for track_obj in release.data['tracklist']:
                            if utils.is_similar(track_obj['title'],
                                                track[1],
                                                normalize=True):
                                getDiscogsTrackMetadata(release, track_obj)
                                return

        if not processed_artist and search_artist:
            artists = discogs.search(track[0], type="artist")
            for artist in artists:
                if utils.is_similar(artist.name.lower(), track[0]):
                    getDiscogsArtistMetadata(artist)
                    break
    except requests.exceptions.SSLError:
        track_md.error = True
        print colored("| SSL error...", 'red')
    except discogs_client.exceptions.HTTPError:
        track_md.error = True
        print colored("| Internal discogs-server error...", 'red')
Example #6
0
def getDiscogsMetadata(track, search_artist=True):
    # artists = discogs.search(track[1], type='release', artist=track[0])

    # TODO: discogs offers a really really REALLY weird search functionality. You never get what you expect to get (if you get anything at all...)
    # The best, most performant and according to discogs 'correct' way to query the data is the call above this comment, but... well, it does not work, so I try to get the best results with
    # this call:
    try:
        releases = discogs.search(u"{0}+{1}".format(track[0], track[1]), type="release")
        processed_artist = False
        checked_releases = 0
        for release in releases:
            '''
            problem: For artists with the same name discogs generates a suffix with the index, e.g. '# TODO: discogs offers a really really REALLY weird search functionality. You never get what you expect to get (if you get anything at all...) Adele', 'Adele (2)', 'Adele (3)',...
            and they don't provide the normal name of the artist in the artist-object.
            The solution is to filter out the suffix using regular expression in order to compare the name from the artist-object with the
            given track artist
            '''
            checked_releases += 1
            if checked_releases > DISCOGS_RELEASES_LIMIT:
                break
            for artist in release.artists:
                name = re.search("^(.*?)(\s\(\d\))?$", artist.name)
                if name:
                    if utils.is_similar(name.group(1).lower(), track[0]):
                        if search_artist and not processed_artist:
                            getDiscogsArtistMetadata(artist)
                            processed_artist = True
                        for track_obj in release.data['tracklist']:
                            if utils.is_similar(track_obj['title'], track[1], normalize=True):
                                getDiscogsTrackMetadata(release, track_obj)
                                return

        if not processed_artist and search_artist:
            artists = discogs.search(track[0], type="artist")
            for artist in artists:
                if utils.is_similar(artist.name.lower(), track[0]):
                    getDiscogsArtistMetadata(artist)
                    break
    except requests.exceptions.SSLError:
        track_md.error = True
        print colored("| SSL error...", 'red')
    except discogs_client.exceptions.HTTPError:
        track_md.error = True
        print colored("| Internal discogs-server error...", 'red')
Example #7
0
def getPeakPosition(tracklist, searchArtist=False, Featurings=True):
    """

    :param tracklist:
    :param Featurings:
    :return: list
    """

    print "| Searching for peak position..."
    results = []
    for track in tracklist:
        '''
        Send a request with the track name as parameter to the search-URL  "https://www.offiziellecharts.de/suche"
        Parse the result and search for the URL of the first entry in the list
        '''

        track_results = {}
        dist_chart_peak = {CAT1: 0, CAT2: 0, CAT3: 0, CAT4: 0, CAT5: 0, CAT6: 0}
        total_chart_weeks = 0
        total_albums_chart_weeks = 0
        mean_chart_weeks = []
        mean_albums_chart_weeks = []
        mean_chart_peak = []
        mean_albums_chart_peak = []
        target_peak_cat = CAT0
        target_peak_weeks = 0
        target_url = None

        search = requests.post("https://www.offiziellecharts.de/suche",
                               data={"artist_search": track[0], "do_search": "do"})
        parsed_search = BeautifulSoup(search.text, 'html.parser')
        '''
        Get the table with the search results
        We only have to continue if there are any results
        '''
        singles_table = parsed_search.find('div', {"id": 'searchtab-0', "class": 'active'})
        if singles_table is not None:
            charts = singles_table.find('table', class_='chart-table')
            if charts is not None:
                '''
                Get all table rows except the first one ("x Treffer in der Kategorie 'Single'")
                Then iterate through all rows
                '''
                charts = charts.find_all('tr', {'class': ''})
                for chart in charts:
                    '''
                    Check if the artist of the song matches the target artist
                    '''
                    if track[0] in chart.findChildren()[
                        2].previousSibling.strip().lower():  # TODO: offiziellecharts.de filters out all featuring data
                        '''
                        Get the chart data of the song ("Wochen: X Peak: Y")
                        '''
                        chart_data = chart.findChildren()[6].text.split()
                        weeks = int(chart_data[1])
                        peak = int(chart_data[3])
                        if searchArtist:
                            '''
                            Get the relevant data:


                            dist_chart_peak:    the distribution of all the artist's chart songs corresponding to their target category
                            total_chart_weeks:  for how many weeks the artist has been in the charts with all of his songs in total
                            mean_chart_weeks:   mean chart position for all of the artist's songs in the charts
                            mean_chart_peak:    mean peak position for all of the artist's songs in the charts
                            '''
                            dist_chart_peak[getPeakCategory(peak)] += 1
                            total_chart_weeks += weeks
                            mean_chart_weeks.append(weeks)
                            mean_chart_peak.append(peak)

                        '''
                        if the current track equals the searched track, then get its peak category and save its detail url
                        (may be interesting for later use)
                        '''
                        a = chart.findChildren()[3]
                        if utils.is_similar(a.text, track[1], normalize=True):
                            target_peak_cat = getPeakCategory(peak)
                            target_peak_weeks = weeks
                            target_url = a['href']
                            if not searchArtist:
                                break
        if searchArtist:
            albums_table = parsed_search.find('div', {"id": 'searchtab-1'})
            if albums_table is None:
                albums_table = parsed_search.find('div', {"id": 'searchtab-0', "class": 'tab-pane'})
            if albums_table is not None:
                albums_charts = albums_table.find('table', class_='chart-table')
                if albums_charts is not None:
                    '''
                    Get all table rows except the first one ("x Treffer in der Kategorie 'Single'")
                    Then iterate through all rows
                    '''
                    albums_charts = albums_charts.find_all('tr', {'class': ''})
                    for album_chart in albums_charts:
                        '''
                        Check if the artist of the song matches the target artist
                        '''
                        if track[0] in album_chart.findChildren()[
                            2].previousSibling.strip().lower():  # TODO: offiziellecharts.de filters out all featuring data
                            '''
                            Get the chart data of the song ("Wochen: X Peak: Y")
                            '''
                            album_chart_data = album_chart.findChildren()[6].text.split()
                            weeks = int(album_chart_data[1])
                            peak = int(album_chart_data[3])

                            # dist_chart_peak[getPeakCategory(peak)] += 1
                            total_albums_chart_weeks += weeks
                            mean_albums_chart_weeks.append(weeks)
                            mean_albums_chart_peak.append(peak)

        if searchArtist:
            mean_chart_weeks = np.mean(mean_chart_weeks) if len(mean_chart_weeks) > 0 else 0
            mean_chart_peak = getPeakCategory(np.mean(mean_chart_peak)) if len(mean_chart_peak) > 0 else CAT0

            mean_album_chart_weeks = np.mean(mean_albums_chart_weeks) if len(mean_albums_chart_weeks) > 0 else 0
            mean_album_chart_peak = getPeakCategory(np.mean(mean_albums_chart_peak)) if len(
                mean_albums_chart_peak) > 0 else CAT0
            track_results['artist_md'] = {'dist_chart_peak': dist_chart_peak, 'total_chart_weeks': total_chart_weeks,
                                          'mean_chart_weeks': mean_chart_weeks, 'mean_chart_peak': mean_chart_peak,
                                          'total_album_chart_weeks': total_albums_chart_weeks,
                                          'mean_album_chart_weeks': mean_album_chart_weeks,
                                          'mean_album_chart_peak': mean_album_chart_peak}
        track_results['target_peak_cat'] = target_peak_cat
        track_results['target_peak_weeks'] = target_peak_weeks
        track_results['target_url'] = target_url
        results.append(track_results)

    return results
Example #8
0
def getMusicbrainzMetadata(track, search_artist=True):
    global tries
    artist_id = None
    possible_tracks = []
    exists_remix = True
    offset = 0
    try:
        recordings = musicbrainzngs.search_recordings(query=track[1].replace('/', ''),
                                                      artistname=track[0].replace('/', ''),
                                                      limit=MUSICBRAINZ_LIMIT,
                                                      offset=offset * MUSICBRAINZ_LIMIT)
        for recording in recordings["recording-list"]:
            for artist_credit in recording['artist-credit']:
                if 'artist' in artist_credit and utils.is_similar(artist_credit['artist']['name'].lower(), track[0],
                                                                  normalize=True):
                    if utils.checkTrackNamingConvention(recording['title'].lower(), track[1]):
                        if 'release-list' in recording:
                            for release in recording['release-list']:
                                if 'status' in release:
                                    if release['status'] == 'Official':
                                        possible_tracks.append(recording)
                                        if artist_id is None:
                                            artist_id = artist_credit['artist']['id']
                                    elif release['status'] == 'Bootleg':
                                        exists_remix = True
                                else:
                                    if utils.isTrackRemixByName(recording['title']):
                                        exists_remix = True
                                    else:
                                        possible_tracks.append(recording)
        getMusicbrainzTrackMetadata(possible_tracks, exists_remix)
        if search_artist:
            if artist_id is None:
                choice = False
                artists = musicbrainzngs.search_artists(track[0].replace('/', ''),
                                                        ("artist", "begin", "end", "country", "ended", "gender",
                                                         "tag", "type", "area", "beginarea", "endarea"))
                for (i, artist) in enumerate(artists['artist-list']):
                    '''
                    resolve any disambiguations
                    if the current artist has the same name as the next artist in the list, then let the user choose the right one
                    '''
                    if len(artists['artist-list']) - 1 > i and utils.is_similar(artist['name'],
                                                                                artists['artist-list'][i + 1]['name'],
                                                                                normalize=True) and utils.is_similar(
                        track[0], artist['name'], normalize=True):
                        choice = True
                        if i == 0:
                            print u"Sorry, the artist '{0}' is ambigious, please chose the right one:\n[{1}] None of the options".format(
                                artist['name'], i)
                        print u"[{0}] {1}: {2}".format(i + 1, artist['name'],
                                                       artist[
                                                           'disambiguation'] if 'disambiguation' in artist else "no description")
                    elif choice:
                        print u"[{0}] {1}: {2}".format(i + 1, artist['name'], artist[
                            'disambiguation'] if 'disambiguation' in artist else "no description")
                        input = raw_input("Your choice: ")
                        try:
                            artist_int = int(input)
                            if artist_int == 0:
                                return
                            # FIXME: why does musicbrainzngs.search_artist() not provide this information? => double request necessary
                            # getMusicbrainzArtistMetadata(artists['artist-list'][artist_int - 1])
                            getMusicbrainzArtistMetadata(
                                musicbrainzngs.get_artist_by_id(artists['artist-list'][artist_int - 1]['id'],
                                                                ['recordings', 'releases',
                                                                 'release-groups', 'works',
                                                                 'aliases', 'artist-rels',
                                                                 'label-rels', 'tags', 'ratings'])[
                                    'artist'])
                        except ValueError:
                            pass  # TODO
                        break
                    elif utils.is_similar(artist['name'], track[0], normalize=True):
                        # FIXME: why does musicbrainzngs.search_artist() not provide this information? => double request necessary
                        getMusicbrainzArtistMetadata(musicbrainzngs.get_artist_by_id(artist['id'],
                                                                                     ['recordings', 'releases',
                                                                                      'release-groups', 'works',
                                                                                      'aliases', 'artist-rels',
                                                                                      'label-rels', 'tags', 'ratings'])[
                                                         'artist'])
                        break
            else:
                getMusicbrainzArtistMetadata(musicbrainzngs.get_artist_by_id(artist_id,
                                                                             ['recordings', 'releases',
                                                                              'release-groups', 'works',
                                                                              'aliases', 'artist-rels',
                                                                              'label-rels', 'tags', 'ratings'])[
                                                 'artist'])
    except musicbrainzngs.NetworkError:
        tries += 1
        track_md.error = True
        print colored("| The Musicbrainz service seems to be not available right now...", 'red')
    except musicbrainzngs.musicbrainz.ResponseError as e:
        track_md.error = True
        print colored("| {}".format(e), 'red')
Example #9
0
def getPeakPosition(tracklist, searchArtist=False, Featurings=True):
    """

    :param tracklist:
    :param Featurings:
    :return: list
    """

    print "| Searching for peak position..."
    results = []
    for track in tracklist:
        '''
        Send a request with the track name as parameter to the search-URL  "https://www.offiziellecharts.de/suche"
        Parse the result and search for the URL of the first entry in the list
        '''

        track_results = {}
        dist_chart_peak = {
            CAT1: 0,
            CAT2: 0,
            CAT3: 0,
            CAT4: 0,
            CAT5: 0,
            CAT6: 0
        }
        total_chart_weeks = 0
        total_albums_chart_weeks = 0
        mean_chart_weeks = []
        mean_albums_chart_weeks = []
        mean_chart_peak = []
        mean_albums_chart_peak = []
        target_peak_cat = CAT0
        target_peak_weeks = 0
        target_url = None

        search = requests.post("https://www.offiziellecharts.de/suche",
                               data={
                                   "artist_search": track[0],
                                   "do_search": "do"
                               })
        parsed_search = BeautifulSoup(search.text, 'html.parser')
        '''
        Get the table with the search results
        We only have to continue if there are any results
        '''
        singles_table = parsed_search.find('div', {
            "id": 'searchtab-0',
            "class": 'active'
        })
        if singles_table is not None:
            charts = singles_table.find('table', class_='chart-table')
            if charts is not None:
                '''
                Get all table rows except the first one ("x Treffer in der Kategorie 'Single'")
                Then iterate through all rows
                '''
                charts = charts.find_all('tr', {'class': ''})
                for chart in charts:
                    '''
                    Check if the artist of the song matches the target artist
                    '''
                    if track[0] in chart.findChildren(
                    )[2].previousSibling.strip().lower(
                    ):  # TODO: offiziellecharts.de filters out all featuring data
                        '''
                        Get the chart data of the song ("Wochen: X Peak: Y")
                        '''
                        chart_data = chart.findChildren()[6].text.split()
                        weeks = int(chart_data[1])
                        peak = int(chart_data[3])
                        if searchArtist:
                            '''
                            Get the relevant data:


                            dist_chart_peak:    the distribution of all the artist's chart songs corresponding to their target category
                            total_chart_weeks:  for how many weeks the artist has been in the charts with all of his songs in total
                            mean_chart_weeks:   mean chart position for all of the artist's songs in the charts
                            mean_chart_peak:    mean peak position for all of the artist's songs in the charts
                            '''
                            dist_chart_peak[getPeakCategory(peak)] += 1
                            total_chart_weeks += weeks
                            mean_chart_weeks.append(weeks)
                            mean_chart_peak.append(peak)
                        '''
                        if the current track equals the searched track, then get its peak category and save its detail url
                        (may be interesting for later use)
                        '''
                        a = chart.findChildren()[3]
                        if utils.is_similar(a.text, track[1], normalize=True):
                            target_peak_cat = getPeakCategory(peak)
                            target_peak_weeks = weeks
                            target_url = a['href']
                            if not searchArtist:
                                break
        if searchArtist:
            albums_table = parsed_search.find('div', {"id": 'searchtab-1'})
            if albums_table is None:
                albums_table = parsed_search.find('div', {
                    "id": 'searchtab-0',
                    "class": 'tab-pane'
                })
            if albums_table is not None:
                albums_charts = albums_table.find('table',
                                                  class_='chart-table')
                if albums_charts is not None:
                    '''
                    Get all table rows except the first one ("x Treffer in der Kategorie 'Single'")
                    Then iterate through all rows
                    '''
                    albums_charts = albums_charts.find_all('tr', {'class': ''})
                    for album_chart in albums_charts:
                        '''
                        Check if the artist of the song matches the target artist
                        '''
                        if track[0] in album_chart.findChildren(
                        )[2].previousSibling.strip().lower(
                        ):  # TODO: offiziellecharts.de filters out all featuring data
                            '''
                            Get the chart data of the song ("Wochen: X Peak: Y")
                            '''
                            album_chart_data = album_chart.findChildren(
                            )[6].text.split()
                            weeks = int(album_chart_data[1])
                            peak = int(album_chart_data[3])

                            # dist_chart_peak[getPeakCategory(peak)] += 1
                            total_albums_chart_weeks += weeks
                            mean_albums_chart_weeks.append(weeks)
                            mean_albums_chart_peak.append(peak)

        if searchArtist:
            mean_chart_weeks = np.mean(
                mean_chart_weeks) if len(mean_chart_weeks) > 0 else 0
            mean_chart_peak = getPeakCategory(
                np.mean(mean_chart_peak)) if len(mean_chart_peak) > 0 else CAT0

            mean_album_chart_weeks = np.mean(mean_albums_chart_weeks) if len(
                mean_albums_chart_weeks) > 0 else 0
            mean_album_chart_peak = getPeakCategory(
                np.mean(mean_albums_chart_peak)
            ) if len(mean_albums_chart_peak) > 0 else CAT0
            track_results['artist_md'] = {
                'dist_chart_peak': dist_chart_peak,
                'total_chart_weeks': total_chart_weeks,
                'mean_chart_weeks': mean_chart_weeks,
                'mean_chart_peak': mean_chart_peak,
                'total_album_chart_weeks': total_albums_chart_weeks,
                'mean_album_chart_weeks': mean_album_chart_weeks,
                'mean_album_chart_peak': mean_album_chart_peak
            }
        track_results['target_peak_cat'] = target_peak_cat
        track_results['target_peak_weeks'] = target_peak_weeks
        track_results['target_url'] = target_url
        results.append(track_results)

    return results
Example #10
0
def getMusicbrainzMetadata(track, search_artist=True):
    global tries
    artist_id = None
    possible_tracks = []
    exists_remix = True
    offset = 0
    try:
        recordings = musicbrainzngs.search_recordings(
            query=track[1].replace('/', ''),
            artistname=track[0].replace('/', ''),
            limit=MUSICBRAINZ_LIMIT,
            offset=offset * MUSICBRAINZ_LIMIT)
        for recording in recordings["recording-list"]:
            for artist_credit in recording['artist-credit']:
                if 'artist' in artist_credit and utils.is_similar(
                        artist_credit['artist']['name'].lower(),
                        track[0],
                        normalize=True):
                    if utils.checkTrackNamingConvention(
                            recording['title'].lower(), track[1]):
                        if 'release-list' in recording:
                            for release in recording['release-list']:
                                if 'status' in release:
                                    if release['status'] == 'Official':
                                        possible_tracks.append(recording)
                                        if artist_id is None:
                                            artist_id = artist_credit[
                                                'artist']['id']
                                    elif release['status'] == 'Bootleg':
                                        exists_remix = True
                                else:
                                    if utils.isTrackRemixByName(
                                            recording['title']):
                                        exists_remix = True
                                    else:
                                        possible_tracks.append(recording)
        getMusicbrainzTrackMetadata(possible_tracks, exists_remix)
        if search_artist:
            if artist_id is None:
                choice = False
                artists = musicbrainzngs.search_artists(
                    track[0].replace('/', ''),
                    ("artist", "begin", "end", "country", "ended", "gender",
                     "tag", "type", "area", "beginarea", "endarea"))
                for (i, artist) in enumerate(artists['artist-list']):
                    '''
                    resolve any disambiguations
                    if the current artist has the same name as the next artist in the list, then let the user choose the right one
                    '''
                    if len(artists['artist-list']) - 1 > i and utils.is_similar(
                            artist['name'],
                            artists['artist-list'][i + 1]['name'],
                            normalize=True) and utils.is_similar(
                                track[0], artist['name'], normalize=True):
                        choice = True
                        if i == 0:
                            print u"Sorry, the artist '{0}' is ambigious, please chose the right one:\n[{1}] None of the options".format(
                                artist['name'], i)
                        print u"[{0}] {1}: {2}".format(
                            i + 1, artist['name'], artist['disambiguation'] if
                            'disambiguation' in artist else "no description")
                    elif choice:
                        print u"[{0}] {1}: {2}".format(
                            i + 1, artist['name'], artist['disambiguation'] if
                            'disambiguation' in artist else "no description")
                        input = raw_input("Your choice: ")
                        try:
                            artist_int = int(input)
                            if artist_int == 0:
                                return
                            # FIXME: why does musicbrainzngs.search_artist() not provide this information? => double request necessary
                            # getMusicbrainzArtistMetadata(artists['artist-list'][artist_int - 1])
                            getMusicbrainzArtistMetadata(
                                musicbrainzngs.get_artist_by_id(
                                    artists['artist-list'][artist_int -
                                                           1]['id'],
                                    [
                                        'recordings', 'releases',
                                        'release-groups', 'works', 'aliases',
                                        'artist-rels', 'label-rels', 'tags',
                                        'ratings'
                                    ])['artist'])
                        except ValueError:
                            pass  # TODO
                        break
                    elif utils.is_similar(artist['name'],
                                          track[0],
                                          normalize=True):
                        # FIXME: why does musicbrainzngs.search_artist() not provide this information? => double request necessary
                        getMusicbrainzArtistMetadata(
                            musicbrainzngs.get_artist_by_id(
                                artist['id'], [
                                    'recordings', 'releases', 'release-groups',
                                    'works', 'aliases', 'artist-rels',
                                    'label-rels', 'tags', 'ratings'
                                ])['artist'])
                        break
            else:
                getMusicbrainzArtistMetadata(
                    musicbrainzngs.get_artist_by_id(artist_id, [
                        'recordings', 'releases', 'release-groups', 'works',
                        'aliases', 'artist-rels', 'label-rels', 'tags',
                        'ratings'
                    ])['artist'])
    except musicbrainzngs.NetworkError:
        tries += 1
        track_md.error = True
        print colored(
            "| The Musicbrainz service seems to be not available right now...",
            'red')
    except musicbrainzngs.musicbrainz.ResponseError as e:
        track_md.error = True
        print colored("| {}".format(e), 'red')
Example #11
0
    def _detect_changes(self):
        labels = ['titles', 'authors']
        for name, article in self.pkg_items.items():
            if name in self.registered_items.keys():
                validations = []
                validations.append((article.textual_titles, self.registered_items[name].textual_titles))
                validations.append((article.textual_contrib_surnames, self.registered_items[name].textual_contrib_surnames))
                self.exact_comparison[name] = [(label, items) for label, items in zip(labels, validations) if not items[0] == items[1]]
                self.relaxed_comparison[name] = [(label, items) for label, items in zip(labels, validations) if not utils.is_similar(items[0], items[1])]

                if len(self.exact_comparison[name]) == 0:
                    # no changes
                    allowed_to_update = True
                    status = validation_status.STATUS_INFO
                elif len(self.relaxed_comparison[name]) == 0:
                    # acceptable changes
                    allowed_to_update = True
                    status = validation_status.STATUS_WARNING
                else:
                    # many changes
                    allowed_to_update = False
                    status = validation_status.STATUS_FATAL_ERROR
                if allowed_to_update:
                    order_change = self.changed_orders.get(name)
                    if order_change is not None:
                        # order change
                        if order_change[1] in self.rejected_order_change.keys():
                            # order change is rejected
                            allowed_to_update = False
                            status = validation_status.STATUS_FATAL_ERROR

                self.allowed_to_update[name] = allowed_to_update
                self.evaluate_changes[name] = status