diff --git a/src/calibre/utils/serialize.py b/src/calibre/utils/serialize.py index 4073e3c537..d900fc2424 100644 --- a/src/calibre/utils/serialize.py +++ b/src/calibre/utils/serialize.py @@ -8,6 +8,8 @@ import json, base64 from functools import partial from datetime import datetime +import msgpack + from calibre.utils.iso8601 import parse_iso8601 MSGPACK_MIME = 'application/x-msgpack' @@ -23,16 +25,18 @@ def encoder(obj, for_json=False): return encoded(0, unicode(obj.isoformat())) if isinstance(obj, (set, frozenset)): return encoded(1, tuple(obj)) - if obj.__class__.__name__ == 'Metadata': + if hasattr(obj, '__calibre_serializable__'): from calibre.ebooks.metadata.book.base import Metadata + from calibre.library.field_metadata import FieldMetadata, fm_as_dict if isinstance(obj, Metadata): from calibre.ebooks.metadata.book.serialize import metadata_as_dict return encoded(2, metadata_as_dict(obj, encode_cover_data=for_json)) + elif isinstance(obj, FieldMetadata): + return encoded(3, fm_as_dict(obj)) raise TypeError('Cannot serialize objects of type {}'.format(type(obj))) def msgpack_dumps(data): - import msgpack return msgpack.packb(data, use_bin_type=True, default=encoder) @@ -55,10 +59,16 @@ def decode_metadata(x, for_json): return obj +def decode_field_metadata(x, for_json): + from calibre.library.field_metadata import fm_from_dict + return fm_from_dict(x) + + decoders = ( lambda x, fj: parse_iso8601(x, assume_utc=True), lambda x, fj: set(x), decode_metadata, + decode_field_metadata, ) @@ -70,7 +80,6 @@ def decoder(obj, for_json=False): def msgpack_loads(data): - import msgpack return msgpack.unpackb(data, encoding='utf-8', object_hook=decoder)