.. /* * This file is part of the SavaPage project . * Copyright (c) 2026 Datraverse B.V. * Author: Rijk Ravestein. * * SPDX-FileCopyrightText: (c) 2020 Datraverse B.V. * SPDX-License-Identifier: CC-BY-SA-4.0 * * For more information, please contact Datraverse B.V. at this * address: info@datraverse.com */ .. _app-plugin-ipp-routing: |IPP_ROUTING| Plug-in --------------------- This plug-in is called on an :ref:`IPP Routing ` event, just before the PDF is send to the |PROXYPRINTER|. The plug-in supports PDF edit actions, like adding header and footer text, and a `QR code `__ image. The QR code itself can optionally be a constant, a generated UUID or obtained by executing a third-party RESTful POST request that registers the print job and delivers the QR code in return. .. note:: The QR code is shown in the :ref:`Documents ` and :ref:`Transactions ` Log. .. tip:: If the :ref:`Document Store ` is enabled for Print Out, and Archive/Journal is not disabled for the target :ref:`Proxy Printer `, a third-party can retrieve the printed PDF by calling a |PRODUCT_NAME| RESTful service with the QR code as ``ext_id``. See :ref:`GET /documents/ext_id=\/pdf `. An annotated ``savapage-ext-ipp-routing.properties.template`` is present in the ``/opt/savapage/ext`` directory. Copy this template to a file with a ``.properties`` extension in the same directory and restrict permissions, since the file contains confidential information. An example: .. code-block:: bash sudo su - savapage cd /opt/savapage/server/ext cp savapage-ext-ipp-routing.properties.template savapage-ext-ipp-routing.properties chmod 600 savapage-ext-ipp-routing.properties Edit the ``.properties`` file to specify the necessary data and restart |PRODUCT_NAME| to test the plug-in. Apart from the standard plug-in keys, the plug-in file contains specific ``routing.*`` keys as explained in the table below. .. list-table:: |IPP_ROUTING| Plug-in: .properties keys :width: 100% :header-rows: 1 * - Key - Description * - routing.id - A fixed or generated routing ID stored as document ext_id (max 64 chars). See :ref:`GET /documents/ext_id=[ext_id] ` |br| |br| *Placeholder values:* - ``$uuid$`` : Generated UUID. * - |br| *RESTful POST request to register print job and obtain QR code.* |br| |br| - * - routing.rest.uri - RESTful resource URI. * - | routing.rest.user | routing.rest.password - HTTP Basic Authentication User and Password * - routing.rest.post.request.entity - The entity to be POST-ed. |br| |br| *Placeholder values:* - ``$uuid$`` : Generated UUID - ``$user_id$`` : User id - ``$client_ip$`` : Client IP address - ``$queue_name$`` : Print-in Queue name - ``$printer_name$`` : CUPS printer name - ``$printer_uri$`` : CUPS printer URI - ``$printer_uri_host$`` : CUPS printer URI host component - ``$job_name$`` : Print Job Name (document name) - ``$job_time$`` : Print Job datetime in ISO_8601 format - ``$page_width_mm$`` : Print Job first page width (millimeters) - ``$page_height_mm$`` : Print Job first page height (millimeters) * - routing.rest.post.request.mediatype - `Media type `__ of request entity. There are two options: - ``text/plain`` - ``application/json`` * - routing.rest.post.response.mediatype - Media type of request entity. There are two options: - ``text/plain`` : delivers the QR code as plain text. - ``application/json`` : delivers the JSON representation of ``org.savapage.ext.print.IppRoutingDto`` POJO [1]_. The routing "id" is mandatory. All other values override the ones that are configured in their respective ``routing.pdf.*`` keys of the ``.properties`` file (see keys below). * - |br| *QR image* |br| |br| - * - routing.pdf.qrcode.content - QR code content. |br| |br| *Placeholder values:* - ``$routing_id$`` : routing.id * - routing.pdf.qrcode.size - Square QR code size in millimeters (width == height). * - routing.pdf.qrcode.qz - Quiet zone [2]_ in millimeters. When not specified, zero (0) is applied. * - routing.pdf.qrcode.pos.anchor - Position in PDF document. ``TL`` (top-left, default), ``TR`` (top-right), ``BL`` (bottom-left), ``BR`` (bottom-right). * - | routing.pdf.qrcode.pos.margin.x | routing.pdf.qrcode.pos.margin.y - Margins in millimeters. * - |br| *Header* |br| |br| - * - routing.pdf.header.text - Header text: Helvetica Font, color Gray. * - routing.pdf.header.font.size - Font size points (pt). * - routing.pdf.header.margin.top - Top margin in millimeters. * - |br| *Footer* |br| |br| - * - routing.pdf.footer.text - Footer text: Helvetica Font, color Gray. * - routing.pdf.footer.font.size - Font size points (pt). * - routing.pdf.footer.margin.bottom - Bottom margin in millimeters. * - |br| *PDF info (optional)* |br| |br| - * - routing.pdf.info.title - PDF Title * - routing.pdf.info.subject - PDF Subject * - routing.pdf.info.author - PDF Author * - routing.pdf.info.keywords - A space separated list of PDF keywords. .. [1] ``org.savapage.ext.print.IppRoutingDto`` POJO can be found in https://code.savapage.org/savapage/savapage-ext. .. [2] The Quiet Zone (QZ) is the area around the QR code that is clear of text, graphics, and any other printing. The QZ helps isolate a QR code of its surroundings in order to guarantee a correct readability. Some examples: - A plug-in using |PRODUCT_NAME| RESTful service to echo the generated ``routing.pdf.qrcode.content``. This has no practical use other than to test the RESTful interface. .. code-block:: ini routing.id=$uuid$ routing.pdf.qrcode.rest.uri=https://localhost:8632/restful/v1/tests/echo routing.pdf.qrcode.rest.user=admin routing.pdf.qrcode.rest.password=password routing.pdf.qrcode.rest.post.request.entity=$uuid$ routing.pdf.qrcode.rest.post.request.mediatype=text/plain routing.pdf.qrcode.rest.post.response.mediatype=text/plain routing.pdf.qrcode.size=12 routing.pdf.qrcode.qz=2 routing.pdf.qrcode.pos=BR routing.pdf.qrcode.pos.margin.x=9 routing.pdf.qrcode.pos.margin.y=35 routing.pdf.header=Sample Header Text routing.pdf.header.font.size=8 routing.pdf.header.margin.top=15 routing.pdf.footer=Sample Footer Text routing.pdf.footer.font.size=6 routing.pdf.foooter.margin.bottom=10 - A plug-in calling a third-party RESTful service to obtain the ``routing.pdf.qrcode.content``. See :ref:`RESTful Client ` configuration properties. .. code-block:: ini routing.id=$uuid$ routing.pdf.qrcode.rest.uri=https://192.168.1.51:8080/register routing.pdf.qrcode.rest.user=savapage routing.pdf.qrcode.rest.password=elah7deV routing.pdf.qrcode.rest.post.request.entity={"printUser":"$user_id$",\ "printIp":"$client_ip$",\ "printerName":"$printer_name$",\ "docTitle":"$job_name$",\ "printTime":"$job_time$"} routing.pdf.qrcode.rest.post.request.mediatype=application/json routing.pdf.qrcode.rest.post.response.mediatype=text/plain routing.pdf.qrcode.size=12 routing.pdf.qrcode.qz=2 routing.pdf.qrcode.pos=BR routing.pdf.qrcode.pos.margin.x=9 routing.pdf.qrcode.pos.margin.y=35 .. note:: Multiple |IPP_ROUTING| Plug-ins can be active in ``/opt/savapage/ext`` directory. Each one will be executed upon an |IPP_ROUTING| event. The order of execution is undefined.