jkj
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import io
|
||||
from concurrent import futures
|
||||
import hashlib
|
||||
import json as json_module
|
||||
@@ -34,6 +35,53 @@ except ImportError:
|
||||
tqdm = None # type: ignore
|
||||
|
||||
|
||||
def _image_paths_to_pdf_bytes(images: List[str]) -> Optional[bytes]:
|
||||
if not images:
|
||||
return None
|
||||
try:
|
||||
from PIL import Image # type: ignore
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
pil_images: List[Any] = []
|
||||
try:
|
||||
for p in images:
|
||||
img_path = Path(p)
|
||||
if not img_path.is_file():
|
||||
continue
|
||||
with Image.open(img_path) as im: # type: ignore[attr-defined]
|
||||
# Ensure PDF-compatible mode.
|
||||
if im.mode in {"RGBA", "LA", "P"}:
|
||||
im = im.convert("RGB")
|
||||
else:
|
||||
im = im.convert("RGB")
|
||||
pil_images.append(im.copy())
|
||||
except Exception:
|
||||
for im in pil_images:
|
||||
try:
|
||||
im.close()
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
if not pil_images:
|
||||
return None
|
||||
|
||||
buf = io.BytesIO()
|
||||
first, rest = pil_images[0], pil_images[1:]
|
||||
try:
|
||||
first.save(buf, format="PDF", save_all=True, append_images=rest)
|
||||
return buf.getvalue()
|
||||
except Exception:
|
||||
return None
|
||||
finally:
|
||||
for im in pil_images:
|
||||
try:
|
||||
im.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _looks_like_isbn(text: str) -> bool:
|
||||
t = (text or "").replace("-", "").strip()
|
||||
return t.isdigit() and len(t) in (10, 13)
|
||||
@@ -941,32 +989,22 @@ class OpenLibrary(SearchProvider):
|
||||
try:
|
||||
images = self._archive_download(session=session, n_threads=10, directory=temp_dir, links=links, scale=3, book_id=archive_id)
|
||||
|
||||
try:
|
||||
import img2pdf # type: ignore
|
||||
|
||||
pdf_bytes = img2pdf.convert(images) if images else None
|
||||
if not pdf_bytes:
|
||||
log("[openlibrary] PDF conversion failed", file=sys.stderr)
|
||||
try:
|
||||
shutil.rmtree(temp_dir)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
pdf_path = unique_path(output_dir / f"{title}.pdf")
|
||||
with open(pdf_path, "wb") as f:
|
||||
f.write(pdf_bytes)
|
||||
|
||||
try:
|
||||
shutil.rmtree(temp_dir)
|
||||
except Exception:
|
||||
pass
|
||||
return pdf_path
|
||||
|
||||
except ImportError:
|
||||
# Keep images folder.
|
||||
pdf_bytes = _image_paths_to_pdf_bytes(images)
|
||||
if not pdf_bytes:
|
||||
# Keep images folder for manual conversion.
|
||||
log("[openlibrary] PDF conversion failed; keeping images folder", file=sys.stderr)
|
||||
return Path(temp_dir)
|
||||
|
||||
pdf_path = unique_path(output_dir / f"{title}.pdf")
|
||||
with open(pdf_path, "wb") as f:
|
||||
f.write(pdf_bytes)
|
||||
|
||||
try:
|
||||
shutil.rmtree(temp_dir)
|
||||
except Exception:
|
||||
pass
|
||||
return pdf_path
|
||||
|
||||
except Exception:
|
||||
try:
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
Reference in New Issue
Block a user