cups 0.0.5 → 0.0.6
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.
- data/ext/cups.c +56 -100
- data/ext/ruby_cups.h +2 -2
- data/lib/cups/print_job/transient.rb +58 -0
- data/lib/cups/printer/printer.rb +35 -0
- data/test/cups_test.rb +8 -0
- metadata +5 -3
data/ext/cups.c
CHANGED
@@ -5,6 +5,40 @@ static cups_option_t *options;
|
|
5
5
|
cups_dest_t *dests, *dest;
|
6
6
|
VALUE rubyCups, printJobs;
|
7
7
|
|
8
|
+
// Need to abstract this out of cups.c
|
9
|
+
char* ipp_state_to_string(int state)
|
10
|
+
{
|
11
|
+
|
12
|
+
char *jstate;
|
13
|
+
|
14
|
+
switch (state) {
|
15
|
+
case IPP_JOB_PENDING :
|
16
|
+
jstate = "Pending...";
|
17
|
+
break;
|
18
|
+
case IPP_JOB_HELD :
|
19
|
+
jstate = "Held";
|
20
|
+
break;
|
21
|
+
case IPP_JOB_PROCESSING :
|
22
|
+
jstate = "Processing...";
|
23
|
+
break;
|
24
|
+
case IPP_JOB_STOPPED :
|
25
|
+
jstate = "Stopped";
|
26
|
+
break;
|
27
|
+
case IPP_JOB_CANCELED :
|
28
|
+
jstate = "Cancelled";
|
29
|
+
break;
|
30
|
+
case IPP_JOB_ABORTED :
|
31
|
+
jstate = "Aborted";
|
32
|
+
break;
|
33
|
+
case IPP_JOB_COMPLETED :
|
34
|
+
jstate = "Completed";
|
35
|
+
break;
|
36
|
+
default:
|
37
|
+
jstate = "Unknown Job Code...";
|
38
|
+
}
|
39
|
+
return jstate;
|
40
|
+
}
|
41
|
+
|
8
42
|
|
9
43
|
/*
|
10
44
|
* call-seq:
|
@@ -25,7 +59,12 @@ static VALUE job_init(int argc, VALUE* argv, VALUE self)
|
|
25
59
|
|
26
60
|
// Fall back to default printer
|
27
61
|
VALUE def_p = rb_funcall(rubyCups, rb_intern("default_printer"), 0);
|
28
|
-
|
62
|
+
|
63
|
+
if (def_p == Qfalse) {
|
64
|
+
rb_raise(rb_eRuntimeError, "There is no default printer!");
|
65
|
+
} else {
|
66
|
+
rb_iv_set(self, "@printer", def_p);
|
67
|
+
}
|
29
68
|
|
30
69
|
} else {
|
31
70
|
// First call Cups#show_destinations
|
@@ -212,34 +251,10 @@ static VALUE cups_get_job_state(VALUE self)
|
|
212
251
|
}
|
213
252
|
}
|
214
253
|
|
215
|
-
|
216
|
-
|
254
|
+
// Free job array
|
255
|
+
cupsFreeJobs(num_jobs, jobs);
|
217
256
|
|
218
|
-
|
219
|
-
case IPP_JOB_PENDING :
|
220
|
-
jstate = rb_str_new2("Pending...");
|
221
|
-
break;
|
222
|
-
case IPP_JOB_HELD :
|
223
|
-
jstate = rb_str_new2("Held");
|
224
|
-
break;
|
225
|
-
case IPP_JOB_PROCESSING :
|
226
|
-
jstate = rb_str_new2("Processing...");
|
227
|
-
break;
|
228
|
-
case IPP_JOB_STOPPED :
|
229
|
-
jstate = rb_str_new2("Stopped");
|
230
|
-
break;
|
231
|
-
case IPP_JOB_CANCELED :
|
232
|
-
jstate = rb_str_new2("Cancelled");
|
233
|
-
break;
|
234
|
-
case IPP_JOB_ABORTED :
|
235
|
-
jstate = rb_str_new2("Aborted");
|
236
|
-
break;
|
237
|
-
case IPP_JOB_COMPLETED :
|
238
|
-
jstate = rb_str_new2("Completed");
|
239
|
-
break;
|
240
|
-
default:
|
241
|
-
jstate = rb_str_new2("Unknown Job Code...");
|
242
|
-
}
|
257
|
+
jstate = rb_str_new2(ipp_state_to_string(job_state));
|
243
258
|
|
244
259
|
return jstate;
|
245
260
|
}
|
@@ -293,14 +308,14 @@ static VALUE cups_job_completed(VALUE self)
|
|
293
308
|
* Cups.all_jobs(printer) -> Hash
|
294
309
|
*
|
295
310
|
* Get all jobs from default CUPS server. Takes a single printer/class string argument.
|
296
|
-
* Returned hash keys are CUPS job ids, and the values are
|
297
|
-
*
|
311
|
+
* Returned hash keys are CUPS job ids, and the values are hashes of job info
|
312
|
+
* with keys:
|
298
313
|
*
|
299
|
-
* [title,submitted_by,size,format,state]
|
314
|
+
* [:title, :submitted_by, :size, :format, :state]
|
300
315
|
*/
|
301
316
|
static VALUE cups_get_jobs(VALUE self, VALUE printer)
|
302
317
|
{
|
303
|
-
VALUE job_list,
|
318
|
+
VALUE job_list, job_info_hash, jid, jtitle, juser, jsize, jformat, jstate;
|
304
319
|
int job_id;
|
305
320
|
int num_jobs;
|
306
321
|
cups_job_t *jobs;
|
@@ -312,44 +327,21 @@ static VALUE cups_get_jobs(VALUE self, VALUE printer)
|
|
312
327
|
job_list = rb_hash_new();
|
313
328
|
|
314
329
|
for (i = 0; i < num_jobs; i ++) { // Construct a hash of individual job info
|
315
|
-
|
330
|
+
job_info_hash = rb_hash_new();
|
316
331
|
jid = INT2NUM(jobs[i].id);
|
317
332
|
jtitle = rb_str_new2(jobs[i].title);
|
318
333
|
juser = rb_str_new2(jobs[i].user);
|
319
334
|
jsize = INT2NUM(jobs[i].size);
|
320
335
|
jformat = rb_str_new2(jobs[i].format);
|
336
|
+
jstate = rb_str_new2(ipp_state_to_string(jobs[i].state));
|
337
|
+
|
338
|
+
rb_hash_aset(job_info_hash, ID2SYM(rb_intern("title")), jtitle);
|
339
|
+
rb_hash_aset(job_info_hash, ID2SYM(rb_intern("submitted_by")), juser);
|
340
|
+
rb_hash_aset(job_info_hash, ID2SYM(rb_intern("size")), jsize);
|
341
|
+
rb_hash_aset(job_info_hash, ID2SYM(rb_intern("format")), jformat);
|
342
|
+
rb_hash_aset(job_info_hash, ID2SYM(rb_intern("state")), jstate);
|
321
343
|
|
322
|
-
//
|
323
|
-
switch (jobs[i].state) {
|
324
|
-
case IPP_JOB_PENDING :
|
325
|
-
jstate = rb_str_new2("Pending...");
|
326
|
-
break;
|
327
|
-
case IPP_JOB_HELD :
|
328
|
-
jstate = rb_str_new2("Held");
|
329
|
-
break;
|
330
|
-
case IPP_JOB_PROCESSING :
|
331
|
-
jstate = rb_str_new2("Processing...");
|
332
|
-
break;
|
333
|
-
case IPP_JOB_STOPPED :
|
334
|
-
jstate = rb_str_new2("Stopped");
|
335
|
-
break;
|
336
|
-
case IPP_JOB_CANCELED :
|
337
|
-
jstate = rb_str_new2("Cancelled");
|
338
|
-
break;
|
339
|
-
case IPP_JOB_ABORTED :
|
340
|
-
jstate = rb_str_new2("Aborted");
|
341
|
-
break;
|
342
|
-
case IPP_JOB_COMPLETED :
|
343
|
-
jstate = rb_str_new2("Completed");
|
344
|
-
}
|
345
|
-
|
346
|
-
rb_ary_push(job_info_ary, jtitle);
|
347
|
-
rb_ary_push(job_info_ary, juser);
|
348
|
-
rb_ary_push(job_info_ary, jsize);
|
349
|
-
rb_ary_push(job_info_ary, jformat);
|
350
|
-
rb_ary_push(job_info_ary, jstate);
|
351
|
-
|
352
|
-
rb_hash_aset(job_list, jid, job_info_ary); // And push it all into job_list hash
|
344
|
+
rb_hash_aset(job_list, jid, job_info_hash); // And push it all into job_list hash
|
353
345
|
}
|
354
346
|
|
355
347
|
// Free job array
|
@@ -391,42 +383,6 @@ static VALUE cups_get_options(VALUE self, VALUE printer)
|
|
391
383
|
|
392
384
|
}
|
393
385
|
|
394
|
-
// TODO
|
395
|
-
// int ipp_state_to_string(int state)
|
396
|
-
// {
|
397
|
-
// // char *jstate;
|
398
|
-
// switch (state) {
|
399
|
-
// case IPP_JOB_PENDING :
|
400
|
-
// // jstate = rb_str_new2("Pending...");
|
401
|
-
// // char jstate[] = "Pending...";
|
402
|
-
// break;
|
403
|
-
// case IPP_JOB_HELD :
|
404
|
-
// // jstate = rb_str_new2("Held");
|
405
|
-
// // char jstate[] = "Held";
|
406
|
-
// break;
|
407
|
-
// case IPP_JOB_PROCESSING :
|
408
|
-
// // jstate = rb_str_new2("Processing...");
|
409
|
-
// // char jstate[] = "Processing...";
|
410
|
-
// break;
|
411
|
-
// case IPP_JOB_STOPPED :
|
412
|
-
// // jstate = rb_str_new2("Stopped");
|
413
|
-
// // char jstate[] = "Stopped";
|
414
|
-
// break;
|
415
|
-
// case IPP_JOB_CANCELED :
|
416
|
-
// // jstate = rb_str_new2("Cancelled");
|
417
|
-
// // char jstate[] = "Cancelled";
|
418
|
-
// break;
|
419
|
-
// case IPP_JOB_ABORTED :
|
420
|
-
// // jstate = rb_str_new2("Aborted");
|
421
|
-
// // char jstate[] = "Aborted";
|
422
|
-
// break;
|
423
|
-
// case IPP_JOB_COMPLETED :
|
424
|
-
// // jstate = rb_str_new2("Completed");
|
425
|
-
// break;
|
426
|
-
// }
|
427
|
-
// return 0;
|
428
|
-
// }
|
429
|
-
|
430
386
|
/*
|
431
387
|
*/
|
432
388
|
|
data/ext/ruby_cups.h
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "cups"
|
2
|
+
require "tempfile"
|
3
|
+
require "digest/sha1"
|
4
|
+
|
5
|
+
module Cups
|
6
|
+
|
7
|
+
class PrintJob
|
8
|
+
|
9
|
+
# Unlike its superclass, a Transient object takes a string of data (e.g. from an IO object).
|
10
|
+
# This is useful when you've got something like a PDF, an ImageMagick byte array, etc that you
|
11
|
+
# just want to send on its way rather than having to touch the file system directly.
|
12
|
+
# === A contrived example:
|
13
|
+
# Say we're using Prawn[http://prawn.majesticseacreature.com/] to generate PDF invoices for some nebulous,
|
14
|
+
# ever-expanding system that promises us sex, drugs, rock & roll, fame and perhaps a pay-rise. Instead of just
|
15
|
+
# generating a file, let's pass the rendered version to a Transient object and let it take care of things:
|
16
|
+
#
|
17
|
+
# ---
|
18
|
+
#
|
19
|
+
# require 'cups/print_job/transient'
|
20
|
+
# require 'prawn'
|
21
|
+
#
|
22
|
+
# invoice = Prawn::Document.new do
|
23
|
+
# text "Invoice."
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# paper_copy = Cups::PrintJob::Transient.new(invoice.render)
|
27
|
+
# paper_copy.print
|
28
|
+
#
|
29
|
+
# ---
|
30
|
+
#
|
31
|
+
# As of 0.0.5, all instance methods inherited from PrintJob are unaltered. This may change if I need to
|
32
|
+
# delay passing the print data or change it after initialization, just as PrintJob currently permits the
|
33
|
+
# file to be written to/moved/nonexistent until print is called.
|
34
|
+
#
|
35
|
+
# Enjoy.
|
36
|
+
|
37
|
+
class Transient < PrintJob
|
38
|
+
|
39
|
+
alias_method :old_init, :initialize
|
40
|
+
|
41
|
+
# Create a print job from a non-empty string. Takes optional printer argument, otherwise uses default.
|
42
|
+
# As the tempfile is written to and closed upon initialization, an error will be raised if an empty
|
43
|
+
# string is passed as the first argument.
|
44
|
+
def initialize(data_string, printer=nil)
|
45
|
+
raise "Temporary print job has no data!" if data_string.empty?
|
46
|
+
|
47
|
+
sha1 = Digest::SHA1.hexdigest(Time.now.to_s)
|
48
|
+
file = Tempfile.new(sha1)
|
49
|
+
file.puts(data_string)
|
50
|
+
file.close
|
51
|
+
|
52
|
+
old_init(file.path, printer)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "cups"
|
2
|
+
|
3
|
+
module Cups
|
4
|
+
|
5
|
+
# Right now this just wraps the Cups.options_for hash using method_missing, allowing you to call
|
6
|
+
# things like Printer#printer_make_and_model on an instance.
|
7
|
+
class Printer
|
8
|
+
|
9
|
+
# Creates a Cups::Printer object. Defaults to the default printer, if there is one.
|
10
|
+
def initialize(printer=nil)
|
11
|
+
if printer.nil?
|
12
|
+
raise "There is no default printer!" if !Cups.default_printer
|
13
|
+
@printer = Cups.default_printer
|
14
|
+
else
|
15
|
+
raise "The printer or destination doesn't exist!" unless Cups.show_destinations.include?(printer)
|
16
|
+
@printer = printer
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Call an options key on this object (with hyphens substituted with underscores). Passes onto super if
|
21
|
+
# no key is found or its value is nil.
|
22
|
+
def method_missing(m)
|
23
|
+
get_options
|
24
|
+
key = m.to_s.gsub(/\_/, "-")
|
25
|
+
@options[key].nil? ? super : @options[key]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def get_options
|
31
|
+
@options ||= Cups.options_for(@printer)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/test/cups_test.rb
CHANGED
@@ -60,6 +60,14 @@ class CupsTest < Test::Unit::TestCase
|
|
60
60
|
def test_all_jobs_returns_hash
|
61
61
|
assert Cups.all_jobs(Cups.default_printer).is_a?(Hash)
|
62
62
|
end
|
63
|
+
|
64
|
+
def test_all_jobs_hash_contains_info_hash
|
65
|
+
pj = Cups::PrintJob.new(sample, "PDF_Printer")
|
66
|
+
pj.print
|
67
|
+
info = Cups.all_jobs("PDF_Printer")[pj.job_id]
|
68
|
+
assert info.is_a?(Hash)
|
69
|
+
assert info.keys.all?{|key| [:title, :format, :submitted_by, :state, :size].include?(key)}
|
70
|
+
end
|
63
71
|
|
64
72
|
def test_dest_list_returns_array
|
65
73
|
assert Cups.show_destinations.is_a?(Array)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cups
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Mowforth
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-13 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,6 +29,8 @@ files:
|
|
29
29
|
- ext/cups.c
|
30
30
|
- ext/ruby_cups.h
|
31
31
|
- ext/extconf.rb
|
32
|
+
- lib/cups/print_job/transient.rb
|
33
|
+
- lib/cups/printer/printer.rb
|
32
34
|
has_rdoc: true
|
33
35
|
homepage: http://cups.rubyforge.org/
|
34
36
|
licenses: []
|
@@ -53,7 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
55
|
requirements: []
|
54
56
|
|
55
57
|
rubyforge_project: cups
|
56
|
-
rubygems_version: 1.3.
|
58
|
+
rubygems_version: 1.3.5
|
57
59
|
signing_key:
|
58
60
|
specification_version: 3
|
59
61
|
summary: A lightweight Ruby library for printing.
|