Ctrl K
ComunidadGuías…

api/libs/epub.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Read EPUB chapters in spine order without extracting archive members to disk."""

import posixpath
from io import BytesIO
from urllib.parse import unquote, urlsplit
from zipfile import ZipFile

from defusedxml import ElementTree
from unstructured.documents.elements import Element
from unstructured.partition.html import partition_html


def partition_epub(file_path: str) -> list[Element]:
    with ZipFile(file_path) as archive:
        container = ElementTree.fromstring(archive.read("META-INF/container.xml"))
        rootfile = container.find(".//{*}rootfile")
        package_path = rootfile.get("full-path") if rootfile is not None else None
        if not package_path:
            raise ValueError("EPUB package path is missing")

        package_path = unquote(urlsplit(package_path).path).lstrip("/")
        package = ElementTree.fromstring(archive.read(package_path))
        manifest = {item.attrib["id"]: item.attrib["href"] for item in package.findall(".//{*}manifest/{*}item")}
        elements: list[Element] = []
        for itemref in package.findall(".//{*}spine/{*}itemref"):
            href = manifest[itemref.attrib["idref"]]
            chapter_path = posixpath.normpath(
                posixpath.join(posixpath.dirname(package_path), unquote(urlsplit(href).path))
            ).lstrip("/")
            with BytesIO(archive.read(chapter_path)) as chapter:
                elements.extend(partition_html(file=chapter))
        return elements