From 7e3ea4bc4def13d9068c6ae07bf3be634d8fd505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Wed, 17 Jun 2026 20:26:59 +0400 Subject: [PATCH] =?UTF-8?q?camelot=20=D0=B4=D0=BB=D1=8F=20=D1=82=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=86=20PDF=20(lattice+stream),=20fallback?= =?UTF-8?q?=20=D0=BD=D0=B0=20pdfplumber,=20v1.27?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- site/parser.py | 50 +++++++++++++++++++++++++++++++++----- site/templates/upload.html | 2 +- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/site/parser.py b/site/parser.py index b37e27b..f456564 100644 --- a/site/parser.py +++ b/site/parser.py @@ -123,7 +123,15 @@ def _parse_doc(file_bytes: bytes) -> dict: def _parse_pdf(file_bytes: bytes) -> dict: result = {"elements": [], "errors": []} + import tempfile, os as _os + + # Сохранить PDF во временный файл (camelot требует путь) + tmp_path = None try: + with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as tmp: + tmp.write(file_bytes) + tmp_path = tmp.name + import pdfplumber with pdfplumber.open(io.BytesIO(file_bytes)) as pdf: @@ -142,18 +150,48 @@ def _parse_pdf(file_bytes: bytes) -> dict: "page": pn, }) - # Таблицы на странице - tables = page.extract_tables() - for tbl in tables: - if tbl: + # Таблицы — camelot (точнее), иначе pdfplumber + tables_found = False + try: + import camelot + # Сначала lattice (таблицы с рамками) + for flavor in ("lattice", "stream"): + try: + ctables = camelot.read_pdf(tmp_path, pages="all", flavor=flavor) + for ct in ctables: + rows = [list(ct.df.columns)] + ct.df.values.tolist() result["elements"].append({ "type": "table", - "rows": tbl, - "page": pn, + "rows": rows, + "page": ct.page, }) + tables_found = True + except Exception: + pass + except ImportError: + result["errors"].append("camelot not installed, using pdfplumber") + except Exception as e: + result["errors"].append(f"camelot error: {e}") + + # Fallback: pdfplumber таблицы если camelot ничего не нашёл + if not tables_found: + with pdfplumber.open(io.BytesIO(file_bytes)) as pdf: + for page in pdf.pages: + pn = page.page_number + tables = page.extract_tables() + for tbl in tables: + if tbl: + result["elements"].append({ + "type": "table", + "rows": tbl, + "page": pn, + }) except Exception as e: result["errors"].append(f"pdf parse error: {e}") + finally: + if tmp_path and _os.path.exists(tmp_path): + _os.unlink(tmp_path) return result diff --git a/site/templates/upload.html b/site/templates/upload.html index 8283894..e09ee70 100644 --- a/site/templates/upload.html +++ b/site/templates/upload.html @@ -59,7 +59,7 @@
Nubes - Сверка договоров v1.26 + Сверка договоров v1.27