mirror of
https://github.com/fergalmoran/picard.git
synced 2026-02-23 08:06:46 +00:00
PICARD-1592: Preserve case for APEv2 tags
When reading APEv2 tags case insensitive, preserve existing casing.
This commit is contained in:
@@ -112,21 +112,26 @@ class APEv2File(File):
|
||||
}
|
||||
__rtranslate = dict([(v.lower(), k) for k, v in __translate.items()])
|
||||
|
||||
def __init__(self, filename):
|
||||
super().__init__(filename)
|
||||
self.__casemap = {}
|
||||
|
||||
def _load(self, filename):
|
||||
log.debug("Loading file %r", filename)
|
||||
self.__casemap = {}
|
||||
file = self._File(encode_filename(filename))
|
||||
metadata = Metadata()
|
||||
if file.tags:
|
||||
for origname, values in file.tags.items():
|
||||
origname = origname.lower()
|
||||
name_lower = origname.lower()
|
||||
if (values.kind == mutagen.apev2.BINARY
|
||||
and origname.startswith("cover art")):
|
||||
and name_lower.startswith("cover art")):
|
||||
if b'\0' in values.value:
|
||||
descr, data = values.value.split(b'\0', 1)
|
||||
try:
|
||||
coverartimage = TagCoverArtImage(
|
||||
file=filename,
|
||||
tag=origname,
|
||||
tag=name_lower,
|
||||
data=data,
|
||||
)
|
||||
except CoverArtImageError as e:
|
||||
@@ -139,7 +144,7 @@ class APEv2File(File):
|
||||
if values.kind != mutagen.apev2.TEXT:
|
||||
continue
|
||||
for value in values:
|
||||
name = origname
|
||||
name = name_lower
|
||||
if name == "year":
|
||||
name = "date"
|
||||
value = sanitize_date(value)
|
||||
@@ -164,6 +169,7 @@ class APEv2File(File):
|
||||
value = value[:start]
|
||||
elif name in self.__rtranslate:
|
||||
name = self.__rtranslate[name]
|
||||
self.__casemap[name] = origname
|
||||
metadata.add(name, value)
|
||||
self._info(metadata, file)
|
||||
return metadata
|
||||
@@ -238,7 +244,9 @@ class APEv2File(File):
|
||||
del tags[real_name]
|
||||
|
||||
def _get_tag_name(self, name):
|
||||
if name.startswith('lyrics:'):
|
||||
if name in self.__casemap:
|
||||
return self.__casemap[name]
|
||||
elif name.startswith('lyrics:'):
|
||||
return 'Lyrics'
|
||||
elif name == 'date':
|
||||
return 'Year'
|
||||
|
||||
@@ -87,6 +87,25 @@ class CommonApeTests:
|
||||
self._read_case_insensitive_tag('tracknumber', 'Track')
|
||||
self._read_case_insensitive_tag('discnumber', 'Disc')
|
||||
|
||||
@skipUnlessTestfile
|
||||
def test_ci_tags_preserve_case(self):
|
||||
# Ensure values are not duplicated on repeated save and are saved
|
||||
# case preserving.
|
||||
for name in ('CUStom', 'ARtist'):
|
||||
tags = {}
|
||||
tags[name] = 'foo'
|
||||
save_raw(self.filename, tags)
|
||||
loaded_metadata = load_metadata(self.filename)
|
||||
loaded_metadata[name.lower()] = 'bar'
|
||||
save_metadata(self.filename, loaded_metadata)
|
||||
raw_metadata = dict(load_raw(self.filename))
|
||||
self.assertIn(name, raw_metadata)
|
||||
self.assertEqual(
|
||||
raw_metadata[name],
|
||||
loaded_metadata[name.lower()])
|
||||
self.assertEqual(1, len(raw_metadata[name]))
|
||||
self.assertNotIn(name.upper(), raw_metadata)
|
||||
|
||||
def _read_case_insensitive_tag(self, name, ape_name):
|
||||
upper_ape_name = ape_name.upper()
|
||||
metadata = {
|
||||
@@ -97,7 +116,7 @@ class CommonApeTests:
|
||||
self.assertEqual(metadata[upper_ape_name], loaded_metadata[name])
|
||||
save_metadata(self.filename, loaded_metadata)
|
||||
raw_metadata = load_raw(self.filename)
|
||||
self.assertIn(ape_name, raw_metadata.keys())
|
||||
self.assertIn(upper_ape_name, raw_metadata.keys())
|
||||
self.assertEqual(metadata[upper_ape_name], raw_metadata[ape_name])
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user