ffi-cups 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +38 -0
- data/LICENSE +21 -0
- data/README.md +78 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ffi-cups.gemspec +26 -0
- data/lib/ffi-cups.rb +39 -0
- data/lib/ffi-cups/connection.rb +57 -0
- data/lib/ffi-cups/constants.rb +95 -0
- data/lib/ffi-cups/enum/http/status.rb +50 -0
- data/lib/ffi-cups/enum/ipp/job_state.rb +15 -0
- data/lib/ffi-cups/enum/ipp/status.rb +53 -0
- data/lib/ffi-cups/ffi/array.rb +17 -0
- data/lib/ffi-cups/ffi/cups.rb +176 -0
- data/lib/ffi-cups/ffi/http.rb +40 -0
- data/lib/ffi-cups/job.rb +13 -0
- data/lib/ffi-cups/printer.rb +105 -0
- data/lib/ffi-cups/struct/destination.rb +9 -0
- data/lib/ffi-cups/struct/job.rb +15 -0
- data/lib/ffi-cups/struct/option.rb +5 -0
- data/lib/ffi-cups/version.rb +3 -0
- metadata +83 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f2e82ad0fb30fa3e5c587658a3eef2af2044b3e06564e581c68e3b6d2d7e18db
|
4
|
+
data.tar.gz: c0f9f05991f788f5e4f2e10cf2e603fea2bb3eb45061d8318bd769e92be2b2f0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4d1d560770915cf815dd32172d4707068401b9b7892babc5c3d099d99de7e10a567dd4a59a7543510f20d0a266361cf73b1e0abf23a971d04c4795d6be6d7c70
|
7
|
+
data.tar.gz: 6e3400f9edef9223e67fc46fbe4c51b1d7492c0e99d3a9e60360d3bb7745df9c6a79eb2d35ca7a805740dbe158f0848b3b4d4f2a3094ac140f1a7bb58ab49656
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ffi-cups (0.1.0)
|
5
|
+
ffi (~> 1.15.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
byebug (11.1.3)
|
11
|
+
diff-lcs (1.4.4)
|
12
|
+
ffi (1.15.0)
|
13
|
+
rake (12.3.3)
|
14
|
+
rspec (3.10.0)
|
15
|
+
rspec-core (~> 3.10.0)
|
16
|
+
rspec-expectations (~> 3.10.0)
|
17
|
+
rspec-mocks (~> 3.10.0)
|
18
|
+
rspec-core (3.10.1)
|
19
|
+
rspec-support (~> 3.10.0)
|
20
|
+
rspec-expectations (3.10.1)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.10.0)
|
23
|
+
rspec-mocks (3.10.2)
|
24
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
+
rspec-support (~> 3.10.0)
|
26
|
+
rspec-support (3.10.2)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
byebug
|
33
|
+
ffi-cups!
|
34
|
+
rake (~> 12.0)
|
35
|
+
rspec (~> 3.0)
|
36
|
+
|
37
|
+
BUNDLED WITH
|
38
|
+
2.1.2
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2021 Hugo Marquez & Contributors
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# ffi-cups
|
2
|
+
ffi-cups is a FFI wrapper around libcups providing access to the Cups API.
|
3
|
+
It was written using Ruby 2.7.0.
|
4
|
+
|
5
|
+
## About
|
6
|
+
This is a complete rewrite of the cupsffi gem, it will deprecate
|
7
|
+
functions deprecated by the CUPS API, if you wish to continue to use them,
|
8
|
+
use the cupsffi gem.
|
9
|
+
|
10
|
+
## Authors
|
11
|
+
- Hugo Marquez @ www.hugomarquez.mx
|
12
|
+
- Contributors @ https://github.com/hugomarquez/ffi-cups/graphs/contributors
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
```bash
|
16
|
+
gem install ffi-cups
|
17
|
+
```
|
18
|
+
|
19
|
+
## Setup
|
20
|
+
ffi-cups requires libcups2 to be installed
|
21
|
+
|
22
|
+
## TODO
|
23
|
+
- send print jobs by creating the job itself first.
|
24
|
+
|
25
|
+
## Example usage
|
26
|
+
```ruby
|
27
|
+
require 'ffi-cups'
|
28
|
+
|
29
|
+
printers = Cups::Printer.get_destinations
|
30
|
+
# [#<Cups::Printer:0x000055fe50b178e0 @name="HP_Officejet_J4500_series_ubuntu", @options={"device-uri"=>"ipps://HP%20Officejet%20J4500%20series%20%40%20ubuntu._ipps._tcp.local/cups", "printer-info"=>"HP Officejet J4500 series @ ubuntu", "printer-location"=>"", "printer-make-and-model"=>"HP Officejet j4585 All-in-one Printer", "printer-type"=>"16814110"}>, #<Cups::Printer:0x000055fe50b15798 @name="Virtual_PDF_Printer", @options={"copies"=>"1", "device-uri"=>"cups-pdf:/", "finishings"=>"3", "job-cancel-after"=>"10800", "job-hold-until"=>"no-hold", "job-priority"=>"50", "job-sheets"=>"none,none", "marker-change-time"=>"0", "number-up"=>"1", "printer-commands"=>"AutoConfigure,Clean,PrintSelfTestPage", "printer-info"=>"Virtual PDF Printer", "printer-is-accepting-jobs"=>"true", "printer-is-shared"=>"false", "printer-is-temporary"=>"false", "printer-location"=>"", "printer-make-and-model"=>"Generic CUPS-PDF Printer (w/ options)", "printer-state"=>"3", "printer-state-change-time"=>"1617884232", "printer-state-reasons"=>"none", "printer-type"=>"10547276", "printer-uri-supported"=>"ipp://localhost/printers/Virtual_PDF_Printer"}>]
|
31
|
+
|
32
|
+
printer = Cups::Printer.get_destination("Virtual_PDF_Printer")
|
33
|
+
#<Cups::Printer:0x0000560f1d4e0958 @name="Virtual_PDF_Printer", @options={"copies"=>"1", "device-uri"=>"cups-pdf:/", "finishings"=>"3", "job-cancel-after"=>"10800", "job-hold-until"=>"no-hold", "job-priority"=>"50", "job-sheets"=>"none,none", "marker-change-time"=>"0", "number-up"=>"1", "printer-commands"=>"AutoConfigure,Clean,PrintSelfTestPage", "printer-info"=>"Virtual PDF Printer", "printer-is-accepting-jobs"=>"true", "printer-is-shared"=>"false", "printer-is-temporary"=>"false", "printer-location"=>"", "printer-make-and-model"=>"Generic CUPS-PDF Printer (w/ options)", "printer-state"=>"3", "printer-state-change-time"=>"1617884232", "printer-state-reasons"=>"none", "printer-type"=>"10547276", "printer-uri-supported"=>"ipp://localhost/printers/Virtual_PDF_Printer"}>
|
34
|
+
|
35
|
+
```
|
36
|
+
|
37
|
+
## Remote CUPS Server
|
38
|
+
You may create a connection object passing a :hostname and/or :port arguments.
|
39
|
+
|
40
|
+
You are in charge of the connection object, remember to close the
|
41
|
+
connection once you stop using it.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
# Create a Connection object with hostname and/or port
|
45
|
+
connection = Cups::Connection.instance(hostname:'print.example.com')
|
46
|
+
|
47
|
+
# Create a http pointer with CUPS API
|
48
|
+
http = connection.httpConnect2
|
49
|
+
|
50
|
+
# Get all printers from the remote connection
|
51
|
+
remote_printers = Cups::Printer.get_destinations(http)
|
52
|
+
|
53
|
+
# Close connection and release pointer
|
54
|
+
Cups::Connection.close(http)
|
55
|
+
```
|
56
|
+
|
57
|
+
## License
|
58
|
+
The MIT License
|
59
|
+
|
60
|
+
Copyright (c) 2021 Hugo Marquez & Contributors
|
61
|
+
|
62
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
63
|
+
of this software and associated documentation files (the "Software"), to deal
|
64
|
+
in the Software without restriction, including without limitation the rights
|
65
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
66
|
+
copies of the Software, and to permit persons to whom the Software is
|
67
|
+
furnished to do so, subject to the following conditions:
|
68
|
+
|
69
|
+
The above copyright notice and this permission notice shall be included in
|
70
|
+
all copies or substantial portions of the Software.
|
71
|
+
|
72
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
73
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
74
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
75
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
76
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
77
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
78
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ffi-cups"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/ffi-cups.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'lib/ffi-cups/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "ffi-cups"
|
5
|
+
s.version = Cups::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ["Hugo Marquez", "Nathan Ehresman"]
|
8
|
+
s.email = ["hugomarquez.dev@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/hugomarquez/ffi-cups"
|
10
|
+
s.summary = "FFI wrapper around libcups"
|
11
|
+
s.description = "Simple wrapper around libcups to give CUPS printing capabilities to Ruby apps."
|
12
|
+
s.license = "MIT"
|
13
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
|
+
|
15
|
+
s.add_runtime_dependency "ffi", "~> 1.15.0"
|
16
|
+
|
17
|
+
# Specify which files should be added to the gem when it is released.
|
18
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
+
s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
end
|
22
|
+
s.bindir = "exe"
|
23
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
end
|
data/lib/ffi-cups.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'byebug'
|
3
|
+
|
4
|
+
module Cups
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
begin
|
8
|
+
if ENV['CUPS_LIB']
|
9
|
+
ffi_lib(ENV['CUPS_LIB'])
|
10
|
+
else
|
11
|
+
ffi_lib('cups')
|
12
|
+
end
|
13
|
+
rescue LoadError => e
|
14
|
+
raise LoadError, "Didn't find libcups on your system."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Constants
|
19
|
+
require 'ffi-cups/constants'
|
20
|
+
|
21
|
+
# Enums
|
22
|
+
require 'ffi-cups/enum/http/status'
|
23
|
+
# IPP
|
24
|
+
require 'ffi-cups/enum/ipp/status'
|
25
|
+
require 'ffi-cups/enum/ipp/job_state'
|
26
|
+
|
27
|
+
# Structs
|
28
|
+
require 'ffi-cups/struct/option'
|
29
|
+
require 'ffi-cups/struct/destination'
|
30
|
+
require 'ffi-cups/struct/job'
|
31
|
+
|
32
|
+
# Functions
|
33
|
+
require 'ffi-cups/ffi/cups'
|
34
|
+
require 'ffi-cups/ffi/http'
|
35
|
+
require 'ffi-cups/ffi/array'
|
36
|
+
|
37
|
+
# wrappers
|
38
|
+
require 'ffi-cups/connection'
|
39
|
+
require 'ffi-cups/printer'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Cups
|
2
|
+
class Connection
|
3
|
+
extend Gem::Deprecate
|
4
|
+
|
5
|
+
attr_accessor :hostname, :port
|
6
|
+
|
7
|
+
@instance_mutex = Mutex.new
|
8
|
+
|
9
|
+
private_class_method :new
|
10
|
+
|
11
|
+
def initialize(args={})
|
12
|
+
@hostname = args.fetch(:hostname) { Cups::CUPS_HTTP_DEFAULT }
|
13
|
+
@port = args.fetch(:port) { 631 }
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns or creates a singleton instance
|
17
|
+
# @param args [Hash] hash argument with hostname and port
|
18
|
+
# @return [Object] a connection object
|
19
|
+
def self.instance(args)
|
20
|
+
return @instance if @instance
|
21
|
+
|
22
|
+
@instance_mutex.synchronize do
|
23
|
+
@instance ||= new(args)
|
24
|
+
end
|
25
|
+
|
26
|
+
@instance
|
27
|
+
end
|
28
|
+
|
29
|
+
# Wrapper around {::FFI::Cups::Http#httpConnectEncrypt}
|
30
|
+
# @deprecated Use {#httpConnect2} instead
|
31
|
+
# @return [Pointer] a http pointer
|
32
|
+
def httpConnectEncrypt
|
33
|
+
http = FFI::Cups::Http.httpConnectEncrypt(hostname, port, FFI::Cups.cupsEncryption())
|
34
|
+
raise "Print server at #{hostname}:#{port} is not available" if http.null?
|
35
|
+
return http
|
36
|
+
end
|
37
|
+
deprecate :httpConnectEncrypt, "This function is deprecated by CUPS, please use httpConnect2 instead", 2025, 12
|
38
|
+
|
39
|
+
# Wrapper around {::FFI::Cups::Http#httpConnect2}
|
40
|
+
# Creates a http connection to a print server
|
41
|
+
# @return [Pointer] a http pointer
|
42
|
+
def httpConnect2
|
43
|
+
http = FFI::Cups::Http.httpConnect2(hostname, port, nil, 0, FFI::Cups.cupsEncryption(), 1, 30000, nil)
|
44
|
+
raise "Print server at #{hostname}:#{port} is not available" if http.null?
|
45
|
+
return http
|
46
|
+
end
|
47
|
+
|
48
|
+
# Closes the http connection and autoreleases the pointer
|
49
|
+
# Wrapper around {::FFI::Cups::Http#httpClose}
|
50
|
+
# @param http (Pointer)
|
51
|
+
def self.close(http)
|
52
|
+
FFI::Cups::Http.httpClose(pointer)
|
53
|
+
pointer.autorelease = true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Cups
|
2
|
+
# cups.h
|
3
|
+
CUPS_FORMAT_JPEG = "image/jpeg"
|
4
|
+
CUPS_FORMAT_PDF = "application/pdf"
|
5
|
+
CUPS_FORMAT_TEXT = "text/plain"
|
6
|
+
CUPS_JOBID_ALL = -1
|
7
|
+
CUPS_WHICHJOBS_ALL = -1
|
8
|
+
CUPS_WHICHJOBS_ACTIVE = 0
|
9
|
+
CUPS_WHICHJOBS_COMPLETED = 1
|
10
|
+
CUPS_HTTP_DEFAULT = nil
|
11
|
+
|
12
|
+
# Options and Values
|
13
|
+
CUPS_COPIES = "copies"
|
14
|
+
CUPS_COPIES_SUPPORTED = "copies-supported"
|
15
|
+
|
16
|
+
CUPS_FINISHINGS = "CUPS_FINISHINGS"
|
17
|
+
CUPS_FINISHINGS_SUPPORTED = "finishings-supported"
|
18
|
+
|
19
|
+
CUPS_FINISHINGS_BIND = "7"
|
20
|
+
CUPS_FINISHINGS_COVER = "6"
|
21
|
+
CUPS_FINISHINGS_FOLD = "10"
|
22
|
+
CUPS_FINISHINGS_NONE = "3"
|
23
|
+
CUPS_FINISHINGS_PUNCH = "5"
|
24
|
+
CUPS_FINISHINGS_STAPLE = "4"
|
25
|
+
CUPS_FINISHINGS_TRIM = "11"
|
26
|
+
|
27
|
+
CUPS_MEDIA = "media"
|
28
|
+
CUPS_MEDIA_READY = "media-ready"
|
29
|
+
CUPS_MEDIA_SUPPORTED = "media-supported"
|
30
|
+
|
31
|
+
CUPS_MEDIA_3X5 = "na_index-3x5_3x5in"
|
32
|
+
CUPS_MEDIA_4X6 = "na_index-4x6_4x6in"
|
33
|
+
CUPS_MEDIA_5X7 = "na_5x7_5x7in"
|
34
|
+
CUPS_MEDIA_8X10 = "na_govt-letter_8x10in"
|
35
|
+
CUPS_MEDIA_A3 = "iso_a3_297x420mm"
|
36
|
+
CUPS_MEDIA_A4 = "iso_a4_210x297mm"
|
37
|
+
CUPS_MEDIA_A5 = "iso_a5_148x210mm"
|
38
|
+
CUPS_MEDIA_A6 = "iso_a6_105x148mm"
|
39
|
+
CUPS_MEDIA_ENV10 = "na_number-10_4.125x9.5in"
|
40
|
+
CUPS_MEDIA_ENVDL = "iso_dl_110x220mm"
|
41
|
+
CUPS_MEDIA_LEGAL = "na_legal_8.5x14in"
|
42
|
+
CUPS_MEDIA_LETTER = "na_letter_8.5x11in"
|
43
|
+
CUPS_MEDIA_PHOTO_L = "oe_photo-l_3.5x5in"
|
44
|
+
CUPS_MEDIA_SUPERBA3 = "na_super-b_13x19in"
|
45
|
+
CUPS_MEDIA_TABLOID = "na_ledger_11x17in"
|
46
|
+
|
47
|
+
CUPS_MEDIA_SOURCE = "media-source"
|
48
|
+
CUPS_MEDIA_SOURCE_SUPPORTED = "media-source-supported"
|
49
|
+
|
50
|
+
CUPS_MEDIA_SOURCE_AUTO = "auto"
|
51
|
+
CUPS_MEDIA_SOURCE_MANUAL = "manual"
|
52
|
+
|
53
|
+
CUPS_MEDIA_TYPE = "media-type"
|
54
|
+
CUPS_MEDIA_TYPE_SUPPORTED = "media-type-supported"
|
55
|
+
|
56
|
+
CUPS_MEDIA_TYPE_AUTO = "auto"
|
57
|
+
CUPS_MEDIA_TYPE_ENVELOPE = "envelope"
|
58
|
+
CUPS_MEDIA_TYPE_LABELS = "labels"
|
59
|
+
CUPS_MEDIA_TYPE_LETTERHEAD = "stationery-letterhead"
|
60
|
+
CUPS_MEDIA_TYPE_PHOTO = "photographic"
|
61
|
+
CUPS_MEDIA_TYPE_PHOTO_GLOSSY = "photographic-glossy"
|
62
|
+
CUPS_MEDIA_TYPE_PHOTO_MATTE = "photographic-matte"
|
63
|
+
CUPS_MEDIA_TYPE_PLAIN = "stationery"
|
64
|
+
CUPS_MEDIA_TYPE_TRANSPARENCY = "transparency"
|
65
|
+
|
66
|
+
CUPS_NUMBER_UP = "number-up"
|
67
|
+
CUPS_NUMBER_UP_SUPPORTED = "number-up-supported"
|
68
|
+
|
69
|
+
CUPS_ORIENTATION = "orientation-requested"
|
70
|
+
CUPS_ORIENTATION_SUPPORTED = "orientation-requested-supported"
|
71
|
+
|
72
|
+
CUPS_ORIENTATION_PORTRAIT = "3"
|
73
|
+
CUPS_ORIENTATION_LANDSCAPE = "4"
|
74
|
+
|
75
|
+
CUPS_PRINT_COLOR_MODE = "print-color-mode"
|
76
|
+
CUPS_PRINT_COLOR_MODE_SUPPORTED = "print-color-mode-supported"
|
77
|
+
|
78
|
+
CUPS_PRINT_COLOR_MODE_AUTO = "auto"
|
79
|
+
CUPS_PRINT_COLOR_MODE_MONOCHROME = "monochrome"
|
80
|
+
CUPS_PRINT_COLOR_MODE_COLOR = "color"
|
81
|
+
|
82
|
+
CUPS_PRINT_QUALITY = "print-quality"
|
83
|
+
CUPS_PRINT_QUALITY_SUPPORTED = "print-quality-supported"
|
84
|
+
|
85
|
+
CUPS_PRINT_QUALITY_DRAFT = "3"
|
86
|
+
CUPS_PRINT_QUALITY_NORMAL = "4"
|
87
|
+
CUPS_PRINT_QUALITY_HIGH = "5"
|
88
|
+
|
89
|
+
CUPS_SIDES = "sides"
|
90
|
+
CUPS_SIDES_SUPPORTED = "sides-supported"
|
91
|
+
|
92
|
+
CUPS_SIDES_ONE_SIDED = "one-sided"
|
93
|
+
CUPS_SIDES_TWO_SIDED_PORTRAIT = "two-sided-long-edge"
|
94
|
+
CUPS_SIDES_TWO_SIDED_LANDSCAPE = "two-sided-short-edge"
|
95
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Cups::Enum
|
2
|
+
module HTTP
|
3
|
+
extend FFI::Library
|
4
|
+
|
5
|
+
Status = enum [
|
6
|
+
:http_error, -1,
|
7
|
+
:http_continue, 100,
|
8
|
+
:http_switching_protocols,
|
9
|
+
:http_ok, 200,
|
10
|
+
:http_created,
|
11
|
+
:http_accepted,
|
12
|
+
:http_not_authoritative,
|
13
|
+
:http_no_content,
|
14
|
+
:http_reset_content,
|
15
|
+
:http_partial_content,
|
16
|
+
:http_multiple_choices, 300,
|
17
|
+
:http_moved_permanently,
|
18
|
+
:http_moved_temporarily,
|
19
|
+
:http_see_other,
|
20
|
+
:http_not_modified,
|
21
|
+
:http_use_proxy,
|
22
|
+
:http_bad_request, 400,
|
23
|
+
:http_unauthorized,
|
24
|
+
:http_payment_required,
|
25
|
+
:http_forbidden,
|
26
|
+
:http_not_found,
|
27
|
+
:http_method_not_allowed,
|
28
|
+
:http_not_acceptable,
|
29
|
+
:http_proxy_authentication,
|
30
|
+
:http_request_timeout,
|
31
|
+
:http_conflict,
|
32
|
+
:http_gone,
|
33
|
+
:http_length_required,
|
34
|
+
:http_precondition,
|
35
|
+
:http_request_too_large,
|
36
|
+
:http_uri_too_long,
|
37
|
+
:http_unsupported_mediatype,
|
38
|
+
:http_requested_range,
|
39
|
+
:http_expectation_failed,
|
40
|
+
:http_upgrade_required, 426,
|
41
|
+
:http_server_error, 500,
|
42
|
+
:http_not_implemented,
|
43
|
+
:http_bad_gateway,
|
44
|
+
:http_service_unavailable,
|
45
|
+
:http_gateway_timeout,
|
46
|
+
:http_not_supported,
|
47
|
+
:http_authorization_canceled, 1000
|
48
|
+
]
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Cups::Enum
|
2
|
+
module IPP
|
3
|
+
extend FFI::Library
|
4
|
+
|
5
|
+
Status = enum [
|
6
|
+
:ipp_ok, 0,
|
7
|
+
:ipp_ok_subst,
|
8
|
+
:ipp_ok_conflict,
|
9
|
+
:ipp_ok_ignored_subscriptions,
|
10
|
+
:ipp_ok_ignored_notifications,
|
11
|
+
:ipp_ok_too_many_events,
|
12
|
+
:ipp_ok_but_cancel_subscription,
|
13
|
+
:ipp_ok_events_complete,
|
14
|
+
:ipp_redirection_other_site, 512,
|
15
|
+
:cups_see_other, 640,
|
16
|
+
:ipp_bad_request, 1024,
|
17
|
+
:ipp_forbidden,
|
18
|
+
:ipp_not_authenticated,
|
19
|
+
:ipp_not_authorized,
|
20
|
+
:ipp_not_possible,
|
21
|
+
:ipp_timeout,
|
22
|
+
:ipp_not_found,
|
23
|
+
:ipp_gone,
|
24
|
+
:ipp_request_entity,
|
25
|
+
:ipp_request_value,
|
26
|
+
:ipp_document_format,
|
27
|
+
:ipp_attributes,
|
28
|
+
:ipp_uri_scheme,
|
29
|
+
:ipp_charset,
|
30
|
+
:ipp_conflict,
|
31
|
+
:ipp_compression_not_supported,
|
32
|
+
:ipp_compression_error,
|
33
|
+
:ipp_document_format_error,
|
34
|
+
:ipp_document_access_error,
|
35
|
+
:ipp_attributes_not_settable,
|
36
|
+
:ipp_ignored_all_subscriptions,
|
37
|
+
:ipp_too_many_subscriptions,
|
38
|
+
:ipp_ignored_all_notifications,
|
39
|
+
:ipp_print_support_file_not_found,
|
40
|
+
:ipp_internal_error, 1280,
|
41
|
+
:ipp_operation_not_supported,
|
42
|
+
:ipp_service_unavailable,
|
43
|
+
:ipp_version_not_supported,
|
44
|
+
:ipp_device_error,
|
45
|
+
:ipp_temporary_error,
|
46
|
+
:ipp_not_accepting,
|
47
|
+
:ipp_printer_busy,
|
48
|
+
:ipp_error_job_canceled,
|
49
|
+
:ipp_multiple_jobs_not_supported,
|
50
|
+
:ipp_printer_is_deactivated
|
51
|
+
]
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module FFI::Cups
|
2
|
+
module Array
|
3
|
+
extend FFI::Library
|
4
|
+
|
5
|
+
ffi_lib('cups')
|
6
|
+
|
7
|
+
# @overload cupsArrayFirst(pointer)
|
8
|
+
# @param pointer [Pointer] to _cups_array_s struct
|
9
|
+
# @return [Pointer] void pointer to first element
|
10
|
+
attach_function 'cupsArrayFirst', [:pointer], :pointer, blocking: true
|
11
|
+
|
12
|
+
# @overload cupsArrayNext(pointer)
|
13
|
+
# @param pointer [Pointer] to _cups_array_s struct
|
14
|
+
# @return [Pointer] void pointer to first element
|
15
|
+
attach_function 'cupsArrayNext', [:pointer], :pointer, blocking: true
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# cups.h
|
2
|
+
# {https://www.cups.org/doc/cupspm.html Programming Manual}
|
3
|
+
# {https://github.com/apple/cups/blob/master/cups/cups.h cups.h source}
|
4
|
+
|
5
|
+
module FFI::Cups
|
6
|
+
extend FFI::Library
|
7
|
+
|
8
|
+
ffi_lib('cups')
|
9
|
+
|
10
|
+
# Get the current encryption settings.
|
11
|
+
# @return [Integer] encryption settings
|
12
|
+
# {https://www.cups.org/doc/cupspm.html#cupsEncryption}
|
13
|
+
attach_function 'cupsEncryption', [], :int, blocking: true
|
14
|
+
|
15
|
+
# Check that the option and value are supported by the destination.
|
16
|
+
# @overload cupsCheckDestSupported(pointer, pointer, pointer, string, string)
|
17
|
+
# @param http [Pointer]
|
18
|
+
# @param destination [Pointer]
|
19
|
+
# @param dinfo [Pointer]
|
20
|
+
# @param option [String]
|
21
|
+
# @param value [String]
|
22
|
+
# @return [Integer] 1 if supported, 0 otherwise
|
23
|
+
# {https://www.cups.org/doc/cupspm.html#cupsCheckDestSupported}
|
24
|
+
attach_function 'cupsCheckDestSupported', [:pointer, :pointer, :pointer, :string, :string], :int, blocking: true
|
25
|
+
|
26
|
+
# Get the named destination from the list.
|
27
|
+
# @overload cupsGetDest(string, string, int, pointer)
|
28
|
+
# @param name [String]
|
29
|
+
# @param instance [String] instance name or NULL
|
30
|
+
# @param num_dests [Integer] number of destinations
|
31
|
+
# @param destinations [Pointer]
|
32
|
+
# @return [Pointer, NULL] destination or NULL
|
33
|
+
# {https://www.cups.org/doc/cupspm.html#cupsGetDest}
|
34
|
+
attach_function 'cupsGetDest', [:string, :string, :int, :pointer], :pointer, blocking: true
|
35
|
+
|
36
|
+
# Get the list of destinations from the specified server.
|
37
|
+
# @overload cupsGetDests2(pointer, pointer)
|
38
|
+
# @param pointer [Pointer] to http connection for server or CUPS_HTTP_DEFAULT
|
39
|
+
# @param pointer [Pointer] to destinations
|
40
|
+
# @return [Integer] number of destinations
|
41
|
+
# {https://www.cups.org/doc/cupspm.html#cupsGetDests2}
|
42
|
+
attach_function 'cupsGetDests2', [:pointer, :pointer], :int, blocking: true
|
43
|
+
|
44
|
+
# Free the memory used by the list of destinations.
|
45
|
+
# @overload cupsFreeDests(int, pointer)
|
46
|
+
# @param number [Integer] of destinations
|
47
|
+
# @param pointer [Pointer] to destinations
|
48
|
+
# {https://www.cups.org/doc/cupspm.html#cupsFreeDests}
|
49
|
+
attach_function 'cupsFreeDests', [ :int, :pointer ], :void, blocking: true
|
50
|
+
|
51
|
+
# Prints a File
|
52
|
+
# @overload cupsPrintFile(string, string, string, int, pointer)
|
53
|
+
# @param name [String] of the printer
|
54
|
+
# @param name [String] of the file
|
55
|
+
# @param title [String] of the job
|
56
|
+
# @param number [Integer] of options
|
57
|
+
# @param pointer [Pointer] to a CupsOptionS struct
|
58
|
+
# @return [Integer] job number or 0 on error
|
59
|
+
attach_function 'cupsPrintFile', [ :string, :string, :string, :int, :pointer ], :int, blocking: true
|
60
|
+
|
61
|
+
# Prints a file from a specific connection
|
62
|
+
# @overload cupsPrintFile2(pointer, string, string, string, int, pointer)
|
63
|
+
# @param pointer [Pointer] to an http connection
|
64
|
+
# @param name [String] of the printer
|
65
|
+
# @param name [String] of the file
|
66
|
+
# @param title [String] of the title
|
67
|
+
# @param number [Integer] of options
|
68
|
+
# @param pointer [Pointer] to a CupsOptionS struct
|
69
|
+
# @return [Integer] number of the job or 0 on error
|
70
|
+
attach_function 'cupsPrintFile2', [ :pointer, :string, :string, :string, :int, :pointer ], :int, blocking: true
|
71
|
+
|
72
|
+
# Returns the last error in string format
|
73
|
+
# @return [String] error
|
74
|
+
attach_function 'cupsLastErrorString', [], :string, blocking: true
|
75
|
+
|
76
|
+
# Cancel a job on a destination.
|
77
|
+
# @overload cupsCancelDestJob(string, int)
|
78
|
+
# @param connection [Pointer] to a http server
|
79
|
+
# @param pointer [Pointer] to a destination
|
80
|
+
# @param id [Integer] of the job
|
81
|
+
# @return [Integer] IPP status
|
82
|
+
# {https://www.cups.org/doc/cupspm.html#cupsCancelDestJob}
|
83
|
+
attach_function 'cupsCancelDestJob', [:string, :int], :void, blocking: true
|
84
|
+
|
85
|
+
# Cancel a job on a destination name
|
86
|
+
# @overload cupsCancelJob(string, int)
|
87
|
+
# @param name [String] of the destination
|
88
|
+
# @param id [Ingeger] of the job
|
89
|
+
attach_function 'cupsCancelJob', [:string, :int], :void, blocking: true
|
90
|
+
|
91
|
+
# Cancel a job on a destination
|
92
|
+
# @overload cupsCancelJob2(pointer, string, int)
|
93
|
+
# @param pointer [Pointer] of the http connection
|
94
|
+
# @param name [String] of the destination
|
95
|
+
# @param id [Ingeger] of the job
|
96
|
+
attach_function 'cupsCancelJob2', [:pointer, :string, :int], :void, blocking: true
|
97
|
+
|
98
|
+
# Get the jobs from a connection
|
99
|
+
# @overload cupsGetJobs2(pointer, pointer, string, int, int)
|
100
|
+
# @param pointer [Pointer] to a http connection object
|
101
|
+
# @param pointer [Pointer] to Cups::Struct::Job
|
102
|
+
# @param name [String] of the printer
|
103
|
+
# @param number [Integer] of type of job (0 == all users, 1 == mine)
|
104
|
+
# @param which [Integer] jobs (CUPS_WHICHJOBS_ALL, CUPS_WHICHJOBS_ACTIVE, or CUPS_WHICHJOBS_COMPLETED)
|
105
|
+
# @return [Integer] number of jobs
|
106
|
+
# {https://www.cups.org/doc/cupspm.html#cupsGetJobs2}
|
107
|
+
attach_function 'cupsGetJobs2', [:pointer, :pointer, :string, :int, :int], :int, blocking: true
|
108
|
+
|
109
|
+
# Get the jobs
|
110
|
+
# @overload cupsGetJobs(pointer, string, int, int)
|
111
|
+
# @param pointer [Pointer] to Cups::Struct::Job to populate
|
112
|
+
# @param name [String] of the printer
|
113
|
+
# @param number [Integer] of type of job (0 == all users, 1 == mine)
|
114
|
+
# @param which [Integer] jobs (CUPS_WHICHJOBS_ALL, CUPS_WHICHJOBS_ACTIVE, or CUPS_WHICHJOBS_COMPLETED)
|
115
|
+
# @return [Integer] number of jobs
|
116
|
+
attach_function 'cupsGetJobs', [:pointer, :string, :int, :int], :int, blocking: true
|
117
|
+
|
118
|
+
# Free memory used by job data.
|
119
|
+
# @overload cupsFreeJobs(int, pointer)
|
120
|
+
# @param number [Integer] of jobs
|
121
|
+
# @param pointer [Pointer] to the first Cups::Struct::Job to free
|
122
|
+
# {https://www.cups.org/doc/cupspm.html#cupsFreeJobs}
|
123
|
+
attach_function 'cupsFreeJobs', [:int, :pointer ], :void, blocking: true
|
124
|
+
|
125
|
+
# Create a job on a destination.
|
126
|
+
# @overload cupsCreateJob(pointer, string, string, int, pointer)
|
127
|
+
# @param pointer [Pointer] to http connection to server or CUPS_HTTP_DEFAULT
|
128
|
+
# @param name [String] of the printer
|
129
|
+
# @param title [String] of the job
|
130
|
+
# @param number [Integer] of options
|
131
|
+
# @param pointer [Pointer] to a Cups::Struct::Option object
|
132
|
+
# @return [Integer] job number or 0 on error
|
133
|
+
attach_function 'cupsCreateJob', [:pointer, :string, :string, :int, :pointer], :int, blocking: true
|
134
|
+
|
135
|
+
# Start a document
|
136
|
+
# @overload cupsStartDocument(pointer, string, int, string, string, int)
|
137
|
+
# @param pointer [Pointer] to http connection to server or CUPS_HTTP_DEFAULT
|
138
|
+
# @param name [String] of the printer
|
139
|
+
# @param id [Integer] of the job
|
140
|
+
# @param name [String] of the document
|
141
|
+
# @param mime_type [String] format of the document
|
142
|
+
# @param number [Integer] of the last document (1 for last document in job, 0 otherwise)
|
143
|
+
# @return [Cups::Enum::HTTP::Status] HttpStatus
|
144
|
+
# {https://www.cups.org/doc/cupspm.html#submitting-a-print-job}
|
145
|
+
attach_function 'cupsStartDocument', [:pointer, :string, :int, :string, :string, :int], Cups::Enum::HTTP::Status, blocking: true
|
146
|
+
|
147
|
+
# @overload cupsWriteRequestData(pointer, pointer, bytesize)
|
148
|
+
# @param pointer [Pointer] to http connection to server or CUPS_HTTP_DEFAULT
|
149
|
+
# @param data [Pointer] in a character string pointer
|
150
|
+
# @param length [Byte] of data
|
151
|
+
# @return [Cups::Enum::HTTP::Status] HttpStatus
|
152
|
+
attach_function 'cupsWriteRequestData', [:pointer, :pointer, :size_t], Cups::Enum::HTTP::Status, blocking: true
|
153
|
+
|
154
|
+
# @overload cupsFinishDocument(pointer, string)
|
155
|
+
# @param pointer [Pointer] to http connection to server or CUPS_HTTP_DEFAULT
|
156
|
+
# @param name [String] of the printer
|
157
|
+
# @return [Cups::Enum::IPP::Status] IppStatus
|
158
|
+
attach_function 'cupsFinishDocument', [:pointer, :string], Cups::Enum::IPP::Status, blocking: true
|
159
|
+
|
160
|
+
# Add an option to an option array.
|
161
|
+
# @overload cupsAddOption(string, string, int, pointer)
|
162
|
+
# @param name [String] of option
|
163
|
+
# @param value [String] of option
|
164
|
+
# @param number [Integer] of options
|
165
|
+
# @param pointer [Pointer] to options
|
166
|
+
# @return [Integer] number of options
|
167
|
+
# {https://www.cups.org/doc/cupspm.html#cupsAddOption}
|
168
|
+
attach_function 'cupsAddOption', [:string, :string, :int, :pointer], :int, blocking: true
|
169
|
+
|
170
|
+
# Free all memory used by options.
|
171
|
+
# @overload cupsFreeOptions(int, pointer)
|
172
|
+
# @param number [Integer] of options
|
173
|
+
# @param pointer [Pointer] to options
|
174
|
+
# {https://www.cups.org/doc/cupspm.html#cupsFreeOptions}
|
175
|
+
attach_function 'cupsFreeOptions', [:int, :pointer], :void, blocking: true
|
176
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module FFI::Cups
|
2
|
+
module Http
|
3
|
+
extend FFI::Library
|
4
|
+
|
5
|
+
ffi_lib('cups')
|
6
|
+
|
7
|
+
# @overload httpConnectEncrypt(string, int, int)
|
8
|
+
# @param hostname [String]
|
9
|
+
# @param port [int]
|
10
|
+
# @param encryption_settings [int]
|
11
|
+
# @return [Pointer] pointer to a http_t object
|
12
|
+
# @deprecated Please use httpConnect2 instead
|
13
|
+
attach_function 'httpConnectEncrypt', [ :string, :int, :int], :pointer, blocking: true
|
14
|
+
|
15
|
+
# @overload httpClose(pointer)
|
16
|
+
# @param pointer [Pointer] to a http_t object
|
17
|
+
attach_function 'httpClose', [ :pointer ], :void, blocking: true
|
18
|
+
|
19
|
+
# Get a list of addresses for a hostname.
|
20
|
+
# @overload httpAddrGetList(string, int, string)
|
21
|
+
# @param hostname [String]
|
22
|
+
# @param family [Integer]
|
23
|
+
# @param port [String]
|
24
|
+
# @return [Pointer] List of addresses or NULL
|
25
|
+
attach_function 'httpAddrGetList', [:string, :int, :string], :pointer, blocking: true
|
26
|
+
|
27
|
+
# Connect to a HTTP server.
|
28
|
+
# @overload httpConnect2(string, int, pointer, int, int, int, int, pointer)
|
29
|
+
# @param hostname [String]
|
30
|
+
# @param port [Integer]
|
31
|
+
# @param addrlist [Pointer] can be NULL
|
32
|
+
# @param family [Integer] (AF_UNSPEC=0)
|
33
|
+
# @param encryption_settings [Integer] from FFI::Cups.cupsEncryption()
|
34
|
+
# @param blocking [Integer]
|
35
|
+
# @param msec [Integer] use 5000 or less
|
36
|
+
# @param cancel[Pointer] integer pointer, can be NULL
|
37
|
+
# @return [Pointer] http_t object
|
38
|
+
attach_function 'httpConnect2', [:string, :int, :pointer, :int, :int, :int, :int, :pointer], :pointer, blocking: true
|
39
|
+
end
|
40
|
+
end
|
data/lib/ffi-cups/job.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
module Cups
|
2
|
+
class Printer
|
3
|
+
attr_reader :name, :options
|
4
|
+
|
5
|
+
# @param name [String] printer's name
|
6
|
+
# @param options [Hash] printer's options
|
7
|
+
def initialize(name, options={})
|
8
|
+
@name = name
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the printer state
|
13
|
+
# @return [Symbol] printer state from options
|
14
|
+
def state
|
15
|
+
case options['printer-state']
|
16
|
+
when '3' then :idle
|
17
|
+
when '4' then :printing
|
18
|
+
when '5' then :stopped
|
19
|
+
else :unkown
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the reason for the printer state
|
24
|
+
# @return [Array] array of reasons in string format
|
25
|
+
def state_reasons
|
26
|
+
options['printer-state-reasons'].split(/,/)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get all destinations (printer devices)
|
30
|
+
# @param connection [Pointer] http pointer from {Cups::Connection#httpConnect2}
|
31
|
+
def self.get_destinations(connection=nil)
|
32
|
+
pointer = FFI::MemoryPointer.new :pointer
|
33
|
+
destinations = cupsGetDests2(connection, pointer)
|
34
|
+
printers = []
|
35
|
+
destinations.each do |k, d|
|
36
|
+
destination_opt = cupsOptions(d)
|
37
|
+
options = {}
|
38
|
+
|
39
|
+
destination_opt.each do |k, o|
|
40
|
+
options[o[:name].dup] = o[:value].dup
|
41
|
+
end
|
42
|
+
|
43
|
+
printer = Cups::Printer.new(d[:name].dup, options)
|
44
|
+
printers.push(printer)
|
45
|
+
end
|
46
|
+
cupsFreeDests(destinations.keys.count, pointer)
|
47
|
+
return printers
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get a destination by name
|
51
|
+
# @param name [String] name of the printer
|
52
|
+
# @param connection [Pointer] http pointer from {Cups::Connection#httpConnect2}
|
53
|
+
def self.get_destination(name, connection=nil)
|
54
|
+
printers = get_destinations(connection)
|
55
|
+
printers.each do |p|
|
56
|
+
return p if p.name == name
|
57
|
+
end
|
58
|
+
raise "Destination with name: #{name} not found!"
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
# Wrapper around {::FFI::Cups#cupsGetDests2}
|
63
|
+
# @param connection [Pointer] http pointer from {Cups::Connection#httpConnect2}
|
64
|
+
# @param pointer [Pointer] pointer to the destinations
|
65
|
+
# @return [Hash] hashmap of destination structs
|
66
|
+
def self.cupsGetDests2(connection=nil, pointer)
|
67
|
+
count_destinations = FFI::Cups.cupsGetDests2(connection, pointer)
|
68
|
+
struct_size = Cups::Struct::Destination.size
|
69
|
+
destinations = {}
|
70
|
+
count_destinations.times do |index|
|
71
|
+
destination = Cups::Struct::Destination.new(pointer.get_pointer(0) + (struct_size * index))
|
72
|
+
destinations[index] = destination
|
73
|
+
end
|
74
|
+
return destinations
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns a destination's options
|
78
|
+
# @param destination [Object] {Cups::Struct::Destination} object
|
79
|
+
# @return [Hash] hashmap of destination' options as {Cups::Struct::Option}
|
80
|
+
def self.cupsOptions(destination)
|
81
|
+
struct_size = Cups::Struct::Option.size
|
82
|
+
options = {}
|
83
|
+
|
84
|
+
destination[:num_options].times do |index|
|
85
|
+
option = Cups::Struct::Option.new(destination[:options] + (struct_size * index))
|
86
|
+
options[index] = option
|
87
|
+
end
|
88
|
+
return options
|
89
|
+
end
|
90
|
+
|
91
|
+
# Wrapper around {::FFI::Cups#cupsFreeDests}
|
92
|
+
# @param number_destinations [Integer]
|
93
|
+
# @param pointer [Pointer] pointer to the destinations
|
94
|
+
def self.cupsFreeDests(number_destinations, pointer)
|
95
|
+
FFI::Cups.cupsFreeDests(number_destinations, pointer.get_pointer(0))
|
96
|
+
end
|
97
|
+
|
98
|
+
# Wrapper around {::FFI::Cups#cupsFreeOptions}
|
99
|
+
# @param number_options [Integer]
|
100
|
+
# @param pointer [Pointer] pointer to the options
|
101
|
+
def self.cupsFreeOptions(number_options, pointer)
|
102
|
+
FFI::Cups.cupsFreeOptions(number_options, pointer.get_pointer(0))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Cups::Struct
|
2
|
+
class Job < FFI::Struct
|
3
|
+
layout :id, :int,
|
4
|
+
:dest, :string,
|
5
|
+
:title, :string,
|
6
|
+
:user, :string,
|
7
|
+
:format, :string,
|
8
|
+
:state, Cups::Enum::IPP::JobState,
|
9
|
+
:size, :int,
|
10
|
+
:priority, :int,
|
11
|
+
:completed_time, :long,
|
12
|
+
:creation_time, :long,
|
13
|
+
:processing_time, :long
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ffi-cups
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hugo Marquez
|
8
|
+
- Nathan Ehresman
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2021-04-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ffi
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 1.15.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 1.15.0
|
28
|
+
description: Simple wrapper around libcups to give CUPS printing capabilities to Ruby
|
29
|
+
apps.
|
30
|
+
email:
|
31
|
+
- hugomarquez.dev@gmail.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- ".gitignore"
|
37
|
+
- Gemfile
|
38
|
+
- Gemfile.lock
|
39
|
+
- LICENSE
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- bin/console
|
43
|
+
- bin/setup
|
44
|
+
- ffi-cups.gemspec
|
45
|
+
- lib/ffi-cups.rb
|
46
|
+
- lib/ffi-cups/connection.rb
|
47
|
+
- lib/ffi-cups/constants.rb
|
48
|
+
- lib/ffi-cups/enum/http/status.rb
|
49
|
+
- lib/ffi-cups/enum/ipp/job_state.rb
|
50
|
+
- lib/ffi-cups/enum/ipp/status.rb
|
51
|
+
- lib/ffi-cups/ffi/array.rb
|
52
|
+
- lib/ffi-cups/ffi/cups.rb
|
53
|
+
- lib/ffi-cups/ffi/http.rb
|
54
|
+
- lib/ffi-cups/job.rb
|
55
|
+
- lib/ffi-cups/printer.rb
|
56
|
+
- lib/ffi-cups/struct/destination.rb
|
57
|
+
- lib/ffi-cups/struct/job.rb
|
58
|
+
- lib/ffi-cups/struct/option.rb
|
59
|
+
- lib/ffi-cups/version.rb
|
60
|
+
homepage: https://github.com/hugomarquez/ffi-cups
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 2.3.0
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubygems_version: 3.1.2
|
80
|
+
signing_key:
|
81
|
+
specification_version: 4
|
82
|
+
summary: FFI wrapper around libcups
|
83
|
+
test_files: []
|