{"id":19218880,"url":"https://github.com/openprinting/ps-printer-app","last_synced_at":"2026-06-25T21:30:17.108Z","repository":{"id":64463132,"uuid":"307431904","full_name":"OpenPrinting/ps-printer-app","owner":"OpenPrinting","description":"PostScript Printer Application","archived":false,"fork":false,"pushed_at":"2025-02-16T07:22:27.000Z","size":338,"stargazers_count":40,"open_issues_count":5,"forks_count":13,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-02-16T08:20:46.099Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PostScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenPrinting.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-26T16:15:10.000Z","updated_at":"2025-02-16T07:22:31.000Z","dependencies_parsed_at":"2024-02-08T17:54:45.877Z","dependency_job_id":"fac3d00f-53ae-455d-80e3-7708141fa2ea","html_url":"https://github.com/OpenPrinting/ps-printer-app","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenPrinting%2Fps-printer-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenPrinting%2Fps-printer-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenPrinting%2Fps-printer-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenPrinting%2Fps-printer-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenPrinting","download_url":"https://codeload.github.com/OpenPrinting/ps-printer-app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240292395,"owners_count":19778311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T14:28:36.457Z","updated_at":"2026-06-25T21:30:15.046Z","avatar_url":"https://github.com/OpenPrinting.png","language":"PostScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostScript Printer Application\n\n## INTRODUCTION\n\nThis repository contains a Printer Application for PostScript printers\nthat uses [PAPPL](https://www.msweet.org/pappl) to support IPP\nprinting from multiple operating systems. In addition, it uses the\nresources of [cups-filters\n2.x](https://github.com/OpenPrinting/cups-filters) (filter functions\nin libcupsfilters, libppd) and\n[pappl-retrofit](https://github.com/OpenPrinting/pappl-retrofit)\n(encapsulating classic CUPS drivers in Printer Applications). This\nwork (or now the code of pappl-retrofit) is derived from the\n[hp-printer-app](https://github.com/michaelrsweet/hp-printer-app).\n\nYour contributions are welcome. Please post [issues and pull\nrequests](https://github.com/OpenPrinting/ps-printer-app).\n\n\n### This Printer Application is a working model for\n\n- A non-raster Printer Application: Destination format is PostScript,\n  a high-level/vector format. Input data in PostScript or PDF is\n  accepted and needed conversion is done without any inbetween raster\n  steps.\n\n- A Printer Application which uses the new filter functions of\n  cups-filters 2.x. Filter functions are library functions derived\n  from the CUPS filters and contain decades of development and\n  refinement starting from the introduction of CUPS in 2000.\n\n- A retro-fit Printer Application for classic CUPS drivers, in this\n  case the simplest form of only PPD files for PostScript printers. It\n  lists PPD files from repositories included in the Snap, loads the\n  PPD needed for the actual printer, extracts options from the PPD to\n  display them in the web interface, accepts job settings as IPP\n  attributes, and inserts the PostScript code provided by the PPD\n  correctly into the output data stream.\n\n- A Printer Application which does not pass through raw (input format\n  is printer's native format) jobs. To assure that always the\n  PostScript code of the PPD file is inserted into the output stream,\n  we call the printer's native format\n  \"application/vnd.printer-specific\" which does not exist as input\n  format, so \"application/postscript\" input is forced through the\n  pstops() filter function.\n\n- An expandable Printer Application: The user can add PPD files via the\n  administration web interface to support additional printer models.\n\nFurther properties are:\n\n- To avoid the need to re-invent the code for forking into sub-processes\n  so that we can pass data through a sequence of filters, we create a\n  filter function to send the data off to the printer and form a chain\n  of the actually converting filter function (one of pstops() and\n  pdftops()) with this filter function using the filterChain() filter\n  function.\n\n- For PWG/Apple Raster input we use raster callbacks so that the\n  processing is streaming, allowing for large and even infinitely long\n  jobs. We use libppd functions to insert the PPD option's PostScript\n  code in the output stream and the filterPOpen() function to create a\n  file descriptor for the libppd functions to send data off to the\n  device.\n\n- The PostScript Printer Application Snap has all PostScript PPD files\n  of the [foomatic-db](https://github.com/OpenPrinting/foomatic-db)\n  and [HPLIP](https://developers.hp.com/hp-linux-imaging-and-printing)\n  projects built-in, so most PostScript printer PPDs which usually\n  come with Linux Distributions. To avoid that this vast number of\n  PPDs blows up the size of the Snap, we highly compress them using\n  [pyppd](https://github.com/OpenPrinting/pyppd). Note that some PPDs\n  use certain CUPS filters for extra functionality. These filters are\n  included in the Snap, so the extra functionality is supported (in\n  most cases PIN-protected printing). The user can add additional PPDs\n  without needing to rebuild the Snap (see below).\n\n- We use the printer's IEEE-1284 device ID to identify at first that\n  it is a PostScript printer (via CMD: field) to see whether it is\n  supported at all and only then check via make and model whether we\n  explicitly support it with a PPD. PostScript printers for which\n  there is no PPD get a generic PPD assigned. By the check of the CMD:\n  field before make/model lookup we assure that if PostScript is\n  provided by an add-on module that the module is actually installed.\n\n- Standard job IPP attributes are mapped to the PPD option settings\n  best fitting to them so that users can print from any type of client\n  (like for example a phone or IoT device) which only supports\n  standard IPP attributes and cannot retrive the PPD options. Trays,\n  media sizes, media types, and duplex can get mapped easily, but when\n  it comes to color and quality it gets more complex, as relevant\n  options differ a lot in the PPD files. Here we use an algorithm\n  which automatically (who wants hand-edit ~10000 PPDs for the\n  assignments) finds the right set of option settings for each\n  combination of `print-color-mode` (`color`/`monochrome`),\n  `print-quality` (`draft`/`normal`/`high`), and\n  `print-content-optimize`\n  (`auto`/`photo`/`graphics`/`text`/`text-and-graphics`) in the PPD of\n  the current printer. So you have easy access to the full quality or\n  speed of your printer without needing to deal with printer-specific\n  option settings (the original options are still accessible via web\n  admin interface).\n\n- The printer capabilities for a given printer model (a \"driver\" in\n  the Printer Application) are not static throughout the life of the\n  print queue set up in the Printer Application. The user can\n  configure via a page in the web admin interface which hardware\n  accessories (extra paper trays, duplex unit, finishers, ...) are\n  installed on the printer and the Printer Application updates the\n  driver data structure and with this the printer capabilities. The\n  response to a get-printer-attributes IPP request gets updated\n  appropriately.\n\n- PostScript is a full-fledged programming language and many PostScript\n  printers allow querying settings of options and the presence of\n  installable hardware accessories executing appropriate PostScript\n  code. If a setting can get queried, the manufacturer puts the needed\n  PostScript code into the PPD file, together with the queriable option.\n  These queries are supported by the web interface of the Printer\n  Application.\n\n- Available printer devices are discovered (and used) with CUPS'\n  backends and not with PAPPL's own backends. This way quirk\n  workarounds for USB printers with compatibility problems are used\n  (and are editable) and PostScript output can get sent to the printer\n  via IPP, IPPS (encrypted!), and LPD in addition to socket (usually\n  port 9100). The SNMP backend can get configured (community, address\n  scope).\n\n- If you have an unusual system configuration or a personal firewall\n  your printer will perhaps not get discovered. In this situation the\n  fully manual \"Network Printer\" entry in combination with the\n  hostname/IP field can be helpful.\n\n\n### Remark\n\n- This Printer Application and its snapping is derived from the\n  hp-printer-app, which uses the \"avahi-observe\" Snap interface to\n  access DNS-SD. This does not work for registering printers. In this\n  Printer Application this is already corrected to \"avahi-control\".\n\n\n### To Do\n\n- On the \"Add PPD files\" page in the list of already added user PPD\n  files mark which ones are actually used by a printer which got set\n  up in the Printer Application, to avoid that the user removes these\n  files.\n\n- Human-readable strings for vendor options (Needs support by PAPPL:\n  [Issue #58: Localization\n  support](https://github.com/michaelrsweet/pappl/issues/58))\n\n- Internationalization/Localization (Needs support by PAPPL: [Issue\n  #58: Localization\n  support](https://github.com/michaelrsweet/pappl/issues/58))\n\n- SNMP Ink level check via ps_status() function (Needs support by PAPPL:\n  [Issue #83: CUPS does IPP and SNMP ink level polls via backends,\n  PAPPL should have functions for\n  this](https://github.com/michaelrsweet/pappl/issues/83))\n\n- Build options for cups-filters, to build without libqpdf and/or\n  without libppd, the former will allow to create the Snap of this\n  Printer Application without downloading and building QPDF\n\n\n## THE SNAP\n\n### Installing and building\n\nTo just run and use this Printer Application, simply install it from\nthe Snap Store:\n\n```\nsudo snap install --edge ps-printer-app\n```\n\nThen follow the instructions below for setting it up.\n\nTo build the Snap by yourself, in the main directory of this\nrepository run\n\n```\nsnapcraft snap\n```\n\nThis will download all needed packages and build the PostScript\nPrinter Application. Note that PAPPL (upcoming 1.0) and cups-filters\n(upcoming 2.0) are pulled directly from their GIT repositories, as\nthere are no appropriate releases yet. This can also lead to the fact\nthat this Printer Application will suddenly not build any more.\n\nNOTE: There is a bug in Ubuntu Groovy (20.10) that prevents it from\nbuilding Snaps, see [this discussion on the Snapcraft\nforum](https://forum.snapcraft.io/t/build-fails-with-a-mksquashfs-error-cannot-pack-root-prime/). The\nproblem is already solved but did not make it into Groovy yet.\n\nAny older (like 20.04) or newer (like 21.04) Ubuntu version should work.\n\nTo install the resulting Snap run\n\n```\nsudo snap install --dangerous ps-printer-app_1.0_amd64.snap\n```\n\n\n### Setting up\n\nThe Printer Application will automatically be started as a server daemon.\n\nEnter the web interface\n\n```\nhttp://localhost:8000/\n```\n\nUse the web interface to add a printer. Supply a name, select the\ndiscovered printer, then select make and model. Also set the installed\naccessories, loaded media and the option defaults. Accessory\nconfiguration and option defaults can also offen get polled from the\nprinter.\n\nThen print PDF, PostScript, JPEG, Apple Raster, or PWG Raster files\nwith\n\n```\nps-printer-app FILE\n```\n\nor print with CUPS, CUPS (and also cups-browsed) discover and treat\nthe printers set up with this Printer Application as driverless IPP\nprinters (IPP Everywhere and AirPrint).\n\nYou can also add PPD files without rebuilding the Snap, either by\nusing the \"Add PPD files\" button in the web interface or by manually\ncopying PPD files:\n\n```\nsudo cp PPDFILE /var/snap/ps-printer-app/common/ppd/\n```\n\nAfter manually copying (or removing) PPD files you need to restart the\nserver or in the web interface, on the \"Add PPD files\" page click the\n\"Refresh\" button at the bottom. This adds the changes to the internal\ndriver list.\n\nOn the \"Add Printer\" page in the drop-down to select the driver,\nuser-added PPD files are marked \"USER-ADDED\". When setting up a\nprinter with automatic driver selection, user-added PPD files are\npreferred.\n\n`PPDFILE` in the command line above cannot only be a single PPD file\nbut any number of single PPD files, `.tar.gz` files containing PPDs\n(in arbitrary directory structure) and PPD-gemerating executables\nwhich are usually put into `/usr/lib/cups/driver`. You can also create\narbitrary sub-directory structures in\n`/var/snap/ps-printer-app/current/ppd/` containing the mentioned types\nof files. Only make sure to not put any executables there which do\nanything else than listing and generating PPD files.\n\nNote that with the web interface you can only manage individual PPDs\n(uncompressed or compressed with `gzip`) in the\n`/var/snap/ps-printer-app/current/ppd/` itself. Archives, executables,\nor sub-directories are not shown and appropriate uploads not\naccepted. This especially prevents adding executables without root\nrights.\n\nAny added PPD file must be for PostScript printers, as non-PostScript\nPPD files are for CUPS drivers and so they would need additional files\nin order to work and such files are not supported by this Printer\nApplication. The \"Add PPD files\" page shows warnings if such files get\nuploaded.\n\nSee\n\n```\nps-printer-app --help\n```\n\nfor more options.\n\nUse the \"-o log-level=debug\" argument for verbose logging in your\nterminal window.\n\nYou can add files to `/var/snap/ps-printer-app/common/usb/` for\nadditional USB quirk rules. Edit the existing files only for quick\ntests, as they get replaced at every update of the Snap (to introduce\nnew rules).\n\nYou can edit the `/var/snap/ps-printer-app/common/cups/snmp.conf` file\nfor configuring SNMP network printer discovery.\n\n## THE ROCK (OCI CONTAINER IMAGE)\n\n### Install from DockerHub\n\n#### Prerequisites\n\n**Docker Installed**: Ensure Docker is installed on your system. You can download it from the [official Docker website](https://www.docker.com/get-started).\n\n#### Step-by-Step Guide\n\nYou can pull the `ps-printer-app` Docker image from either the GitHub Container Registry or Docker Hub.\n\n**From GitHub Container Registry** \u003cbr\u003e\nTo pull the image from the GitHub Container Registry, run the following command:\n```sh\n  sudo docker pull ghcr.io/openprinting/ps-printer-app:latest\n```\n\nTo run the container after pulling the image from the GitHub Container Registry, use:\n```sh\n  sudo docker run -d \\\n      --name ps-printer-app \\\n      --network host \\\n      -e PORT=\u003cport\u003e \\\n      ghcr.io/openprinting/ps-printer-app:latest\n```\n\n**From Docker Hub** \u003cbr\u003e\nAlternatively, you can pull the image from Docker Hub, by running:\n```sh\n  sudo docker pull openprinting/ps-printer-app\n```\n\nTo run the container after pulling the image from Docker Hub, use:\n```sh\n  sudo docker run -d \\\n      --name ps-printer-app \\\n      --network host \\\n      -e PORT=\u003cport\u003e \\\n      openprinting/ps-printer-app:latest\n```\n\n- `PORT` is an optional environment variable used to start the printer-app on a specified port. If not provided, it will start on the default port 8000 or, if port 8000 is busy, on 8001 and so on.\n- **The container must be started in `--network host` mode** to allow the Printer-Application instance inside the container to access and discover printers available in the local network where the host system is in.\n- Alternatively using the internal network of the Docker instance (`-p \u003cport\u003e:8000` instead of `--network host -e PORT=\u003cport\u003e`) only gives access to local printers running on the host system itself.\n\n### Setting up and running a ps-printer-app container locally\n\n#### Prerequisites\n\n**Docker Installed**: Ensure Docker is installed on your system. You can download it from the [official Docker website](https://www.docker.com/get-started) or from the Snap Store:\n```\nsudo snap install docker\n```\n\n**Rockcraft**: Rockcraft should be installed. You can install Rockcraft using the following command:\n```sh\n  sudo snap install rockcraft --classic\n```\n\n**Skopeo**: Skopeo should be installed to compile `*.rock` files into Docker images. It comes bundled with Rockcraft, so no separate installation is required.\n\n#### Step-by-Step Guide\n\n**Build the ps-printer-app Rock**\n\nThe first step is to build the Rock from the `rockcraft.yaml`. This image will contain all the configurations and dependencies required to run ps-printer-app.\n\nOpen your terminal and navigate to the directory containing your `rockcraft.yaml` (base directory of this package), then run the following command:\n```sh\n  rockcraft pack -v\n```\n\n**Compile to Docker image**\n\nOnce the rock is built, you need to compile a docker image from it:\n```sh\n  sudo rockcraft.skopeo --insecure-policy copy oci-archive:\u003crock_image\u003e docker-daemon:ps-printer-app:latest\n```\n\n**Run the ps-printer-app Docker Container**\n\n```sh\n  sudo docker run -d \\\n      --name ps-printer-app \\\n      --network host \\\n      -e PORT=\u003cport\u003e \\\n      ps-printer-app:latest\n```\n- `PORT` is an optional environment variable used to start the printer-app on a specified port. If not provided, it will start on the default port 8000 or, if port 8000 is busy, on 8001 and so on.\n- **The container must be started in `--network host` mode** to allow the Printer-Application instance inside the container to access and discover printers available in the local network where the host system is in.\n- Alternatively using the internal network of the Docker instance (`-p \u003cport\u003e:8000` instead of `--network host -e PORT=\u003cport\u003e`) only gives access to local printers running on the host system itself.\n\n#### Setting up\n\nEnter the web interface:\n```\nhttp://localhost:\u003cport\u003e/\n```\nUse the web interface to add a printer. Supply a name, select the\ndiscovered printer, then select automatic driver selection or choose a\nmake and model. Also set the installed accessories, loaded media and\nthe option defaults. Accessory configuration and option defaults can\nalso often get polled from the printer.\n\n\u003c!-- Begin Included Components --\u003e\n## Included Components\n  - pappl v1.4.8\n  - qpdf v11.10.1\n  - ghostscript ghostpdl-10.05.0-test-base-001\n  - cups v2.4.11\n  - libcupsfilters 2.1.1\n  - libppd 2.1.1\n  - cups-filters 2.0.1\n  - pyppd release-1-1-0\n  - foomatic-db 20240504\n  - hplip debian/3.22.10+dfsg0-8\n\u003c!-- End Included Components --\u003e\n\n## BUILDING WITHOUT PACKAGING OR INSTALLATION\n\nYou can also do a \"quick-and-dirty\" build without snapping and without\nneeding to install [PAPPL](https://www.msweet.org/pappl),\n[cups-filters 2.x](https://github.com/OpenPrinting/cups-filters), and\n[pappl-retrofit](https://github.com/OpenPrinting/pappl-retrofit) into\nyour system. You need a directory with the latest GIT snapshot of\nPAPPL, the latest GIT snapshot of cups-filters, and the latest GIT\nsnapshot of pappl-retrofit (master branches of each). They all need to\nbe compiled (`./autogen.sh; ./configure; make`), installing not\nneeded. Also install the header files of all needed libraries\n(installing \"libcups2-dev\" should do it).\n\nIn the directory with ps-printer-app.c run the command line\n\n```\ngcc -o ps-printer-app ps-printer-app.c $PAPPL_SRC/pappl/libpappl.a $CUPS_FILTERS_SRC/.libs/libppd.a $CUPS_FILTERS_SRC/.libs/libcupsfilters.a $PAPPL_RETROFIT_SRC/.libs/libpappl-retrofit.a -ldl -lpthread  -lppd -lcups -lavahi-common -lavahi-client -lgnutls -ljpeg -lpng16 -ltiff -lz -lm -lusb-1.0 -lpam -lqpdf -lstdc++ -I. -I$PAPPL_SRC/pappl -I$CUPS_FILTERS_SRC/ppd -I$CUPS_FILTERS_SRC/cupsfilters -I$PAPPL_RETROFIT_SRC/pappl/retrofit -L$CUPS_FILTERS_SRC/.libs/ -L$PAPPL_RETROFIT_SRC/.libs/\n```\n\nThere is also a Makefile, but this needs PAPPL, cups-filters 2.x, and\npappl-retrofit to be installed into your system.\n\nRun\n\n```\n./ps-printer-app --help\n```\n\nWhen running the non-snapped version, by default, PPD files are\nsearched for in\n\n```\n/usr/share/ppd/\n/usr/lib/cups/driver/\n/var/lib/ps-printer-app/ppd/\n```\n\nThe last path is used when adding PPD files using the \"Add PPD files\"\npage in the web interface.\n\nYou can set the `PPD_PATHS` environment variable to search other\nplaces instead:\n\n```\nPPD_PATHS=/path/to/my/ppds:/my/second/place ./ps-printer-app server\n```\n\nSimply put a colon-separated list of any amount of paths into the\nvariable, always the last being used by the \"Add PPD files\"\npage. Creating a wrapper script is recommended.\n\nThis Printer Application uses CUPS' backends and not PAPPL's, meaning\nthat for USB printers CUPS' USB quirk workarounds for compatibility\nproblems are used, network printers can also be used with IPP, IPPS,\nand LPD protocols, and SNMP printer discovery is configurable.\n\nUSB Quirk rules in `/usr/share/cups/usb` and the `/etc/cups/snmp.conf`\nfile can get edited if needed.\n\nMake sure you have CUPS (at least its backends) installed.\n\nYou also need Ghostscript to print PDF jobs.\n\nFor access to the test page `testpage.ps` use the TESTPAGE_DIR\nenvironment variable:\n\n```\nTESTPAGE_DIR=`pwd` PPD_PATHS=/path/to/my/ppds:/my/second/place ./ps-printer-app server\n```\n\nor for your own creation of a test page (PostScript, PDF, PNG, JPEG,\nApple Raster, PWG Raster):\n\n```\nTESTPAGE=/path/to/my/testpage/my_testpage.ps PPD_PATHS=/path/to/my/ppds:/my/second/place ./ps-printer-app server\n```\n\n## LEGAL STUFF\n\nThe PostScript Printer Application is Copyright © 2020 by Till Kamppeter.\n\nIt is derived from the HP PCL Printer Application, a first working model of\na raster Printer Application using PAPPL. It is available here:\n\nhttps://github.com/michaelrsweet/hp-printer-app\n\nThe HP PCL Printer Application is Copyright © 2019-2020 by Michael R Sweet.\n\nThis software is licensed under the Apache License Version 2.0 with an exception\nto allow linking against GPL2/LGPL2 software (like older versions of CUPS).  See\nthe files \"LICENSE\" and \"NOTICE\" for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenprinting%2Fps-printer-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenprinting%2Fps-printer-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenprinting%2Fps-printer-app/lists"}