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 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
- rb_iv_set(self, "@printer", def_p);
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
- // Free job array
216
- cupsFreeJobs(num_jobs, jobs);
254
+ // Free job array
255
+ cupsFreeJobs(num_jobs, jobs);
217
256
 
218
- switch (job_state) {
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 arrays of job info in the
297
- * following order:
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, job_info_ary, jid, jtitle, juser, jsize, jformat, jstate;
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
- job_info_ary = rb_ary_new();
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
- // Let's elaborate on that job state...
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
@@ -1,8 +1,8 @@
1
1
  #include <cups/cups.h>
2
2
  #ifdef __APPLE__
3
- #include <ruby/ruby.h>
3
+ #include <ruby/ruby.h>
4
4
  #else
5
- #include <ruby.h>
5
+ #include <ruby.h>
6
6
  #endif
7
7
 
8
8
  #ifndef MAXOPTS
@@ -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.5
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: 2009-05-22 00:00:00 +01:00
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.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.