mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Make the serialization code more efficient
This commit is contained in:
parent
686bc23593
commit
da689143c6
@ -11,18 +11,23 @@ from datetime import datetime
|
|||||||
from calibre.utils.iso8601 import parse_iso8601
|
from calibre.utils.iso8601 import parse_iso8601
|
||||||
|
|
||||||
MSGPACK_MIME = 'application/x-msgpack'
|
MSGPACK_MIME = 'application/x-msgpack'
|
||||||
|
CANARY = 'jPoAv3zOyHvQ5JFNYg4hJ9'
|
||||||
|
|
||||||
|
|
||||||
|
def encoded(typ, data):
|
||||||
|
return {CANARY: typ, 'v': data}
|
||||||
|
|
||||||
|
|
||||||
def encoder(obj, for_json=False):
|
def encoder(obj, for_json=False):
|
||||||
if isinstance(obj, datetime):
|
if isinstance(obj, datetime):
|
||||||
return {'__datetime__': unicode(obj.isoformat())}
|
return encoded(0, unicode(obj.isoformat()))
|
||||||
if isinstance(obj, (set, frozenset)):
|
if isinstance(obj, (set, frozenset)):
|
||||||
return {'__serset__': tuple(obj)}
|
return encoded(1, tuple(obj))
|
||||||
if obj.__class__.__name__ == 'Metadata':
|
if obj.__class__.__name__ == 'Metadata':
|
||||||
from calibre.ebooks.metadata.book.base import Metadata
|
from calibre.ebooks.metadata.book.base import Metadata
|
||||||
if isinstance(obj, Metadata):
|
if isinstance(obj, Metadata):
|
||||||
from calibre.ebooks.metadata.book.serialize import metadata_as_dict
|
from calibre.ebooks.metadata.book.serialize import metadata_as_dict
|
||||||
return {'__metadata__': metadata_as_dict(obj, encode_cover_data=for_json)}
|
return encoded(2, metadata_as_dict(obj, encode_cover_data=for_json))
|
||||||
raise TypeError('Cannot serialize objects of type {}'.format(type(obj)))
|
raise TypeError('Cannot serialize objects of type {}'.format(type(obj)))
|
||||||
|
|
||||||
|
|
||||||
@ -40,23 +45,30 @@ def json_dumps(data, **kw):
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def decoder(obj, for_json=False):
|
def decode_metadata(x, for_json):
|
||||||
dt = obj.get('__datetime__')
|
from calibre.ebooks.metadata.book.serialize import metadata_from_dict
|
||||||
if dt is not None:
|
obj = metadata_from_dict(x)
|
||||||
return parse_iso8601(dt, assume_utc=True)
|
if for_json and obj.cover_data and obj.cover_data[1]:
|
||||||
s = obj.get('__serset__')
|
obj.cover_data = obj.cover_data[0], base64.standard_b64decode(
|
||||||
if s is not None:
|
obj.cover_data[1]
|
||||||
return set(s)
|
)
|
||||||
m = obj.get('__metadata__')
|
|
||||||
if m is not None:
|
|
||||||
from calibre.ebooks.metadata.book.serialize import metadata_from_dict
|
|
||||||
obj = metadata_from_dict(m)
|
|
||||||
if for_json and obj.cover_data and obj.cover_data[1]:
|
|
||||||
obj.cover_data = obj.cover_data[0], base64.standard_b64decode(obj.cover_data[1])
|
|
||||||
return obj
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
decoders = (
|
||||||
|
lambda x, fj: parse_iso8601(x, assume_utc=True),
|
||||||
|
lambda x, fj: set(x),
|
||||||
|
decode_metadata,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def decoder(obj, for_json=False):
|
||||||
|
typ = obj.get(CANARY)
|
||||||
|
if typ is None:
|
||||||
|
return obj
|
||||||
|
return decoders[typ](obj['v'], for_json)
|
||||||
|
|
||||||
|
|
||||||
def msgpack_loads(data):
|
def msgpack_loads(data):
|
||||||
import msgpack
|
import msgpack
|
||||||
return msgpack.unpackb(data, encoding='utf-8', object_hook=decoder)
|
return msgpack.unpackb(data, encoding='utf-8', object_hook=decoder)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user