From fc7016596925586eea7f272f73e9524d4d699a77 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Wed, 5 Aug 2020 09:19:44 +0100 Subject: [PATCH] When updating an OPF, remove custom columns from the target that don't exist in the source --- src/calibre/ebooks/metadata/book/base.py | 13 +++++++++++++ src/calibre/ebooks/metadata/opf2.py | 1 + src/calibre/ebooks/metadata/opf3.py | 1 + 3 files changed, 15 insertions(+) diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index b8f85dc05b..ecf924ac9b 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -436,6 +436,19 @@ class Metadata(object): _data = object.__getattribute__(self, '_data') _data['user_metadata'][field] = m + def remove_stale_user_metadata(self, other_mi): + ''' + Remove user metadata keys (custom column keys) if they + don't exist in 'other_mi', which must be a metadata object + ''' + me = self.get_all_user_metadata(make_copy=False) + other = set(other_mi.custom_field_keys()) + new = {} + for k,v in me.items(): + if k in other: + new[k] = v + self.set_all_user_metadata(new) + def template_to_attribute(self, other, ops): ''' Takes a list [(src,dest), (src,dest)], evaluates the template in the diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 9aeee85ed7..aaa4734851 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -1312,6 +1312,7 @@ class OPF(object): # {{{ if apply_null or langs: self.languages = langs or [] temp = self.to_book_metadata() + temp.remove_stale_user_metadata(mi) temp.smart_update(mi, replace_metadata=replace_metadata) if not replace_metadata and callable(getattr(temp, 'custom_field_keys', None)): # We have to replace non-null fields regardless of the value of diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py index 509f45b669..e181d2fdfd 100644 --- a/src/calibre/ebooks/metadata/opf3.py +++ b/src/calibre/ebooks/metadata/opf3.py @@ -1066,6 +1066,7 @@ def apply_metadata(root, mi, cover_prefix='', cover_data=None, apply_null=False, set_application_id(root, prefixes, refines, mi.application_id) if mi.uuid: set_uuid(root, prefixes, refines, mi.uuid) + current_mi.remove_stale_user_metadata(mi) new_user_metadata, current_user_metadata = mi.get_all_user_metadata(True), current_mi.get_all_user_metadata(True) missing = object() for key in tuple(new_user_metadata):