| from __future__ import annotations |
| from pathlib import Path |
| import fitz |
| from pypdf import PdfReader, PdfWriter |
| from src.core.models import PDFOperation |
|
|
| class OfflinePDFEditingAgent: |
| name = "editing_agent" |
|
|
| def run(self, input_pdf: Path, output_pdf: Path, operations: list[PDFOperation]) -> Path: |
| doc = fitz.open(input_pdf) |
| page_ops = [op for op in operations if op.type in ("insert_text","whiteout_region","rotate_page")] |
| delete_ops = [op for op in operations if op.type == "delete_page"] |
| reorder_ops = [op for op in operations if op.type == "reorder_pages"] |
|
|
| for op in page_ops: |
| if op.page is None or op.page >= len(doc): continue |
| page = doc[op.page] |
| if op.type == "insert_text" and op.position and op.text: |
| color = tuple(op.color) if op.color else (0, 0, 0) |
| page.insert_text(op.position, op.text, fontsize=12, color=color, overlay=True) |
| elif op.type == "whiteout_region" and op.rect: |
| page.draw_rect(fitz.Rect(op.rect), color=(1,1,1), fill=(1,1,1), overlay=True) |
| if op.text: |
| x0, y0 = op.rect[0], op.rect[1] |
| page.insert_text((x0+4, y0+14), op.text, fontsize=12, color=(0,0,0), overlay=True) |
| elif op.type == "rotate_page" and op.rotation is not None: |
| page.set_rotation(op.rotation) |
|
|
| stage = output_pdf.with_name(output_pdf.stem + "-pre.pdf") |
| stage.parent.mkdir(parents=True, exist_ok=True) |
| doc.save(stage, garbage=4, deflate=True, clean=True) |
| doc.close() |
|
|
| reader = PdfReader(str(stage)) |
| writer = PdfWriter() |
| delete_indices = {op.page for op in delete_ops if op.page is not None} |
| order = reorder_ops[-1].pages if reorder_ops else None |
| indices = [i for i in range(len(reader.pages)) if i not in delete_indices] |
| if order: |
| indices = [i for i in order if i not in delete_indices] |
| for idx in indices: |
| writer.add_page(reader.pages[idx]) |
| output_pdf.parent.mkdir(parents=True, exist_ok=True) |
| with output_pdf.open("wb") as f: |
| writer.write(f) |
| stage.unlink(missing_ok=True) |
| return output_pdf |
|
|