#!/usr/bin/env -S uv run --script # /// script # requires-python = ">=3.11" # dependencies = [ # "reportlab>=4.0", # "python-barcode>=0.15", # ] # /// """Generate a Paperless-ngx separator page (PATCHT Code-128 barcode). Run: ./generate_separator.py [out.pdf] Default output: separator-patchT.pdf next to this script. m prints the resulting PDF and lays one sheet between each document in a multi-letter scan stack. Paperless-ngx (with PAPERLESS_CONSUMER_ENABLE_BARCODES=true) detects the barcode and splits the consumed PDF into separate documents. """ import sys from pathlib import Path from barcode import Code128 from barcode.writer import ImageWriter from reportlab.lib.pagesizes import A4 from reportlab.lib.units import cm from reportlab.pdfgen import canvas SEPARATOR_STRING = "PATCHT" def main(out_path: Path) -> None: page_w, page_h = A4 # Render barcode to a temporary PNG (reportlab needs an image source). tmp_png = out_path.with_suffix(".tmp") barcode = Code128(SEPARATOR_STRING, writer=ImageWriter()) barcode_path = barcode.save( str(tmp_png), options={ "module_width": 0.6, # mm per bar — bigger = easier OCR detection "module_height": 30.0, # mm tall "font_size": 14, "text_distance": 5, "quiet_zone": 8, "write_text": True, }, ) c = canvas.Canvas(str(out_path), pagesize=A4) # Header c.setFont("Helvetica-Bold", 36) c.drawCentredString(page_w / 2, page_h - 4 * cm, "SEPARATOR") c.setFont("Helvetica", 14) c.drawCentredString(page_w / 2, page_h - 5 * cm, "Zwischen zwei Dokumente legen — Paperless splittet hier.") # Big crosshair for easy alignment when scanning c.setLineWidth(1) c.setStrokeGray(0.7) c.line(page_w / 2 - 4 * cm, page_h - 6 * cm, page_w / 2 + 4 * cm, page_h - 6 * cm) # Barcode — large, centred img_w, img_h = 14 * cm, 5 * cm c.drawImage( barcode_path, (page_w - img_w) / 2, (page_h - img_h) / 2 - 1 * cm, width=img_w, height=img_h, preserveAspectRatio=True, mask="auto", ) # Footer c.setFont("Helvetica", 10) c.setFillGray(0.3) c.drawCentredString(page_w / 2, 4 * cm, f"Code-128 · {SEPARATOR_STRING} · Paperless-ngx Barcode-Splitter") c.drawCentredString(page_w / 2, 3 * cm, "Detection: PAPERLESS_CONSUMER_ENABLE_BARCODES=true") c.drawCentredString(page_w / 2, 2.4 * cm, "Generator: infra/paperless/generate_separator.py (mDMS)") c.showPage() c.save() Path(barcode_path).unlink(missing_ok=True) print(f"wrote {out_path}") if __name__ == "__main__": out = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).parent / "separator-patchT.pdf" main(out)