1# -*- coding: utf-8 -*- 2 3PLUGIN_NAME = u"Compatible TXXX frames" 4PLUGIN_AUTHOR = u'Tungol' 5PLUGIN_DESCRIPTION = """This plugin improves the compatibility of ID3 tags \ 6by using only a single value for TXXX frames. Multiple value TXXX frames \ 7technically don't comply with the ID3 specification.""" 8PLUGIN_VERSION = "0.1" 9PLUGIN_API_VERSIONS = ["2.0"] 10PLUGIN_LICENSE = "GPL-2.0-or-later" 11PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html" 12 13from picard import config 14from picard.formats import register_format 15from picard.formats.id3 import MP3File, TrueAudioFile, DSFFile, AiffFile 16from mutagen import id3 17 18 19id3v24_join_with = '; ' 20 21 22def build_compliant_TXXX(self, encoding, desc, values): 23 """Return a TXXX frame with only a single value. 24 25 Use id3v23_join_with as the sperator if using id3v2.3, otherwise the value 26 set in this plugin (default "; "). 27 """ 28 if config.setting['write_id3v23']: 29 sep = config.setting['id3v23_join_with'] 30 else: 31 sep = id3v24_join_with 32 joined_values = [sep.join(values)] 33 return id3.TXXX(encoding=encoding, desc=desc, text=joined_values) 34 35 36# I can't actually remove the original MP3File et al formats once they're 37# registered. This depends on the name of the replacements sorting after the 38# name of the originals, because picard.formats.guess_format picks the last 39# item from a sorted list. 40 41 42class MP3FileCompliant(MP3File): 43 """Alternate MP3 format class which uses single-value TXXX frames.""" 44 45 build_TXXX = build_compliant_TXXX 46 47 48class TrueAudioFileCompliant(TrueAudioFile): 49 """Alternate TTA format class which uses single-value TXXX frames.""" 50 51 build_TXXX = build_compliant_TXXX 52 53 54class DSFFileCompliant(DSFFile): 55 """Alternate DSF format class which uses single-value TXXX frames.""" 56 57 build_TXXX = build_compliant_TXXX 58 59 60class AiffFileCompliant(AiffFile): 61 """Alternate AIFF format class which uses single-value TXXX frames.""" 62 63 build_TXXX = build_compliant_TXXX 64 65 66register_format(MP3FileCompliant) 67register_format(TrueAudioFileCompliant) 68register_format(DSFFileCompliant) 69register_format(AiffFileCompliant) 70