mirror of
https://github.com/langgenius/dify.git
synced 2026-11-11 13:51:25 +08:00
33 lines
1.4 KiB
Python
33 lines
1.4 KiB
Python
"""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
|