Example #1
0
    def getCoverArt(self, path, release_id):
        """
        Get cover art image from Cover Art Archive.

        :param path: where to store the fetched image
        :type  path: str
        :param release_id: a release id (self.program.metadata.mbid)
        :type  release_id: str
        :returns: path to the downloaded cover art, else `None`
        :rtype: str or None
        """
        cover_art_path = os.path.join(path, 'cover.jpg')

        logger.debug('fetching cover art for release: %r', release_id)
        try:
            data = musicbrainzngs.get_image_front(release_id, 500)
        except musicbrainzngs.ResponseError as e:
            logger.error('error fetching cover art: %r', e)
            return

        if data:
            with NamedTemporaryFile(suffix='.cover.jpg', delete=False) as f:
                f.write(data)
            os.chmod(f.name, 0o644)
            shutil.move(f.name, cover_art_path)
            logger.debug('cover art fetched at: %r', cover_art_path)
            return cover_art_path
        return
def fetch_cover(release_id, refresh=False):
    if not os.path.isfile(release_id[0]) or refresh:
        logger.debug("Hard refreshing cover art for {0}".format(release_id[0]))
        try:
            data = musicbrainzngs.get_image_front(release_id[0])
        except musicbrainzngs.WebServiceError as exc:
            logger.error("Error fetching cover art for {0}".format(
                release_id[0]))
            logger.error(exc)
            logger.info('Shutting down')
            return False

        try:
            with open(release_id[0], "wb") as out_file:
                out_file.write(data)
        except EnvironmentError:
            logger.error('Cannot write cover art for {0} to file'.format(
                release_id[0]))
            logger.info('Shutting down')
            return False
    else:
        logger.debug("Using pre-fetched cover art for {0}".format(
            release_id[0]))

    return True
Example #3
0
def downloadAndCacheArtworkFile(tag):
    album = tag.album
    artist = tag.artist
    print("Attempting to download cover for %s %s..." % (album, artist))

    result = mb.search_releases(artist=tag.artist, release=tag.album, type='album', format='cd', strict=True)
    result = result['release-list']
    
    if len(result) == 0:
        raise "Couldn't find entry for %s %s" % (album, artist)
    
    mbid = result[0]['id']
    cover = None
    try:
        cover = mb.get_image_front(mbid)
    except:
        raise "Couldn't find artwork for %s %s" % (album, artist)
    
    filename = getCacheFilename(tag)
    f = open(filename, 'wb')
    f.write(cover)
    f.close()
    
    print("Downloaded.")
    
    resizeImage(filename)

    print("Resized.")
    
    return filename
Example #4
0
def _fetch_from_musicbrainz(album: Album, width: int) -> Optional[str]:
    """
    Looks up the album and artist on musicbrainz and
    fetches the front cover album art for it.

    :param album: The album to find the cover for.
    :return: The filename of the downloaded image
    if one was found.
    """
    releases = mb.search_releases(artist=album.artist_name,
                                  release=album.name,
                                  limit=10)['release-list']
    filename = get_image_path(album, width)

    with open(filename, 'wb') as f:
        cover = None
        i = 0
        while not cover and i < len(releases):
            try:
                cover = mb.get_image_front(releases[i]['id'], size=width)
            except mb.ResponseError:
                i += 1
        if cover:
            f.write(cover)

    return filename if cover else None
Example #5
0
def get_cover_art_as_data(id):
    '''Gets cover art as binary data if not already stored.'''
    global cover_art_dict
    if id in cover_art_dict:
        return cover_art_dict[id]
    try:
        cover_art_dict[id] = musicbrainzngs.get_image_front(id).encode('base64')
    except musicbrainzngs.musicbrainz.ResponseError:
        cover_art_dict[id] = ''
    return cover_art_dict[id]
Example #6
0
    def getMusicBrainzReleaseID(self, imageSearch=False):
        #Here we setup our useragent for the webqueries 
        musicbrainzngs.set_useragent('CS3030MusicApp', 'V0.5')

        #we construct a query string from existing metadata
        if(self.album != '' and self.artist != ''):
            temp = '{0} AND artist:{1}'.format(self.album, self.artist)
        elif(self.album != ''):
            temp = '"{}"'.format(self.album)
        elif(self.artist != '' and self.title != ''):
            temp = '{0} AND artist:{1}'.format(self.title.replace(' ', '_'), self.artist)
        else:
            print('Insufficient MetaData for {}'.format(self.filename))
            return ''
        
        print('Looking for online profile for {}'.format(self.title))
        #if there is enough information to create a viable query string, we search the musicBrainz database
        results = musicbrainzngs.search_releases(query=temp, limit=50)

        #if any of the results are produced by the same artist, the id is saved
        for release in results['release-list']:
            #we try to get a succesful response from the database without any HTTP errors
            try:
                musicbrainzngs.get_image_front(release['id'])
                hasImage = True
            #if it doesn't work we move on to the next result
            except:
                hasImage = False

            if((release['title'].lower() == self.album.lower()) and hasImage):
                print('Release match found!')
                return release['id']

        # If nothing is found in releases try recordings but not if the function is called for album art
        if not imageSearch:
            self.updateMetaDataInteractive()
            return ''
        else:
            #if nothing is returned we print a notification to console
            print('No viable database results available for {}'.format(self.album))
            return ''
Example #7
0
def fetch_musicbrainz_art(album: Album):
    releases = mb.search_releases(artist=album.artist.name, release=album.name, limit=10)['release-list']

    cover = None
    i = 0
    while not cover and i < len(releases):
        try:
            cover = mb.get_image_front(releases[i]['id'])
        except mb.ResponseError:
            i += 1
    if cover:
        return io.BytesIO(cover)
Example #8
0
def getMusicBrainzArt(release):
    try:
        image = musicbrainzngs.get_image_front(release["id"], size="250")
        return image

    except musicbrainzngs.ResponseError as err:
        if err.cause.code == 404:
            log("ERROR.  Image not found")
        else:
            log("ERROR. Received bad response from the MB server")

    return None
Example #9
0
    def find_art(self, artist, album):
        print("Musicbrainz: find_art:", artist, album)
        """ Search for the album and then identify the best match
            Algorithm for chosing the right album:
            put the search results into a table, search and sort the table accordingly
            1. Highest ex-score, highest fuzzy match of album and artist -weighted towards the alnum
            2. Best match on Artist name
            3. Best match on Album
            4. Album type could be used but some will be compilations??  """
        ALBUM_MATCH_WEIGHT = 1.5
        d = musicbrainzngs.search_release_groups(artist + ' ' + album)

        albums = []
        for k in d['release-group-list']:
            a = {}

            if 'id' in k and 'title' and 'artist-credit' and 'ext:score':
                print("Musicbrainz: find_art: looking for", k['title'])
                if self.coverart_exists(k['id']):
                    a['id'] = k['id']
                else:
                    continue
                a['score'] = int(k['ext:score'])
                a['title'] = k['title']
                a['match'] = ALBUM_MATCH_WEIGHT * fuzz.token_sort_ratio(
                    a['title'], album) + a['score']

            for n in k['artist-credit']:
                if 'name' in n:
                    a['name'] = n['name']
                    a['match'] += fuzz.token_sort_ratio(a['name'], artist)

            print(a)
            albums.append(a)

        best_match = 0
        best_id = ''
        for a in albums:
            if a['match'] > best_match:
                best_id = a['id']

        if best_match > 200:
            imagebin = musicbrainzngs.get_image_front(best_id)
            print("Image successfully found, match score was", best_match)
            return imagebin
        else:
            return None
Example #10
0
def getAlbumArtwork(musicbrainzalbumid, artwork=None):
    if not artwork: artwork = {}
    #get fanart.tv artwork for album
    artwork = getfanartTVimages("album",musicbrainzalbumid,artwork)
    #get album info on theaudiodb (and use as spare for artwork)
    try:
        audiodb_url = 'http://www.theaudiodb.com/api/v1/json/193621276b2d731671156g/album-mb.php?i=%s' %musicbrainzalbumid
        response = requests.get(audiodb_url)
    except Exception as e:
        logMsg("getMusicArtworkByDbId AudioDB lookup failed --> " + str(e), 0)
        return {}
    if response and response.content:
        data = json.loads(response.content.decode('utf-8','replace'))
        if data and data.get("album") and len(data.get("album")) > 0:
            adbdetails = data["album"][0]
            if not artwork.get("folder") and adbdetails.get("strAlbumThumb"): artwork["folder"] = adbdetails.get("strAlbumThumb")
            if not artwork.get("discart") and adbdetails.get("strAlbumCDart"): artwork["discart"] = adbdetails.get("strAlbumCDart")
            if not artwork.get("info") and adbdetails.get("strDescription" + KODILANGUAGE.upper()): artwork["info"] = adbdetails.get("strDescription" + KODILANGUAGE.upper())
            if not artwork.get("info") and adbdetails.get("strDescriptionEN"): artwork["info"] = adbdetails.get("strDescriptionEN")
    
    if not artwork.get("thumb") and not artwork.get("folder") and not WINDOW.getProperty("SkinHelper.TempDisableMusicBrainz"): 
        try: 
            new_file = "special://profile/addon_data/script.skin.helper.service/musicart/%s.jpg" %musicbrainzalbumid
            thumbfile = m.get_image_front(musicbrainzalbumid)
            if thumbfile: 
                f = xbmcvfs.File(new_file, 'w')
                f.write(thumbfile)
                f.close()
            artwork["folder"] = new_file
        except: pass
    
    if not artwork.get("thumb") and not artwork.get("folder") and not WINDOW.getProperty("SkinHelper.TempDisableMusicBrainz"): 
        try: 
            new_file = "special://profile/addon_data/script.skin.helper.service/musicart/%s.jpg" %musicbrainzalbumid
            thumbfile = m.get_release_group_image_front(musicbrainzalbumid)
            if thumbfile: 
                f = xbmcvfs.File(new_file, 'w')
                f.write(thumbfile)
                f.close()
            artwork["folder"] = new_file
        except: pass
    
    
    
    return artwork
Example #11
0
    def getAlbumArtwork(self):
        print(
            'Searching Music Brainz database for album artwork\n This could take several minutes...'
        )
        for song in self.songs:
            #we should skip any files that don't have the appropriate metadata
            if (song.artist == '' or song.album == ''):
                print('Skipping {}'.format(song.filename))
                continue

            artworkFolder = os.path.join(self.homeDirectory, 'Album Artwork--')
            artistFolder = os.path.join(artworkFolder, song.artist + '--')
            song.artworkPath = os.path.join(artistFolder, song.album + '.jpg')

            #if album artwork already exists, we continue to the next song
            if (not os.path.exists(artworkFolder)):
                os.mkdir(artworkFolder)
            if (not os.path.exists(artistFolder)):
                os.mkdir(artistFolder)

            if (not os.path.exists(song.artworkPath)):
                print('Searching: {}'.format(song.album))
                #we first initiate a search query to find the database id for the album in question
                song.MBID = song.getMusicBrainzReleaseID(imageSearch=True)
                #If the song search comes back with an ID we continue
                if (song.MBID != ''):
                    #then we lookup the artwork using the song's release id and download the raw data
                    try:
                        print('Downloading the image file to {}'.format(
                            song.artworkPath))
                        rawAlbumArt = musicbrainzngs.get_image_front(song.MBID)
                        #we open a .jpg file and write the binary data to the file
                        file = open(song.artworkPath, 'wb')
                        file.write(rawAlbumArt)
                        file.close()
                    except Exception as ex:
                        print('Problems downloading artwork: {}'.format(ex))
                        continue
                #else we create a placeholder file that prevents further search attempts
                else:
                    file = open(song.artworkPath, 'wb')
                    file.write(b'NO ARTWORK FOUND')
                    file.close()
            self.dataBase.updateEntry(song)
Example #12
0
    def front_cover(self, release):
        """Return the front cover, or None.

        Tries the release first, then the release group. Returns the image's
        bytes.
        """
        try:
            return mb_client.get_image_front(release['id'])
        except mb_client.ResponseError as e:
            if isinstance(e.cause, HTTPError) and e.cause.code == 404:
                pass  # no front cover
            else:
                raise MusicBrainzError from e
        try:
            return mb_client.get_release_group_image_front(release['group-id'])
        except mb_client.ResponseError as e:
            if isinstance(e.cause, HTTPError) and e.cause.code == 404:
                pass  # no front cover
            else:
                raise MusicBrainzError from e
        return None
Example #13
0
def save_cover_art(release, max_retries=3):
    """Save the front cover image for the release `release`. Return
    the saved image's ID, or None if the image isn't available."""
    if release['cover-art-archive']['front'] == 'false':
        return None

    for retry in range(max_retries):
        try:
            image_data = musicbrainzngs.get_image_front(release['id'],
                                                        size="500")
            return image.save(image_data, 'catalog')
        except ResponseError as err:
            if err.cause.code == 404:  # image doesn't exist
                break
            elif err.cause.code == 503:
                print('rate limit exceeded: retrying in {} seconds.'.format(
                    RETRY_SECS))
                time.sleep(RETRY_SECS)
        except NetworkError:
            break
    return None
Example #14
0
def tag_file(song_file):

    musicbrainzngs.auth(BRAINZ_USER, BRAINZ_PASS)
    musicbrainzngs.set_useragent("Auto tag script", "0.1", "http://localhost")

    #song = path.join(MP3_DIR, '3.mp3')
    print song_file
    for score, recording_id, title, artist in acoustid.match(
            APIKEY, song_file):
        # Get song data
        result_data = musicbrainzngs.get_recording_by_id(
            recording_id, includes=['artists', 'releases'])
        title = result_data['recording']['title']
        artist = result_data['recording']['artist-credit-phrase']
        print "%s - %s" % (title, artist)

        # Set ID3 tags
        audiofile = eyed3.load(song_file)
        audiofile.tag.artist = unicode(artist)
        audiofile.tag.title = unicode(title)

        # Get Cover Art
        if result_data['recording']['release-count']:
            try:
                imagedata = musicbrainzngs.get_image_front(
                    result_data['recording']['release-list'][0]['id'])
                print audiofile.tag.images.set(
                    eyed3.id3.frames.ImageFrame.FRONT_COVER, imagedata,
                    'image/jpeg')
                cover = open(
                    path.join(
                        COVER_DIR,
                        result_data['recording']['release-list'][0]['title'] +
                        '.jpg'), "w+")
                cover.write(imagedata)
                print "---"
            except musicbrainzngs.musicbrainz.ResponseError:
                pass

        audiofile.tag.save()
         filename = f"{release['date'].split('-')[0]};{release['title']};{genre}.png"
         correct_path = f"{subdirectory}/{dont_fuck_up_path(filename)}"
         # check if file with filename exists -> was already saved before
         if path.exists(correct_path):
             print(
                 "SKIIIIIP : RELEASE WAS ALREADY SAVED BEFORE!!"
             )
             continue
     except KeyError:
         print(
             "SKIIIIIP : RELEASE DOES NOT HAVE DATE OR TITLE"
         )
         continue
     # donwload image
     try:
         art = brainz.get_image_front(release['id'],
                                      size=250)
         image = Image.open(io.BytesIO(art))
     except brainz.ResponseError:
         print("SKIIIIIP : ARTWORK IS NOT AVAIABLE IN 250")
         continue
     except brainz.NetworkError:
         print("SKIIIIIP : NETWORK ERROR.")
         continue
     try:
         image.save(correct_path)
         print("FILE SAVED")
     except:
         print("UNKNOWN ERROR OCCURED!!!")
         continue
 # reset variables
 release_offset += release_limitsize
Example #16
0
    def parse(self, relnum):
        if not self.mblist:
            self.mblist = {'manual': 'manual'}  #lazy bugfix is lazy
        for k in self.mblist:
            if k == 'disc':
                data = self.mblist['disc']['release-list'][relnum]
                self.infodict = { 'artist': data['artist-credit-phrase'], 'album': data['title'], 'discnum': '',\
                                  'multidisc': False, 'date': data['date'], 'relid': data['id'], \
                                  'infotype': 'musicbrainz', 'tracklist': []}

                if int(data['medium-count']) > 1:
                    self.infodict['multidisc'] = True

                for x in data['medium-list']:
                    for y in x['disc-list']:
                        if str(self.disc) == y['id']:
                            self.infodict['discnum'] = x['position']
                dindex = int(self.infodict['discnum']) - 1
                for x in data['medium-list'][dindex]['track-list']:
                    self.infodict['tracklist'].append(x['recording']['title'])
                break

            elif k == 'cdstub':
                data = self.mblist['cdstub']
                self.infodict = { 'artist': data['artist'], 'album': data['title'], 'date': '0000',\
                                  'discnum': '1', 'multidisc': False, 'relid': data['id'], \
                                  'infotype': 'cdstub', 'tracklist': []}
                for x in data['track-list']:
                    self.infodict['tracklist'].append(x['title'])
                break

            else:
                self.infodict = { 'artist': 'Artist', 'album': 'Album Title', 'date': '0000', 'discnum': '1',\
                                  'multidisc': False, 'relid': 'helpmeihavenoentryonmusicbrainz',
                                  'infotype': 'manual', 'tracklist': []}
                for x in range(len(self.disc.tracks)):
                    self.infodict['tracklist'].append(f'Track {(x+1):02d}')
                break

        try:
            imageinfo = False
            imagelist = musicbrainzngs.get_image_list(self.infodict['relid'])
            for x in imagelist['images']:
                if x['front']:
                    imageinfo = x
        except Exception as e:
            print(e)

        if os.path.exists(f"{temppath}/{self.infodict['relid']}"):
            shutil.rmtree(f"{temppath}/{self.infodict['relid']}")
        os.makedirs(f"{temppath}/{self.infodict['relid']}")

        if imageinfo:
            self.infodict[
                'cover'] = f"{temppath}/{self.infodict['relid']}/cover{imageinfo['image'][-4:]}"
            coverart = open(self.infodict['cover'], 'wb')
            coverart.write(
                musicbrainzngs.get_image_front(self.infodict['relid']))
            coverart.close()
        else:
            self.infodict['cover'] = False
            print("Couldn't find cover art for this release.")

        return (self.infodict)
rm *.aiff
'''
os.system(
    'cdparanoia -Bf; count=1; for i in $(ls); do ffmpeg -i $i ${count}.flac && ((count++)); done; rm *.aiff'
)
songs = os.listdir()

# add the appropriate tags to each track, then rename each track to the track's album listing
for song in songs:
    os.system(
        f"lltag --yes -t '{disc_info['tracks'][int(song[:-5]) - 1]}' -a '{disc_info['artist']}' -A '{disc_info['title']}' -n '{int(song[:-5])}' --flac {song}"
    )
    os.system(f"mv -v {song} '{disc_info['tracks'][int(song[:-5]) - 1]}'.flac")

# create a png image file of the front cover art
if args.cover_art:
    try:
        image = mb.get_image_front(release_id)
        with open('cover.png', 'wb') as file:
            file.write(image)

        # set the cover art as the tracks' picture value value
        os.system(f'metaflac --import-picture-from=cover.png *.flac')
        print('Applied cover art ...')
    except:
        print('No cover art found...')
        pass

# eject the CD from the optical drive
os.system('eject /dev/sr0')
Example #18
0
def get_cover_art_as_data(id):
    '''Gets cover art as binary data if not already stored.'''
    try:
        return musicbrainzngs.get_image_front(id).encode('base64')
    except musicbrainzngs.musicbrainz.ResponseError:
        return ''