From 2399b01a26e5a9a33bac223bef37953b9144f497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Tue, 23 Jun 2026 12:18:48 +0400 Subject: [PATCH] v1.0.148: PDF parsing via PyPDF2 on VM (replaces broken PDFBox on Lucee) --- deploy/convert_server.py | 46 ++++++++++++++++++++++++++++++++++++ deploy/nginx-contracts.conf | 5 ++++ parser.cfm | 47 ++++++++++--------------------------- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/deploy/convert_server.py b/deploy/convert_server.py index 307c0b0..7d20404 100755 --- a/deploy/convert_server.py +++ b/deploy/convert_server.py @@ -57,6 +57,13 @@ class Handler(BaseHTTPRequestHandler): self.send_header("Access-Control-Allow-Headers", "Content-Type") self.end_headers() + def do_GET(self): + parsed = urlparse(self.path) + if parsed.path == "/process-v2": + self._handle_process_v2(parsed) + else: + self.send_error(404) + def do_POST(self): if self.path == "/llm-ops": self._handle_llm_ops() @@ -64,6 +71,8 @@ class Handler(BaseHTTPRequestHandler): self._handle_unzip_upload() elif self.path == "/upload": self._handle_upload() + elif self.path == "/parse-pdf": + self._handle_parse_pdf() else: self._handle_doc_convert() @@ -345,6 +354,43 @@ class Handler(BaseHTTPRequestHandler): else: self._send_error_cors(502, f"assemble failed: HTTP {resp.status_code}") + def _handle_parse_pdf(self): + """Распарсить PDF через PyPDF2 (получает base64 тело от Lucee).""" + import base64 + from PyPDF2 import PdfReader + import io as io_module + + length = int(self.headers.get("Content-Length", 0)) + body = self.rfile.read(length).decode("utf-8", errors="ignore").strip() + raw = base64.b64decode(body) + + try: + reader = PdfReader(io_module.BytesIO(raw)) + elements = [] + for page in reader.pages: + text = page.extract_text() + if text: + for line in text.split('\n'): + line = line.strip() + if line: + elements.append({"type": "paragraph", "text": line, "style": ""}) + result = { + "ok": True, + "status": "parsed", + "element_count": len(elements), + "elements": elements, + "tables": 0, + "paragraphs": len(elements), + } + except Exception as e: + result = {"ok": False, "status": "error", "error": str(e), "element_count": 0} + + self.send_response(200) + self.send_header("Content-Type", "application/json; charset=utf-8") + self.send_header("Access-Control-Allow-Origin", "*") + self.end_headers() + self.wfile.write(json.dumps(result, ensure_ascii=False).encode()) + def _handle_unzip_upload(self): """Распаковать ZIP и загрузить каждый файл в Lucee. Только файлы из корня архива.""" import zipfile, io diff --git a/deploy/nginx-contracts.conf b/deploy/nginx-contracts.conf index efb16a8..509ce2f 100644 --- a/deploy/nginx-contracts.conf +++ b/deploy/nginx-contracts.conf @@ -43,6 +43,11 @@ server { add_header Access-Control-Allow-Methods "GET, OPTIONS" always; } + location /parse-pdf { + proxy_pass http://127.0.0.1:8766; + proxy_read_timeout 60s; + } + location /upload { if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin "*"; diff --git a/parser.cfm b/parser.cfm index e64ef68..2607e90 100644 --- a/parser.cfm +++ b/parser.cfm @@ -10,42 +10,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - +