ffi-cups 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|