Skip to content

Latest commit

 

History

History
127 lines (111 loc) · 4.6 KB

README.md

File metadata and controls

127 lines (111 loc) · 4.6 KB

Hippy

Hippy is an Internet Printing Protocol (IPP) client implementation in Elixir for performing distributed printing over HTTP. In addition to printing documents, IPP also supports a number of other operations such as retrieving print job status, pausing jobs, resuming jobs, etc.

CUPS provides a standard IPP server out of the box, though some higher-end networked printers are also capable of providing their own server. That said, testing at this early stage has been 100% against CUPS, which is likely more tolerant of any outstanding abuses of the protocol in Hippy alpha versions. ;)

Obligatory Warning

This is currently very alpha-stage software and will be evolving quickly. Please only consider it for production use at your own risk.

Usage Examples

Print a PDF document

doc = File.read!("tps_report.pdf") 
printer_uri = "http://localhost:631/printers/HP_Color_LaserJet"

Hippy.Operation.PrintJob.new(printer_uri, doc, job_name: "TPS Report", orientation: Hippy.Protocol.Orientation.portrait())
|> Hippy.send_operation()

{:ok,
 %Hippy.Response{
   job_attributes: [
     [
       {:uri, "job-uri", "ipp://localhost:631/jobs/47"},
       {:integer, "job-id", 47},
       {:enum, "job-state", :pending},
       {:text_without_language, "job-state-message", ""},
       {:keyword, "job-state-reasons", "none"}
     ]
   ],
   operation_attributes: [
     [
       {:charset, "attributes-charset", "utf-8"}, 
       {:natural_language, "attributes-natural-language", "en"}
     ]
   ],
   request_id: 1,
   status_code: :successful_ok,
   version: %Hippy.IPPVersion{major: 1, minor: 1}
 }}

Get recently completed jobs

Hippy.Operation.GetJobs.new("http://localhost:631/printers/HP_Color_LaserJet")
|> Hippy.send_operation()

{:ok,
 %Hippy.Response{
   job_attributes: [
     [
       {:name_without_language, "job-name", "TPS Report"},
       {:name_without_language, "job-originating-user-name", "anonymous"},
       {:integer, "job-id", 47},
       {:enum, "job-state", :completed},
       {:keyword, "job-state-reasons", "processing-to-stop-point"},
       {:integer, "job-media-sheets-completed", 8}
     ],
     [
       {:name_without_language, "job-name", "Untitled Job"},
       {:name_without_language, "job-originating-user-name", "anonymous"},
       {:integer, "job-id", 46},
       {:enum, "job-state", :completed},
       {:keyword, "job-state-reasons", "processing-to-stop-point"},
       {:integer, "job-media-sheets-completed", 2}
     ],
     # ...
   ],
   operation_attributes: [
     [
       {:charset, "attributes-charset", "utf-8"},
       {:natural_language, "attributes-natural-language", "en"},
       {:integer, "limit", 500}
     ]
   ],
   request_id: 1,
   status_code: :successful_ok,
   version: %Hippy.IPPVersion{major: 1, minor: 1}
 }}

Convert the response to a map for easier access by key

Note: Hippy.AttributeGroup.to_map/1 currently doesn't support nested attribute groups such as when returning multiple jobs through the Get-Jobs IPP operation. If given a list of attribute groups, instead of returning a list of maps, it will return the group at the head of the list. If you wish to access other groups in the list, you can use AttributeGroup.to_map/2 to provide an index for the nested group at the target index. This behavior may change for AttributeGroup.to_map/1 in the future, so if you intend to rely on a single map being returned, it would be advisable to use AttributeGroup.to_map(response.job_attributes, 0) in order to future-proof your code.

response = %Hippy.Response{
  data: "",
  job_attributes: [
    [
      {:uri, "job-uri", "ipp://localhost:631/jobs/47"},
      {:integer, "job-id", 47},
      {:enum, "job-state", :pending},
      {:text_without_language, "job-state-message", ""},
      {:keyword, "job-state-reasons", "none"}
    ]
  ],
  operation_attributes: [
    [
      {:charset, "attributes-charset", "utf-8"},
      {:natural_language, "attributes-natural-language", "en"}
    ]
  ],
  printer_attributes: [],
  request_id: 1,
  status_code: :successful_ok,
  unknown_attributes: [],
  version: %Hippy.IPPVersion{major: 1, minor: 1}
}

Hippy.AttributeGroup.to_map(response.job_attributes)
%{
  "job-id" => 47,
  "job-state" => :pending,
  "job-state-message" => "",
  "job-state-reasons" => "none",
  "job-uri" => "ipp://localhost:631/jobs/47"
}

Copyright and License

Copyright (c) 2018-2024 Jeff Smith

Hippy source code is licensed under the MIT License.