sliemeobn / ipp-nio

Internet Printing Protocol (IPP) implementation for Swift based on swift-nio.
https://swiftpackageindex.com/sliemeobn/ipp-nio/main/documentation
Apache License 2.0
9 stars 1 forks source link

Adding paper source to JobTemplate #5

Open ronnybremer opened 1 month ago

ronnybremer commented 1 month ago

I am not an expert in the IPP protocol, but where would be the correct place to specify the paper source / input try to use? I would be happy to provide a PR once I know my way around.

ronnybremer commented 1 month ago

PR #4

sliemeobn commented 1 month ago

good question ; )

I would assume it is specified using the media attribute as described here: https://www.rfc-editor.org/rfc/rfc8011#section-5.2.11

for quick-and-dirty "raw" support, I would assume something like this will work:

let response = try await printer.printJob(
    documentFormat: "application/pdf",
    jobAttributes: [
        .media: .init(.name(.withoutLanguage("some-media"))),
    ],
    data: .bytes(pdf)
)

But I am not sure about using name vs keyword. Also, one would probably have to first inspect the media-supported attribute for this to make sense generically.

ronnybremer commented 1 month ago

Thank you @sliemeobn, that already works perfectly to specify the media size.

According to the RFC, a keyword is a tighter specification of a nameWithoutLanguage, so as an ad-hoc solution this would work, I will try to integrate it as keywords in a PR, but that will take a bit of time. Probably going to add a few standard paper sizes as constants, too.

For the paper source there seems to be a job template attribute, see here: IPP Javascript Lib. However, the RFC seems to have deprecated the use of "media-col". I will need to read up further on that.

For now I will try with your documented "some custom keyword" approach.

ronnybremer commented 1 month ago

Small correction, the media-col does not seem to be deprecated but rather an option for the printer to implement.

A Printer MAY support the "media" attribute without supporting the "media-col" attribute. However, if a Printer supports the "media-col" attribute, it MUST also support the "media" attribute.

ronnybremer commented 1 month ago

As a working example I am using this code and it seems to work:

        // A6, Bypass Tray
        jobAttributes["media-col"] = .init(.collection([
            "media-size" : .init(.collection(["x-dimension" : .init(.integer(105 * 100)),
                                              "y-dimension" : .init(.integer(148 * 100))
                                             ])),
            "media-source" : .init(.keyword("by-pass-tray"))
        ]))

This is printer specific, the by-pass-tray was taken from the media-source-supported of the printer attributes.

sliemeobn commented 1 month ago

cool to see, thanks for sharing!

but as this code demonstrates: it gets intricate very quickly, with many variants and asterisks (like "what does this printer support")

so, I wonder if it is at all worth the trouble trying to wrap this all in a nicely typed API 🤔

ronnybremer commented 1 month ago

but as this code demonstrates: it gets intricate very quickly, with many variants and asterisks (like "what does this printer support")

Absolutely agree, in order to build a sophisticated application, you need to query the printer and determine the options needed/supported. However, in that case you can also use AirPrint, if supported, which will do exactly that for some options already. However, if your application is more "industrial" and tied to a specific range of printers / use cases, you will probably get away with more fixed assumptions.

so, I wonder if it is at all worth the trouble trying to wrap this all in a nicely typed API

I would say that the majority of the options is way too vast to be included, however, a few items are very likely to be used more often, like

Maybe they should be included in a more prominent way and for the rest an example code like mine above could serve as a starting point for a possible implementation.