From 5a124d8bf1dc9a854635c2b33d3562d1f6a623af Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 21 Oct 2015 07:12:08 +0530 Subject: [PATCH] More compact representation of book metadata as JSON --- src/calibre/srv/ajax.py | 5 +++-- src/calibre/srv/metadata.py | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/calibre/srv/metadata.py diff --git a/src/calibre/srv/ajax.py b/src/calibre/srv/ajax.py index 95b4dd8f8d..c2bbaa1ede 100644 --- a/src/calibre/srv/ajax.py +++ b/src/calibre/srv/ajax.py @@ -16,6 +16,7 @@ from calibre.db.view import sanitize_sort_field_name from calibre.ebooks.metadata import title_sort from calibre.ebooks.metadata.book.json_codec import JsonCodec from calibre.srv.errors import HTTPNotFound +from calibre.srv.metadata import book_as_json from calibre.srv.routes import endpoint, json from calibre.srv.session import defaults from calibre.srv.content import get as get_content, icon as get_icon @@ -584,11 +585,11 @@ def interface_data(ctx, rd, library_id): db = get_db(ctx, library_id) with db.safe_read_lock: ans['search_result'] = _search(ctx, rd, db, '', num, 0, ','.join(sorts), ','.join(orders)) - ans['field_metadata'] = db.field_metadata + ans['field_metadata'] = db.field_metadata.all_metadata() # ans['categories'] = ctx.get_categories(rd, db) mdata = ans['metadata'] = {} for book_id in ans['search_result']['book_ids']: - data, last_modified = book_to_json(ctx, rd, db, book_id) + data = book_as_json(db, book_id) mdata[book_id] = data return ans diff --git a/src/calibre/srv/metadata.py b/src/calibre/srv/metadata.py new file mode 100644 index 0000000000..ad22472dfd --- /dev/null +++ b/src/calibre/srv/metadata.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python2 +# vim:fileencoding=utf-8 +# License: GPLv3 Copyright: 2015, Kovid Goyal + +from __future__ import (unicode_literals, division, absolute_import, + print_function) +from datetime import datetime, time + +from calibre.utils.date import isoformat, UNDEFINED_DATE, local_tz + +IGNORED_FIELDS = frozenset('cover ondevice path marked id au_map'.split()) + +def encode_datetime(dateval): + if dateval is None: + return "None" + if not isinstance(dateval, datetime): + dateval = datetime.combine(dateval, time()) + if hasattr(dateval, 'tzinfo') and dateval.tzinfo is None: + dateval = dateval.replace(tzinfo=local_tz) + if dateval <= UNDEFINED_DATE: + return None + return isoformat(dateval) + +def add_field(field, db, book_id, ans, field_metadata): + datatype = field_metadata.get('datatype') + if datatype is not None: + val = db._field_for(field, book_id) + if val is not None and val != (): + if datatype == 'datetime': + val = encode_datetime(val) + if val is None: + return + ans[field] = val + +def book_as_json(db, book_id): + db = db.new_api + with db.safe_read_lock: + ans = {'formats':db._formats(book_id)} + fm = db.field_metadata + for field in fm.all_field_keys(): + if field not in IGNORED_FIELDS: + add_field(field, db, book_id, ans, fm[field]) + return ans