Exemplo n.º 1
0
class FlacStripper(MutagenStripper):
    """ Represent a Flac audio file
    """
    def _create_mfile(self):
        self.mfile = FLAC(self.filename)

    def remove_all(self):
        """ Remove the "metadata" block from the file
        """
        super(FlacStripper, self).remove_all()
        self.mfile.clear_pictures()
        self.mfile.save()
        return True

    def is_clean(self):
        """ Check if the "metadata" block is present in the file
        """
        return super(FlacStripper, self).is_clean() and not self.mfile.pictures

    def get_meta(self):
        """ Return the content of the metadata block if present
        """
        metadata = super(FlacStripper, self).get_meta()
        if self.mfile.pictures:
            metadata['picture:'] = 'yes'
        return metadata
Exemplo n.º 2
0
class MetaFLAC(MetaAudio):
    def __init__(self, path):
        self.audio_path = path
        self.audio = FLAC(path)
        try:
            if 'albumartist' in self.audio:
                # use Album Artist first
                self.artist = self.audio['albumartist'][0]
            else:
                self.artist = self.audio['artist'][0]
            self.album = self.audio['album'][0]
            self.title = self.audio['title'][0]
        except Exception:
            raise Exception("missing FLAC tags")

    def has_embedded_art(self):
        return self.audio.pictures != []

    def detach_art(self):
        self.audio.clear_pictures()

    def embed_art(self, art_path):
        pic = Picture()
        with open(art_path, "rb") as f:
            pic.data = f.read()
        pic.type = 3  # front cover
        pic.mime = MetaAudio.get_mime_type(art_path)
        pic.desc = 'front cover'
        self.audio.add_picture(pic)

    def save(self):
        self.audio.save()
Exemplo n.º 3
0
class FlacStripper(MutagenStripper):
    """ Represent a Flac audio file
    """
    def _create_mfile(self):
        self.mfile = FLAC(self.filename)

    def remove_all(self):
        """ Remove the "metadata" block from the file
        """
        super(FlacStripper, self).remove_all()
        self.mfile.clear_pictures()
        self.mfile.save()
        return True

    def is_clean(self):
        """ Check if the "metadata" block is present in the file
        """
        return super(FlacStripper, self).is_clean() and not self.mfile.pictures

    def get_meta(self):
        """ Return the content of the metadata block if present
        """
        metadata = super(FlacStripper, self).get_meta()
        if self.mfile.pictures:
            metadata['picture:'] = 'yes'
        return metadata
def main():
    print("start")
    tracks = []
    root = tkinter.Tk()
    root.withdraw()
    root.update()
    folder = askdirectory(title = "choose the dir u want to delete on tags in",initialdir = r"C:\Users\User\Desktop", mustexist=True )
    root.destroy()


    for root, dirs, files, in os.walk(folder):
        for name in files:
            if name.endswith((".mp3", ".flac")):
                print("the name= "+os.path.splitext(name)[0])
                print("the type= "+os.path.splitext(name)[1])
                if(name.endswith(".flac")):
                    print("its .flac")
                    audio=FLAC(root + "\\" + name)
                    audio.delete()
                    audio.clear_pictures()
                    audio.save()
                if(name.endswith(".mp3")):
                    print("its .mp3")
                    audio=MP3(root + "\\" + name)
                    audio.delete()
                    audio.clear()
                    audio.save()
Exemplo n.º 5
0
	def on_save(self):
		audio = FLAC(self.song.get("~filename", ""))
		## if file has no images -> leave
		if (audio.pictures is None) or (len(audio.pictures) <= 0):
			return
		## first,clear all pictures, then add the images in order
		try:
			audio.clear_pictures()
		except:
			self.printError()
			return False
		for row in self.liststore:
			img = row[1]
			try:
				audio.add_picture(img)
			except:
				self.printError()
				return False
		audio.save()
		count = 0
		if (audio.pictures is None) or (len(audio.pictures) <= 0):
			pass
		else:
			count = str(len(audio.pictures))

		self.song["pictures"] = count
		app.window.emit("artwork-changed", [self.song])
		del self.coverlist[:]
		self.liststore.clear()
		self.start_search()
		return True
Exemplo n.º 6
0
    def on_save(self):
        audio = FLAC(self.song.get("~filename", ""))
        ## if file has no images -> leave
        if (audio.pictures is None) or (len(audio.pictures) <= 0):
            return
        ## first,clear all pictures, then add the images in order
        try:
            audio.clear_pictures()
        except:
            self.printError()
            return False
        for row in self.liststore:
            img = row[1]
            try:
                audio.add_picture(img)
            except:
                self.printError()
                return False
        audio.save()
        count = 0
        if (audio.pictures is None) or (len(audio.pictures) <= 0):
            pass
        else:
            count = str(len(audio.pictures))

        self.song["pictures"] = count
        app.window.emit("artwork-changed", [self.song])
        del self.coverlist[:]
        self.liststore.clear()
        self.start_search()
        return True
Exemplo n.º 7
0
 def test_clear_pictures(self):
     f = FLAC(self.NEW)
     c1 = len(f.pictures)
     c2 = len(f.metadata_blocks)
     f.clear_pictures()
     f.save()
     f = FLAC(self.NEW)
     self.failUnlessEqual(len(f.metadata_blocks), c2 - c1)
Exemplo n.º 8
0
 def add_flac_image_set(self,filename, images):
     audio = FLAC(filename)
     if self.replace_images:
         audio.clear_pictures()
     for img in images:
         self.add_flac_cover(audio, img['file'], desc=img['desc'], file_type=img['type'])
         print(f'{filename} images updated')
     audio.save()
Exemplo n.º 9
0
 def test_clear_pictures(self):
     f = FLAC(self.NEW)
     c1 = len(f.pictures)
     c2 = len(f.metadata_blocks)
     f.clear_pictures()
     f.save()
     f = FLAC(self.NEW)
     self.failUnlessEqual(len(f.metadata_blocks), c2 - c1)
Exemplo n.º 10
0
def write_tags(song, data):
    try:
        tag = FLAC(song)
        tag.delete()
        images = Picture()
        images.type = 3
        images.data = data["image"]
        tag.clear_pictures()
        tag.add_picture(images)
        tag["lyrics"] = data["lyric"]
    except FLACNoHeaderError:
        try:
            tag = File(song, easy=True)
            tag.delete()
        except:
            if isfile(song):
                remove(song)

            raise exceptions.TrackNotFound("")
    except NOTVALIDSONG:
        raise exceptions.TrackNotFound("")

    tag["artist"] = data["artist"]
    tag["title"] = data["music"]
    tag["date"] = data["year"]
    tag["album"] = data["album"]
    tag["tracknumber"] = data["tracknum"]
    tag["discnumber"] = data["discnum"]
    tag["genre"] = data["genre"]
    tag["albumartist"] = data["ar_album"]
    tag["author"] = data["author"]
    tag["composer"] = data["composer"]
    tag["copyright"] = data["copyright"]
    tag["bpm"] = data["bpm"]
    tag["length"] = data["duration"]
    tag["organization"] = data["label"]
    tag["isrc"] = data["isrc"]
    tag["lyricist"] = data["lyricist"]
    tag.save()

    try:
        audio = ID3(song)

        audio.add(
            APIC(
                encoding=3,
                mime="image/jpeg",
                type=3,
                desc=u"Cover",
                data=data["image"],
            ))

        audio.add(
            USLT(encoding=3, lang=u"eng", desc=u"desc", text=data["lyric"]))

        audio.save()
    except ID3NoHeaderError:
        pass
Exemplo n.º 11
0
 def cleanTags(filepath):
     if Path(filepath).suffix == ".flac":
         audiof = FLAC(filepath)
         audiof.clear_pictures()
         audiof.delete()
     elif Path(filepath).suffix == ".mp3":
         audiof = EasyID3(filepath)
         audiof.delete()
     audiof.save()
Exemplo n.º 12
0
    def embed_cover_art(self, audio_file, cover_file):
        """Embeds cover art into an audio file.

		Arguments:
			audio_file (str): The path to the audio file to embed the artwork in.
			cover_file (str): The path to the artwork file to embed.
		"""
        if path.isfile(audio_file) and path.isfile(cover_file):
            mimetype = "image/png" if cover_file.endswith("png") else "image/jpeg"
            artwork = open(cover_file, "rb").read()
            desc = u"Cover Art"

            # Determine which filetype we're handling
            if audio_file.endswith("m4a"):
                audio = MP4(audio_file)

                covr = []
                if cover_file.endswith("png"):
                    covr.append(MP4Cover(artwork, MP4Cover.FORMAT_PNG))
                else:
                    covr.append(MP4Cover(artwork, MP4Cover.FORMAT_JPEG))

                audio.tags["covr"] = covr
            elif audio_file.endswith("mp3"):
                audio = MP3(audio_file, ID3=ID3)

                # Add ID3 tags if they don't exist
                try:
                    audio.add_tags()
                except error:
                    pass

                audio.tags.add(
                    APIC(
                        encoding=3,  # 3 is UTF-8
                        mime=mimetype,
                        type=3,  # 3 is for cover artwork
                        desc=desc,
                        data=artwork,
                    )
                )
            elif audio_file.endswith("flac"):
                audio = FLAC(audio_file)

                image = Picture()
                image.type = 3  # 3 is for cover artwork
                image.mime = mimetype
                image.desc = desc
                image.data = artwork

                audio.clear_pictures()  # Clear existing pictures
                audio.add_picture(image)

                # Save the audio file
        audio.save()
Exemplo n.º 13
0
def write_tags(song, data):
    try:
        tag = FLAC(song)
        tag.delete()
        images = Picture()
        images.type = 3
        images.data = data['image']
        tag.clear_pictures()
        tag.add_picture(images)
        tag['lyrics'] = data['lyric']
    except FLACNoHeaderError:
        try:
            tag = File(song, easy=True)
            tag.delete()
        except:
            raise exceptions.TrackNotFound("")
    except error:
        raise exceptions.TrackNotFound("")

    tag['artist'] = data['artist']
    tag['title'] = data['music']
    tag['date'] = data['year']
    tag['album'] = data['album']
    tag['tracknumber'] = data['tracknum']
    tag['discnumber'] = data['discnum']
    tag['genre'] = data['genre']
    tag['albumartist'] = data['ar_album']
    tag['author'] = data['author']
    tag['composer'] = data['composer']
    tag['copyright'] = data['copyright']
    tag['bpm'] = data['bpm']
    tag['length'] = data['duration']
    tag['organization'] = data['label']
    tag['isrc'] = data['isrc']
    tag['replaygain_*_gain'] = data['gain']
    tag['lyricist'] = data['lyricist']
    tag.save()

    try:
        audio = ID3(song)

        audio.add(
            APIC(encoding=3,
                 mime="image/jpeg",
                 type=3,
                 desc=u"Cover",
                 data=data['image']))

        audio.add(
            USLT(encoding=3, lang=u"eng", desc=u"desc", text=data['lyric']))

        audio.save()
    except _util.ID3NoHeaderError:
        pass
Exemplo n.º 14
0
    def remove_all(self):
        '''
            Remove the "metadata" block from the file
        '''
        if self.backup is True:
            shutil.copy2(self.filename, self.output)
            self.filename = self.output

        mfile = FLAC(self.filename)
        mfile.delete()
        mfile.clear_pictures()
        mfile.save()
Exemplo n.º 15
0
    def remove_all(self):
        '''
            Remove the "metadata" block from the file
        '''
        if self.backup is True:
            shutil.copy2(self.filename, self.output)
            self.filename = self.output

        mfile = FLAC(self.filename)
        mfile.delete()
        mfile.clear_pictures()
        mfile.save()
Exemplo n.º 16
0
    def clear_images(self):
        """Delete all embedded images"""

        with translate_errors():
            tag = FLAC(self["~filename"])
            tag.clear_pictures()
            tag.save()

        # clear vcomment tags
        super().clear_images()

        self.has_images = False
Exemplo n.º 17
0
    def clear_images(self):
        """Delete all embedded images"""

        with translate_errors():
            tag = FLAC(self["~filename"])
            tag.clear_pictures()
            tag.save()

        # clear vcomment tags
        super(FLACFile, self).clear_images()

        self.has_images = False
Exemplo n.º 18
0
def tag_flac(path_audio,path_pic,lrc,title,artist,album,disc,track,**kw):
    '''
    ref:
    https://www.xiph.org/vorbis/doc/v-comment.html
    FLAC tags also call Vorbis comment.
    It doesn't support lyrics.
    So use ID3 to tag FLAC instead FLAC tags.
    '''
    tags=FLAC(path_audio)
    tags.clear()
    tags.clear_pictures()
    tags.save()
    tag_mp3(path_audio,path_pic,lrc,title,artist,album,disc,track,**kw)
Exemplo n.º 19
0
    def update_flac(self, path: str, track: beatport.Track):
        f = FLAC(path)

        if UpdatableTags.title in self.config.update_tags and self.config.overwrite:
            f['TITLE'] = track.title
        if UpdatableTags.artist in self.config.update_tags and self.config.overwrite:
            f['ARTIST'] = self.config.artist_separator.join(
                [a.name for a in track.artists])
        if UpdatableTags.album in self.config.update_tags and (
                self.config.overwrite or f.get('ALBUM') == None):
            f['ALBUM'] = track.album.name
        if UpdatableTags.label in self.config.update_tags and (
                self.config.overwrite or f.get('LABEL') == None):
            f['LABEL'] = track.label.name
        if UpdatableTags.bpm in self.config.update_tags and (
                self.config.overwrite or f.get('BPM') == None):
            f['BPM'] = str(track.bpm)
        if UpdatableTags.genre in self.config.update_tags and (
                self.config.overwrite or f.get('GENRE') == None):
            f['GENRE'] = ', '.join([g.name for g in track.genres])
        if UpdatableTags.date in self.config.update_tags and (
                self.config.overwrite or f.get('DATE') == None):
            f['DATE'] = track.release_date.strftime('%Y-%m-%d')
            #Year - part of date
        if UpdatableTags.key in self.config.update_tags and (
                self.config.overwrite or f.get('INITIALKEY') == None):
            f['INITIALKEY'] = track.id3key()
        if UpdatableTags.publishdate in self.config.update_tags and (
                self.config.overwrite or f.get('ORIGINALDATE') == None):
            f['ORIGINALDATE'] = str(track.publish_date.year)
        #Other tags
        if UpdatableTags.other in self.config.update_tags:
            f['WWWAUDIOFILE'] = track.url()
            f['WWWPUBLISHER'] = track.label.url('label')

        #Redownlaod cover
        if self.config.replace_art:
            try:
                url = track.art(self.config.art_resolution)
                r = requests.get(url)
                image = Picture()
                image.type = 3
                image.mime = 'image/jpeg'
                image.desc = 'Cover'
                image.data = r.content
                f.clear_pictures()
                f.add_picture(image)
            except Exception:
                logging.warning('Error downloading cover for file: ' + path)

        f.save()
Exemplo n.º 20
0
class _FLACWrapper(_AbstractWrapper):
    VALID_TAG_KEYS = (
        'artwork',
        'artist',
        'album',
        'title',
        'genre',
    )

    def __init__(self, filename):
        _AbstractWrapper.__init__(self)
        self.audio = FLAC(filename)

    def __getattr__(self, attr):
        if attr in self.VALID_TAG_KEYS:
            if attr == 'artwork':
                if self.audio.pictures:
                    picture = self.audio.pictures[0]
                    return Artwork(picture.mime, picture.data)
                else:
                    return None
            else:
                try:
                    return self.audio[attr][0]
                except KeyError:
                    return None
        raise TagError(self, attr)

    def __setattr__(self, attr, value):
        if attr in self.VALID_TAG_KEYS:
            if isinstance(value, Artwork):
                picture = Picture()
                picture.type = 3
                picture.mime = value.mime
                picture.data = value.data
                self.audio.clear_pictures()
                self.audio.add_picture(picture)
            elif isinstance(value, str):
                self.audio[attr] = [value]
            else:
                raise TagValueError(value)
        else:
            object.__setattr__(self, attr, value)

    def __repr__(self):
        return repr(self.audio)

    def save(self):
        self.audio.save()
Exemplo n.º 21
0
    def clear_images(self):
        """Delete all embedded images"""

        try:
            tag = FLAC(self["~filename"])
        except EnvironmentError:
            return

        tag.clear_pictures()
        tag.save()

        # clear vcomment tags
        super(FLACFile, self).clear_images()

        self.has_images = False
Exemplo n.º 22
0
    def clear_images(self):
        """Delete all embedded images"""

        try:
            tag = FLAC(self["~filename"])
        except EnvironmentError:
            return

        tag.clear_pictures()
        tag.save()

        # clear vcomment tags
        super(FLACFile, self).clear_images()

        self.has_images = False
Exemplo n.º 23
0
 def _image_flac(self):
     if self.image and cfg.embed_cover:
         audio = FLAC(self.path)
         img = Picture()
         img.type = 3
         img.data = requests.get(self.image).content
         if cfg.overwrite_cover:
             audio.clear_pictures()
             audio.add_picture(img)
             self.cover_updated = True
         else:
             if self.cover_embedded is False:
                 audio.clear_pictures()
                 audio.add_picture(img)
                 self.cover_updated = True
         audio.save()
Exemplo n.º 24
0
    def test_invalid_overflow_recover_and_save_back(self):
        # save a picture which is too large for flac, but still write it
        # with a wrong block size
        f = FLAC(self.filename)
        f.clear_pictures()
        pic = Picture()
        pic.data = b"\x00" * (2**24 - 32)
        pic._invalid_overflow_size = 42
        f.add_picture(pic)
        f.save()

        # make sure we can read it and save it again
        f = FLAC(self.filename)
        self.assertTrue(f.pictures)
        self.assertEqual(len(f.pictures[0].data), 2**24 - 32)
        f.save()
Exemplo n.º 25
0
    def test_invalid_overflow_recover_and_save_back(self):
        # save a picture which is too large for flac, but still write it
        # with a wrong block size
        f = FLAC(self.filename)
        f.clear_pictures()
        pic = Picture()
        pic.data = b"\x00" * (2 ** 24 - 32)
        pic._invalid_overflow_size = 42
        f.add_picture(pic)
        f.save()

        # make sure we can read it and save it again
        f = FLAC(self.filename)
        self.assertTrue(f.pictures)
        self.assertEqual(len(f.pictures[0].data), 2 ** 24 - 32)
        f.save()
Exemplo n.º 26
0
    def setImage(self, song):
        audio = FLAC(song.get("~filename", ""))
        ## if file has no images -> leave
        if (audio.pictures is None) or (len(audio.pictures) <= 0):
            return

        ## if first image is frontcover -> leave
        img = audio.pictures[0]
        if img.type == 3:
            return

        ## ok, we have to lookup the data...
        images = list()
        frontcover = None
        for img in audio.pictures:
            if img.type == 3:
                frontcover = img
            else:
                images.append(img)

        ## if file has no frontcover -> leave
        if (frontcover is None):
            print(
                _("No frontcover found in {!s}.").format(
                    song.get("~filename", "")))
            return

        ## first,clear all pictures, then add the frontcover
        try:
            audio.clear_pictures()
            audio.add_picture(frontcover)
        except:
            self.printError()
            return False
        ## now add all other images
        for img in images:
            try:
                audio.add_picture(img)
            except:
                self.printError()
                return False
        audio.save()
        app.window.emit("artwork-changed", [song])
        return
Exemplo n.º 27
0
	def removeImage(self, song):
		audio = FLAC(song.get("~filename", ""))
		store = False
		## if file has no images -> leave
		if (audio.pictures is None) or (len(audio.pictures) <= 0):
			return
		images = list()
		for img in audio.pictures:
			if img.type == self.type \
			and img.desc == self.desc:
				store = True
			else:
				images.append(img)

		if store:
			## first,clear all pictures, then add the frontcover
			try:
				audio.clear_pictures()
			except:
				self.printError()
				return False
			## now add all other images
			for img in images:
				try:
					audio.add_picture(img)
				except:
					self.printError()
					return False
			audio.save()
			## and now count the images
			count = "0"
			## if file has no images -> set to 0
			if (audio.pictures is None) or (len(audio.pictures) <= 0):
				pass
			else:
				count = str(len(audio.pictures))

			if not "pictures" in song:
				song["pictures"] = count

			if song["pictures"] <> count:
				song["pictures"] = count
			app.window.emit("artwork-changed", [song])
		return
Exemplo n.º 28
0
class _FLACWrapper(_AbstractWrapper):
    VALID_TAG_KEYS = ('artwork', 'artist', 'album', 'title', 'genre', )

    def __init__(self, filename):
        _AbstractWrapper.__init__(self)
        self.audio = FLAC(filename)

    def __getattr__(self, attr):
        if attr in self.VALID_TAG_KEYS:
            if attr == 'artwork':
                if self.audio.pictures:
                    picture = self.audio.pictures[0]
                    return Artwork(picture.mime, picture.data)
                else:
                    return None
            else:
                try:
                    return self.audio[attr][0]
                except KeyError:
                    return None
        raise TagError(self, attr)

    def __setattr__(self, attr, value):
        if attr in self.VALID_TAG_KEYS:
            if isinstance(value, Artwork):
                picture = Picture()
                picture.type = 3
                picture.mime = value.mime
                picture.data = value.data
                self.audio.clear_pictures()
                self.audio.add_picture(picture)
            elif isinstance(value, str):
                self.audio[attr] = [value]
            else:
                raise TagValueError(value)
        else:
            object.__setattr__(self, attr, value)

    def __repr__(self):
        return repr(self.audio)

    def save(self):
        self.audio.save()
Exemplo n.º 29
0
    def clearCoverArt(self):
        for fileShortName in os.listdir(self.path):
            fileName = os.path.join(self.path,fileShortName)

            if os.path.isdir(fileName):

                continue
            try:
                metadata = FLAC(fileName)
            except FLACNoHeaderError as (strerror):
                self.log.info("strerror=%s" % ( strerror))
                continue
            except error as E:
                self.log.info("strerror=%s" % ( E))
                continue

            metadata.clear_pictures()
            metadata.save()
            del(metadata)
Exemplo n.º 30
0
	def setImage(self, song):
		audio = FLAC(song.get("~filename", ""))
		## if file has no images -> leave
		if (audio.pictures is None) or (len(audio.pictures) <= 0):
			return

		## if first image is frontcover -> leave
		img = audio.pictures[0]
		if img.type == 3:
			return

		## ok, we have to lookup the data...
		images = list()
		frontcover = None
		for img in audio.pictures:
			if img.type == 3:
				frontcover = img
			else:
				images.append(img)

		## if file has no frontcover -> leave
		if (frontcover is None):
			print(_("No frontcover found in {!s}.").format(song.get("~filename", "")))
			return

		## first,clear all pictures, then add the frontcover
		try:
			audio.clear_pictures()
			audio.add_picture(frontcover)
		except:
			self.printError()
			return False
		## now add all other images
		for img in images:
			try:
				audio.add_picture(img)
			except:
				self.printError()
				return False
		audio.save()
		app.window.emit("artwork-changed", [song])
		return
Exemplo n.º 31
0
def set_tag_info_flac(f_path, tag_info, cover_data=None):
    if tag_info.get('date'):
        tag_info['date'] = tag_info['date'] + 'Z'
    if tag_info.get('tracknumber'):
        tag_info['tracknumber'], tag_info['tracktotal'] = tag_info['tracknumber'].split('/')
    if tag_info.get('discnumber'):
        tag_info['discnumber'], tag_info['disctotal'] = tag_info['discnumber'].split('/')

    audio = FLAC(f_path)
    audio.delete()
    for key in tag_info.keys():
        audio[key] = tag_info[key]
    if cover_data:
        pic = mutagen.flac.Picture()
        pic.mime = 'image/jpeg'
        pic.type = 3
        pic.data = cover_data
        audio.clear_pictures()
        audio.add_picture(pic)
    audio.save()
Exemplo n.º 32
0
    def _tag_flac(self, file):
        """
        Tag Flac file only called from `track.tag()`
        """
        tagger = Tagger(self, '.flac')
        tag = FLAC(file)
        tag.delete()

        for tag_obj in tagger.tag_map:
            tag[tag_obj.key] = str(tag_obj.value)

        # image
        if cc.tag_cover and self.album.picture_url is not None:
            cover_data = self.get_cover_data()
            if cover_data:
                img = Picture()
                img.type = 3
                img.data = cover_data
                tag.clear_pictures()
                tag.add_picture(img)
            else:
                log.warning(f'No Cover for {self}')
        tag.save()
Exemplo n.º 33
0
def reset_flac_tags(full_path):

    f = FLAC(full_path)

    t = f.tags

    # we need to save the 'vendor' string because calling mutagen's delete() removes it too
    for block in list(f.metadata_blocks):
        if isinstance(block, VCFLACDict):
            vendor = block.vendor

    f.clear_pictures()

    f.delete()

    for item in 'artist', 'album', 'tracknumber', 'tracktotal', 'title', 'date':
        if item in t:
            f[item] = t[item]

    for block in list(f.metadata_blocks):
        if isinstance(block, VCFLACDict):
            block.vendor = vendor

    f.save(deleteid3=True)
Exemplo n.º 34
0
def tag(file_path: Path, track: Track) -> None:
    """
    Tag the music file at the given file path using the specified
    [Track][deethon.types.Track] instance.

    Args:
        file_path (Path): The music file to be tagged
        track: The [Track][deethon.types.Track] instance to be used for tagging.
    """
    ext = file_path.suffix

    if ext == ".mp3":
        tags = ID3()
        tags.clear()

        tags.add(Frames["TALB"](encoding=3, text=track.album.title))
        tags.add(Frames["TBPM"](encoding=3, text=str(track.bpm)))
        tags.add(Frames["TCON"](encoding=3, text=track.album.genres))
        tags.add(Frames["TCOP"](encoding=3, text=track.copyright))
        tags.add(Frames["TDAT"](encoding=3,
                                text=track.release_date.strftime("%d%m")))
        tags.add(Frames["TIT2"](encoding=3, text=track.title))
        tags.add(Frames["TPE1"](encoding=3, text=track.artist))
        tags.add(Frames["TPE2"](encoding=3, text=track.album.artist))
        tags.add(Frames["TPOS"](encoding=3, text=str(track.disk_number)))
        tags.add(Frames["TPUB"](encoding=3, text=track.album.label))
        tags.add(Frames["TRCK"](
            encoding=3, text=f"{track.number}/{track.album.total_tracks}"))
        tags.add(Frames["TSRC"](encoding=3, text=track.isrc))
        tags.add(Frames["TYER"](encoding=3, text=str(track.release_date.year)))

        tags.add(Frames["TXXX"](encoding=3,
                                desc="replaygain_track_gain",
                                text=str(track.replaygain_track_gain)))

        if track.lyrics:
            tags.add(Frames["USLT"](encoding=3, text=track.lyrics))

        tags.add(Frames["APIC"](encoding=3,
                                mime="image/jpeg",
                                type=3,
                                desc="Cover",
                                data=track.album.cover_xl))

        tags.save(file_path, v2_version=3)

    else:
        tags = FLAC(file_path)
        tags.clear()
        tags["album"] = track.album.title
        tags["albumartist"] = track.album.artist
        tags["artist"] = track.artist
        tags["bpm"] = str(track.bpm)
        tags["copyright"] = track.copyright
        tags["date"] = track.release_date.strftime("%Y-%m-%d")
        tags["genre"] = track.album.genres
        tags["isrc"] = track.isrc
        if track.lyrics:
            tags["lyrics"] = track.lyrics
        tags["replaygain_track_gain"] = str(track.replaygain_track_gain)
        tags["title"] = track.title
        tags["tracknumber"] = str(track.number)
        tags["year"] = str(track.release_date.year)

        cover = Picture()
        cover.type = 3
        cover.data = track.album.cover_xl
        cover.width = 1000
        cover.height = 1000
        tags.clear_pictures()
        tags.add_picture(cover)
        tags.save(deleteid3=True)
Exemplo n.º 35
0
    print ["Sorry, i need piece of covert art labeled: ", picpath]

p_data = open(picpath).read()
# pic =   Picture(
#        encoding=3, # 3 is for utf-8
#        mime='image/jpeg', # image/jpeg or image/png
#        type=3, # 3 is for the cover image
#        desc=u'Cover',
#        data=p_data
#    )
# apic =   APIC(
#        encoding=3, # 3 is for utf-8
#        mime='image/jpeg', # image/jpeg or image/png
#        type=3, # 3 is for the cover image
#        desc=u'Cover',
#        data=p_data
#    )
pic = Picture()
pic.load(open(picpath))
flaccount = 0
flext = re.compile(".*\.flac")
for f in files:
    if re.search(flext, f) != None:
        flaccount = flaccount + 1
        ftag = FLAC(f)
        ftag.clear_pictures()
        ftag.add_picture(pic)
        ftag.save

exit(0)
Exemplo n.º 36
0
                    artists_str = artists_str[1:]
                    artists.append(artists_str)

                    audio['artist'] = artists
                    audio['album'] = track['al']['name']

                    image = Picture()
                    image.type = 3
                    image.desc = 'front cover'
                    image.mime = 'image/jpeg'
                    image.width = 640
                    image.height = 640
                    image.data = open(cover_file_path, 'rb').read()

                    audio.save()
                    audio.clear_pictures()
                    audio.add_picture(image)
                    log.debug(audio.tags)
                    audio.save()
                except FLACNoHeaderError:
                    log.error('Not a validate FLAC file!')
                    playlist_tracks.append(track)
                    track_error[track['id']] = 1
                    continue
        except Exception as e:
            log.error('Error while adding metadata: ' + str(e))
            playlist_tracks.append(track)
            track_error[track['id']] = 1
            continue

        # delete cover file
Exemplo n.º 37
0
def clear_pictures(filename):
    audio = FLAC(filename)
    audio.clear_pictures()
    audio.save()
    print('  Cleared pictures.')
Exemplo n.º 38
0
            'ffmpeg', '-i', tag_path[i], '-ac', '2', '-acodec', 'flac',
            'tag.flac'
        ]
        try:
            subprocess.check_output(cli_args)
        except:
            print("convert tag flac error")

        # read tag info
        tag_info = FLAC('tag.flac')
        key_list = tag_info.keys()

        # write tag info
        audio_flac = FLAC(flac_path[i])
        audio_flac.clear()
        audio_flac.clear_pictures()
        for key in key_list:
            audio_flac[key] = tag_info[key]

        # write cover image info
        if os.path.exists('./cover.jpg'):
            img = fimg()
            img.type = 3
            img.mime = 'image/jpg'
            img.desc = 'front cover'
            img.colors = 0
            img.data = open('cover.jpg', mode='rb').read()
            audio_flac.add_picture(img)

        # save music info
        audio_flac.save()
Exemplo n.º 39
0
class FileInfo(object):
    """Read and write FLAC metadata.

    Variables:
    - path: The FLAC file.
    - parse_ok: True if the file was parsed successfully.
                If False, most other variables will be None.
    - parse_exception: The exception raised during parsing, or None.
    - streaminfo: The file's StreamInfo.
    - cuesheet: The file's CueSheet.
    - tags: The file's Tags.

    This class supports only one picture per type.
    """

    def __init__(self, path):
        self.path = str(path)
        self.parse()

    @property
    def summary(self):
        """Return a Summary for this FileInfo."""
        return Summary(self)

    def parse(self):
        """Read the FLAC file and update the variables."""
        try:
            self._flac = FLAC(self.path)
            info = self._flac.info
            self.streaminfo = StreamInfo(
                info.channels,
                info.bits_per_sample,
                info.sample_rate,
                info.total_samples
            )
            if self._flac.cuesheet is not None:
                self.cuesheet = CueSheet(self._flac.cuesheet)
            else:
                self.cuesheet = None
            self.tags = Tags(self._flac.tags)
            self.parse_ok = True
            self.parse_exception = None
        except Exception as e:
            self.parse_ok = False
            self.parse_exception = e
            self.streaminfo = None
            self.cuesheet = None
            self.tags = None

    def update(self):
        """Save the current metadata and re-parse the FLAC file."""
        self._flac.save()
        self.parse()

    def pictures(self):
        """Return a tuple of Pictures, or None."""
        if self.parse_ok:
            return tuple(self._picture_m2f(p) for p in self._flac.pictures)
        else:
            return None

    def get_picture(self, type_):
        """Return the Picture of the given type, or None."""
        result = None
        if self.parse_ok:
            matches = [p for p in self._flac.pictures if p.type == type_]
            if matches:
                result = self._picture_m2f(matches[0])
        return result

    def set_picture(self, picture):
        """Set or replace the Picture of its type.

        Returns True if anything changed.
        """
        changed = False
        old = self.get_picture(picture.type)
        if old != picture:
            self.remove_picture(picture.type)
            self._flac.add_picture(self._picture_f2m(picture))
            changed = True
        return changed

    def remove_picture(self, type_):
        """Remove the picture of the given type.

        Returns True if anything changed.
        """
        changed = False
        pics = self._flac.pictures
        keep = [p for p in pics if p.type != type_]
        if len(pics) != len(keep):
            self._flac.clear_pictures()
            for picture in keep:
                self._flac.add_picture(picture)
            changed = True
        return changed

    @staticmethod
    def _picture_m2f(mutagen_picture):
        """Create a Flackup Picture from a Mutagen Picture."""
        return Picture(
            mutagen_picture.type,
            mutagen_picture.mime,
            mutagen_picture.width,
            mutagen_picture.height,
            mutagen_picture.depth,
            mutagen_picture.data
        )

    @staticmethod
    def _picture_f2m(flackup_picture):
        """Create a Mutagen Picture from a Flackup Picture."""
        picture = MutagenPicture()
        picture.type = flackup_picture.type
        picture.mime = flackup_picture.mime
        picture.width = flackup_picture.width
        picture.height = flackup_picture.height
        picture.depth = flackup_picture.depth
        picture.data = flackup_picture.data
        return picture
Exemplo n.º 40
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)
Exemplo n.º 41
0
def flac_tag(flac_dirname, flac_filename, artist, album, track, tracks, title, year, genre, bpms, compilation):
	# Delete existing tags
	id3 = FLAC(flac_filename)
	id3.clear_pictures()
	id3.delete()
	
	# Artist, Composer
	id3["ARTIST"] = artist
	id3["ALBUM_ARTIST"] = artist
	id3["ALBUMARTIST"] = artist
	id3["COMPOSER"] = artist
	
	# Artistsort
	id3["SORT_ARTIST"] = artist
	id3["SORT_COMPOSER"] = artist
	id3["SORT_ALBUM_ARTIST"] = artist
	id3["ARTISTSORT"] = artist
	id3["ALBUMARTISTSORT"] = artist
	id3["COMPOSERSORT"] = artist
	id3["soar"] = artist
	id3["soaa"] = artist
	id3["soco"] = artist
	
	# Album
	id3["ALBUM"] = album
	
	# Albumsort
	id3["SORT_ALBUM"] = album
	id3["ALBUMSORT"] = album
	
	# Track
	id3["TRACKNUMBER"] = tracks
	id3["TRACK"] = tracks
	id3["DISCNUMBER"] = '1/1'
	
	# Title
	id3["TITLE"] = title
	
	# Year
	id3["YEAR_OF_RELEASE"] = year
	id3["DATE"] = year
	
	# Genre
	id3["GENRE"] = genre
	
	# BPMs
	id3["BPM"] = bpms
	id3["tmpo"] = bpms

	# Compilation
	if (compilation):
		id3["COMPILATION"] = '1'
	else:
		id3["COMPILATION"] = '0'
	
	# Cover
	id3.clear_pictures()
	try:
		image = Picture()
		image.data = open(str(flac_dirname + '/Cover.jpg'), 'rb').read()
		image.type = PictureType.COVER_FRONT
		image.mime = "image/jpeg"
		id3.add_picture(image)
	except:
		print("Warning. No Cover.jpg in directory " + flac_dirname + ".")
	
	# Save tags to file
	id3.save(filename=flac_filename, deleteid3=True)
Exemplo n.º 42
0
def set_release_metadata(artist_name, album_name, record_id):
    translation = {'/': '-'}
    table = str.maketrans(translation)
    record = get_local_record_list(artist_name, album_name.translate(table))
    record_dir = record['record_dir']

    try:
        release = musicbrainzngs.get_release_by_id(record_id,
                                                   includes=[
                                                       'recordings',
                                                   ])
        release = release['release']
    except:
        release = musicbrainzngs.get_release_by_id(record_id)
    try:
        album = release['title']
    except KeyError:
        album = 'not defined'
    try:
        date = release['date']
    except KeyError:
        date = 'not defined'
    try:
        country = release['country']
    except KeyError:
        country = 'not defined'
    try:
        mediumtotal = release['medium-count']
    except KeyError:
        mediumtotal = 0

    tracknumber = 1
    for i in range(1, mediumtotal + 1):

        if mediumtotal > 1:
            base_dir = record_dir + f'/CD{i}/'
            base_dir_art = record_dir + '/'
        else:
            base_dir = record_dir + '/'
            base_dir_art = record_dir + '/'

        try:
            pic = Picture()
            with open(f'{base_dir_art}fanart.jpg', "rb") as f:
                pic.data = f.read()
            pic.mime = u"image/jpeg"
            pic.width = 1000
            pic.height = 1000
            pic.depth = 16
        except:
            logger.warning('No Fan Art Available!')

        songs = os.listdir(base_dir)
        for song in songs:
            fullpath = base_dir + song
            extension = pathlib.Path(fullpath).suffix

            if extension == '.flac':
                metadata = FLAC(fullpath)

                for item in metadata.items():
                    if item[0] == 'tracknumber':
                        tracknumber = int(item[1].pop())

                records = filter(lambda x: int(x['position']) == i,
                                 release['medium-list'])
                for recording in records:
                    tracktotal = recording['track-count']
                    for track in recording['track-list']:
                        if int(track['number']) == tracknumber:
                            tracktitle = track['recording']['title'].translate(
                                table)
                            trackid = track['recording']['id']
                            track_musicbrainz = musicbrainzngs.get_recording_by_id(
                                trackid, includes=[
                                    'artists',
                                ])
                            artist = track_musicbrainz['recording'][
                                'artist-credit-phrase']

                metadata.delete()
                metadata.clear_pictures()
                if pic:
                    metadata.add_picture(pic)
                metadata["Album"] = album
                metadata["Albumartist"] = artist_name
                metadata["Artist"] = artist_name
                metadata["Country"] = country
                metadata["Date"] = date
                metadata["Discnumber"] = str(i)
                metadata["Title"] = tracktitle
                metadata["Tracktotal"] = str(tracktotal)
                metadata["Tracknumber"] = str(tracknumber)
                metadata.save()

                logger.info(f'old name: {song}')
                if mediumtotal != 1:
                    logger.info(
                        f'new name: {artist} - {album.translate(table)} - CD{i} - {tracknumber:02} - {tracktitle}.flac'
                    )
                    os.rename(
                        fullpath,
                        f'{base_dir}{artist} - {album.translate(table)} - CD{i} - {tracknumber:02} - {tracktitle}.flac'
                    )
                else:
                    logger.info(
                        f'new name: {artist} - {album.translate(table)} - {tracknumber:02} - {tracktitle}.flac'
                    )
                    os.rename(
                        fullpath,
                        f'{base_dir}{artist} - {album.translate(table)} - {tracknumber:02} - {tracktitle}.flac'
                    )