We have moved to a new Sailfish OS Forum. Please start new discussions there.

# Input wanted: I made a printing app...

asked 2019-08-06 16:54:44 +0300

Was: Collaborators wanted: share-to-printer plugin

Update 2020-05-16

Slowly but steadily I have now managed to add support for raster formats needed by simpler printers. This now means that there is a very good chance your IPP-compatible printer is supported, and a near-guarantee if it is from the last 10 years. I have very limited access to printers to test with, so it would be really appreciated if some people could step up and help iron out the bugs. Keep up with any extra releases here:

https://github.com/attah/harbour-seaprint/releases/

--- Post-Devember status update ---

So SeaPrint has been out for a bit over a month, passing 500 installs with over 85% retention. I'd call that moderately successful.

Since printing at home is a sort of thrice-a-year activity for me, i'm not the best driver for new features, or for judging what is "enough", so i'd like to turn to you guys for priorities.

I have a list of minor things left on the TODO-list (which will probably happen by virtue of enough rainy days passing) but i'm nor sure anybody really needs it:

• Setting to prefer/require ipps/https
• A password dialog for connections that require it
• ipv6 support (had it been Internet facing this would have made more sense imo)

I could also look at exposing some few more settings for print-jobs. Ranges is the only one i can think of right now, and that's a bit of a mess UI-wise. Anything else that is obviously missing?

Then there is making an actual sharing plugin... how interesting is that to people? I'm thinking that it would just invoke the main app, so losing out on progress etc... good/bad/ugly? Needed?

The last, and probably biggest thing is format conversions to both PWG raster and URF raster. I have it more or less working, but performance would be not-so-fun. A single color A4 page is about 26MB at 300dpi "raw", and about 1/10th of that compressed to PWG/URF (for normal text, better for large solid colors, worse for detailed graphics). A more normal 600dpi is a whopping 104 MB, again before compression. I can easily see how putting even a document of compressed pages in RAM would not go so well, especially on older phones.

On top of that, both conversion and transfer would take significant time. I can easily see how say a 25-page b/w document at 600 dpi would take a minute to transfer under normal wifi conditions. Make that 3 minutes for color. Also, currently the raster encoder i made would not quite keep up with the speed required for that either. I probably just did something too naively, and will hopefully get it to within margin of error eventually.

The other day i also found out that even if i make my transcode pipeline walk and quack like a QIODevice, that won't save me from putting the entire encoded thing in RAM anyway. QNetworkAccessManager insists on reading the entire thing, as it does not support chunked transfer from what i can find. I mean, if one is going to wait for those kind of file sizes to pass through two steps that does 20-40Mb/s they can at least be allowed to move in lock-step, one would have hoped. But no.

What remains is putting it on /tmp and then, only when it is done encoding, ship it over IPP. Boy howdy would that be tedious to wait for if the document has any size at all. I don't see myself improving the codec by an order of magnitude, even if eMMC throughput would allow it. Do i go fishing for an http client that allows streaming? Needless to say, fixing a problem i don't really have myself, isn't the easiest thing to keep working at.

Ideas? Feedback? Collaborators?

--- Original post ---

I was recently reminded that there still is no printer support in SFOS, so i took a look at the printer support situation. Yes, there is CUPS, and there is QtPrintSupport bindings for that. However, they are quite big and complicated. Sure, if one was to implement bindings for the whole API the configuration possibilities would be pretty great, but simple things like "just throwing a PDF at the printer" seems to involve rendering it client-side (ugh!).

This lead me to looking in to what network printing support actually means. The Printer Working Group would at least want you to think that it is IPP (Internet Printing Protocol), which supposedly ships with 98% of modern (network-enabled) printers. Also, any Linux box or Mac should be able to act as an IPP server. It seems that IPP-enabled printers tend to accept PDFs as a transport format. Sure, this approach limits printing to supported formats, at least initially, but PDF alone would take care of a sizeable chunk of printing needs.

So i made a quick IPP client in my favourite protocol handling language, Erlang, and before too long i had printed a PDF. IPP is pretty simple, and relying of huge monolith libraries seems as unnecessary as i thought. Following this, I started on a client in QT-flavoured C++, i.e. for SailfishOS. It sort of works, but boy was it painful. It must have taken an order of magnitude more time for a similar level of functionality. No GUI bindings or anything yet either... Since i print things about twice a year, the chances i'll bother finishing this are approaching zero.

Does anyone feel like pitching in? Do you just want to complain that this is the wrong approach?

Find me on IRC, #sailfishos at freenode.

More on sharing plugins here: https://together.jolla.com/question/164166/how-to-create-sharing-plugin-for-sailfish/

PS, while disillusioned by C++ i started a mDNS (discovery protocol used by IPP) client in Erlang too, and unless there is a really spot-on implementation available i'd say we are better off making our own client here too.

Update 2019-08-29 It appears that not listing pdf in the format query is less fatal than i thought. Upon further consultation of the RFC i came across this:

4.1.9.1 Application/octet-stream -- Auto-Sensing the document format

One special type is 'application/octet-stream'. If the Printer object supports this value, the Printer object MUST be capable of auto-sensing the format

That could mean that printers claiming to support PDFs (e.g. in their manual) still do, they just advertise it poorly.

edit retag close delete

I'm just wondering why you don't invest your time and energy into making cups work on the phone.

You know the use cases are limited because many printers can work only via USB or whatever local driver, but for the network printers a simple configuration should work

( 2020-05-17 11:22:21 +0300 )edit

Those printers are very well served by a CUPS instance on another computer. I don't see may people plugging in their printers via USB to their phones, and any "speciality" drivers are unlikely to be available for ARM anyway. The RPC protocol of choice for CUPS is IPP, or as someone describing it put it: "CUPS thinks in IPP". So, if you like you can see this as the better part of a frontend for CUPS on the phone. I just think we are much better of with direct IPP or CUPS on another machine. I also value harbour-friendlyness highly, so that it becomes usable for regular users. And i must disagree with the use cases being limited by not using CUPS locally, compared to using CUPS remotely.

( 2020-05-17 11:36:56 +0300 )edit

I am sorry but I have not looked into the solution as I do not have a use case for this. A use case on my end would involve BT or USB through the local network. The WLAN is on the other side of the firewall and the phone can never see the cups printer. The printer itself do not have WLAN on purpose. But all this does not really matter when handling the possible use cases.

IMO there are 3 possibilities:

1. talk directly to the printer (many of them use kind of direct print)
2. use local cups server (on the phone)
3. use remote server (on the network)

Are you saying the solution covers option 2.?

thanks

( 2020-05-17 13:26:12 +0300 )edit
1

I can't really cater specifically to people segmenting their networks, as non-reachability is the intended effect of it. Not sure what you mean by "USB through the local network", as to me that implies a computer with CUPS in-between.

1. That's what it is meant to do, talk directly to the printer. I don't know what more things hide behind the buzzword "Direct Print", but i got the impression that it was basically IPP and some p2p WiFi mode.

2. Any CUPS instance, including on the phone should work as a go-between. However configuring the printer in CUPS is of course out of the scope of the app.

3. Same as 2.

( 2020-05-17 13:59:55 +0300 )edit

OK, thank you for explanation.

There is a clear requirement to keep the WLAN outside of the local network, which is used for business as well. Of course I could configure the firewall to let access to the cups server, but I usually do not print via the phone, because I have the desktop in the same network as the printer. Anyway I was curious what was behind the software. Thanks again for explaining.

With BT or USB, I mean that I can have the phone access the local network via BT or USB on a local machine. I can then decide if I use cups on the phone or cups server on the local network. I was wondering if I had a option in the gui to configure the phone, but this is also answered.

( 2020-05-17 14:41:30 +0300 )edit

Sort by » oldest newest most voted

answered 2019-08-07 00:57:08 +0300

Do you just want to complain that this is the wrong approach?

I would vote for "this is the wrong approach" (though I understand you find interesting to re-invent the wheel).

I would vote for still using CUPS:

• Sailfish OS is a full blown GNU/Linux, just like the Ubuntu/Fedora/Tumbleweed running on your laptop.
• CUPS is the de-facto standard printing system on most Unix (Linux, Mac OS X, BSD, etc.)
• CUPS is the most likely software to get upgraded/updated as newer stuff appear.

Specially since it already works:

## Demo

### Install cups

zypper install cups


or

pkcon install cups


and ignore & override complains about missing chkconfig (as Sailfish is systemd-based and doesn't use this anymore).

### Configure non-root usage

As user Root doesn't have any password on Sailfish OS, it's unusable.

#### Groups-based

I've misssed it in the first version, but as pointed out in older threads, you can also add user nemo to the lp group:

usermod -a -G lp nemo


#### Access rights-based

Basically, for any right that you want to grant ( <Limit CUPS-Add-Modify-Printer...) you need to change Require user @SYSTEM into Require user @SYSTEM nemo.

For example:

sed -ri '/<Limit CUPS-Add-Modify-Printer/,+4s/Require user @SYSTEM/\0 nemo/' /etc/cups/cupsd.conf


That's the only step that is unusual.

### Start cups

systemctl start cups


Browse to http://localhost:631/admin click on the Add printer button and configure your printer (almost) as if you would be doing on your laptop (with the exception that you need to log as nemo, not root).

The beauty is that CUPS will support IPP, but also LPD or straigh raw TCP/IP printing (port 9100).

Keep in mind that out-of-the-box Sailfish OS doesn't have any mDNS installed (no avahi here). So for the moment being you can't (yet) use .local network addresses. Use either IP addresses (hint: IPv6 Link Local fe80:: addresses derived from the MAC address are stable so prefer that if the printers support IPv6) or the domain provided by your home modem-router (e.g.: .fritz.box )

Simply use one of the Generic drivers (e.g.: Generic PostScript, Generic PCL). Throw your printer out of the window if it doesn't support any of PDF, PS nor PCL. (URF and other similar proprietary protocols should burn in hell). No self-respecting networked printer should skip that.

#### Pro tips:

If you find the screen of your smartphone too small, you can also use an SSH tunnel to have it on your laptop (remember to stop your local CUPS before, otherwise your port will be busy, or simply use a different port on the right hand side of the mapping with -L) :

systemctl stop cups
ssh -L 631:127.0.0.1:631 nemo@192.168.2.15


And then you can open the settings on your browser.

(Same can also be done with the advanced settings of PuTTY on Windows)

(Or you can go down the whole rabbit hole and configure network administration on your smartphone's CUPS. But this will require a hostname, a SSL certificate, etc.)

### Print

From the command line:

lp -d{your printer}--{your PDF}

where your printer is the pintername, as listed in the left-most column of /etc/printcap or as listed by lpstat -a. e.g.:

lp -d samsung -- Downloads/mail_attachments/21/4945-2/volvo.pdf


That's it. It works. You can "just send a PDF to the printer" from the command line.

You'll notice that, except for switching from root to nemo as an administrative user, everything else is nearly similar to any other UNIX system.

What would be needed from here to have a quick "send to printer":

• Automate the administrative user (see either sed script or usermod above)
• make a nice "send-to" handle for PDF (application/pdf) and Postscript (application/postscript) mime-types that simply calls the lp command. the various share plugins on openrepos would be a starting point.
• add a nice drop-down list of pinters based on lpstat -a
• compile a Sailfish version of CUPS Cloud Print to have possibility of printing to Google Cloud.
• recompile a newer version of avahi for Sailfish OS (because my package is horrendously out of date and doesn't work anymore) so that .local addresses work again.
• at this point CUPS would get some automatic discovery of networked printers.

Further developments:

• a full blown integration of QtPrint
• a full blown printer native administration in QML as some distribution do (e.g.: Suse's YaST printer module) :-P
more

1

While I really like this solution from the perspective of the operating system, I still fear that this will fail with the majority of users, simply because of the lack of data format support with most cheap printers. People just don't check these things before buying, and with "people", I don't mean us TJC nerds.

( 2019-08-07 09:55:04 +0300 )edit

Regarding data formats, the thing is that we're looking at networked/wifi printers.

• AirPrint is the only slightly problematic, because the only hard requirement is the URF format, which is patented. (On the other hand, Jolla is euro-centric, and it's going to be rather easy to have an .rpm package with the filter hosted in a country that doesn't recognize pure software patents, like France. See VLC). It is possible to have printer that only supports URF and a bunch of proprietary bullshit.
• Google Cloud Printing: support for PDF is mandatory
• Random networked printers and MFC: most support at least one out of PDF, PS and/or PCL - all either standards or defacto standard. The ones that don't are expensive door stopper that are going to break anyway once support for Windows 7 runs out and the user realize that they can't get them to work on Windows 10 due to missing proprietary binary drivers from a company that doesn't exist anymore.
( 2019-08-07 11:41:51 +0300 )edit

Wow, very comprehensive. Thanks. Although i still sort of doubt how much useful functionality CUPS adds. Or should I say, how much of the functionality added would actually be used... Like, how many printers can it actually deal with without rendering plugins/drivers, that doesn't already have have PDF or PWG? As you say, add URF and PCL to the mix and there can't be a whole lot left. I mean it really does mainly exist to keep these drivers associated with the printers and provide render plugins, from what i understand. Ideally neither would actually be needed, or only one or two rendering plugins would be used. After all, Apple, the "owner" of CUPS use AirPrint and nothing more for their mobile devices.... Hmm, the OKI i mentioned does support some Google Cloud Printing, but still not PDF over IPP. That's a bit odd. I thought they (Android) only do local plugins drivers, and that the cloud indeed dictates some common interface. AFAIK CUPS only has URF to PDF and not the other way around... but i guess it could be doable to make something for the inverse. BTW, where did you find that it was patented? Edit: oh, it's the whole thing... that's silly. Still not sure how much of the format is covered.

( 2019-08-07 21:30:07 +0300 )edit
1

Although i still sort of doubt how much useful functionality CUPS adds.

Multiple connection protocols: not only the IPP you've implemented, but also LPD (very popular on networked Laserprinter and MFCs, in my experience), raw 9100.

Has also connectors for Google Cloud Printing (Note: that doesn't have a package in Sailfish OS yet).

Has capabilities to autodetect network printers (Note: this depends on Avahi which currently isn't on Sailfish OS neither)

Missing package wouldn't be a huge problem to add through openrepos.net, though.

Also it's a general printing service which is able to handle all the ancillary tasks: configuring permanent printers (your home printer, your Google Printers, etc. basically anything that you won't auto-detect on the fly). And managing Jobs and print queues.

But the main reason: it's the generic solution used by virtually all other unices. If it needs maintenance (bugfixes, security fixes, etc.) chances are high that it's going to get it. (e.g.: it has devs on Apple's payroll).

I mean it really does mainly exist to keep these drivers associated with the printers and provide render plugins, from what i understand.

No, it's not only a driver collection, it's also a printing service.

Also regarding drivers: they are stored in separate package, and Sailfish doesn't even have them (no cups-filters, neither foomatic nor gutemprint). Which makes sense: portable devices are most likely to print to a networked printer.

Like, how many printers can it actually deal with without rendering plugins/drivers, that doesn't already have have PDF or PWG?

No printer that isn't garbage should.

AFAIK CUPS only has URF to PDF and not the other way around... but i guess it could be doable to make something for the inverse.

It's patented, only doable in jurisdictions that don't allow pure software patents like VLC does in France.

( 2019-08-08 11:40:27 +0300 )edit
1

I noticed that CUPS Cloud Print is actually a noarch package (it's python).

The RPM package that they provide should be usable on Sailfish.

To be tested next time...

( 2019-08-08 12:21:30 +0300 )edit

answered 2019-08-06 22:23:43 +0300

This post is a wiki. Anyone with karma >75 is welcome to improve it.

devel-su pkcon install cups-ipptool
LC_ALL=POSIX ipptool -t -v http://<ip to printer here>:631/ipp/print get-printer-attributes.test | grep document-format-supported


(your printer could have another url, but /ipp/print is the most common)

Find the entry document-format-supported, and post results below.

We are looking for application/pdf or (more hassle, but still driver-free) image/pwg-raster

Results:

• CUPS on Linux ( @attah ): application/pdf,image/jpeg,image/pwg-raster [pass]
• OKI MB461: application/octet-stream,application/vnd.hp-PCL,image/urf [fail]
• Canon MX920: application/octet-stream,image/jpeg,image/urf [fail]
• Kyocera FS2100DN: application/octet-stream,application/pdf,image/tiff,image/jpeg,image/urf,application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXL,application/vnd.xpsdocument,image/pwg-raster [pass]
• Xerox C8030: application/octet-stream,application/vnd.hp-PCL,text/plain,image/urf,image/pwg-raster,application/postscript,application/pdf,application/PCLm,image/jpeg,image/tiff [pass]
• HP M401dne: image/urf,application/pdf,application/postscript,application/vnd.hp-PCL,application/vnd.hpPCLXL,application/PCLm,application/octet-stream [pass]
• HP Laserjet P3015DN: text/plain,text/plain; charset=US-ASCII,application/postscript,application/vnd.hp-PCL,application/octet-stream
• printer-info (textWithoutLanguage) = MFG:Hewlett-Packard;CMD:PJL,BIDI-ECP,PJL,POSTSCRIPT,PDF,PCLXL,PCL;MDL:HP LaserJet P3010 Series;CLS:PRINTER;DES:Hewlett-Packard [????]
more

1

The printer in my office (Canon-iR-ADV-C5030i) doesn't support IPP, at least it's not listening to port 631. However it listens to port 9100, the raw TCP port for printing. If I send a PDF to the printer via netcat it gets printed.

( 2019-08-06 23:14:37 +0300 )edit

@jollajo: that's a very unexpected, but convenient behaviour! It would be interesting to know if/how printers that work like that can be discovered.

( 2019-08-06 23:28:54 +0300 )edit

HP M401dne: image/urf,application/pdf,application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXL,application/PCLm,application/octet-stream

( 2019-08-09 16:17:47 +0300 )edit

Samsung M2026W: application/octet-stream,application/x-QPDL,image/urf [fail] It listens to 9100 but doesn't react when I send it pdf or ps with netcat.

( 2019-08-30 01:28:14 +0300 )edit

answered 2019-08-06 18:17:17 +0300

It's not that easy, especially with popular customer grade printers. IPP is just a kind of transport standard. You still need to have custom rendering software, and there are a bunch of "standards" for this. Each printer (class) brings its own rendering filter, generating appropriate (usually bitmapped) data for the printer, and you would need to package that, too. Some (most) printer vendors don't have open-sourced these filters, and if you're lucky, you can find some (i386) binaries.

While I find this very interesting, I doubt it can be achieved with reasonable effort.

more

3

I know this used to be the case, but i got the distinct impression PDF as a rendering format is becoming widely supported, along with image/pwg-raster. Sounds like we need to find/make a survey.

( 2019-08-06 19:00:21 +0300 )edit

I'd love to be proved wrong!

( 2019-08-06 20:52:14 +0300 )edit

I went to check on a networkable printer i have access to. It is a very simple monochrome OKI, but it makes a point of having PDF support. However, it would appear you are still correct. It does not support PDF over IPP, it appears to be limited to USB drives plugged in to the front. To its defence it was a much older model then i thought (ca 2011). It lists the following formats:

application/octet-stream,application/vnd.hp-PCL,image/urf


So i assume native, ancient compat format, and Apple AirPrint. OKI actually does support (seemingly cross-platform) plugins for CUPS, but for these intents and purposes that's besides the point. AirPrint-urf is unfortunately not an open format (shocker!), but it leads me to this page https://wiki.debian.org/DriverlessPrinting#PDLs_for_Driverless_Printing

So I still have hope for PDF and PWG-raster being common enough to be useful. (I'll update the question with a survey)

( 2019-08-06 22:13:38 +0300 )edit

PCL is also a somewhat de facto standard, not as popular as PS nor PDF, but still standard (and supported by standard pxl driver in cups, no need of proprietary x86 binary)

Basically any networked printer worth its salt supports at least one out of PDF, PS and/or PCL. Those who don't are basically expensive door stopper.

PDF and PS are a bit more memory hungry than PCL, so some printer might only support that one out of the box and require a memory DIMM installed + firmware update before supporting (the turing complete) PS (e.g.: some old Samsung).

(By printer I mean Laser Printer. Ink jets are single use devices that shouldn't be used beyond the ink that came pre-packaged with them. Otherwise you'd need a few organs to sell on the black market to afford the price of the replacement ink, which cost probably 3x the price of the printer. Per cartridge. It's probably made out of unicorn blood or something.)

UFR is a proprietary language supported by Canon, I suspect your OKI uses a main board by Canon. (There aren't that many manufacturers of laser components - basically it's Xerox, Canon and HP. Everybody else uses parts from them).

( 2019-08-06 23:32:35 +0300 )edit

Thanks for the info. However, it is urf, not ufr. Pretty sure it is AirPrint unirast.

( 2019-08-06 23:57:24 +0300 )edit

answered 2020-01-26 23:42:19 +0300

Maybe i did something wrong, but i could not even find my wifi-printer. Does the app search for available printers? Or can you just find them through the ip-address?

more

You can try entering the IP address, and then send some JPEG. From a statistics perspective, this is the case you should test. Other use cases are less likely to work.

The app does not find any printers here, too, but I guess that's because they're on a different subnet, and mDNS multicast is not received.

( 2020-01-27 00:02:49 +0300 )edit

Yes it searches with mDNS, it should find most compatible printers. But there will always be some oddball one, or network issues, thus the manual mode for those few corner cases (note that you need the path/resource and not just ip in most cases). Have you checked that your printer supports IPP?

( 2020-01-27 09:14:45 +0300 )edit

@attah This was not a problem report. Those printers are in their own corporate subnet, mDNS is not relayed, and printing works well if you know the name or address -- even with your app! :-)

( 2020-01-27 09:35:06 +0300 )edit

@Maus Thanks, yes i noticed... i meant it for Firefox84

( 2020-01-27 10:45:03 +0300 )edit

printer on different local subnet but manual entry working just fine. very convenient for the quick pdf printout, thx @attah

( 2020-02-03 17:07:38 +0300 )edit

answered 2020-01-27 02:41:25 +0300

have no ipp printers around, so I've uninstalled it. Thought hp1102w might support it. Guess I need to connect printer to an openwrt router or a server with ipp?

more

1

Yeah, no IPP on that one... not even any somewhat standard formats, like PCL. Looks to be HPLIP only, so maybe it's even x86-only. If you do get it in to CUPS, the served instance of it should work just fine though.

( 2020-01-27 09:02:35 +0300 )edit

## Stats

Asked: 2019-08-06 16:54:44 +0300

Seen: 2,227 times

Last updated: May 18