ffi-cups2 0.4.0
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
- checksums.yaml.gz.sig +0 -0
- data/.gitignore +14 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/README.md +110 -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/connection.rb +39 -0
- data/lib/ffi-cups/constants.rb +98 -0
- data/lib/ffi-cups/enum/http/ppd.rb +22 -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/res.rb +10 -0
- data/lib/ffi-cups/enum/ipp/status.rb +53 -0
- data/lib/ffi-cups/enum/ipp/tag.rb +51 -0
- data/lib/ffi-cups/ffi/array.rb +17 -0
- data/lib/ffi-cups/ffi/cups.rb +216 -0
- data/lib/ffi-cups/ffi/http.rb +40 -0
- data/lib/ffi-cups/ffi/ipp_attribute.rb +74 -0
- data/lib/ffi-cups/ffi/ppd.rb +65 -0
- data/lib/ffi-cups/job.rb +89 -0
- data/lib/ffi-cups/printer.rb +342 -0
- data/lib/ffi-cups/struct/destination.rb +9 -0
- data/lib/ffi-cups/struct/ipp_attribute.rb +6 -0
- data/lib/ffi-cups/struct/job.rb +15 -0
- data/lib/ffi-cups/struct/option.rb +5 -0
- data/lib/ffi-cups/struct/ppd_choice.rb +9 -0
- data/lib/ffi-cups/struct/ppd_file.rb +6 -0
- data/lib/ffi-cups/struct/ppd_option.rb +14 -0
- data/lib/ffi-cups/version.rb +3 -0
- data/lib/ffi-cups.rb +48 -0
- data/lib/ffi-cups2.rb +1 -0
- data.tar.gz.sig +4 -0
- metadata +117 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
module Cups
|
|
2
|
+
class Printer
|
|
3
|
+
attr_reader :name, :is_default, :options, :connection
|
|
4
|
+
|
|
5
|
+
# @param name [String] printer's name
|
|
6
|
+
# @param options [Hash] printer's options
|
|
7
|
+
def initialize(name, is_default=nil, options={}, connection=nil)
|
|
8
|
+
@name = name
|
|
9
|
+
@is_default = is_default
|
|
10
|
+
@options = options
|
|
11
|
+
@connection = connection
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns the printer state
|
|
15
|
+
# @return [Symbol] printer state from options
|
|
16
|
+
def state
|
|
17
|
+
case options['printer-state']
|
|
18
|
+
when '3' then :idle
|
|
19
|
+
when '4' then :printing
|
|
20
|
+
when '5' then :stopped
|
|
21
|
+
else :unknown
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns the reason for the printer state
|
|
26
|
+
# @return [Array] array of reasons in string format
|
|
27
|
+
def state_reasons
|
|
28
|
+
options['printer-state-reasons'].split(/,/)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Print a file (pdf, jpg, ps, etc.).
|
|
32
|
+
#
|
|
33
|
+
# You can pass in a hash of printing options if you want to override the printer's defaults.
|
|
34
|
+
#
|
|
35
|
+
# @return [Cups::Job] can be used to check on the job status.
|
|
36
|
+
def print_file(filename, title, options={})
|
|
37
|
+
raise "File not found: #{filename}" unless File.exist? filename
|
|
38
|
+
|
|
39
|
+
http = @connection.nil? ? nil : @connection.httpConnect2
|
|
40
|
+
with_destination(http) do |dest|
|
|
41
|
+
p_options = nil
|
|
42
|
+
num_options = 0
|
|
43
|
+
unless options.empty?
|
|
44
|
+
p_options = FFI::MemoryPointer.new :pointer
|
|
45
|
+
options.each do |k, v|
|
|
46
|
+
# Do not raise invalid options, since cupsCheckDestSupported states valid PPD options as unsupported.
|
|
47
|
+
# unless self.class.cupsCheckDestSupported(dest.to_ptr, k, v, http)
|
|
48
|
+
# raise "Option:#{k} #{v if v} not supported for printer: #{@name}"
|
|
49
|
+
#end
|
|
50
|
+
num_options = Cups.cupsAddOption(k, v, num_options, p_options)
|
|
51
|
+
end
|
|
52
|
+
p_options = p_options.get_pointer(0)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
job_id = Cups.cupsPrintFile2(http, @name, filename, title, num_options, p_options)
|
|
56
|
+
|
|
57
|
+
if job_id == 0
|
|
58
|
+
raise Cups.cupsLastErrorString()
|
|
59
|
+
end
|
|
60
|
+
#Cups::Job.new(job_id, title, @name)
|
|
61
|
+
Cups::Job.get_job(job_id, @name, 0, @connection)
|
|
62
|
+
ensure
|
|
63
|
+
self.class.cupsFreeOptions(num_options, p_options) if p_options
|
|
64
|
+
end
|
|
65
|
+
ensure
|
|
66
|
+
Cups::Connection.close(http) if http
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Print a binary blob of data provided as a String.
|
|
70
|
+
#
|
|
71
|
+
# You must also specify the mime type.
|
|
72
|
+
# Like {print_file}, printing options are optional.
|
|
73
|
+
#
|
|
74
|
+
# @return [Cups::Job] can be used to check on the job status.
|
|
75
|
+
def print_data(data, mime_type, title, options = {})
|
|
76
|
+
http = @connection.nil? ? nil : @connection.httpConnect2
|
|
77
|
+
with_destination(http) do |dest|
|
|
78
|
+
p_options = nil
|
|
79
|
+
num_options = 0
|
|
80
|
+
unless options.empty?
|
|
81
|
+
p_options = FFI::MemoryPointer.new :pointer
|
|
82
|
+
options.each do |k, v|
|
|
83
|
+
num_options = Cups.cupsAddOption(k, v, num_options, p_options)
|
|
84
|
+
end
|
|
85
|
+
p_options = p_options.get_pointer(0)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
job_id = Cups.cupsCreateJob(http, @name, title, num_options, p_options)
|
|
89
|
+
if job_id == 0
|
|
90
|
+
raise CupsFFI::cupsLastErrorString()
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Copy the data into a char pointer to allow null bytes
|
|
94
|
+
data_pointer = FFI::MemoryPointer.new(:char, data.bytesize)
|
|
95
|
+
data_pointer.put_bytes(0, data)
|
|
96
|
+
|
|
97
|
+
http_status = Cups.cupsStartDocument(@connection, @name,
|
|
98
|
+
job_id, title, mime_type, 1)
|
|
99
|
+
|
|
100
|
+
http_status = Cups.cupsWriteRequestData(@connection, data_pointer, data.bytesize)
|
|
101
|
+
|
|
102
|
+
ipp_status = Cups.cupsFinishDocument(@connection, @name)
|
|
103
|
+
|
|
104
|
+
data_pointer.free
|
|
105
|
+
|
|
106
|
+
raise ipp_status.to_s unless ipp_status == :ipp_ok
|
|
107
|
+
|
|
108
|
+
Cups::Job.get_job(job_id, @name, 0, @connection)
|
|
109
|
+
ensure
|
|
110
|
+
self.class.cupsFreeOptions(num_options, p_options) if p_options
|
|
111
|
+
end
|
|
112
|
+
ensure
|
|
113
|
+
Cups::Connection.close(http) if http
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private def with_destination(http, &block)
|
|
117
|
+
self.class.with_destination(http, @name, &block)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def self.with_destination(http, name)
|
|
121
|
+
# Get all destinations with cupsGetDests2
|
|
122
|
+
dests = FFI::MemoryPointer.new :pointer
|
|
123
|
+
num_dests = Cups.cupsGetDests2(http, dests)
|
|
124
|
+
|
|
125
|
+
# Get the destination from name with cupsGetDest
|
|
126
|
+
p_dest = Cups.cupsGetDest(name, nil, num_dests, dests.get_pointer(0))
|
|
127
|
+
dest = Cups::Struct::Destination.new(p_dest)
|
|
128
|
+
raise "Destination with name: #{name} not found!" if dest.null?
|
|
129
|
+
yield dest
|
|
130
|
+
ensure
|
|
131
|
+
Cups.cupsFreeDests(num_dests, dests.get_pointer(0))
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
class IppGetResolutionParams < FFI::Struct
|
|
135
|
+
layout yres: :int, :units => Enum::IPP::Res
|
|
136
|
+
end
|
|
137
|
+
private_constant :IppGetResolutionParams
|
|
138
|
+
|
|
139
|
+
# Find the supported value(s) for the given option.
|
|
140
|
+
#
|
|
141
|
+
# If no option is given then the available options are returned.
|
|
142
|
+
#
|
|
143
|
+
# @return [Hash, nil] hash with keys :type and :values or nil when option is not supported
|
|
144
|
+
def find_dest_supported(option = "job-creation-attributes")
|
|
145
|
+
http = @connection.nil? ? nil : @connection.httpConnect2
|
|
146
|
+
with_destination(http) do |dest|
|
|
147
|
+
attr = self.class.cupsFindDestSupported(dest.to_ptr,
|
|
148
|
+
option, http);
|
|
149
|
+
return nil if attr.null?
|
|
150
|
+
|
|
151
|
+
count = IppAttibute.ippGetCount(attr)
|
|
152
|
+
name = IppAttibute.ippGetName(attr)
|
|
153
|
+
type = IppAttibute.ippGetValueTag(attr)
|
|
154
|
+
values = count.times.map do |idx|
|
|
155
|
+
case type
|
|
156
|
+
when :ipp_tag_resolution then
|
|
157
|
+
params = IppGetResolutionParams.new
|
|
158
|
+
xres = IppAttibute.ippGetResolution(attr, idx, params.to_ptr + params.offset_of(:yres), params.to_ptr + params.offset_of(:units))
|
|
159
|
+
if xres != 0
|
|
160
|
+
{xres: xres, yres: params[:yres], units: params[:units]}
|
|
161
|
+
end
|
|
162
|
+
when :ipp_tag_range then
|
|
163
|
+
p_uppervalue = FFI::MemoryPointer.new :int
|
|
164
|
+
low = IppAttibute.ippGetRange(attr, idx, p_uppervalue)
|
|
165
|
+
if low != 0
|
|
166
|
+
{lowervalue: low, uppervalue: p_uppervalue.read_int}
|
|
167
|
+
end
|
|
168
|
+
when :ipp_tag_enum then
|
|
169
|
+
int = IppAttibute.ippGetInteger(attr, idx)
|
|
170
|
+
name = IppAttibute.ippEnumString(option, int)
|
|
171
|
+
{int: int, name: name}
|
|
172
|
+
else
|
|
173
|
+
IppAttibute.ippGetString(attr, idx, nil) || IppAttibute.ippGetInteger(attr, idx)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
{ type: type, values: values, name: name }
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Get all destinations (printer devices)
|
|
181
|
+
# @param connection [Pointer] http pointer from {Cups::Connection#httpConnect2}
|
|
182
|
+
def self.get_destinations(connection=nil)
|
|
183
|
+
pointer = FFI::MemoryPointer.new :pointer
|
|
184
|
+
dests = cupsGetDests2(pointer, connection)
|
|
185
|
+
printers = []
|
|
186
|
+
dests.each do |d|
|
|
187
|
+
printer = Cups::Printer.new(d[:name].dup, d[:is_default]!=0, printer_options(d), connection)
|
|
188
|
+
printers.push(printer)
|
|
189
|
+
end
|
|
190
|
+
cupsFreeDests(dests.count, pointer)
|
|
191
|
+
return printers
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Get a destination by name
|
|
195
|
+
# @param name [String] name of the printer
|
|
196
|
+
# @param connection [Pointer] http pointer from {Cups::Connection#httpConnect2}
|
|
197
|
+
# @return [Printer] a printer object
|
|
198
|
+
def self.get_destination(name, connection=nil)
|
|
199
|
+
http = connection.nil? ? nil : connection.httpConnect2
|
|
200
|
+
printer = with_destination(http, name) do |dest|
|
|
201
|
+
Cups::Printer.new(dest[:name].dup, dest[:is_default]!=0, printer_options(dest), connection)
|
|
202
|
+
end
|
|
203
|
+
Cups::Connection.close(http) if http
|
|
204
|
+
return printer
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Get all possible options of the PPD file of the printer.
|
|
208
|
+
#
|
|
209
|
+
# These options can be passed to {print_file}.
|
|
210
|
+
# CUPS's PPD functions are deprecated, but many PPD based printers can be controlled only by PPD options, instead of IPP options.
|
|
211
|
+
#
|
|
212
|
+
# @return [Array<Hash>] List of accepted options and their attributes.
|
|
213
|
+
def ppd_options
|
|
214
|
+
ppd_path = Cups::Ppd.cupsGetPPD(name)
|
|
215
|
+
if ppd_path.nil? || ppd_path.empty?
|
|
216
|
+
raise "Error: Could not retrieve PPD for printer '#{name}'"
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
ppd_ptr = Cups::Ppd.ppdOpenFile(ppd_path)
|
|
220
|
+
if ppd_ptr.null?
|
|
221
|
+
raise "Error: Failed to open PPD file at #{ppd_path}"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Let CUPS evaluate current printer system runtime option defaults
|
|
225
|
+
# Cups::Ppd.cupsMarkOptions(ppd_ptr, 0, nil)
|
|
226
|
+
|
|
227
|
+
options = []
|
|
228
|
+
|
|
229
|
+
opt_ptr = Cups::Ppd.ppdFirstOption(ppd_ptr)
|
|
230
|
+
|
|
231
|
+
while !opt_ptr.null?
|
|
232
|
+
option = Cups::Struct::PpdOption.new(opt_ptr)
|
|
233
|
+
choices_array = []
|
|
234
|
+
|
|
235
|
+
# Safe pointer stepping through contiguous C memory slots of choice definitions
|
|
236
|
+
option[:num_choices].times do |c_idx|
|
|
237
|
+
choice_stride = Cups::Struct::PpdChoice.size
|
|
238
|
+
choice_element_ptr = option[:choices] + (c_idx * choice_stride)
|
|
239
|
+
choice = Cups::Struct::PpdChoice.new(choice_element_ptr)
|
|
240
|
+
|
|
241
|
+
choices_array << {
|
|
242
|
+
choice: choice[:choice].to_s,
|
|
243
|
+
marked: choice[:marked] != 0,
|
|
244
|
+
}
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
options << {
|
|
248
|
+
keyword: option[:keyword].to_s,
|
|
249
|
+
text: option[:text].to_s,
|
|
250
|
+
choices: choices_array,
|
|
251
|
+
defchoice: option[:defchoice].to_s,
|
|
252
|
+
ui: option[:ui],
|
|
253
|
+
section: option[:section],
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
opt_ptr = Cups::Ppd.ppdNextOption(ppd_ptr)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
options
|
|
260
|
+
ensure
|
|
261
|
+
if ppd_ptr && !ppd_ptr.null?
|
|
262
|
+
Cups::Ppd.ppdClose(ppd_ptr)
|
|
263
|
+
end
|
|
264
|
+
File.delete(ppd_path) if ppd_path && File.exist?(ppd_path)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
private
|
|
268
|
+
# Wrapper around {::Cups#cupsGetDests2}
|
|
269
|
+
# @param connection [Pointer] http pointer from {Cups::Connection#httpConnect2}
|
|
270
|
+
# @param pointer [Pointer] pointer to the destinations
|
|
271
|
+
# @return [Hash] hashmap of destination structs
|
|
272
|
+
def self.cupsGetDests2(pointer, connection=nil)
|
|
273
|
+
http = connection.nil? ? nil : connection.httpConnect2
|
|
274
|
+
num_dests = Cups.cupsGetDests2(http, pointer)
|
|
275
|
+
size = Cups::Struct::Destination.size
|
|
276
|
+
destinations = []
|
|
277
|
+
num_dests.times do |i|
|
|
278
|
+
destination = Cups::Struct::Destination.new(pointer.get_pointer(0) + (size * i))
|
|
279
|
+
destinations.push(destination)
|
|
280
|
+
end
|
|
281
|
+
Cups::Connection.close(http) if http
|
|
282
|
+
return destinations
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Wrapper around {::Cups#cupsCheckDestSupported}
|
|
286
|
+
# @param dest [Pointer] pointer to the destination
|
|
287
|
+
# @param option [String]
|
|
288
|
+
# @param value [String]
|
|
289
|
+
# @param connection [Pointer] http pointer from {Cups::Connection#httpConnect2}
|
|
290
|
+
# @return [Boolean] true if supported, false otherwise
|
|
291
|
+
def self.cupsCheckDestSupported(dest, option, value, connection=nil)
|
|
292
|
+
info = Cups.cupsCopyDestInfo(connection, dest)
|
|
293
|
+
i = Cups.cupsCheckDestSupported(connection, dest, info, option, value)
|
|
294
|
+
return !i.zero?
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def self.cupsFindDestSupported(dest, option, connection=nil)
|
|
298
|
+
info = Cups.cupsCopyDestInfo(connection, dest)
|
|
299
|
+
Cups.cupsFindDestSupported(connection, dest, info, option)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# Returns a destination's options
|
|
303
|
+
# @param dest [Object] {Cups::Struct::Destination} object
|
|
304
|
+
# @return [Hash] hash of destination' options as {Cups::Struct::Option}
|
|
305
|
+
def self.cups_options(dest)
|
|
306
|
+
size = Cups::Struct::Option.size
|
|
307
|
+
options = []
|
|
308
|
+
|
|
309
|
+
dest[:num_options].times do |i|
|
|
310
|
+
option = Cups::Struct::Option.new(dest[:options] + (size * i))
|
|
311
|
+
options.push(option)
|
|
312
|
+
end
|
|
313
|
+
return options
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Returns a destination's options as hash
|
|
317
|
+
# @param dest [Object] {Cups::Struct::Destination} object
|
|
318
|
+
# @return [Hash] hash of destination' options
|
|
319
|
+
def self.printer_options(dest)
|
|
320
|
+
dest_opts = cups_options(dest)
|
|
321
|
+
options = {}
|
|
322
|
+
dest_opts.each do |o|
|
|
323
|
+
options[o[:name].dup] = o[:value].dup
|
|
324
|
+
end
|
|
325
|
+
return options
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Wrapper around {::Cups#cupsFreeDests}
|
|
329
|
+
# @param num_dests [Integer]
|
|
330
|
+
# @param pointer [Pointer] pointer to the destinations
|
|
331
|
+
def self.cupsFreeDests(num_dests, pointer)
|
|
332
|
+
Cups.cupsFreeDests(num_dests, pointer.get_pointer(0))
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
# Wrapper around {::Cups#cupsFreeOptions}
|
|
336
|
+
# @param num_opts [Integer]
|
|
337
|
+
# @param pointer [Pointer] pointer to the options
|
|
338
|
+
def self.cupsFreeOptions(num_opts, pointer)
|
|
339
|
+
Cups.cupsFreeOptions(num_opts, pointer)
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
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
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module Cups::Struct
|
|
2
|
+
class PpdChoice < FFI::Struct
|
|
3
|
+
layout :marked, :char, # 0 if unselected, 1 if active
|
|
4
|
+
:choice, [:char, Cups::PPD_MAX_NAME], # Computer key (e.g., "Letter")
|
|
5
|
+
:text, [:char, Cups::PPD_MAX_TEXT], # Human readable text
|
|
6
|
+
:code, :pointer, # Pointer to raw PostScript snippet string
|
|
7
|
+
:option, :pointer # Pointer to parent PpdOption struct
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Cups::Struct
|
|
2
|
+
class PpdOption < FFI::Struct
|
|
3
|
+
layout :conflicted, :char, # Conflict status code
|
|
4
|
+
:keyword, [:char, Cups::PPD_MAX_NAME], # Main option key (e.g., "PageSize")
|
|
5
|
+
:defchoice, [:char, Cups::PPD_MAX_NAME], # Default option fallback choice
|
|
6
|
+
:text, [:char, Cups::PPD_MAX_TEXT], # Human readable descriptive flag
|
|
7
|
+
:ui, Cups::Enum::Ppd::Ui, # UI type enum (PickOne, PickMany, etc.)
|
|
8
|
+
:section, Cups::Enum::Ppd::Section, # Order dependency section code
|
|
9
|
+
:order, :float, # Sequence execution priority
|
|
10
|
+
:num_choices, :int, # Choices element scale length
|
|
11
|
+
:choices, :pointer, # Points to sequential array block of PpdChoice
|
|
12
|
+
:subgroup, :pointer # PpdSubgroup relationship tracking link
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/ffi-cups.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'ffi'
|
|
2
|
+
|
|
3
|
+
module Cups
|
|
4
|
+
|
|
5
|
+
# Custom or default path for libcups.so
|
|
6
|
+
def self.libcups
|
|
7
|
+
if ENV['CUPS_LIB']
|
|
8
|
+
ENV['CUPS_LIB']
|
|
9
|
+
else
|
|
10
|
+
FFI::LibraryPath.new('cups', abi_number: 2)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Constants
|
|
17
|
+
require 'ffi-cups/constants'
|
|
18
|
+
|
|
19
|
+
# Enums
|
|
20
|
+
require 'ffi-cups/enum/http/status'
|
|
21
|
+
require 'ffi-cups/enum/http/ppd'
|
|
22
|
+
|
|
23
|
+
# IPP
|
|
24
|
+
require 'ffi-cups/enum/ipp/status'
|
|
25
|
+
require 'ffi-cups/enum/ipp/job_state'
|
|
26
|
+
require 'ffi-cups/enum/ipp/res'
|
|
27
|
+
require 'ffi-cups/enum/ipp/tag'
|
|
28
|
+
|
|
29
|
+
# Structs
|
|
30
|
+
require 'ffi-cups/struct/option'
|
|
31
|
+
require 'ffi-cups/struct/destination'
|
|
32
|
+
require 'ffi-cups/struct/job'
|
|
33
|
+
require 'ffi-cups/struct/ipp_attribute'
|
|
34
|
+
require 'ffi-cups/struct/ppd_choice'
|
|
35
|
+
require 'ffi-cups/struct/ppd_file'
|
|
36
|
+
require 'ffi-cups/struct/ppd_option'
|
|
37
|
+
|
|
38
|
+
# Functions
|
|
39
|
+
require 'ffi-cups/ffi/cups'
|
|
40
|
+
require 'ffi-cups/ffi/http'
|
|
41
|
+
require 'ffi-cups/ffi/array'
|
|
42
|
+
require 'ffi-cups/ffi/ipp_attribute'
|
|
43
|
+
require 'ffi-cups/ffi/ppd'
|
|
44
|
+
|
|
45
|
+
# wrappers
|
|
46
|
+
require 'ffi-cups/connection'
|
|
47
|
+
require 'ffi-cups/job'
|
|
48
|
+
require 'ffi-cups/printer'
|
data/lib/ffi-cups2.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require_relative 'ffi-cups'
|
data.tar.gz.sig
ADDED
metadata
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ffi-cups2
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Hugo Marquez
|
|
8
|
+
- Nathan Ehresman
|
|
9
|
+
- Lars Kanis
|
|
10
|
+
bindir: exe
|
|
11
|
+
cert_chain:
|
|
12
|
+
- |
|
|
13
|
+
-----BEGIN CERTIFICATE-----
|
|
14
|
+
MIIEBDCCAmygAwIBAgIBBDANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
|
|
15
|
+
L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNjAxMDUxMTE5MzRaFw0yNzAx
|
|
16
|
+
MDUxMTE5MzRaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
|
|
17
|
+
PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
|
|
18
|
+
mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
|
|
19
|
+
eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
|
|
20
|
+
8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
|
|
21
|
+
SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
|
|
22
|
+
JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
|
|
23
|
+
eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
|
|
24
|
+
chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
|
|
25
|
+
9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
|
|
26
|
+
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
|
|
27
|
+
7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAg/1LuXN3X8xwHVnhRvmBCZYkNErko40y
|
|
28
|
+
juq/qPF9vkPGxLEGaeZF1rv/obTs5SgIGEUkWdRsOl3F6bQN4MYUFlN/n6rPx19g
|
|
29
|
+
CqUMkmRtuFD+9EFBI4twoF2IJS0pYr9tkjUq8mb0VXblvfbEEUf460BJmuBXZTc6
|
|
30
|
+
OoLQHxjhhqhKBoP4lHXg/OMK9dnGn8+5DoKcsyWQvqq/GdK8pi4E47M/egzw54Go
|
|
31
|
+
g+oeyGDsNKOQlnIA9gbyPpExD1+akJ4v88T8jOUnsOkhBBUkpSktC2QmEYIU5e9j
|
|
32
|
+
N7muw6O5Bz3CQuSWIEjj9mMUS2fEEfq2km6zO5vs5eD6TdFnt8AC/HlOrPaxGcUX
|
|
33
|
+
Hjw/K7ZTvZLEb4awRijdy4wx3OlL9FAyZPjYOh8TdJrLl076c7GyimAkgnc8BrL5
|
|
34
|
+
g1vGc759o2t3KNnlUg8VwqkhFJp4gCko1QO/8Io5hPQZOvJw8dmqNiiiHqaDupfl
|
|
35
|
+
CI4mk2K8yQa8xtQ/RmFZxYS5XbHhDJCw
|
|
36
|
+
-----END CERTIFICATE-----
|
|
37
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
38
|
+
dependencies:
|
|
39
|
+
- !ruby/object:Gem::Dependency
|
|
40
|
+
name: ffi
|
|
41
|
+
requirement: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - "~>"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '1.16'
|
|
46
|
+
type: :runtime
|
|
47
|
+
prerelease: false
|
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - "~>"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '1.16'
|
|
53
|
+
description: Simple wrapper around libcups to give CUPS printing capabilities to Ruby
|
|
54
|
+
apps.
|
|
55
|
+
email:
|
|
56
|
+
- hugomarquez.dev@gmail.com
|
|
57
|
+
- n_github@ehresman.org
|
|
58
|
+
- lars@greiz-reinsdorf.de
|
|
59
|
+
executables: []
|
|
60
|
+
extensions: []
|
|
61
|
+
extra_rdoc_files: []
|
|
62
|
+
files:
|
|
63
|
+
- ".gitignore"
|
|
64
|
+
- Gemfile
|
|
65
|
+
- LICENSE
|
|
66
|
+
- README.md
|
|
67
|
+
- Rakefile
|
|
68
|
+
- bin/console
|
|
69
|
+
- bin/setup
|
|
70
|
+
- ffi-cups.gemspec
|
|
71
|
+
- lib/ffi-cups.rb
|
|
72
|
+
- lib/ffi-cups/connection.rb
|
|
73
|
+
- lib/ffi-cups/constants.rb
|
|
74
|
+
- lib/ffi-cups/enum/http/ppd.rb
|
|
75
|
+
- lib/ffi-cups/enum/http/status.rb
|
|
76
|
+
- lib/ffi-cups/enum/ipp/job_state.rb
|
|
77
|
+
- lib/ffi-cups/enum/ipp/res.rb
|
|
78
|
+
- lib/ffi-cups/enum/ipp/status.rb
|
|
79
|
+
- lib/ffi-cups/enum/ipp/tag.rb
|
|
80
|
+
- lib/ffi-cups/ffi/array.rb
|
|
81
|
+
- lib/ffi-cups/ffi/cups.rb
|
|
82
|
+
- lib/ffi-cups/ffi/http.rb
|
|
83
|
+
- lib/ffi-cups/ffi/ipp_attribute.rb
|
|
84
|
+
- lib/ffi-cups/ffi/ppd.rb
|
|
85
|
+
- lib/ffi-cups/job.rb
|
|
86
|
+
- lib/ffi-cups/printer.rb
|
|
87
|
+
- lib/ffi-cups/struct/destination.rb
|
|
88
|
+
- lib/ffi-cups/struct/ipp_attribute.rb
|
|
89
|
+
- lib/ffi-cups/struct/job.rb
|
|
90
|
+
- lib/ffi-cups/struct/option.rb
|
|
91
|
+
- lib/ffi-cups/struct/ppd_choice.rb
|
|
92
|
+
- lib/ffi-cups/struct/ppd_file.rb
|
|
93
|
+
- lib/ffi-cups/struct/ppd_option.rb
|
|
94
|
+
- lib/ffi-cups/version.rb
|
|
95
|
+
- lib/ffi-cups2.rb
|
|
96
|
+
homepage: https://github.com/larskanis/ffi-cups
|
|
97
|
+
licenses:
|
|
98
|
+
- MIT
|
|
99
|
+
metadata: {}
|
|
100
|
+
rdoc_options: []
|
|
101
|
+
require_paths:
|
|
102
|
+
- lib
|
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
|
+
requirements:
|
|
105
|
+
- - ">="
|
|
106
|
+
- !ruby/object:Gem::Version
|
|
107
|
+
version: '3.2'
|
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
|
+
requirements:
|
|
110
|
+
- - ">="
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: '0'
|
|
113
|
+
requirements: []
|
|
114
|
+
rubygems_version: 4.0.16
|
|
115
|
+
specification_version: 4
|
|
116
|
+
summary: FFI wrapper around libcups2
|
|
117
|
+
test_files: []
|
metadata.gz.sig
ADDED
|
Binary file
|