diff --git a/picard/plugins/picardmutagen/__init__.py b/picard/plugins/picardmutagen/__init__.py index 4d37bd14e..f35d18cff 100644 --- a/picard/plugins/picardmutagen/__init__.py +++ b/picard/plugins/picardmutagen/__init__.py @@ -17,50 +17,58 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -"""Collection of Mutagen-based metadata readers.""" - -from picard.component import Component, implements from picard.api import IFileOpener +from picard.component import Component, implements from picard.plugins.picardmutagen.asf import MutagenASFFile from picard.plugins.picardmutagen.mp3 import MutagenMP3File -from picard.plugins.picardmutagen.vorbis import MutagenOggVorbisFile -from picard.plugins.picardmutagen.musepack import MutagenMusepackFile -from picard.plugins.picardmutagen.optimfrog import MutagenOptimFROGFile -from picard.plugins.picardmutagen.wavpack import MutagenWavPackFile -from picard.plugins.picardmutagen.mac import MutagenMACFile +from picard.plugins.picardmutagen.apev2 import ( + MonkeysAudioFile, + MusepackFile, + OptimFROGFile, + WavPackFile, + ) +from picard.plugins.picardmutagen.vorbis import ( + FLACFile, + OggFLACFile, + OggSpeexFile, + OggTheoraFile, + OggVorbisFile, + ) class MutagenComponent(Component): implements(IFileOpener) - # IFileOpener - - _supported_formats = { - u".mp3": (MutagenMP3File, u"MPEG Layer-3"), - u".ogg": (MutagenOggVorbisFile, u"Ogg Vorbis"), - u".mpc": (MutagenMusepackFile, u"Musepack"), - u".wma": (MutagenASFFile, u"Windows Media Audio"), - u".wmv": (MutagenASFFile, u"Windows Media Video"), - u".asf": (MutagenASFFile, u"ASF"), - u".ofr": (MutagenOptimFROGFile, u"OptimFROG Lossless Audio"), - u".ofs": (MutagenOptimFROGFile, u"OptimFROG DualStream Audio"), - u".wv": (MutagenWavPackFile, u"WavPack"), - u".ape": (MutagenMACFile, u"Monkey's Audio"), + __supported_formats = { + ".mp3": (MutagenMP3File, "MPEG Layer-3"), + ".mpc": (MusepackFile, "Musepack"), + ".wma": (MutagenASFFile, "Windows Media Audio"), + ".wmv": (MutagenASFFile, "Windows Media Video"), + ".asf": (MutagenASFFile, "ASF"), + ".ofr": (OptimFROGFile, "OptimFROG Lossless Audio"), + ".ofs": (OptimFROGFile, "OptimFROG DualStream Audio"), + ".wv": (WavPackFile, "WavPack"), + ".ape": (MonkeysAudioFile, "Monkey's Audio"), + ".flac": (FLACFile, "FLAC"), + ".oggflac": (OggFLACFile, "Ogg FLAC"), + ".spx": (OggSpeexFile, "Ogg Speex"), + ".oggx": (OggVorbisFile, "Ogg Vorbis"), } def get_supported_formats(self): - return [(key, value[1]) for key, value in self._supported_formats.items()] + return [(key, value[1]) for key, value in + self.__supported_formats.items()] def can_open_file(self, filename): - for ext in self._supported_formats.keys(): + for ext in self.__supported_formats.keys(): if filename.lower().endswith(ext): return True return False def open_file(self, filename): - for ext in self._supported_formats.keys(): + for ext in self.__supported_formats.keys(): if filename.lower().endswith(ext): - file = self._supported_formats[ext][0](filename) + file = self.__supported_formats[ext][0](filename) file.read() return (file,) return None diff --git a/picard/plugins/picardmutagen/_apev2.py b/picard/plugins/picardmutagen/_apev2.py deleted file mode 100644 index ee126956e..000000000 --- a/picard/plugins/picardmutagen/_apev2.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Picard, the next-generation MusicBrainz tagger -# Copyright (C) 2006 Lukáš Lalinský -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -from picard.util import sanitize_date - -_translate = { - "Album Artist": "albumartist" -} - -def read_apev2_tags(tags, metadata): - for name, values in tags.items(): - value = ";".join(values) - if name == "Year": - name = "date" - value = sanitize_date(value) - elif name == "Track": - name = "tracknumber" - track = value.split("/") - if len(track) > 1: - metadata["totaltracks"] = track[1] - value = track[0] - elif name in _translate: - name = _translate[name] - else: - name = name.lower() - metadata[name] = value - -def write_apev2_tags(tags, metadata): - pass diff --git a/picard/plugins/picardmutagen/apev2.py b/picard/plugins/picardmutagen/apev2.py new file mode 100644 index 000000000..aa91c5149 --- /dev/null +++ b/picard/plugins/picardmutagen/apev2.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# +# Picard, the next-generation MusicBrainz tagger +# Copyright (C) 2006 Lukáš Lalinský +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +import mutagen.apev2 +import mutagen.musepack +import mutagen.wavpack +import mutagenext.optimfrog +from picard.file import File +from picard.util import encode_filename, sanitize_date + +class APEv2File(File): + """Generic APEv2-based file.""" + _File = None + + __translate = { + "Album Artist": "albumartist", + } + + def read(self): + file = self._File(encode_filename(self.filename)) + if file.tags: + for name, value in file.tags.items(): + value = ";".join(value) + if name == "Year": + name = "date" + value = sanitize_date(value) + elif name == "Track": + name = "tracknumber" + track = value.split("/") + if len(track) > 1: + self.metadata["totaltracks"] = track[1] + value = track[0] + elif name in self.__translate: + name = self.__translate[name] + else: + name = name.lower() + self.metadata[name] = value + self.metadata["~#length"] = int(file.info.length * 1000) + self.orig_metadata.copy(self.metadata) + + def save(self): + """Save metadata to the file.""" + try: + tags = mutagen.apev2.APEv2(encode_filename(self.filename)) + except mutagen.apev2.APENoHeaderError: + tags = mutagen.apev2.APEv2() + for name, value in self.metadata.items(): + if name.startswith("~"): + continue + if name == "date": + name = "Year" + elif name == "totaltracks": + pass + elif name == "tracknumber": + name = "Track" + totaltracks = self.metadata["totaltracks"] + if totaltracks: + value = "%s/%s" % (value, totaltracks) + elif name == "albumartist": + name = "Album Artist" + else: + name = name.title() + tags[name] = value + tags.save(encode_filename(self.filename)) + +class MusepackFile(APEv2File): + """Musepack file.""" + _File = mutagen.musepack.Musepack + +class WavPackFile(APEv2File): + """WavPack file.""" + _File = mutagen.wavpack.WavPack + +class OptimFROGFile(APEv2File): + """OptimFROG file.""" + _File = mutagenext.optimfrog.OptimFROG + +class MonkeysAudioFile(APEv2File): + """Monkey's Audio file.""" + _File = mutagen.apev2.APEv2File + diff --git a/picard/plugins/picardmutagen/mac.py b/picard/plugins/picardmutagen/mac.py deleted file mode 100644 index 1d7c3d5e6..000000000 --- a/picard/plugins/picardmutagen/mac.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Picard, the next-generation MusicBrainz tagger -# Copyright (C) 2006 Lukáš Lalinský -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -"""Mutagen-based Ogg Vorbis metadata reader.""" - -from picard.file import File -from picard.util import encode_filename -from mutagen.apev2 import APEv2 -from picard.plugins.picardmutagen._apev2 import read_apev2_tags, \ - write_apev2_tags - -class MutagenMACFile(File): - - def read(self): - """Load metadata from the file.""" - - mpcfile = APEv2(encode_filename(self.filename)) - - metadata = self.orig_metadata - read_apev2_tags(mpcfile, metadata) - - #metadata["~#length"] = int(mpcfile.info.length * 1000) - #metadata["~#bitrate"] = mpcfile.info.bitrate - - self.metadata.copy(self.orig_metadata) - - def save(self): - apev2 = APEv2(encode_filename(self.filename)) - write_apev2_tags(apev2, self.metadata) - apev2.save() - diff --git a/picard/plugins/picardmutagen/musepack.py b/picard/plugins/picardmutagen/musepack.py deleted file mode 100644 index 28e598c89..000000000 --- a/picard/plugins/picardmutagen/musepack.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Picard, the next-generation MusicBrainz tagger -# Copyright (C) 2006 Lukáš Lalinský -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -"""Mutagen-based Ogg Vorbis metadata reader.""" - -from picard.file import File -from picard.util import encode_filename -from mutagen.musepack import Musepack -from mutagen.apev2 import APEv2 -from picard.plugins.picardmutagen._apev2 import read_apev2_tags, \ - write_apev2_tags - -class MutagenMusepackFile(File): - - def read(self): - """Load metadata from the file.""" - - mpcfile = Musepack(encode_filename(self.filename)) - - metadata = self.orig_metadata - read_apev2_tags(mpcfile.tags, metadata) - - metadata["~#length"] = int(mpcfile.info.length * 1000) - metadata["~#bitrate"] = mpcfile.info.bitrate - - self.metadata.copy(self.orig_metadata) - - def save(self): - apev2 = APEv2(encode_filename(self.filename)) - write_apev2_tags(apev2, self.metadata) - apev2.save() - diff --git a/picard/plugins/picardmutagen/optimfrog.py b/picard/plugins/picardmutagen/optimfrog.py deleted file mode 100644 index 73b5709ef..000000000 --- a/picard/plugins/picardmutagen/optimfrog.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Picard, the next-generation MusicBrainz tagger -# Copyright (C) 2006 Lukáš Lalinský -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -"""Mutagen-based OptimFROG metadata reader.""" - -from picard.file import File -from picard.util import encode_filename -from mutagenext.optimfrog import OptimFROG -from mutagen.apev2 import APEv2 -from picard.plugins.picardmutagen._apev2 import read_apev2_tags, \ - write_apev2_tags - -class MutagenOptimFROGFile(File): - - def read(self): - """Load metadata from the file.""" - - ofrfile = OptimFROG(encode_filename(self.filename)) - - metadata = self.orig_metadata - read_apev2_tags(ofrfile.tags, metadata) - - metadata["~#length"] = int(ofrfile.info.length * 1000) - metadata["~#bitrate"] = ofrfile.info.bitrate - - self.metadata.copy(self.orig_metadata) - - def save(self): - apev2 = APEv2(encode_filename(self.filename)) - write_apev2_tags(apev2, self.metadata) - apev2.save() - diff --git a/picard/plugins/picardmutagen/vorbis.py b/picard/plugins/picardmutagen/vorbis.py index 22a9595f3..9e5fe103a 100644 --- a/picard/plugins/picardmutagen/vorbis.py +++ b/picard/plugins/picardmutagen/vorbis.py @@ -17,42 +17,53 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -"""Mutagen-based Ogg Vorbis metadata reader.""" - +import mutagen.flac +import mutagen.oggflac +import mutagen.oggspeex +import mutagen.oggtheora +import mutagen.oggvorbis from picard.file import File from picard.util import encode_filename, sanitize_date -from mutagen.oggvorbis import OggVorbis -class MutagenOggVorbisFile(File): +class VCommentFile(File): + """Generic VComment-based file.""" + _File = None def read(self): - """Load metadata from the file.""" - - mfile = OggVorbis(encode_filename(self.filename)) - - metadata = self.orig_metadata - for name, values in mfile.items(): + file = self._File(encode_filename(self.filename)) + for name, values in file.tags.items(): value = ";".join(values) if name == "date": value = sanitize_date(value) - metadata[name] = value - - metadata["~#length"] = int(mfile.info.length * 1000) - metadata["~#bitrate"] = mfile.info.bitrate - - self.metadata.copy(self.orig_metadata) + self.metadata[name] = value + self.metadata["~#length"] = int(file.info.length * 1000) + self.orig_metadata.copy(self.metadata) def save(self): """Save metadata to the file.""" - - mfile = OggVorbis(encode_filename(self.filename)) - + file = self._File(encode_filename(self.filename)) for name, value in self.metadata.items(): if not name.startswith("~"): - mfile[name] = value + file.tags[name] = value + file.save() - mfile.save() +class FLACFile(VCommentFile): + """FLAC file.""" + _File = mutagen.flac.FLAC - self.orig_metadata.copy(self.metadata) - self.metadata.set_changed(False) +class OggFLACFile(VCommentFile): + """FLAC file.""" + _File = mutagen.oggflac.OggFLAC + +class OggSpeexFile(VCommentFile): + """Ogg Speex file.""" + _File = mutagen.oggspeex.OggSpeex + +class OggTheoraFile(VCommentFile): + """Ogg Theora file.""" + _File = mutagen.oggtheora.OggTheora + +class OggVorbisFile(VCommentFile): + """Ogg Vorbis file.""" + _File = mutagen.oggvorbis.OggVorbis diff --git a/picard/plugins/picardmutagen/wavpack.py b/picard/plugins/picardmutagen/wavpack.py deleted file mode 100644 index c945800d1..000000000 --- a/picard/plugins/picardmutagen/wavpack.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Picard, the next-generation MusicBrainz tagger -# Copyright (C) 2006 Lukáš Lalinský -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -"""Mutagen-based WavPack metadata reader.""" - -from picard.file import File -from picard.util import encode_filename -from mutagen.wavpack import WavPack -from mutagen.apev2 import APEv2 -from picard.plugins.picardmutagen._apev2 import read_apev2_tags, \ - write_apev2_tags - -class MutagenWavPackFile(File): - - def read(self): - """Load metadata from the file.""" - - mpcfile = WavPack(encode_filename(self.filename)) - - metadata = self.orig_metadata - read_apev2_tags(mpcfile.tags, metadata) - - metadata["~#length"] = int(mpcfile.info.length * 1000) - - self.metadata.copy(self.orig_metadata) - - def save(self): - apev2 = APEv2(encode_filename(self.filename)) - write_apev2_tags(apev2, self.metadata) - apev2.save() -