| from __future__ import annotations |
| from pathlib import Path |
| import fitz |
| from src.core.models import PDFOperation |
|
|
| class OfflineAnnotationAgent: |
| name = "annotation_agent" |
|
|
| def run(self, input_pdf: Path, output_pdf: Path, operations: list[PDFOperation]) -> Path: |
| doc = fitz.open(input_pdf) |
| for op in operations: |
| if op.page is None or op.page >= len(doc): continue |
| page = doc[op.page] |
| rect = fitz.Rect(op.rect) if op.rect else None |
| color = tuple(op.color) if op.color else (1, 1, 0) |
| if op.type == "highlight" and rect: |
| annot = page.add_highlight_annot(rect) |
| annot.set_colors(stroke=color) |
| annot.update() |
| elif op.type == "comment" and op.position and op.text: |
| annot = page.add_text_annot(fitz.Point(op.position), op.text) |
| annot.set_info(title=op.author, content=op.text) |
| annot.update() |
| elif op.type == "rectangle" and rect: |
| annot = page.add_rect_annot(rect) |
| annot.set_colors(stroke=color) |
| annot.update() |
| elif op.type == "redact" and rect: |
| page.add_redact_annot(rect, text=op.text or "", fill=(0,0,0)) |
| for page in doc: |
| try: |
| page.apply_redactions(images=fitz.PDF_REDACT_IMAGE_REMOVE) |
| except Exception: |
| pass |
| output_pdf.parent.mkdir(parents=True, exist_ok=True) |
| doc.save(output_pdf, garbage=4, deflate=True, clean=True) |
| return output_pdf |
|
|