461bf6fd40
CI / lint (3.11) (push) Has been cancelled
CI / lint (3.12) (push) Has been cancelled
CI / lint (3.13) (push) Has been cancelled
CI / shellcheck (push) Has been cancelled
CI / shfmt (push) Has been cancelled
CI / setup (3.11) (push) Has been cancelled
CI / setup (3.12) (push) Has been cancelled
CI / setup (3.13) (push) Has been cancelled
CI / check-licenses (3.12) (push) Has been cancelled
CI / test_unit (3.11) (push) Has been cancelled
CI / test_unit (3.12) (push) Has been cancelled
CI / test_unit (3.13) (push) Has been cancelled
CI / test_unit_no_extras (3.11) (push) Has been cancelled
CI / test_unit_no_extras (3.12) (push) Has been cancelled
CI / test_json_to_html (3.12) (push) Has been cancelled
CI / test_unit_no_extras (3.13) (push) Has been cancelled
CI / test_unit_dependency_extras (csv, 3.12, --extra csv) (push) Has been cancelled
CI / test_unit_dependency_extras (xlsx, 3.11, --extra xlsx) (push) Has been cancelled
CI / test_unit_dependency_extras (xlsx, 3.12, --extra xlsx) (push) Has been cancelled
CI / test_unit_dependency_extras (csv, 3.11, --extra csv) (push) Has been cancelled
CI / test_unit_dependency_extras (csv, 3.13, --extra csv) (push) Has been cancelled
CI / test_unit_dependency_extras (docx, 3.11, --extra docx) (push) Has been cancelled
CI / test_unit_dependency_extras (docx, 3.12, --extra docx) (push) Has been cancelled
CI / test_unit_dependency_extras (docx, 3.13, --extra docx) (push) Has been cancelled
CI / test_unit_dependency_extras (markdown, 3.11, --extra md) (push) Has been cancelled
CI / test_unit_dependency_extras (markdown, 3.12, --extra md) (push) Has been cancelled
CI / test_unit_dependency_extras (markdown, 3.13, --extra md) (push) Has been cancelled
CI / test_unit_dependency_extras (odt, 3.11, --extra odt) (push) Has been cancelled
CI / test_unit_dependency_extras (odt, 3.12, --extra odt) (push) Has been cancelled
CI / test_unit_dependency_extras (odt, 3.13, --extra odt) (push) Has been cancelled
CI / test_unit_dependency_extras (pdf-image, 3.11, --extra pdf --extra image --extra paddleocr) (push) Has been cancelled
CI / test_unit_dependency_extras (pdf-image, 3.12, --extra pdf --extra image --extra paddleocr) (push) Has been cancelled
CI / test_unit_dependency_extras (pdf-image, 3.13, --extra pdf --extra image --extra paddleocr) (push) Has been cancelled
CI / test_unit_dependency_extras (pptx, 3.11, --extra pptx) (push) Has been cancelled
CI / test_unit_dependency_extras (pptx, 3.12, --extra pptx) (push) Has been cancelled
CI / test_unit_dependency_extras (pptx, 3.13, --extra pptx) (push) Has been cancelled
CI / test_unit_dependency_extras (pypandoc, 3.11, --extra epub --extra org --extra rtf --extra rst) (push) Has been cancelled
CI / test_unit_dependency_extras (pypandoc, 3.12, --extra epub --extra org --extra rtf --extra rst) (push) Has been cancelled
CI / test_unit_dependency_extras (pypandoc, 3.13, --extra epub --extra org --extra rtf --extra rst) (push) Has been cancelled
Build And Push Docker Image / set-short-sha (push) Has been cancelled
Partition Benchmark / setup (push) Has been cancelled
Partition Benchmark / Measure and compare partition() runtime (push) Has been cancelled
CI / test_unit_dependency_extras (xlsx, 3.13, --extra xlsx) (push) Has been cancelled
CI / test_ingest_src (3.12) (push) Has been cancelled
CI / test_json_to_markdown (3.12) (push) Has been cancelled
CI / changelog (push) Has been cancelled
CI / test_dockerfile (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Build And Push Docker Image / build-images (linux/amd64, opensource-linux-8core) (push) Has been cancelled
Build And Push Docker Image / build-images (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build And Push Docker Image / publish-images (push) Has been cancelled
126 lines
5.0 KiB
Python
126 lines
5.0 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import tempfile
|
|
from typing import IO, Any, Optional, cast
|
|
|
|
from unstructured.documents.elements import Element
|
|
from unstructured.file_utils.model import FileType
|
|
from unstructured.partition.common.common import exactly_one
|
|
from unstructured.partition.common.metadata import get_last_modified_date
|
|
from unstructured.partition.docx import partition_docx
|
|
from unstructured.utils import requires_dependencies
|
|
|
|
|
|
def partition_odt(
|
|
filename: Optional[str] = None,
|
|
*,
|
|
file: Optional[IO[bytes]] = None,
|
|
metadata_filename: Optional[str] = None,
|
|
metadata_last_modified: Optional[str] = None,
|
|
**kwargs: Any,
|
|
) -> list[Element]:
|
|
"""Partitions Open Office Documents in .odt format into its document elements.
|
|
|
|
All parameters that are available on `partition_docx()` are also available here.
|
|
|
|
Parameters
|
|
----------
|
|
filename
|
|
A string defining the target filename path.
|
|
file
|
|
A file-like object using "rb" mode --> open(filename, "rb").
|
|
infer_table_structure
|
|
If True, any Table elements that are extracted will also have a metadata field
|
|
named "text_as_html" where the table's text content is rendered into an html string.
|
|
I.e., rows and cells are preserved.
|
|
Whether True or False, the "text" field is always present in any Table element
|
|
and is the text content of the table (no structure).
|
|
metadata_last_modified
|
|
The last modified date for the document.
|
|
languages
|
|
User defined value for `metadata.languages` if provided. Otherwise language is detected
|
|
using naive Bayesian filter via `langdetect`. Multiple languages indicates text could be
|
|
in either language.
|
|
Additional Parameters:
|
|
detect_language_per_element
|
|
Detect language per element instead of at the document level.
|
|
"""
|
|
|
|
last_modified = get_last_modified_date(filename) if filename else None
|
|
|
|
with tempfile.TemporaryDirectory() as target_dir:
|
|
docx_path = _convert_odt_to_docx(target_dir, filename, file)
|
|
elements = partition_docx(
|
|
filename=docx_path,
|
|
metadata_filename=metadata_filename or filename,
|
|
metadata_file_type=FileType.ODT,
|
|
metadata_last_modified=metadata_last_modified or last_modified,
|
|
**kwargs,
|
|
)
|
|
|
|
return elements
|
|
|
|
|
|
@requires_dependencies("pypandoc")
|
|
def _convert_odt_to_docx(
|
|
target_dir: str, filename: Optional[str], file: Optional[IO[bytes]]
|
|
) -> str:
|
|
"""Convert ODT document to DOCX returning the new .docx file's path.
|
|
|
|
Parameters
|
|
----------
|
|
target_dir
|
|
The str directory-path to use for conversion purposes. The new DOCX file is written to this
|
|
directory. When passed as a file-like object, a copy of the source file is written here as
|
|
well. It is the caller's responsibility to remove this directory and its contents when
|
|
they are no longer needed.
|
|
filename
|
|
A str file-path specifying the location of the source ODT file on the local filesystem.
|
|
file
|
|
A file-like object open for reading in binary mode ("rb" mode).
|
|
"""
|
|
exactly_one(filename=filename, file=file)
|
|
|
|
# -- validate file-path when provided so we can provide a more meaningful error than whatever
|
|
# -- would come from pandoc.
|
|
if filename is not None and not os.path.exists(filename):
|
|
raise ValueError(f"The file {filename} does not exist.")
|
|
|
|
# -- Pandoc is a command-line program running in its own memory-space. It can therefore only
|
|
# -- operate on files on the filesystem. If the source document was passed as `file`, write
|
|
# -- it to `target_dir/document.odt` and use that path as the source-path.
|
|
source_file_path = f"{target_dir}/document.odt" if file is not None else cast(str, filename)
|
|
if file is not None:
|
|
with open(source_file_path, "wb") as f:
|
|
f.write(file.read())
|
|
|
|
# -- Compute the path of the resulting .docx document. We want its file-name to be preserved
|
|
# -- if the source-document was provided as `filename`.
|
|
# -- a/b/foo.odt -> foo.odt --
|
|
file_name = os.path.basename(source_file_path)
|
|
# -- foo.odt -> foo --
|
|
base_name, _ = os.path.splitext(file_name)
|
|
# -- foo -> foo.docx --
|
|
target_docx_path = os.path.join(target_dir, f"{base_name}.docx")
|
|
|
|
import pypandoc
|
|
|
|
# Try with sandbox=True first for security. If it fails due to Pandoc's known limitation
|
|
# with DOCX output in sandbox mode (see jgm/pandoc#8128), fallback without sandbox only
|
|
# if ALLOW_PANDOC_NO_SANDBOX env var is set to "true".
|
|
try:
|
|
pypandoc.convert_file(
|
|
source_file_path, "docx", format="odt", outputfile=target_docx_path, sandbox=True
|
|
)
|
|
except RuntimeError:
|
|
allow_no_sandbox = os.environ.get("ALLOW_PANDOC_NO_SANDBOX", "").lower() == "true"
|
|
if allow_no_sandbox:
|
|
pypandoc.convert_file(
|
|
source_file_path, "docx", format="odt", outputfile=target_docx_path
|
|
)
|
|
else:
|
|
raise
|
|
|
|
return target_docx_path
|