Source code for sanskrit_data.schema.books

"""
Intro
-----------

Here we define data-containers to store books. Books are stored or represented as a tree of BookPortion objects - book
containing many chapters containing many lines etc..

-  JSON schema mindmap
   `here <https://drive.mindmup.com/map?state=%7B%22ids%22:%5B%220B1_QBT-hoqqVbHc4QTV3Q2hjdTQ%22%5D,%22action%22:%22open%22,%22userId%22:%22109000762913288837175%22%7D>`__
   (Updated as needed).
- `An introductory video <https://youtu.be/bkd1pPL8HXk>`_.
- For general context and class diagram, refer to :mod:`~sanskrit_data.schema`.
"""
import logging
import sys

from sanskrit_data.schema import common
from sanskrit_data.schema.common import JsonObjectWithTarget, TYPE_FIELD, JsonObject, Target, Text


[docs]class BookPositionTarget(Target): schema = common.recursively_merge(Target.schema, { "type": "object", "description": "A BookPortion could represent a Book or a chapter or a verse or a half-verse or a sentence or any such unit.", "properties": { TYPE_FIELD: { "enum": ["BookPositionTarget"] }, "position": { "type": "number", "description": "Any number describing the position of one BookPortion within another." } } })
[docs] @classmethod def from_details(cls, container_id=None, position=None): target = BookPositionTarget() if container_id: target.container_id = container_id if position: target.position = position target.validate(db_interface=None) return target
[docs]class PublicationDetails(JsonObject): schema = common.recursively_merge(JsonObject.schema, ({ "type": "object", "description": "Publication details of a BookPortion.", "properties": { TYPE_FIELD: { "enum": ["PublicationDetails"] }, "release_time": { "type": "string" }, "publisher": { "type": "string" }, } }))
[docs]class BookMetadata(JsonObject): schema = common.recursively_merge(JsonObject.schema, ({ "type": "object", "properties": { TYPE_FIELD: { "enum": ["Language"] }, "name": { "type": Text.schema, }, "authors": { "type": "array", "items": { "type": Text.schema } }, "canonicalSource": { "type": "string", }, "issuePage": { "type": "string", }, }, "required": ["name"] })) # noinspection PyPep8Naming
[docs] @classmethod def from_details(cls, name, authors=None, canonicalSource=None, issuePage=None): obj = BookMetadata() obj.name = name if authors is not None: obj.authors = authors if canonicalSource is not None: obj.canonicalSource = canonicalSource if issuePage is not None: obj.issuePage = issuePage return obj
[docs]class BookPortion(JsonObjectWithTarget): schema = common.recursively_merge(JsonObject.schema, ({ "type": "object", "description": "A BookPortion could represent a Book or a chapter or a verse or a half-verse or a sentence or any such unit.", "properties": { TYPE_FIELD: { "enum": ["BookPortion"] }, "title": { "type": "string" }, "path": { "type": "string" }, "thumbnail_path": { "type": "string" }, "authors": { "type": "array", "items": { "type": "string" } }, "base_data": { "type": "string", "enum": ["image", "text"] }, "publication_details": PublicationDetails.schema, "portion_class": { "type": "string", "description": "book, part, chapter, verse, line etc.." }, "curated_content": Text.schema, "targets": { "maxLength": 1, "items": BookPositionTarget.schema, "description": "Target for BookPortion of which this BookPortion is a part. It is an array only for consistency. " "For any given BookPortion, one can get the right order of contained BookPortions by seeking all " "BookPortions referring to it in the targets list, and sorting them by their target position values." } }, })) target_class = BookPositionTarget
[docs] @classmethod def get_allowed_target_classes(cls): return [BookPortion]
[docs] @classmethod def from_details(cls, title, path=None, authors=None, targets=None, base_data=None, curated_content=None, portion_class=None, publication_details=None): if authors is None: authors = [] book_portion = BookPortion() book_portion.title = title book_portion.authors = authors # logging.debug(str(book_portion)) if path: book_portion.path = path targets = targets or [] logging.debug(str(book_portion)) book_portion.targets = targets if curated_content is not None: book_portion.curated_content = curated_content if base_data is not None: book_portion.base_data = base_data if portion_class is not None: book_portion.portion_class = portion_class if publication_details is not None: book_portion.publication_details = publication_details book_portion.validate() return book_portion
[docs] @classmethod def from_path(cls, path, db_interface): book_portion_dict = db_interface.find_one(find_filter={"path": path}) if book_portion_dict is None: return None else: book_portion = JsonObject.make_from_dict(book_portion_dict) return book_portion
# Essential for depickling to work. common.update_json_class_index(sys.modules[__name__]) logging.debug(common.json_class_index)