fix: drhider PDF→DOCX via pdfplumber (LibreOffice cant do it) v1.12
Deploy contracts-flask / validate (push) Successful in 0s
Deploy contracts-flask / validate (push) Successful in 0s
This commit is contained in:
+30
-27
@@ -252,8 +252,9 @@ class TwoPassObfuscator:
|
||||
self._sorted_keys.clear()
|
||||
|
||||
def _convert_pdfs_to_docx(self, files: List[Tuple[str, bytes, str]]) -> List[Tuple[str, bytes, str]]:
|
||||
"""Конвертировать PDF в DOCX через LibreOffice. При совпадении имён — _из_pdf."""
|
||||
import subprocess, tempfile
|
||||
"""Конвертировать PDF в DOCX через pdfplumber. При совпадении имён — _из_pdf."""
|
||||
import pdfplumber
|
||||
from docx import Document as DocxDocument
|
||||
result = []
|
||||
existing_names = {f[0] for f in files}
|
||||
for fname, content, ctype in files:
|
||||
@@ -261,34 +262,36 @@ class TwoPassObfuscator:
|
||||
result.append((fname, content, ctype))
|
||||
continue
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as tmp:
|
||||
tmp.write(content)
|
||||
pdf_path = tmp.name
|
||||
outdir = tempfile.mkdtemp()
|
||||
subprocess.run(['libreoffice', '--headless', '--convert-to', 'docx',
|
||||
'--outdir', outdir, pdf_path], timeout=30, capture_output=True)
|
||||
docx_files = [f for f in os.listdir(outdir) if f.endswith('.docx')]
|
||||
if docx_files:
|
||||
with open(os.path.join(outdir, docx_files[0]), 'rb') as f:
|
||||
docx_content = f.read()
|
||||
new_name = fname[:-4] + '.docx'
|
||||
if new_name in existing_names:
|
||||
new_name = fname[:-4] + '_из_pdf.docx'
|
||||
existing_names.add(new_name)
|
||||
result.append((new_name, docx_content, ctype))
|
||||
else:
|
||||
log.warning("PDF→DOCX failed for %s", fname)
|
||||
result.append((fname, content, ctype))
|
||||
doc = DocxDocument()
|
||||
with pdfplumber.open(io.BytesIO(content)) as pdf:
|
||||
for page in pdf.pages:
|
||||
tables = page.extract_tables()
|
||||
for table in tables:
|
||||
if table:
|
||||
rows = [[str(c or "").strip() for c in (row or [])] for row in table]
|
||||
rows = [r for r in rows if any(r)]
|
||||
if rows:
|
||||
t = doc.add_table(rows=len(rows), cols=len(rows[0]))
|
||||
t.style = 'Table Grid'
|
||||
for ri, row in enumerate(rows):
|
||||
for ci, cell_text in enumerate(row):
|
||||
t.rows[ri].cells[ci].text = cell_text
|
||||
text = page.extract_text()
|
||||
if text:
|
||||
for line in text.split('\n'):
|
||||
line = line.strip()
|
||||
if line:
|
||||
doc.add_paragraph(line)
|
||||
buf = io.BytesIO()
|
||||
doc.save(buf)
|
||||
new_name = fname[:-4] + '.docx'
|
||||
if new_name in existing_names:
|
||||
new_name = fname[:-4] + '_из_pdf.docx'
|
||||
existing_names.add(new_name)
|
||||
result.append((new_name, buf.getvalue(), ctype))
|
||||
except Exception as e:
|
||||
log.warning("PDF→DOCX error for %s: %s", fname, e)
|
||||
result.append((fname, content, ctype))
|
||||
finally:
|
||||
if os.path.exists(pdf_path):
|
||||
os.unlink(pdf_path)
|
||||
if os.path.exists(outdir):
|
||||
for f in os.listdir(outdir):
|
||||
os.unlink(os.path.join(outdir, f))
|
||||
os.rmdir(outdir)
|
||||
return result
|
||||
|
||||
def _expand_zips(self, files: List[Tuple[str, bytes, str]]) -> List[Tuple[str, bytes, str]]:
|
||||
|
||||
Reference in New Issue
Block a user