From 43adf4226a6d381cf121ad5871b9237af57c58af Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Mon, 13 Sep 2010 08:18:09 +0100 Subject: [PATCH] Rationalize how smart_update knows what to do. Introduced 2 more metadata groups. One is the list of attributes that smart_update is to process specially. The other is the list of attributes that are to be copied if not none (what you called SPECIAL_FIELDS). These two help keep the replace and merge branches in sync. --- src/calibre/ebooks/metadata/book/__init__.py | 17 ++++++++++----- src/calibre/ebooks/metadata/book/base.py | 23 ++++++++++++-------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/calibre/ebooks/metadata/book/__init__.py b/src/calibre/ebooks/metadata/book/__init__.py index 84a88606f2..e087f8072d 100644 --- a/src/calibre/ebooks/metadata/book/__init__.py +++ b/src/calibre/ebooks/metadata/book/__init__.py @@ -101,16 +101,23 @@ STANDARD_METADATA_FIELDS = SOCIAL_METADATA_FIELDS.union( DEVICE_METADATA_FIELDS).union( CALIBRE_METADATA_FIELDS) +# Metadata fields that smart update must do special processing to copy. + +SC_FIELDS_NOT_COPIED = frozenset(['title', 'title_sort', 'authors', + 'author_sort', 'author_sort_map', + 'cover_data', 'tags', 'language']) + +# Metadata fields that smart update should copy only if the source is not None +SC_FIELDS_COPY_NOT_NULL = frozenset(['lpath', 'size', 'comments', 'thumbnail']) + # Metadata fields that smart update should copy without special handling -COPYABLE_METADATA_FIELDS = SOCIAL_METADATA_FIELDS.union( +SC_COPYABLE_FIELDS = SOCIAL_METADATA_FIELDS.union( PUBLICATION_METADATA_FIELDS).union( BOOK_STRUCTURE_FIELDS).union( DEVICE_METADATA_FIELDS).union( CALIBRE_METADATA_FIELDS) - \ - frozenset(['title', 'title_sort', 'authors', - 'author_sort', 'author_sort_map' 'comments', - 'cover_data', 'tags', 'language', 'lpath', - 'size', 'thumbnail']) + SC_FIELDS_NOT_COPIED.union( + SC_FIELDS_COPY_NOT_NULL) SERIALIZABLE_FIELDS = SOCIAL_METADATA_FIELDS.union( USER_METADATA_FIELDS).union( diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index 7812f81180..8538ed886c 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -9,7 +9,8 @@ import copy import traceback from calibre import prints -from calibre.ebooks.metadata.book import COPYABLE_METADATA_FIELDS +from calibre.ebooks.metadata.book import SC_COPYABLE_FIELDS +from calibre.ebooks.metadata.book import SC_FIELDS_COPY_NOT_NULL from calibre.ebooks.metadata.book import STANDARD_METADATA_FIELDS from calibre.ebooks.metadata.book import TOP_LEVEL_CLASSIFIERS from calibre.utils.date import isoformat, format_date @@ -223,22 +224,23 @@ class Metadata(object): self.author_sort = other.author_sort if replace_metadata: - SPECIAL_FIELDS = frozenset(['lpath', 'size', 'comments', 'thumbnail']) - for attr in COPYABLE_METADATA_FIELDS: + # SPECIAL_FIELDS = frozenset(['lpath', 'size', 'comments', 'thumbnail']) + for attr in SC_COPYABLE_FIELDS: setattr(self, attr, getattr(other, attr, 1.0 if \ attr == 'series_index' else None)) self.tags = other.tags self.cover_data = getattr(other, 'cover_data', - NULL_VALUES['cover_data']) + NULL_VALUES['cover_data']) self.set_all_user_metadata(other.get_all_user_metadata(make_copy=True)) - for x in SPECIAL_FIELDS: + for x in SC_FIELDS_COPY_NOT_NULL: copy_not_none(self, other, x) # language is handled below else: - for attr in COPYABLE_METADATA_FIELDS: - if hasattr(other, attr): - copy_not_none(self, other, attr) - copy_not_none(self, other, 'thumbnail') + for attr in SC_COPYABLE_FIELDS: + copy_not_none(self, other, attr) + for x in SC_FIELDS_COPY_NOT_NULL: + copy_not_none(self, other, x) + if other.tags: # Case-insensitive but case preserving merging lotags = [t.lower() for t in other.tags] @@ -249,6 +251,7 @@ class Metadata(object): oidx = lotags.index(t) self.tags[sidx] = other.tags[oidx] self.tags += [t for t in other.tags if t.lower() in ot-st] + if getattr(other, 'cover_data', False): other_cover = other.cover_data[-1] self_cover = self.cover_data[-1] if self.cover_data else '' @@ -256,6 +259,7 @@ class Metadata(object): if not other_cover: other_cover = '' if len(other_cover) > len(self_cover): self.cover_data = other.cover_data + if getattr(other, 'user_metadata_keys', None): for x in other.user_metadata_keys: meta = other.get_user_metadata(x, make_copy=True) @@ -274,6 +278,7 @@ class Metadata(object): self_tags[sidx] = other.tags[oidx] self_tags += [t for t in other.tags if t.lower() in ot-st] setattr(self, x, self_tags) + my_comments = getattr(self, 'comments', '') other_comments = getattr(other, 'comments', '') if not my_comments: