clean-tags.py: add support for cleaning vorbis comments in FLAC files
This commit is contained in:
parent
51e703e41c
commit
fc8417a670
1 changed files with 64 additions and 4 deletions
|
|
@ -11,6 +11,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from mutagen.id3 import ID3
|
from mutagen.id3 import ID3
|
||||||
|
from mutagen.flac import FLAC
|
||||||
from mutagen import MutagenError
|
from mutagen import MutagenError
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,14 +31,17 @@ class TagCleaner:
|
||||||
them.
|
them.
|
||||||
"""
|
"""
|
||||||
INDENTATION = " "
|
INDENTATION = " "
|
||||||
FILE_EXTENSIONS = ['.mp3']
|
FILE_EXTENSIONS = ['.mp3', '.flac', '.ogg']
|
||||||
TAGS_ID3 = ['TALB', 'TDRC', 'TIT2', 'TPE1', 'TRCK']
|
TAGS_ID3 = ['TALB', 'TDRC', 'TIT2', 'TPE1', 'TRCK']
|
||||||
|
TAGS_VORBIS_COMMENTS = ['ALBUM', 'ARTIST', 'DATE', 'TITLE', 'TRACKNUMBER']
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, folder):
|
def __init__(self, folder):
|
||||||
"""Construct a new tag cleaner instancce."""
|
"""Construct a new tag cleaner instancce."""
|
||||||
self._logger = logging.getLogger(__class__.__name__)
|
self._logger = logging.getLogger(__class__.__name__)
|
||||||
self._dry = False
|
self._dry = False
|
||||||
|
self._id3 = True
|
||||||
|
self._flac = True
|
||||||
self._folder = folder
|
self._folder = folder
|
||||||
self._files = []
|
self._files = []
|
||||||
self._read_files(folder)
|
self._read_files(folder)
|
||||||
|
|
@ -48,6 +52,16 @@ class TagCleaner:
|
||||||
self._dry = dry
|
self._dry = dry
|
||||||
|
|
||||||
|
|
||||||
|
def set_id3(self, do):
|
||||||
|
"""Set whether to clean ID3 tags or not."""
|
||||||
|
self._id3 = do
|
||||||
|
|
||||||
|
|
||||||
|
def set_flac(self, do):
|
||||||
|
"""Set whether to clean FLAC vorbis comments or not."""
|
||||||
|
self._flac = do
|
||||||
|
|
||||||
|
|
||||||
def clean_files(self):
|
def clean_files(self):
|
||||||
"""Clean all found files."""
|
"""Clean all found files."""
|
||||||
self._logger.info("Clean files")
|
self._logger.info("Clean files")
|
||||||
|
|
@ -66,7 +80,7 @@ class TagCleaner:
|
||||||
continue
|
continue
|
||||||
self._logger.debug("Found file \"%s\"", os.path.join(dirname, filename))
|
self._logger.debug("Found file \"%s\"", os.path.join(dirname, filename))
|
||||||
self._files.append(os.path.join(dirname, filename))
|
self._files.append(os.path.join(dirname, filename))
|
||||||
self._logger.info("Found %d files".format(len(self._files)))
|
self._logger.info("Found %d files", len(self._files))
|
||||||
|
|
||||||
|
|
||||||
def _clean_file(self, filename):
|
def _clean_file(self, filename):
|
||||||
|
|
@ -74,7 +88,11 @@ class TagCleaner:
|
||||||
self._logger.info("Clean file \"%s\"", filename)
|
self._logger.info("Clean file \"%s\"", filename)
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
# ID3
|
# ID3
|
||||||
self._clean_id3(filename)
|
if self._id3:
|
||||||
|
self._clean_id3(filename)
|
||||||
|
# FLAC
|
||||||
|
if self._flac:
|
||||||
|
self._clean_flac(filename)
|
||||||
else:
|
else:
|
||||||
self._logger.info("Not a file: \"%s\"", filename)
|
self._logger.info("Not a file: \"%s\"", filename)
|
||||||
|
|
||||||
|
|
@ -136,7 +154,44 @@ class TagCleaner:
|
||||||
else:
|
else:
|
||||||
self._logger.info("Clean, nothing to do")
|
self._logger.info("Clean, nothing to do")
|
||||||
except MutagenError as e:
|
except MutagenError as e:
|
||||||
self._logger.error("Cleaning of ID3 tags failed: %s", e)
|
self._logger.info("Cleaning of ID3 tags failed: %s", e)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_flac(self, filename):
|
||||||
|
"""Clean FLAC vorbis comments."""
|
||||||
|
self._logger.info("Clean FLAC vorbis comments")
|
||||||
|
try:
|
||||||
|
flac = FLAC(filename)
|
||||||
|
invalid_comments = {}
|
||||||
|
if flac.tags:
|
||||||
|
invalid_comments = self._clean_vorbis_comments(flac.tags)
|
||||||
|
# Delete comments
|
||||||
|
if invalid_comments:
|
||||||
|
for key in invalid_comments.keys():
|
||||||
|
print("Delete", key)
|
||||||
|
del flac.tags[key]
|
||||||
|
if not self._dry:
|
||||||
|
flac.save()
|
||||||
|
print("File saved")
|
||||||
|
else:
|
||||||
|
print("File not saved (running in dry mode)")
|
||||||
|
else:
|
||||||
|
self._logger.info("Clean, nothing to do")
|
||||||
|
except MutagenError as e:
|
||||||
|
self._logger.info("Cleaning of FLAC vorbis comments failed: %s", e)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_vorbis_comments(self, comments):
|
||||||
|
invalid_comments = {}
|
||||||
|
for key, value in comments:
|
||||||
|
if key not in TagCleaner.TAGS_VORBIS_COMMENTS:
|
||||||
|
invalid_comments[key] = value
|
||||||
|
if invalid_comments:
|
||||||
|
print("Unwanted comments:")
|
||||||
|
for key in invalid_comments.keys():
|
||||||
|
print("{}{}: {}".format(TagCleaner.INDENTATION, key, invalid_comments[key]))
|
||||||
|
|
||||||
|
return invalid_comments
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -147,7 +202,10 @@ if __name__ == "__main__":
|
||||||
parser.add_argument('-d', '--dry', dest='dry', action='store_true', default=False, help="dry run, do not modify any file, just print information")
|
parser.add_argument('-d', '--dry', dest='dry', action='store_true', default=False, help="dry run, do not modify any file, just print information")
|
||||||
parser.add_argument('-v', '--verbose', dest='verbosity', action='count', default=0, help="be verbose, show more information")
|
parser.add_argument('-v', '--verbose', dest='verbosity', action='count', default=0, help="be verbose, show more information")
|
||||||
parser.add_argument('-l', '--logfile', dest='logfile', help="specify name of logfile")
|
parser.add_argument('-l', '--logfile', dest='logfile', help="specify name of logfile")
|
||||||
|
parser.add_argument('--no-id3', dest='id3', action='store_false', help="disable cleaning of ID3 tags")
|
||||||
|
parser.add_argument('--no-fac', dest='flac', action='store_false', help="disable cleaning of FLAC vorbis comments")
|
||||||
parser.add_argument('folder', help="source folder to read audio files from")
|
parser.add_argument('folder', help="source folder to read audio files from")
|
||||||
|
parser.set_defaults(id3=True, flac=True)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Setup logging
|
# Setup logging
|
||||||
|
|
@ -160,6 +218,8 @@ if __name__ == "__main__":
|
||||||
# Create tag cleaner instance
|
# Create tag cleaner instance
|
||||||
tag_cleaner = TagCleaner(args.folder)
|
tag_cleaner = TagCleaner(args.folder)
|
||||||
tag_cleaner.set_dry(args.dry)
|
tag_cleaner.set_dry(args.dry)
|
||||||
|
tag_cleaner.set_id3(args.id3)
|
||||||
|
tag_cleaner.set_flac(args.flac)
|
||||||
|
|
||||||
# Run action
|
# Run action
|
||||||
tag_cleaner.clean_files()
|
tag_cleaner.clean_files()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue