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