viewer2: Make serialization of book metadata more robust

This commit is contained in:
Kovid Goyal 2019-06-04 20:43:40 +05:30
parent 188c59b6e8
commit 27c5324269
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -11,6 +11,7 @@ import sys
from collections import OrderedDict, defaultdict from collections import OrderedDict, defaultdict
from functools import partial from functools import partial
from itertools import count from itertools import count
from datetime import datetime
from css_parser import replaceUrls from css_parser import replaceUrls
from css_parser.css import CSSRule from css_parser.css import CSSRule
@ -30,6 +31,7 @@ from calibre.ebooks.oeb.polish.toc import get_landmarks, get_toc
from calibre.ebooks.oeb.polish.utils import extract, guess_type from calibre.ebooks.oeb.polish.utils import extract, guess_type
from calibre.utils.logging import default_log from calibre.utils.logging import default_log
from calibre.utils.short_uuid import uuid4 from calibre.utils.short_uuid import uuid4
from calibre.srv.metadata import encode_datetime
from polyglot.binary import as_base64_unicode as encode_component, from_base64_unicode as decode_component from polyglot.binary import as_base64_unicode as encode_component, from_base64_unicode as decode_component
from polyglot.builtins import iteritems, map, is_py3, unicode_type from polyglot.builtins import iteritems, map, is_py3, unicode_type
from polyglot.urllib import quote, urlparse from polyglot.urllib import quote, urlparse
@ -522,20 +524,30 @@ def html_as_dict(root):
return {'ns_map':ns_map, 'tag_map':tags, 'tree':tree} return {'ns_map':ns_map, 'tag_map':tags, 'tree':tree}
def serialize_datetimes(d):
for k in tuple(d):
v = d[k]
if isinstance(v, datetime):
v = encode_datetime(v)
d[k] = v
def render(pathtoebook, output_dir, book_hash=None, serialize_metadata=False): def render(pathtoebook, output_dir, book_hash=None, serialize_metadata=False):
container = Container(pathtoebook, output_dir, book_hash=book_hash) container = Container(pathtoebook, output_dir, book_hash=book_hash)
if serialize_metadata: if serialize_metadata:
from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.metadata.meta import get_metadata
from calibre.utils.serialize import json_dumps
from calibre.ebooks.metadata.book.serialize import metadata_as_dict from calibre.ebooks.metadata.book.serialize import metadata_as_dict
with lopen(pathtoebook, 'rb') as f: with lopen(pathtoebook, 'rb') as f:
mi = get_metadata(f, os.path.splitext(pathtoebook)[1][1:].lower()) mi = get_metadata(f, os.path.splitext(pathtoebook)[1][1:].lower())
d = metadata_as_dict(mi) d = metadata_as_dict(mi)
serialize_datetimes(d), serialize_datetimes(d.get('user_metadata', {}))
cdata = d.pop('cover_data', None) cdata = d.pop('cover_data', None)
if cdata and cdata[1] and container.book_render_data['raster_cover_name']: if cdata and cdata[1] and container.book_render_data['raster_cover_name']:
with lopen(os.path.join(output_dir, container.book_render_data['raster_cover_name']), 'wb') as f: with lopen(os.path.join(output_dir, container.book_render_data['raster_cover_name']), 'wb') as f:
f.write(cdata[1]) f.write(cdata[1])
with lopen(os.path.join(output_dir, 'calibre-book-metadata.json'), 'wb') as f: with lopen(os.path.join(output_dir, 'calibre-book-metadata.json'), 'wb') as f:
f.write(json.dumps(d)) f.write(json_dumps(d))
if __name__ == '__main__': if __name__ == '__main__':