92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
||
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import shutil
|
||
import tempfile
|
||
from pathlib import Path
|
||
from typing import Any
|
||
|
||
from _pptx_common import (
|
||
PRESENTATION_INPUT_SUFFIXES,
|
||
SkillArgumentParser,
|
||
input_file,
|
||
output_file,
|
||
publish_file,
|
||
run_cli,
|
||
run_soffice_convert,
|
||
)
|
||
|
||
|
||
def build_parser() -> argparse.ArgumentParser:
|
||
parser = SkillArgumentParser(description="转换 PowerPoint 演示文稿格式。")
|
||
parser.add_argument("--input", required=True)
|
||
parser.add_argument("--output", required=True)
|
||
parser.add_argument("--timeout", type=int, default=180)
|
||
parser.add_argument("--overwrite", action="store_true")
|
||
return parser
|
||
|
||
|
||
def main() -> dict[str, Any]:
|
||
from pptx import Presentation
|
||
|
||
args = build_parser().parse_args()
|
||
source = input_file(args.input, PRESENTATION_INPUT_SUFFIXES)
|
||
destination = output_file(
|
||
args.output,
|
||
{".pptx", ".pdf"},
|
||
overwrite=args.overwrite,
|
||
)
|
||
target_suffix = destination.suffix.lower()
|
||
if source.suffix.lower() == ".ppt" and target_suffix != ".pptx":
|
||
raise ValueError("旧版 .ppt 必须先转换为 .pptx,再转换为 PDF")
|
||
|
||
with tempfile.TemporaryDirectory(prefix="pptx-convert-") as temp_name:
|
||
temp_dir = Path(temp_name)
|
||
staged_source = temp_dir / f"source{source.suffix.lower()}"
|
||
shutil.copy2(source, staged_source)
|
||
office_output = {"stdout": "", "stderr": ""}
|
||
if target_suffix == ".pptx" and source.suffix.lower() == ".pptx":
|
||
converted = temp_dir / "converted.pptx"
|
||
shutil.copy2(staged_source, converted)
|
||
else:
|
||
converted, office_output = run_soffice_convert(
|
||
staged_source,
|
||
target_format=target_suffix.lstrip("."),
|
||
output_dir=temp_dir / "converted",
|
||
timeout=args.timeout,
|
||
filter_name=(
|
||
"Impress MS PowerPoint 2007 XML"
|
||
if target_suffix == ".pptx"
|
||
else None
|
||
),
|
||
)
|
||
if target_suffix == ".pptx":
|
||
presentation = Presentation(str(converted))
|
||
page_count = len(presentation.slides)
|
||
if page_count < 1:
|
||
raise ValueError("转换后的演示文稿不包含页面")
|
||
else:
|
||
from pypdf import PdfReader
|
||
|
||
page_count = len(PdfReader(str(converted)).pages)
|
||
if page_count < 1:
|
||
raise ValueError("转换后的 PDF 不包含页面")
|
||
staged_output = temp_dir / f"publish{target_suffix}"
|
||
shutil.copy2(converted, staged_output)
|
||
publish_file(staged_output, destination, overwrite=args.overwrite)
|
||
return {
|
||
"source": str(source),
|
||
"path": str(destination),
|
||
"format": target_suffix.lstrip("."),
|
||
"page_count": page_count,
|
||
"size_bytes": destination.stat().st_size,
|
||
"office_stdout": office_output["stdout"],
|
||
"office_stderr": office_output["stderr"],
|
||
}
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(run_cli(main))
|