diff --git a/app/io/presentation.py b/app/io/presentation.py new file mode 100644 index 0000000..d27be8c --- /dev/null +++ b/app/io/presentation.py @@ -0,0 +1,58 @@ +# All comments in English. + +from pptx import Presentation +from odf.opendocument import load +from odf.draw import Page +from odf.text import P + +def normalize_newlines(value): + if value is None: + return "" + return ( + str(value) + .replace("\r\n", "\\n") + .replace("\n\r", "\\n") + .replace("\r", "\\n") + .replace("\n", "\\n") + ) + +def convert_pptx(path): + prs = Presentation(path) + slides = [] + for idx, slide in enumerate(prs.slides, start=1): + texts = [] + for shape in slide.shapes: + if hasattr(shape, "text"): + texts.append(normalize_newlines(shape.text)) + slides.append((f"Slide_{idx}", "\n".join(texts))) + return slides + +def convert_ppt(path): + # PPT (binary) is not supported by python-pptx. + # We convert using LibreOffice headless via subprocess. + import subprocess, tempfile, os + + tmp = tempfile.mktemp(suffix=".pptx") + subprocess.run(["soffice", "--headless", "--convert-to", "pptx", "--outdir", "/tmp", path]) + return convert_pptx(tmp) + +def convert_odp(path): + doc = load(path) + slides = [] + idx = 1 + for page in doc.getElementsByType(Page): + texts = [] + for p in page.getElementsByType(P): + texts.append(normalize_newlines(p.firstChild.data if p.firstChild else "")) + slides.append((f"Slide_{idx}", "\n".join(texts))) + idx += 1 + return slides + +def convert_presentation(path): + if path.endswith(".pptx"): + return convert_pptx(path) + if path.endswith(".ppt"): + return convert_ppt(path) + if path.endswith(".odp"): + return convert_odp(path) + raise ValueError("Unsupported presentation format")