mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Make Metadata smart update handle classifiers correctly
This commit is contained in:
parent
3941b9c4a1
commit
4ae7a3b8c9
@ -104,7 +104,8 @@ STANDARD_METADATA_FIELDS = SOCIAL_METADATA_FIELDS.union(
|
||||
|
||||
SC_FIELDS_NOT_COPIED = frozenset(['title', 'title_sort', 'authors',
|
||||
'author_sort', 'author_sort_map',
|
||||
'cover_data', 'tags', 'language'])
|
||||
'cover_data', 'tags', 'language',
|
||||
'classifiers'])
|
||||
|
||||
# Metadata fields that smart update should copy only if the source is not None
|
||||
SC_FIELDS_COPY_NOT_NULL = frozenset(['lpath', 'size', 'comments', 'thumbnail'])
|
||||
@ -114,8 +115,7 @@ SC_COPYABLE_FIELDS = SOCIAL_METADATA_FIELDS.union(
|
||||
PUBLICATION_METADATA_FIELDS).union(
|
||||
BOOK_STRUCTURE_FIELDS).union(
|
||||
DEVICE_METADATA_FIELDS).union(
|
||||
CALIBRE_METADATA_FIELDS).union(
|
||||
TOP_LEVEL_CLASSIFIERS) - \
|
||||
CALIBRE_METADATA_FIELDS) - \
|
||||
SC_FIELDS_NOT_COPIED.union(
|
||||
SC_FIELDS_COPY_NOT_NULL)
|
||||
|
||||
|
@ -164,6 +164,18 @@ class Metadata(object):
|
||||
def set(self, field, val, extra=None):
|
||||
self.__setattr__(field, val, extra)
|
||||
|
||||
def get_classifiers(self):
|
||||
'''
|
||||
Return a copy of the classifiers dictionary.
|
||||
The dict is small, and the penalty for using a reference where a copy is
|
||||
needed is large. Also, we don't want any manipulations of the returned
|
||||
dict to show up in the book.
|
||||
'''
|
||||
return copy.deepcopy(object.__getattribute__(self, '_data')['classifiers'])
|
||||
|
||||
def set_classifiers(self, classifiers):
|
||||
object.__getattribute__(self, '_data')['classifiers'] = classifiers
|
||||
|
||||
# field-oriented interface. Intended to be the same as in LibraryDatabase
|
||||
|
||||
def standard_field_keys(self):
|
||||
@ -369,6 +381,7 @@ class Metadata(object):
|
||||
self.set_all_user_metadata(other.get_all_user_metadata(make_copy=True))
|
||||
for x in SC_FIELDS_COPY_NOT_NULL:
|
||||
copy_not_none(self, other, x)
|
||||
self.set_classifiers(other.get_classifiers())
|
||||
# language is handled below
|
||||
else:
|
||||
for attr in SC_COPYABLE_FIELDS:
|
||||
@ -423,6 +436,17 @@ class Metadata(object):
|
||||
if len(other_comments.strip()) > len(my_comments.strip()):
|
||||
self.comments = other_comments
|
||||
|
||||
# Copy all the non-none classifiers
|
||||
if callable(getattr(other, 'get_classifiers', None)):
|
||||
d = self.get_classifiers()
|
||||
s = other.get_classifiers()
|
||||
d.update([v for v in s.iteritems() if v[1] is not None])
|
||||
self.set_classifiers(d)
|
||||
else:
|
||||
# other structure not Metadata. Copy the top-level classifiers
|
||||
for attr in TOP_LEVEL_CLASSIFIERS:
|
||||
copy_not_none(self, other, attr)
|
||||
|
||||
other_lang = getattr(other, 'language', None)
|
||||
if other_lang and other_lang.lower() != 'und':
|
||||
self.language = other_lang
|
||||
|
Loading…
x
Reference in New Issue
Block a user