def write_tags(f, meta, tag_cfg, cov, ext, embed_cov):
    if ext == ".flac":
        audio = FLAC(f)
        for k, v in meta.items():
            if tag_cfg[k]:
                audio[k] = str(v)
        if embed_cov and cov:
            with open(cov, 'rb') as cov_obj:
                image = Picture()
                image.type = 3
                image.mime = "image/jpeg"
                image.data = cov_obj.read()
                audio.add_picture(image)
        audio.save()
    elif ext == ".mp3":
        try:
            audio = id3.ID3(f)
        except ID3NoHeaderError:
            audio = id3.ID3()
        if tag_cfg['TRACKNUMBER'] and tag_cfg['TRACKTOTAL']:
            audio['TRCK'] = id3.TRCK(encoding=3,
                                     text=str(meta['TRACKNUMBER']) + "/" +
                                     str(meta['TRACKTOTAL']))
        elif tag_cfg['TRACKNUMBER']:
            audio['TRCK'] = id3.TRCK(encoding=3, text=str(meta['TRACKNUMBER']))
        if tag_cfg['DISCNUMBER']:
            audio['TPOS'] = id3.TPOS(encoding=3,
                                     text=str(meta['DISCNUMBER']) + "/" +
                                     str(meta['DISCTOTAL']))
        legend = {
            "ALBUM": id3.TALB,
            "ALBUMARTIST": id3.TPE2,
            "ARTIST": id3.TPE1,
            "COMMENT": id3.COMM,
            "COMPOSER": id3.TCOM,
            "COPYRIGHT": id3.TCOP,
            "DATE": id3.TDAT,
            "GENRE": id3.TCON,
            "ISRC": id3.TSRC,
            "LABEL": id3.TPUB,
            "PERFORMER": id3.TOPE,
            "TITLE": id3.TIT2,
            # Not working.
            "URL": id3.WXXX,
            "YEAR": id3.TYER
        }
        for k, v in meta.items():
            try:
                if tag_cfg[k]:
                    id3tag = legend[k]
                    audio[id3tag.__name__] = id3tag(encoding=3, text=v)
            except KeyError:
                pass
        if embed_cov and cov:
            with open(cov, 'rb') as cov_obj:
                audio.add(id3.APIC(3, 'image/jpeg', 3, '', cov_obj.read()))
        audio.save(f, 'v2_version=3')
Exemplo n.º 2
0
def updateRatingToFile(rating, file):
    #update the rating from Emby to the file

    f = xbmcvfs.File(file)
    org_size = f.size()
    f.close()

    #create tempfile
    if "/" in file: filepart = file.split("/")[-1]
    else: filepart = file.split("\\")[-1]
    tempfile = "special://temp/" + filepart
    xbmcvfs.copy(file, tempfile)
    tempfile = utils.tryDecode(xbmc.translatePath(tempfile))

    logMsg("setting song rating: %s for filename: %s - using tempfile: %s" %
           (rating, file, tempfile))

    if not tempfile:
        return

    try:
        if tempfile.lower().endswith(".flac"):
            audio = FLAC(tempfile)
            calcrating = int(round((float(rating) / 5) * 100, 0))
            audio["rating"] = str(calcrating)
            audio.save()
        elif tempfile.lower().endswith(".mp3"):
            audio = ID3(tempfile)
            calcrating = int(round((float(rating) / 5) * 255, 0))
            audio.add(
                id3.POPM(email="Windows Media Player 9 Series",
                         rating=calcrating,
                         count=1))
            audio.save()
        else:
            logMsg("Not supported fileformat: %s" % (tempfile))

        #once we have succesfully written the flags we move the temp file to destination, otherwise not proceeding and just delete the temp
        #safety check: we check the file size of the temp file before proceeding with overwite of original file
        f = xbmcvfs.File(tempfile)
        checksum_size = f.size()
        f.close()
        if checksum_size >= org_size:
            xbmcvfs.delete(file)
            xbmcvfs.copy(tempfile, file)
        else:
            logMsg(
                "Checksum mismatch for filename: %s - using tempfile: %s  -  not proceeding with file overwite!"
                % (rating, file, tempfile))

        #always delete the tempfile
        xbmcvfs.delete(tempfile)

    except Exception as e:
        #file in use ?
        logMsg("Exception in updateRatingToFile %s" % e, 0)
Exemplo n.º 3
0
def write_tags(pre_abs, meta, fmt, cov_abs):
    if fmt == "FLAC":
        audio = FLAC(pre_abs)
        del meta['track_padded']
        for k, v in meta.items():
            if v:
                audio[k] = str(v)
        if cov_abs:
            with open(cov_abs, "rb") as f:
                image = Picture()
                image.type = 3
                image.mime = "image/jpeg"
                image.data = f.read()
                audio.add_picture(image)
    elif fmt == "MP3":
        try:
            audio = id3.ID3(pre_abs)
        except ID3NoHeaderError:
            audio = id3.ID3()
        audio['TRCK'] = id3.TRCK(encoding=3,
                                 text="{}/{}".format(meta['track'],
                                                     meta['tracktotal']))
        legend = {
            "album": id3.TALB,
            "albumartist": id3.TPE2,
            "artist": id3.TPE1,
            #"comment": id3.COMM,
            "copyright": id3.TCOP,
            "isrc": id3.TSRC,
            "label": id3.TPUB,
            "title": id3.TIT2,
            "year": id3.TYER
        }
        for k, v in meta.items():
            id3tag = legend.get(k)
            if v and id3tag:
                audio[id3tag.__name__] = id3tag(encoding=3, text=v)
        if cov_abs:
            with open(cov_abs, "rb") as cov_obj:
                audio.add(id3.APIC(3, "image/jpeg", 3, None, cov_obj.read()))
    else:
        audio = MP4(pre_abs)
        audio['\xa9nam'] = meta['title']
        audio['\xa9alb'] = meta['album']
        audio['aART'] = meta['albumartist']
        audio['\xa9ART'] = meta['artist']
        audio['trkn'] = [(meta['track'], meta['tracktotal'])]
        audio['\xa9day'] = meta['year']
        audio['cprt'] = meta['copyright']
        if cov_abs:
            with open(cov_abs, "rb") as f:
                audio['covr'] = [
                    MP4Cover(f.read(), imageformat=MP4Cover.FORMAT_JPEG)
                ]
    audio.save(pre_abs)
Exemplo n.º 4
0
def updateRatingToFile(rating, file):
    #update the rating from Emby to the file
    
    f = xbmcvfs.File(file)
    org_size = f.size()
    f.close()
    
    #create tempfile
    if "/" in file: filepart = file.split("/")[-1]
    else: filepart = file.split("\\")[-1]
    tempfile = "special://temp/"+filepart
    xbmcvfs.copy(file, tempfile)
    tempfile = xbmc.translatePath(tempfile).decode("utf-8")
    
    log.info( "setting song rating: %s for filename: %s - using tempfile: %s" %(rating,file,tempfile))
    
    if not tempfile:
        return
    
    try:
        if tempfile.lower().endswith(".flac"):
            audio = FLAC(tempfile)
            calcrating = int(round((float(rating) / 5) * 100, 0))
            audio["rating"] = str(calcrating)
            audio.save()
        elif tempfile.lower().endswith(".mp3"):
            audio = ID3(tempfile)
            calcrating = int(round((float(rating) / 5) * 255, 0))
            audio.add(id3.POPM(email="Windows Media Player 9 Series", rating=calcrating, count=1))
            audio.save()
        else:
            log.info( "Not supported fileformat: %s" %(tempfile))
            
        #once we have succesfully written the flags we move the temp file to destination, otherwise not proceeding and just delete the temp
        #safety check: we check the file size of the temp file before proceeding with overwite of original file
        f = xbmcvfs.File(tempfile)
        checksum_size = f.size()
        f.close()
        if checksum_size >= org_size:
            xbmcvfs.delete(file)
            xbmcvfs.copy(tempfile,file)
        else:
            log.info( "Checksum mismatch for filename: %s - using tempfile: %s  -  not proceeding with file overwite!" %(rating,file,tempfile))
        
        #always delete the tempfile
        xbmcvfs.delete(tempfile)
            
    except Exception as e:
        #file in use ?
        log.error("Exception in updateRatingToFile %s" % e)
Exemplo n.º 5
0
 def saveArtwork(self):
   if Path(self.file_name).suffix == ".flac":
     audiof = FLAC(self.file_path)  
     if len(audiof.pictures) != 0:
       return
     dl_img = urllib3.PoolManager(cert_reqs='CERT_NONE', assert_hostname=False).request('GET', self.artwork_url).data
     img = Picture()
     img.type = 3
     img.desc = 'artwork'
     img.data = dl_img
     audiof.add_picture(img)
   elif Path(self.file_name).suffix == ".mp3":
     audiof = ID3(self.file_path)  
     if hasattr(audiof, "pictures") and len(audiof.pictures) != 0:
       return
     dl_img = urllib3.PoolManager(cert_reqs='CERT_NONE', assert_hostname=False).request('GET', self.artwork_url).data
     audiof.add(mutagen.id3.APIC(3, 'image/jpeg', 3, 'Front cover', dl_img))
   audiof.save()
Exemplo n.º 6
0
class Track(object):
    def __init__(self, fileType, pathList, fileName, audioTagPath):
        # ID3 tags
        self.title = ''
        self.artists = []
        self.albumTitle = ''
        self.albumArtist = ''
        self.year = ''  # YYYY
        self.date = ''  # YYYY-MM-DD
        self.performers = []
        self.composedPerformer = []
        self.composers = ''
        self.genres = []
        self.producers = []
        self.label = ''
        self.trackNumber = 0
        self.totalTrack = 0
        self.discNumber = 0
        self.totalDisc = 0
        self.bpm = ''
        self.lang = ''
        self.compilation = ''
        # Computed
        self.audioTagPath = audioTagPath
        self.audioTag = {}
        self.feat = []
        self.remix = []
        self.hasCover = False
        self.cover = {}
        self.coverType = ''
        self.coverDesc = ''
        # Filesystem path and name as lists (separator is ` - `)
        self.pathList = pathList
        self.fileType = fileType
        self.fileName = fileName  # Filename as a string
        # %releaseArtists% - %year% - %albumTitle% - %discNumber%%trackNumber% - %artists% - %title%
        self.fileNameList = []
        self.folderNameList = []  # %year% - %albumTitle%
        # Self fill
        if fileType == 'MP3':
            self.audioTag = ID3(audioTagPath)
            self._fillFromMP3()
        elif fileType == 'FLAC':
            self.audioTag = FLAC(audioTagPath)
            self._fillFromFLAC()
        self._computeInternals()

    # Read the mp3 track ID3 tags and extract all interresting values into a Track object
    def _fillFromMP3(self):
        if 'TIT2' in self.audioTag and self.audioTag['TIT2'].text[0] != '':
            self.title = self.audioTag['TIT2'].text[0].rstrip()
        if 'TPE1' in self.audioTag:
            self.artists = self.audioTag['TPE1'].text[0].split('; ')
        if 'TPE2' in self.audioTag:
            self.albumArtist = self.audioTag['TPE2'].text[0].rstrip()
        if 'TALB' in self.audioTag:
            self.albumTitle = self.audioTag['TALB'].text[0].rstrip()
        if 'TDRC' in self.audioTag and self.audioTag['TDRC'].text[0].get_text(
        ) != '':
            self.year = self.audioTag['TDRC'].text[0].get_text()[:4].rstrip()
        if 'TPUB' in self.audioTag and self.audioTag['TPUB'].text[0] != '':
            self.producers = self.audioTag['TPUB'].text[0].rstrip().split('; ')
        if 'TCOP' in self.audioTag and self.audioTag['TCOP'].text[0] != '':
            self.label = self.audioTag['TCOP'].text[0].rstrip()
        if 'TCOM' in self.audioTag and self.audioTag['TCOM'].text[0] != '':
            self.composers = self.audioTag['TCOM'].text[0].rstrip().split('; ')
        if 'TOPE' in self.audioTag and self.audioTag['TOPE'].text[0] != '':
            self.performers = self.audioTag['TOPE'].text[0].rstrip().split(
                '; ')
        if 'TLAN' in self.audioTag:
            self.lang = self.audioTag['TLAN'].text[0].rstrip().split('; ')
        if 'TRCK' in self.audioTag and self.audioTag['TRCK'].text[0] != '':
            if '/' in self.audioTag['TRCK'].text[0]:
                tags = self.audioTag['TRCK'].text[0].rstrip().split('/')
                self.trackNumber = tags[0]
                self.totalTrack = tags[1]
            else:
                self.trackNumber = self.audioTag['TRCK'].text[0].rstrip()
        if 'TPOS' in self.audioTag and self.audioTag['TPOS'].text[0] != '':
            tags = self.audioTag['TPOS'].text[0].rstrip().split('/')
            self.discNumber = tags[0]
            if len(tags) > 1:
                self.totalDisc = tags[1]
            else:
                self.totalDisc = -1
        if 'TBPM' in self.audioTag and self.audioTag['TBPM'].text[0] != '':
            self.bpm = self.audioTag['TBPM'].text[0].rstrip()
        if 'TCMP' in self.audioTag and self.audioTag['TCMP'].text[0] != '':
            self.compilation = self.audioTag['TCMP'].text[0].rstrip()
        if 'TDOR' in self.audioTag and self.audioTag['TDOR'].text[0] != '':
            self.date = str(self.audioTag['TDOR'].text[0])

    # Read the flac track Vorbis tags and extract all interresting values into a Track object
    def _fillFromFLAC(self):
        if 'TITLE' in self.audioTag:
            self.title = self.audioTag['TITLE'][0]
        if 'DATE' in self.audioTag:
            self.year = self.audioTag['DATE'][0]
        if 'TRACKNUMBER' in self.audioTag:
            self.trackNumber = self.audioTag['TRACKNUMBER'][0]
        if 'PRODUCER' in self.audioTag:
            self.producers = self.audioTag['PRODUCER'][0].split('; ')
        if 'LABEL' in self.audioTag:
            self.label = self.audioTag['LABEL'][0]
        if 'DISCNUMBER' in self.audioTag:
            self.discNumber = self.audioTag['DISCNUMBER'][0]
        if 'DISCTOTAL' in self.audioTag:
            self.totalDisc = self.audioTag['DISCTOTAL'][0]
        if 'TRACKTOTAL' in self.audioTag:
            self.totalTrack = self.audioTag['TRACKTOTAL'][0]
        if 'COMPOSER' in self.audioTag:
            self.composers = self.audioTag['COMPOSER'][0].split('; ')
        if 'PERFORMER' in self.audioTag:
            self.performers = self.audioTag['PERFORMER'][0].split('; ')
        if 'GENRE' in self.audioTag:
            self.genres = self.audioTag['GENRE'][0].split('; ')
        if 'ARTIST' in self.audioTag:
            self.artists = self.audioTag['ARTIST'][0].split('; ')
        if 'ALBUM' in self.audioTag:
            self.albumTitle = self.audioTag['ALBUM'][0]
        if 'ALBUMARTIST' in self.audioTag:
            self.albumArtist = self.audioTag['ALBUMARTIST'][0]
        if 'BPM' in self.audioTag:
            self.bpm = self.audioTag['BPM'][0]
        if 'LANGUAGE' in self.audioTag:
            self.lang = self.audioTag['LANGUAGE'][0].split('; ')
        if 'COMPILATION' in self.audioTag:
            self.compilation = self.audioTag['COMPILATION'][0]
        if 'RELEASEDATE' in self.audioTag:
            self.date = self.audioTag['RELEASEDATE'][0]

    # Compute all class internals that can not be extracted from ID3 tags
    def _computeInternals(self):
        self._computeFileNameList()
        self._computeFolderNameList()
        self._computeFeaturing()
        self._computeRemixer()
        self._containsCover()

    # Splits the filename into its components
    # (%releaseArtists% - %year% - %albumTitle% - %discNumber%%trackNumber% - %artists% - %title%)
    def _computeFileNameList(self):
        # We split the filename into its differents parts, as mentioned in this method description
        self.fileNameList = self.fileName.split(' - ')
        forbiddenPattern = ['Single', 'Intro', 'ÉPILOGUE', '25', 'Interlude']
        # Here we handle all specific cases (when ' - ' is not a separator)
        if len(self.fileNameList
               ) > 6 and self.fileNameList[3] in forbiddenPattern:
            # When album is a single, we must re-join the album name and the 'Single' suffix
            self.fileNameList[2:4] = [' - '.join(self.fileNameList[2:4])
                                      ]  # Re-join with a ' - ' separator

    # Splits the folderame into its components (%year% - %albumTitle%)
    def _computeFolderNameList(self):
        # We also split the folder name to make a double check for Year and Album name
        self.folderNameList = self.pathList[len(self.pathList) -
                                            1].split(' - ')
        forbiddenPattern = ['Single', 'Intro', 'ÉPILOGUE', '25', 'Interlude']

        if len(self.folderNameList
               ) == 3 and self.folderNameList[2] in forbiddenPattern:
            # When album is a single, we must re-join the album name and the 'Single' suffix
            self.folderNameList[1:3] = [' - '.join(self.folderNameList[1:3])
                                        ]  # Re-join with a ' - ' separator

    # Extract the featured artist(s) name(s) from the track fileName
    def _computeFeaturing(self):
        if self.fileName.find('(feat.') != -1:
            startIndex = self.fileName.rfind('(feat.', 0, len(self.fileName))
            self.feat = self.fileName[startIndex + 7:self.fileName.
                                      find(')', startIndex)].split(', ')
            # +7 is to remove the `(feat. ` string from feat artist
            if len(self.feat) > 0 and self.feat[0] != '':
                self.composedPerformer = [*self.feat, *self.artists]
                return
        self.composedPerformer = self.artists  # No featuring so performer should be equal to artist

    # Extract the track remix artist name from the track fileName
    def _computeRemixer(self):
        if self.fileNameList[len(self.fileNameList) - 1].find(' Remix)') != -1:
            self.remix = self.fileName[
                # +1 is to remove the opening parenthesis
                self.fileName.rfind('(', 0, len(self.fileName)) +
                1:self.fileName.rfind(' Remix)')].split(', ')

    # Test the cover existence in the file
    def _containsCover(self):
        # Extract image from file
        if self.fileType == 'MP3':
            if len(self.audioTag.getall('APIC')) > 0:
                mp3Cover = self.audioTag.getall('APIC')[0]
                self.cover = mp3Cover.data
                self.coverType = mp3Cover.mime
                self.coverDesc = mp3Cover.desc
        elif self.fileType == 'FLAC':
            if len(self.audioTag.pictures) > 0:
                self.cover = self.audioTag.pictures[0].data
                self.coverType = self.audioTag.pictures[0].mime
                self.coverDesc = self.audioTag.pictures[0].desc
            else:
                self.cover = self.audioTag.pictures
        # Test cover existence
        if len(self.cover) != 0:
            self.hasCover = True
        else:
            self.hasCover = False

    # Inspects the track object to find if any of its tags has multiple fields
    def testTagsUnicity(self):
        if self.fileType == 'MP3':
            if 'TIT2' in self.audioTag and len(self.audioTag['TIT2'].text) > 1:
                return False
            if 'TPE1' in self.audioTag and len(self.audioTag['TPE1'].text) > 1:
                return False
            if 'TPE2' in self.audioTag and len(self.audioTag['TPE2'].text) > 1:
                return False
            if 'TALB' in self.audioTag and len(self.audioTag['TALB'].text) > 1:
                return False
            if 'TDRC' in self.audioTag and len(self.audioTag['TDRC'].text) > 1:
                return False
            if 'TPUB' in self.audioTag and len(self.audioTag['TPUB'].text) > 1:
                return False
            if 'TCOP' in self.audioTag and len(self.audioTag['TCOP'].text) > 1:
                return False
            if 'TCOM' in self.audioTag and len(self.audioTag['TCOM'].text) > 1:
                return False
            if 'TOPE' in self.audioTag and len(self.audioTag['TOPE'].text) > 1:
                return False
            if 'TLAN' in self.audioTag and len(self.audioTag['TLAN'].text) > 1:
                return False
            if 'TRCK' in self.audioTag and len(self.audioTag['TRCK'].text) > 1:
                return False
            if 'TPOS' in self.audioTag and len(self.audioTag['TPOS'].text) > 1:
                return False
            if 'TBPM' in self.audioTag and len(self.audioTag['TBPM'].text) > 1:
                return False
            if 'TCMP' in self.audioTag and len(self.audioTag['TCMP'].text) > 1:
                return False
            if 'TDOR' in self.audioTag and len(self.audioTag['TDOR'].text) > 1:
                return False
        elif self.fileType == 'FLAC':
            if 'TITLE' in self.audioTag and len(self.audioTag['TITLE']) > 1:
                return False
            if 'DATE' in self.audioTag and len(self.audioTag['DATE']) > 1:
                return False
            if 'TRACKNUMBER' in self.audioTag and len(
                    self.audioTag['TRACKNUMBER']) > 1:
                return False
            if 'PRODUCER' in self.audioTag and len(
                    self.audioTag['PRODUCER']) > 1:
                return False
            if 'LABEL' in self.audioTag and len(self.audioTag['LABEL']) > 1:
                return False
            if 'DISCNUMBER' in self.audioTag and len(
                    self.audioTag['DISCNUMBER']) > 1:
                return False
            if 'DISCTOTAL' in self.audioTag and len(
                    self.audioTag['DISCTOTAL']) > 1:
                return False
            if 'TRACKTOTAL' in self.audioTag and len(
                    self.audioTag['TRACKTOTAL']) > 1:
                return False
            if 'COMPOSER' in self.audioTag and len(
                    self.audioTag['COMPOSER']) > 1:
                return False
            if 'PERFORMER' in self.audioTag and len(
                    self.audioTag['PERFORMER']) > 1:
                return False
            if 'GENRE' in self.audioTag and len(self.audioTag['GENRE']) > 1:
                return False
            if 'ARTIST' in self.audioTag and len(self.audioTag['ARTIST']) > 1:
                return False
            if 'ALBUM' in self.audioTag and len(self.audioTag['ALBUM']) > 1:
                return False
            if 'ALBUMARTIST' in self.audioTag and len(
                    self.audioTag['ALBUMARTIST']) > 1:
                return False
            if 'BPM' in self.audioTag and len(self.audioTag['BPM']) > 1:
                return False
            if 'LANGUAGE' in self.audioTag and len(
                    self.audioTag['LANGUAGE']) > 1:
                return False
            if 'COMPILATION' in self.audioTag and len(
                    self.audioTag['COMPILATION']) > 1:
                return False
            if 'RELEASEDATE' in self.audioTag and len(
                    self.audioTag['RELEASEDATE']) > 1:
                return False
        return True

    # Clear all previously existing tags
    def clearInternalTags(self, album):
        # We could use audioTag.delete() but we just want to clear the tags supported by convention
        if self.fileType == 'MP3':
            self.audioTag.add(TIT2(text=''))
            self.audioTag.add(TPE1(text=''))
            self.audioTag.add(TPE2(text=''))
            self.audioTag.add(TALB(text=''))
            self.audioTag.add(TDRC(text=''))
            self.audioTag.add(TPUB(text=''))
            self.audioTag.add(TCOP(text=''))
            self.audioTag.add(TCOM(text=''))
            self.audioTag.add(TOPE(text=''))
            self.audioTag.add(TLAN(text=''))
            self.audioTag.add(TRCK(text=''))
            self.audioTag.add(TPOS(text=''))
            self.audioTag.add(TBPM(text=''))
            self.audioTag.add(TCMP(text=''))
            self.audioTag.add(TDOR(text=''))
        elif self.fileType == 'FLAC':
            self.audioTag['TITLE'] = ''
            self.audioTag['DATE'] = ''
            self.audioTag['ALBUM'] = ''
            self.audioTag['ARTIST'] = ''
            self.audioTag['ALBUMARTIST'] = ''
            self.audioTag['PERFORMER'] = ''
            self.audioTag['TRACKNUMBER'] = ''
            self.audioTag['DISCNUMBER'] = ''
            self.audioTag['TRACKTOTAL'] = ''
            self.audioTag['TOTALTRACK'] = ''
            self.audioTag['TOTALTRACKS'] = ''
            self.audioTag['DISCTOTAL'] = ''
            self.audioTag['TOTALDISC'] = ''
            self.audioTag['TOTALDISCS'] = ''
            self.audioTag['COMPILATION'] = ''
            self.audioTag['RELEASEDATE'] = ''
            self.audioTag.clear_pictures()
        self.audioTag.save(self.audioTagPath)

    # Compute all class internals that can not be extracted from ID3 tags
    def setInternalTags(self, album):
        # Compilation tag is '0' for regular release, '1' for various artist and '2' for mixes
        compilation = '0'
        default = '<fill me>'
        # Since record company must contain this string, we then admit its a compilation
        if ' Records' in album.albumArtist:
            compilation = '1'
        if self.fileType == 'FLAC':
            if len(self.fileNameList) == 6:  # Avoid range exception
                self._buildArtistsList()
                self._buildPerformersList()
                self._addCoverToFile(album)
                # Append tag by tag o the track
                if self.fileNameList[5] is not None:
                    self._setInternalTag('TITLE', self.fileNameList[5][:-5],
                                         default)
            if album.year is not None:
                self._setInternalTag('DATE', str(album.year), '1900')
            else:
                self._setInternalTag('DATE', '1900')
            if self.artists is not None:
                self._setInternalTag('ARTIST', '; '.join(self.artists),
                                     default)
            else:
                self._setInternalTag('ARTIST', default)
            if album.albumArtist is not None:
                self._setInternalTag('ALBUMARTIST', album.albumArtist, default)
            else:
                self._setInternalTag('ALBUMARTIST', default)
            if self.performers is not None:
                self._setInternalTag('PERFORMER', '; '.join(self.performers),
                                     default)
            else:
                self._setInternalTag('PERFORMER', default)
            if len(self.fileNameList
                   ) == 6 and self.fileNameList[3] is not None:
                self._setInternalTag('TRACKNUMBER',
                                     str(self.fileNameList[3][1:]).lstrip('0'),
                                     '0')
            else:
                self._setInternalTag('TRACKNUMBER', '0')
            if album.totalTrack is not None:
                self._setInternalTag('TRACKTOTAL', str(album.totalTrack), '0')
            else:
                self._setInternalTag('TRACKTOTAL', '0')
            if len(self.folderNameList
                   ) == 2 and self.folderNameList[1] is not None:
                self._setInternalTag('ALBUM', self.folderNameList[1], default)
            else:
                self._setInternalTag('ALBUM', default)
            if album.totalDisc is not None:
                self._setInternalTag('DISCTOTAL', str(album.totalDisc), '0')
            else:
                self._setInternalTag('DISCTOTAL', '0')
            if len(self.fileNameList
                   ) == 6 and self.fileNameList[3] is not None:
                self._setInternalTag('DISCNUMBER',
                                     str(self.fileNameList[3][0]), '0')
            else:
                self._setInternalTag('DISCNUMBER', '0')
            # No need for test value as compilation is built locally (only for regular(0)/compilation(1), not live(2)/mix(3))
            self._setInternalTag('COMPILATION', compilation, '-1')
            # Create fields with default value to fasten manual tagging
            self._setInternalTag('COMPOSER', default)
            self._setInternalTag('LANGUAGE', default)
            self._setInternalTag('PRODUCER', default)
            self._setInternalTag(
                'LABEL', default
            )  # May be overwritten in _fillTagsFromPreviouslyExistingTag()
            # Release date
            if len(album.folderNameList[0]) > 4:
                self._setInternalTag('RELEASEDATE', album.folderNameList[0],
                                     '1900-01-01')
            else:
                self._setInternalTag('RELEASEDATE',
                                     '{}-01-01'.format(album.year),
                                     '1900-01-01')
            # If other tags were previously filled, try to integrate them according to the tagging convention
            self._fillTagsFromPreviouslyExistingTag()
        elif self.fileType == 'MP3':
            if len(self.fileNameList) == 6:  # Avoid range exception
                self._buildArtistsList()
                self._buildPerformersList()
                self._addCoverToFile(album)
                # Append tag by tag on the track
                if self.fileNameList[5] is not None:  # Track title
                    self.audioTag.add(TIT2(text=self.fileNameList[5]
                                           [:-4]))  # -4 for '.mp3' string
            if self.artists is not None:  # Artist
                self.audioTag.add(TPE1(text='; '.join(self.artists)))
            if album.albumArtist is not None:  # Album artist
                self.audioTag.add(TPE2(text=album.albumArtist))
            if len(
                    self.folderNameList
            ) == 2 and self.folderNameList[1] is not None:  # Album title
                self.audioTag.add(TALB(text=self.folderNameList[1]))
            if album.year is not None:  # Year
                self.audioTag.add(TDRC(text=str(album.year)))
            if self.performers is not None:  # Performer (original artist)
                self.audioTag.add(TOPE(text='; '.join(self.performers)))
            if len(self.fileNameList) == 6 and self.fileNameList[
                    3] is not None and album.totalTrack is not None:  # track N°/track total
                self.audioTag.add(
                    TRCK(text=str(self.fileNameList[3][1:]).lstrip('0') + '/' +
                         str(album.totalTrack)))
            if len(self.fileNameList) == 6 and self.fileNameList[
                    3] is not None and album.totalDisc is not None:  # disc N°/disc total
                self.audioTag.add(
                    TPOS(text=str(self.fileNameList[3][0]) + '/' +
                         str(album.totalDisc)))
            self.audioTag.add(TCMP(text=compilation))  # Compilation
            self.audioTag.add(TPUB(text=default))  # Producer
            self.audioTag.add(TCOP(text=default))  # Label
            self.audioTag.add(TCOM(text=default))  # Composer
            self.audioTag.add(TLAN(text=default))  # Language
            # Release date
            if len(album.folderNameList[0]) > 4:
                self.audioTag.add(TDOR(text=album.folderNameList[0]))
            else:
                self.audioTag.add(TDOR(text='{}-01-01'.format(album.year)))
        # Now save all the new tags into the audio file
        self.audioTag.save(self.audioTagPath)

    # Check if the tag is already filled before adding one
    def _setInternalTag(self, tag, value, default=''):
        if tag in self.audioTag and self.audioTag[tag] is not value:
            self.audioTag[tag] = value
        else:
            self.audioTag[tag] = default

    # This method will fill :
    # - Label tag if publisher tag was previously filled (according to this convention, the label is stored in publisher (TPUB) for mp3 files)
    def _fillTagsFromPreviouslyExistingTag(self):
        if self.fileType == 'FLAC':
            if 'PUBLISHER' in self.audioTag and self.audioTag['PUBLISHER'] != [
                    ''
            ]:
                self._setInternalTag('LABEL', self.audioTag['PUBLISHER'][0],
                                     '<fill me>')
                self.audioTag['PUBLISHER'] = ''  # Clear publisher tag

    # Build artist array from artist string and support remix artist if any
    def _buildArtistsList(self):
        outputList = []
        if len(self.remix) == 0:  # Not a remixed track
            artists = self.fileNameList[4].split(', ')
            for artist in artists:
                outputList.append(artist)
        else:
            outputList = list(set(outputList + self.remix))
        outputList.sort()
        self.artists = outputList

    # Build performers array from artist string and support remix artist if any
    def _buildPerformersList(self):
        outputList = []
        if len(self.remix) == 0:  # Not a remixed track
            performers = self.fileNameList[4].split(', ')
            for performer in performers:
                outputList.append(performer)
        else:
            outputList = list(set(outputList + self.remix))
        if len(self.feat) > 0:  # Append featuring artists if any
            outputList = list(set(outputList + self.feat))
        outputList.sort()
        self.performers = outputList

    # Append a cover to the track only if it is 1k by 1k and if there is not any cover
    def _addCoverToFile(self, album):
        # Build the file path by concatenating folder in the file path
        path = ''
        for folder in self.pathList:
            path += '{}/'.format(folder)
        path += album.coverName
        if self.fileType == 'FLAC':
            if not self.hasCover or (self.audioTag.pictures[0].height != 1000
                                     and
                                     self.audioTag.pictures[0].width != 1000):
                if self.hasCover:
                    self.audioTag.clear_pictures()
                with open(path, 'rb') as img:
                    data = img.read()
                # Open physical image
                im = PIL.Image.open(path)
                width, height = im.size
                # Create picture and set its internals
                picture = Picture()
                picture.data = data
                picture.type = 3  # COVER_FRONT
                picture.desc = path.rsplit(
                    '/', 1)[-1]  # Add picture name as a description
                picture.mime = mimetypes.guess_type(path)[0]
                picture.width = width
                picture.height = height
                picture.depth = mode_to_bpp[im.mode]
                # Save into file's audio tag
                self.audioTag.add_picture(picture)
                self.audioTag.save()
        else:
            # Remove any previous cover
            self.audioTag.delall('APIC')
            # Read and save cover into file
            imgData = open(path, 'rb').read()
            mime = mimetypes.guess_type(path)[0]
            self.audioTag.add(APIC(3, mime, 3, album.coverName, imgData))
            self.audioTag.save(v2_version=3)