Source code for yael.simpleepub
#!/usr/bin/env python
# coding=utf-8
"""
A simplified interface
for reading, editing, and writing
EPUB 2 and EPUB 3 eBooks
with just one Rendition.
It also exposes some vanity functions.
If you need Multiple Renditions or more control,
you should use :class:`yael.publication.Publication` instead.
"""
from yael.dc import DC
from yael.navnode import NavNode
from yael.ncxtocnode import NCXTocNode
from yael.parsing import Parsing
from yael.publication import Publication
import yael.util
__author__ = "Alberto Pettarin"
__copyright__ = "Copyright 2015, Alberto Pettarin (www.albertopettarin.it)"
__license__ = "MIT"
__version__ = "0.0.6"
__email__ = "alberto@albertopettarin.it"
__status__ = "Development"
[docs]class SimpleEPUB(object):
"""
Build a simple EPUB programmatically or parse it from `path`.
:param path: a path to an EPUB (compressed) file
or to a directory (uncompressed)
:type path: str
:param parsing_options: a list of parsing options
:type parsing_options: list of :class:`yael.parsing.Parsing` values
"""
def __init__(self, path=None, parsing_options=None):
self.path = path
self.parsing_options = parsing_options
if parsing_options == None:
self.parsing_options = [Parsing.NO_MEDIA_OVERLAY]
self.ebook = Publication(
path=self.path,
parsing_options=self.parsing_options)
def __str__(self):
return str(self.ebook)
@property
def manifestation(self):
"""
The manifestation of this Publication.
:rtype: :class:`yael.manifestation.Manifestation`
"""
return self.ebook.manifestation
@property
def size(self):
"""
Compute and return the size of the publication.
For a :const:`yael.manifestation.Manifestation.COMPRESSED`
publication, it is the size of the EPUB (ZIP) Container, in bytes.
For a :const:`yael.manifestation.Manifestation.UNCOMPRESSED`
publication, it is the sum of the sizes, in bytes, of the files
in the uncompressed directory.
In all other cases (i.e.,
for a :const:`yael.manifestation.Manifestation.MEMORY`
publication), returns -1.
:rtype: int
"""
return self.ebook.size
@property
def version(self):
"""
The value of the EPUB version (it should be "2.0" or "3.0").
:rtype: str
"""
return self.ebook.version
@property
def dcterms_modified(self):
"""
The value of the dcterms:modified date. (EPUB 3)
:rtype: str
"""
return self.ebook.dcterms_modified
@property
def unique_identifier(self):
"""
The value of the unique identifier.
:rtype: str
"""
return self.ebook.unique_identifier
@property
def release_identifier(self):
"""
The value of the release identifier.
:rtype: str
"""
return self.ebook.release_identifier
@property
def identifier(self):
"""
The value of the (first) dc:identifier metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_IDENTIFIER)
@property
def title(self):
"""
The value of the (first) dc:title metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_TITLE)
@property
def language(self):
"""
The value of the (first) dc:language metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_LANGUAGE)
@property
def author(self):
"""
The value of the (first) dc:author metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_CREATOR)
@property
def date(self):
"""
The value of the (first) dc:date metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_DATE)
@property
def description(self):
"""
The value of the (first) dc:description metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_DESCRIPTION)
@property
def publisher(self):
"""
The value of the (first) dc:publisher metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_PUBLISHER)
@property
def rights(self):
"""
The value of the (first) dc:rights metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_RIGHTS)
@property
def source(self):
"""
The value of the (first) dc:source metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_SOURCE)
@property
def subjects(self):
"""
The list of values of dc:subject metadata.
:rtype: list of str
"""
return self.get_dc_metadatum(tag=DC.E_NS_SUBJECT, only_first=False)
@property
def type(self):
"""
The value of the (first) dc:type metadatum.
:rtype: str
"""
return self.get_dc_metadatum(tag=DC.E_NS_TYPE)
@property
def internal_path_cover_image(self):
"""
The path of cover image, relative to the Container root.
:rtype: str
"""
return self.ebook.internal_path_cover_image
@property
def cover_image(self):
"""
The contents of the cover image.
:rtype: bytes
"""
try:
i_p_cover = self.internal_path_cover_image
return self.ebook.assets[i_p_cover].contents
except:
pass
return None
@property
def toc(self):
"""
The TOC.
:rtype: :class:`yael.navelement.NavElement` or
:class:`yael.ncxtoc.NCXToc`
"""
return self.ebook.container.default_rendition.toc
@property
def resolved_toc(self):
"""
The TOC, where the src values have been resolved
into the corresponding internal paths
(relative to the container root).
:rtype: :class:`yael.navelement.NavElement` or
:class:`yael.ncxtoc.NCXToc`
"""
resolved_toc = self.toc
if resolved_toc != None:
i_p_toc = resolved_toc.internal_path
for node in resolved_toc.children:
self._resolve_reference(i_p_toc, node)
return resolved_toc
@property
def landmarks(self):
"""
The landmarks (EPUB 3 only).
:rtype: :class:`yael.navelement.NavElement`
"""
return self.ebook.container.default_rendition.landmarks
@property
def resolved_landmarks(self):
"""
The landmarks (EPUB 3 only),
where the src values have been resolved
into the corresponding internal paths
(relative to the container root).
:rtype: :class:`yael.navelement.NavElement`
"""
resolved_landmarks = self.landmarks
if resolved_landmarks != None:
i_p_landmarks = resolved_landmarks.internal_path
for node in resolved_landmarks.children:
self._resolve_reference(i_p_landmarks, node)
return resolved_landmarks
@property
def resolved_spine(self):
"""
The spine, as a (ordered) list of internal paths
to the assets referenced in the actual OPF `<spine>`.
:rtype: list of str
"""
return self.ebook.container.default_rendition.pac_document.files_referenced_spine
[docs] def spine_index_by_internal_path(self, internal_path):
"""
Return the index in the spine of the file located
at the given internal path (relative to the Container root).
:param internal_path: the internal path of the desired item
:type internal_path: str
:returns: the index in the spine, or -1 if not found
:rtype: int
"""
return self.ebook.container.default_rendition.pac_document.spine_index_by_internal_path(internal_path)
@property
def resolved_spine_linear(self):
"""
The spine, as a (ordered) list of internal paths
to the assets referenced in the actual OPF `<spine>`,
with attribute linear="yes" or omitted.
:rtype: list of str
"""
return self.ebook.container.default_rendition.pac_document.files_referenced_spine_linear
[docs] def spine_linear_index_by_internal_path(self, internal_path):
"""
Return the index in the linear spine of the file located
at the given internal path (relative to the Container root).
:param internal_path: the internal path of the desired item
:type internal_path: str
:returns: the index in the spine, or -1 if not found
:rtype: int
"""
return self.ebook.container.default_rendition.pac_document.spine_linear_index_by_internal_path(internal_path)
def _resolve_reference(self, internal_path, node):
if (isinstance(node, NavNode)) and (node.v_href != None):
node.v_href = yael.util.norm_join_parent(
internal_path,
node.v_href)
if (isinstance(node, NCXTocNode)) and (node.v_src != None):
node.v_src = yael.util.norm_join_parent(
internal_path,
node.v_src)
for child in node.children:
self._resolve_reference(internal_path, child)
[docs] def asset_contents(self, internal_path):
"""
Return the contents of the asset with the given
internal path, relative to the container root.
:param internal_path: the internal path of the desired asset
:type internal_path: str
:rtype: bytes
"""
try:
return self.ebook.assets[internal_path].contents
except:
pass
return None