diff --git a/src/gotenberg_client/_base.py b/src/gotenberg_client/_base.py index bf223bf..d8a6c11 100644 --- a/src/gotenberg_client/_base.py +++ b/src/gotenberg_client/_base.py @@ -4,6 +4,7 @@ import logging from contextlib import ExitStack from pathlib import Path +from tempfile import TemporaryDirectory from types import TracebackType from typing import Dict from typing import Optional @@ -102,8 +103,23 @@ def _add_file_map(self, filepath: Path, name: Optional[str] = None) -> None: """ if name is None: name = filepath.name + if name in self._file_map: # pragma: no cover logger.warning(f"{name} has already been provided, overwriting anyway") + + try: + name.encode("utf8").decode("ascii") + except UnicodeDecodeError: + logger.warning(f"filename {name} includes non-ascii characters, compensating for Gotenberg") + tmp_dir = self._stack.enter_context(TemporaryDirectory()) + # Filename can be fixed, the directory is random + new_path = Path(tmp_dir) / Path(name).with_stem("clean-filename-copy") + logger.warning(f"New path {new_path}") + new_path.write_bytes(filepath.read_bytes()) + filepath = new_path + name = new_path.name + logger.warning(f"New name {name}") + self._file_map[name] = filepath def pdf_format(self, pdf_format: PdfAFormat) -> Self: diff --git a/tests/test_misc_stuff.py b/tests/test_misc_stuff.py index f6e9cb4..b71e5dd 100644 --- a/tests/test_misc_stuff.py +++ b/tests/test_misc_stuff.py @@ -1,4 +1,7 @@ +import shutil +import tempfile import uuid +from pathlib import Path from httpx import codes @@ -43,3 +46,24 @@ def test_output_filename( assert resp.headers["Content-Type"] == "application/pdf" assert "Content-Disposition" in resp.headers assert f"{filename}.pdf" in resp.headers["Content-Disposition"] + + def test_libre_office_convert_cyrillic(self, client: GotenbergClient): + """ + Gotenberg versions before 8.0.0 could not internally handle filenames with + non-ASCII characters. This replicates such a thing against 1 endpoint to + verify the workaround inside this library + """ + test_file = SAMPLE_DIR / "sample.odt" + + with tempfile.TemporaryDirectory() as temp_dir: + copy = shutil.copy( + test_file, + Path(temp_dir) / "Карточка партнера Тауберг Альфа.odt", # noqa: RUF001 + ) + + with client.libre_office.to_pdf() as route: + resp = call_run_with_server_error_handling(route.convert(copy)) + + assert resp.status_code == codes.OK + assert "Content-Type" in resp.headers + assert resp.headers["Content-Type"] == "application/pdf"