Giter Site home page Giter Site logo

tjfontaine / airprint-generate Goto Github PK

View Code? Open in Web Editor NEW
401.0 34.0 120.0 11 KB

Automatically generate AirPrint Avahi service files for CUPS printers

Home Page: http://www.atxconsulting.com/blog/tjfontaine/2010/11/21/automatically-generate-airprint-avahi-service-files-cups-printers

Python 96.94% Dockerfile 3.06%

airprint-generate's Introduction

airprint-generate.py

This script will generate avahi .service files for shared CUPS printers.

This script will connect to a CUPS server and for each printer configured and marked as shared will generate a .service file for avahi that is compatible with Apple's AirPrint announcements. Any printer that can be configured to work with CUPS can be used. Printers should not be configured in CUPS as raw, unless the printer can natively print PDF. That is to say, CUPS needs to already be configured with a PDF filter. Debian based distributions ship CUPS pre-configured this way.

DNSSD has a limit of 255 Chars for a given txt-record, because of this the list of accepted pdl's will be truncated to fit. If you're curious to see which ones are trimmed out of the list run with the script with the verbose flag (--verbose)

If python-lxml is installed, .service files will be generated in a human readble format, I wasn't able to get minidom's version to work acceptably.

Usage: airprint-generate.py [options]

Options: -h, --help show this help message and exit -H HOSTNAME, --host=HOSTNAME Hostname of CUPS server (optional) -P PORT, --port=PORT Port number of CUPS server -u USER, --user=USER Username to authenticate with against CUPS -d DIRECTORY, --directory=DIRECTORY Directory to create service files -v, --verbose Print debugging information to STDERR -p PREFIX, --prefix=PREFIX Prefix all files with this string

Docker containerized avahi .service generation

After the printers have been configured in the cups server, docker can interactively generate the avahi .service while making use of the container.

  • Build the container
docker build -t airprint-generate .
  • Generate the avahi service by defining the ip address of the cups server
docker run --rm -it -v $(pwd):/tmp airprint-generate -H ${CUPS_SERVER_IP} -d /tmp

airprint-generate's People

Contributors

rchenzheng avatar superna9999 avatar tjfontaine avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

airprint-generate's Issues

cups.IPPError: (1280, 'Success')

I am trying to run this from a Windows host running Docker/WSL2. The docker image is built and is run with the command below. There is some output from the printer (two blank sheets and a lead sheet) which suggests that contact is made from the script using an HTTP post from CUPS. This is mentioned on the lead sheet.

PS C:\opt\sw\src\repos\airprint-generate> docker run --rm -it -v C:\opt\sw\src\repos\airprint-generate:/tmp airprint-generate:latest -H 192.168.1.1 -P 9100 -d /tmp
Traceback (most recent call last):
  File "./airprint-generate.py", line 279, in <module>
    apg.generate()
  File "./airprint-generate.py", line 124, in generate
    printers = conn.getPrinters()
cups.IPPError: (1280, 'Success')
PS C:\opt\sw\src\repos\airprint-generate>

Any comment?

Thanks
-paul

SOLVED - avahi 64bit

hello,

I'm using a 64bit RHEL6. bash works well
but the launch of avahi-daemon 0.6.25 I have error in the log

open ("/ services / AirPrint-myprinter.service", O_RDONLY): Permission denied
Failed to load service group file / services / AirPrint-myprinter.service, ignoring.

I copy / services / AirPrint-myprinter.service on RHEL5 32bit version of the file works well

a question, is there a version incompatibility between this script and the version of avahi?

thank you

Ps: the file " AirPrint-myprinter.service" permissions are 644

Add image/urf

Hi,

I just created an urftopdf filter for cups, and it would be cool if the image/urf type was added to the pdl= with your script.

Emulate/advertise official AirPrint compatibility

Hi all,
I‘ve got an issue that is not limited to this script, yet I think for a start chances are that the good people here could guide me to the right direction.

Project idea:
Use CUPS to print text via a thermal printer from a specific app (iZettle) that requires AirPrint functionality.

Outcome:
Printing to thermal printer works flawlessly when using the airprint-generate.py code here to print some random text within iOS apps like Notes and Mail. However, when using the specific iZettle App, CUPS printer gets detected as an AirPrint printer but when wanting to print, the following error occurs:
„UIPrintErrorDomain Error 4“ followed by „Printer couldn‘t be reached“

After talking to Customer Service, iZettle told me that this is a correct behaviour as only official AirPrint printers are allowed to work. This seems to be true as a compatible Canon printer could do the job.

Question (finally)
Is there a way to advertise my CUPS printer so that it is recognized as officially AirPrint compatible? Stated differently, does anyone know what it is (key, certificate?) that printer and app have to share with each other to be identified correctly?

Sorry for such a long message. In case that I should try my luck elsewhere, advice on where to go would be highly appreciated. You can find two CUPS logs here. The “faulty” one with iZettle and a working print job using the standard iOS Notes app

Thank you very much and best regards!
iZettle.txt
Normal_Print.txt

Append to log

How to append to log ?

got it all working but i would love to append the verbose information to a log

ModuleNotFoundError: No module named 'cups'

Any idea what's the issue here after running ./airprint-generate.py under Debian 10 Buster?

Traceback (most recent call last):
  File "./airprint-generate.py", line 25, in <module>
    import cups, os, optparse, re
ModuleNotFoundError: No module named 'cups'

iOS device reports 'Printer is Offline'

On a default Ubuntu 12.04 LTS install I used the airprint-generate script and followed the steps mentioned in issue #5 to add the mime types. The printer appeared to my iOS devices but when you attempted to print iOS would report "The printer is offline".

The fix is that you have to make sure the CUPS server is publishing it's printers. I suspect what happens is that Avahi publishes the name of the printer but since CUPS isn't set to make that printer available to network users the printer appears to be offline when iOS attempts to use it.

Look for the setting "Share published printers connected to this system" in the CUPS server prefs menu.

I am going to immediately close this issue; just leaving it here for the benefit of others.

empty service file created

I got an empty service file 'AirPrint-hplaserjet100colormfpm175a.service' created:

--

@linux:~/Downloads/airprint-generate> ./airprint-generate.py -v
hplaserjet100colormfpm175a Losing support for: text/css,image/x-photocd,image/x-bitmap,image/pwg-raster,application/vnd.cups-raw,application/vnd.cups-postscript,application/vnd.cups-pdf-banner,application/vnd.hp lasercups-pdf
Traceback (most recent call last):
File "./airprint-generate.py", line 279, in
apg.generate()
File "./airprint-generate.py", line 226, in generate
tree.write(f, pretty_print=True, xml_declaration=True, encoding="UTF-8")
File "src/lxml/etree.pyx", line 2057, in lxml.etree._ElementTree.write
File "src/lxml/serializer.pxi", line 758, in lxml.etree._tofilelike
File "src/lxml/etree.pyx", line 318, in lxml.etree._ExceptionContext._raise_if_stored
File "src/lxml/serializer.pxi", line 682, in lxml.etree._FilelikeWriter.write
TypeError: write() argument must be str, not bytes

--
My OS: openSUSE Tumbleweed
Shared printer connected to printer server: HP Laserjet 100 Color MFP M175a

any idea about this TypeError? Thanks!

didn't build on fedora with python3

I changed line 223 in airprint-generate.py from
f = open(fname, 'w')
to
f= open(fname, 'wb')

otherwise, it would not build (I am using fedora 32)

Duplex and Color support

Since Duplex attribute is not mapped in printer attributes, I suggest to add a "Duplex=T" into XML_TEMPLATE.
To include a color atribute simply add this.

             colorsup = Element('txt-record')
             colorsup.text = 'Color=%s' % (str(attrs['color-supported'])[0])
             service.append(colorsup)

ImportError: No module named cups

import cups, os, optparse, re, urlparse
ImportError: No module named cups

I get this when I run this. I am running a RPi and it may be an issue with how the RPi package unpacked.

No iOS 5 support

Ran your script and got a working AirPrinter for iOS6 iPad 2 but my iOS5 iPad 1 can't see the printer.

What logs can I provide to assist with troubleshooting/fixing this?

No ouput generated

Hi

This script generates no output for me. Any hints what is wrong?

Best
Zeno

IOS6 Compatibility

Hi,

today I've installed IOS6 update, and the printer are no more discoverable.

Anyone have this issue?

Thanks

Does not generate file, but also does not report error or verbose output.

Running the script
python3 airprint-generate.py -H {CUPS_SERVER_IP} -P {PORT} -d /home/myUser/ -v
or from the docker container... does not generate the service file.
docker run --rm -it -v /home/myUser/:/tmp airprint:1.0 -H {CUPS_SERVER_IP} -d /tmp

but it doesn't report any error passing the -v or --verbose as parameter either

packages installed

# apt install libcups2-dev python3-dev python3-libxml2 gcc python3
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
libcups2-dev is already the newest version (2.3.3op2-3+deb11u1).
gcc is already the newest version (4:10.2.1-1).
gcc set to manually installed.
python3 is already the newest version (3.9.2-3).
python3-dev is already the newest version (3.9.2-3).
The following NEW packages will be installed:
  python3-libxml2
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 194 kB of archives.
After this operation, 915 kB of additional disk space will be used.
Do you want to continue? [Y/n] y

python3

# python3 --version
Python 3.9.2

avahi

# dpkg -l | grep avahi
ii  avahi-daemon                    0.8-5                          arm64        Avahi mDNS/DNS-SD daemon
ii  avahi-utils                     0.8-5                          arm64        Avahi browsing, publishing and discovery utilities
ii  libavahi-client3:arm64          0.8-5                          arm64        Avahi client library
ii  libavahi-common-data:arm64      0.8-5                          arm64        Avahi common data files
ii  libavahi-common3:arm64          0.8-5                          arm64        Avahi common library
ii  libavahi-core7:arm64            0.8-5                          arm64        Avahi's embeddable mDNS/DNS-SD library
ii  libavahi-glib1:arm64            0.8-5                          arm64        Avahi GLib integration library

Cups

# dpkg -l | grep cups
ii  cups                            2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - PPD/driver support, web interface
ii  cups-backend-bjnp               2.0.3-1                        arm64        printer backend for Canon BJNP protocol
ii  cups-browsed                    1.28.7-1+deb11u1               arm64        OpenPrinting CUPS Filters - cups-browsed
ii  cups-bsd                        2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - BSD commands
ii  cups-client                     2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - client programs (SysV)
ii  cups-common                     2.3.3op2-3+deb11u1             all          Common UNIX Printing System(tm) - common files
ii  cups-core-drivers               2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - driverless printing
ii  cups-daemon                     2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - daemon
ii  cups-filters                    1.28.7-1+deb11u1               arm64        OpenPrinting CUPS Filters - Main Package
ii  cups-filters-core-drivers       1.28.7-1+deb11u1               arm64        OpenPrinting CUPS Filters - Driverless printing
ii  cups-ipp-utils                  2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - IPP developer/admin utilities
ii  cups-pk-helper                  0.2.6-1+b1                     arm64        PolicyKit helper to configure cups with fine-grained privileges
ii  cups-ppdc                       2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - PPD manipulation utilities
ii  cups-server-common              2.3.3op2-3+deb11u1             all          Common UNIX Printing System(tm) - server common files
ii  cups-tea4cups                   3.14~alpha0+svn3576-2          all          Swiss Army's knife of advanced CUPS administrators
ii  cups-x2go                       3.0.1.4-1                      all          Virtual X2Go printer for CUPS
ii  libcups2:arm64                  2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - Core library
ii  libcups2-dev:arm64              2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - Development files CUPS library
ii  libcupsfilters1:arm64           1.28.7-1+deb11u1               arm64        OpenPrinting CUPS Filters - Shared library
ii  libcupsimage2:arm64             2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - Raster image library
ii  libcupsimage2-dev:arm64         2.3.3op2-3+deb11u1             arm64        Common UNIX Printing System(tm) - Development files CUPS image library
ii  printer-driver-cups-pdf         3.0.1-9                        arm64        printer driver for PDF writing via CUPS
ii  python3-cups:arm64              2.0.1-4+b1                     arm64        Python3 bindings for CUPS

No error message comes out, nor does it generate the file, simply after executing the command, it does nothing, I have the printer with the shared option in cups.

Does this script work with CentOs 8

Does this script work with CentOs 8 when ran with python 3.6.8 I experience error:
./airprint-generate.py
Traceback (most recent call last):
File "./airprint-generate.py", line 306, in
apg.generate()
File "./airprint-generate.py", line 140, in generate
uri = urlparse.urlparse(v['printer-uri-supported'])
NameError: name 'urlparse' is not defined

No module named 'urlparse' and No module named 'StringIO'

This is an old, un-updated script that lots of people still use but has not kept up with python changes. If you get either of the above errors you need to just:

cd /opt/airprint
sudo nano airprint-generate.py

[Edit]

#import cups, os, optparse, re, urlparse
import cups, os, optparse, re, urllib.parse

[Edit]

#from StringIO import StringIO
from io import StringIO

I would just try to branch, but I am not a skilled programmer and just found these edits through searches.

Does nothing

airprint-generate.py doesn't generate any files on Ubuntu 14.04

RuntimeError: failed to connect to server

When running the python script, I get this result.
Forgive my ignorance, but I don't know the cause of the error below.
Can you assist?

python airprint-generate.py

Traceback (most recent call last):
File "airprint-generate.py", line 277, in
apg.generate()
File "airprint-generate.py", line 116, in generate
conn = cups.Connection()
RuntimeError: failed to connect to server

Encryption Required in /printers location not checked

if CUPS is set to secure printing only, airpint-generate should write ipps instead of ipp mDNS-Records.

Otherwise printing brings an error

<Location /printers>
Encryption Required

should lead to ipps resource records.

Correct behaviour has been tested with current versions of IOS and macOS. Unfortunately, several Android print services (i.e. CUPS for Android) do not work with ipps records

AirPrint-Services breaking WLAN in some circumstances

Hello,

I was trying to use your Script in a way that was probably not intended, but seemed to work just fine:
My University has a CUPS-Server with some printers attached. We can ssh into the university network and tunnel a port to the cups-server to print from home.

I used the following steps:

  1. Create an SSH tunnel that links my local port 6631 to the remote port 631 on the CUPS server
  2. Add "BrowsePoll localhost:6631" to the /etc/cups/cupsd.conf file, restarted cups
  3. Checked that the printers are recognized correctly (they are)
  4. Downloaded your Script and ran it with the following parameters:
    -H localhost -P 6631 -u [my_username_on_the_server]
  5. The script created the .service-files just fine. I moved them to /etc/avahi/services and restarted the avahi-daemon
  6. All WLAN devices lost internet access, trying to connect to the WLAN yielded error messages stating that the device was unable to join the network
  7. I removed all AirPrint-*.service-Files from the directory, restarted the avahi-daemon and everything was fine again.

I am using the latest version of avahi that is available on the ubuntu repos. Other version information:
OS: Linux Mint 12 (latest version)
Router: TP-Link TL-WR841N

Devices I have tried to connect:
iPad 3
Laptop with Linux Mint 12
Google Nexus S

A sample .service file the script generated looks like this:

AirPrint r135_hp @ %h_ipp._tcp_universal._sub._ipp._tcp631txtvers=1qtotal=1Transparent=TURF=nonerp=printers/r135_hpnote=r135_hp SW-Laserdrucker in R135 (KogS)product=(GPL Ghostscript)printer-state=3printer-type=0x90d4pdl=application/octet-stream,application/pdf,application/postscript,image/gif,image/jpeg,image/png,image/tiff,text/html,text/plain,application/mozilla-ps,application/netscape-ps,application/vnd.cups-postscript,application/vnd.cups-raw

(no line breaks)

I don't know if this is a bug in Avahi, my Router or your script, but since everything is running fine while I am not using the script, I thought I'll report that bug here first and see what you can make of it.

If you need any more version information, ask.

Sincerely,
Malexmave

Script fails with Python 3.x when py-lxml installed

I stumbled upon a Python 2 to Python 3 conversion issue when trying to run the script with py-lxml installed.

# ./airprint-generate.py
Traceback (most recent call last):
  File "/root/./airprint-generate.py", line 279, in <module>
    apg.generate()
  File "/root/./airprint-generate.py", line 226, in generate
    tree.write(f, pretty_print=True, xml_declaration=True, encoding="UTF-8")
  File "src/lxml/etree.pyx", line 2057, in lxml.etree._ElementTree.write
  File "src/lxml/serializer.pxi", line 758, in lxml.etree._tofilelike
  File "src/lxml/etree.pyx", line 318, in lxml.etree._ExceptionContext._raise_if_stored
  File "src/lxml/serializer.pxi", line 682, in lxml.etree._FilelikeWriter.write
TypeError: write() argument must be str, not bytes

I fixed it by opening the file as binary:

--- airprint-generate.py.us.bak 2020-12-02 14:00:09.404088000 +0200
+++ airprint-generate.py        2020-12-02 14:05:06.222074000 +0200
@@ -220,7 +220,7 @@
                 if self.directory:
                     fname = os.path.join(self.directory, fname)
                 
-                f = open(fname, 'w')
+                f = open(fname, 'wb')
 
                 if etree:
                     tree.write(f, pretty_print=True, xml_declaration=True, encoding="UTF-8")

I could see no adverse effects when py-lxml was not installed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.