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',
|
SC_FIELDS_NOT_COPIED = frozenset(['title', 'title_sort', 'authors',
|
||||||
'author_sort', 'author_sort_map',
|
'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
|
# Metadata fields that smart update should copy only if the source is not None
|
||||||
SC_FIELDS_COPY_NOT_NULL = frozenset(['lpath', 'size', 'comments', 'thumbnail'])
|
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(
|
PUBLICATION_METADATA_FIELDS).union(
|
||||||
BOOK_STRUCTURE_FIELDS).union(
|
BOOK_STRUCTURE_FIELDS).union(
|
||||||
DEVICE_METADATA_FIELDS).union(
|
DEVICE_METADATA_FIELDS).union(
|
||||||
CALIBRE_METADATA_FIELDS).union(
|
CALIBRE_METADATA_FIELDS) - \
|
||||||
TOP_LEVEL_CLASSIFIERS) - \
|
|
||||||
SC_FIELDS_NOT_COPIED.union(
|
SC_FIELDS_NOT_COPIED.union(
|
||||||
SC_FIELDS_COPY_NOT_NULL)
|
SC_FIELDS_COPY_NOT_NULL)
|
||||||
|
|
||||||
|
@ -164,6 +164,18 @@ class Metadata(object):
|
|||||||
def set(self, field, val, extra=None):
|
def set(self, field, val, extra=None):
|
||||||
self.__setattr__(field, val, extra)
|
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
|
# field-oriented interface. Intended to be the same as in LibraryDatabase
|
||||||
|
|
||||||
def standard_field_keys(self):
|
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))
|
self.set_all_user_metadata(other.get_all_user_metadata(make_copy=True))
|
||||||
for x in SC_FIELDS_COPY_NOT_NULL:
|
for x in SC_FIELDS_COPY_NOT_NULL:
|
||||||
copy_not_none(self, other, x)
|
copy_not_none(self, other, x)
|
||||||
|
self.set_classifiers(other.get_classifiers())
|
||||||
# language is handled below
|
# language is handled below
|
||||||
else:
|
else:
|
||||||
for attr in SC_COPYABLE_FIELDS:
|
for attr in SC_COPYABLE_FIELDS:
|
||||||
@ -423,6 +436,17 @@ class Metadata(object):
|
|||||||
if len(other_comments.strip()) > len(my_comments.strip()):
|
if len(other_comments.strip()) > len(my_comments.strip()):
|
||||||
self.comments = other_comments
|
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)
|
other_lang = getattr(other, 'language', None)
|
||||||
if other_lang and other_lang.lower() != 'und':
|
if other_lang and other_lang.lower() != 'und':
|
||||||
self.language = other_lang
|
self.language = other_lang
|
||||||
|
Loading…
x
Reference in New Issue
Block a user