PICARD-2685: Preserve calculated AcoustID and ReplayGain tags

Preserve calculated AcoustID fingerprint and ReplayGain tags set on a file
object when that file object gets moved between tracks.
This commit is contained in:
Philipp Wolfer
2023-07-24 15:51:59 +02:00
parent c9e728f97d
commit 112e0d885e
3 changed files with 36 additions and 8 deletions

View File

@@ -98,7 +98,10 @@ from picard.util.filenaming import (
)
from picard.util.preservedtags import PreservedTags
from picard.util.scripttofilename import script_to_filename_with_metadata
from picard.util.tags import PRESERVED_TAGS
from picard.util.tags import (
CALCULATED_TAGS,
PRESERVED_TAGS,
)
from picard.ui.item import Item
@@ -305,9 +308,14 @@ class File(QtCore.QObject, Item):
to_metadata[info] = from_metadata[info]
def copy_metadata(self, metadata, preserve_deleted=True):
acoustid = self.metadata["acoustid_id"]
saved_metadata = {}
# Keep current value for special tags that got calculated from audio content
for tag in CALCULATED_TAGS:
if tag not in metadata.deleted_tags and self.metadata[tag]:
saved_metadata[tag] = self.metadata[tag]
# Keep original values of preserved tags
preserved_tags = PreservedTags()
for tag, values in self.orig_metadata.rawitems():
if tag in preserved_tags or tag in PRESERVED_TAGS:
@@ -321,8 +329,6 @@ class File(QtCore.QObject, Item):
del self.metadata[tag]
self.metadata.update(saved_metadata)
if acoustid and "acoustid_id" not in metadata.deleted_tags:
self.metadata["acoustid_id"] = acoustid
if images_changed:
self.metadata_images_changed.emit()

View File

@@ -3,7 +3,7 @@
# Picard, the next-generation MusicBrainz tagger
#
# Copyright (C) 2007-2008, 2011 Lukáš Lalinský
# Copyright (C) 2008-2009, 2018-2021 Philipp Wolfer
# Copyright (C) 2008-2009, 2018-2021, 2023 Philipp Wolfer
# Copyright (C) 2011 Johannes Weißl
# Copyright (C) 2011-2013 Michael Wiencek
# Copyright (C) 2012 Chad Wilson
@@ -144,6 +144,23 @@ PRESERVED_TAGS = (
'~video',
)
# Tags that got generated in some way from the audio content.
# Those can be set by Picard but the new values usually should be kept
# when moving the file between tags.
CALCULATED_TAGS = {
'acoustid_fingerprint',
'acoustid_id',
'replaygain_album_gain',
'replaygain_album_peak',
'replaygain_album_range',
'replaygain_reference_loudness',
'replaygain_track_gain',
'replaygain_track_peak',
'replaygain_track_range',
'r128_album_gain',
'r128_track_gain',
}
def display_tag_name(name):
if ':' in name:

View File

@@ -38,6 +38,7 @@ from picard.const.sys import (
)
from picard.file import File
from picard.metadata import Metadata
from picard.util.tags import CALCULATED_TAGS
class DataObjectTest(PicardTestCase):
@@ -671,11 +672,15 @@ class FileCopyMetadataTest(PicardTestCase):
self.assertEqual(self.file.metadata, new_metadata)
self.assertEqual(self.file.metadata.deleted_tags, {'foo'})
def test_copy_metadata_must_not_clear_acoustid_id(self):
self.file.metadata['acoustid_id'] = 'foo'
def test_copy_metadata_must_keep_file_content_specific_tags(self):
for tag in CALCULATED_TAGS:
self.file.metadata[tag] = 'foo'
new_metadata = Metadata()
self.file.copy_metadata(new_metadata)
self.assertEqual(self.file.metadata['acoustid_id'], 'foo')
for tag in CALCULATED_TAGS:
self.assertEqual(
self.file.metadata[tag], 'foo',
f'Tag {tag}: {self.file.metadata[tag]!r} != "foo"')
def test_copy_metadata_must_remove_deleted_acoustid_id(self):
self.file.metadata['acoustid_id'] = 'foo'