cups 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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.