noggin 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +39 -0
- data/Rakefile +49 -0
- data/ext/noggin/extconf.rb +106 -0
- data/ext/noggin/noggin.c +239 -0
- data/ext/noggin/noggin.cr +176 -0
- data/ext/noggin/noggin.rd +21 -0
- data/lib/noggin/version.rb +4 -0
- data/lib/noggin.rb +2 -0
- metadata +89 -0
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
noggin
|
2
|
+
======
|
3
|
+
|
4
|
+
Cups API wrapper for ruby
|
5
|
+
|
6
|
+
Noggin.destinations ->
|
7
|
+
[
|
8
|
+
{
|
9
|
+
'name' => printerName,
|
10
|
+
'instance' => instanceName,
|
11
|
+
'is_default' => is_default,
|
12
|
+
'options' => { ... },
|
13
|
+
}
|
14
|
+
]
|
15
|
+
|
16
|
+
|
17
|
+
Noggin::WHICHJOBS_ALL
|
18
|
+
Noggin::WHICHJOBS_ACTIVE
|
19
|
+
Noggin::WHICHJOBS_COMPLETED
|
20
|
+
|
21
|
+
Noggin.jobs(printerName, bool justMine, int whichJobs) ->
|
22
|
+
[
|
23
|
+
{
|
24
|
+
'id' => id,
|
25
|
+
'dest' => printerName,
|
26
|
+
'completed_time' => ,
|
27
|
+
'creation_time'
|
28
|
+
'format' => mimetype,
|
29
|
+
'priority' => int,
|
30
|
+
'processing_time' => time,
|
31
|
+
'size' => size in kb,
|
32
|
+
'user' => owner,
|
33
|
+
'state' => one of :aborted, :cancelled, :completed, :held, :pending, :processing, :stopped
|
34
|
+
}
|
35
|
+
]
|
36
|
+
|
37
|
+
|
38
|
+
Noggin::Job.cancel(printer, job_id)
|
39
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'rake-compiler'
|
3
|
+
require 'rake/extensiontask'
|
4
|
+
BASE_DIR = Dir.pwd
|
5
|
+
require 'rubygems/package_task'
|
6
|
+
require 'rake/testtask'
|
7
|
+
|
8
|
+
exts = []
|
9
|
+
|
10
|
+
namespace :prepare do
|
11
|
+
FileList["ext/*/*.cr"].each do |cr|
|
12
|
+
dir = File.dirname(cr)
|
13
|
+
name = File.basename(dir)
|
14
|
+
desc "Generate source for #{name}"
|
15
|
+
task(name.intern) do
|
16
|
+
sh 'rubber-generate', '--build-dir', dir, cr
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
$: << File.dirname(__FILE__)+"/lib"
|
22
|
+
require 'noggin/version'
|
23
|
+
spec = Gem::Specification.new do |s|
|
24
|
+
s.name = "noggin"
|
25
|
+
s.author = "Geoff Youngs"
|
26
|
+
s.email = "git@intersect-uk.co.uk"
|
27
|
+
s.version = Noggin::VERSION
|
28
|
+
s.homepage = "http://github.com/geoffyoungs/noggin"
|
29
|
+
s.summary = "libcups bindings for ruby"
|
30
|
+
s.add_dependency("rubber-generate", ">= 0.0.17")
|
31
|
+
s.platform = Gem::Platform::RUBY
|
32
|
+
s.license = 'MIT'
|
33
|
+
s.extensions = FileList["ext/*/extconf.rb"]
|
34
|
+
s.files = FileList['ext/*/*.{c,h,cr,rd}'] + ['Rakefile', 'README.md'] + FileList['lib/**/*.rb']
|
35
|
+
s.description = <<-EOF
|
36
|
+
smb
|
37
|
+
EOF
|
38
|
+
end
|
39
|
+
Gem::PackageTask.new(spec) do |pkg|
|
40
|
+
pkg.need_tar = true
|
41
|
+
end
|
42
|
+
Rake::ExtensionTask.new("noggin", spec)
|
43
|
+
|
44
|
+
Rake::TestTask.new do |t|
|
45
|
+
t.test_files = FileList['test/*_test.rb']
|
46
|
+
end
|
47
|
+
|
48
|
+
task :default, :compile
|
49
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
use_gems = false
|
3
|
+
begin
|
4
|
+
require 'mkmf-gnome2'
|
5
|
+
rescue LoadError
|
6
|
+
use_gems = true
|
7
|
+
end
|
8
|
+
|
9
|
+
if use_gems or Object.const_defined?('Gem')
|
10
|
+
require 'rubygems'
|
11
|
+
gem 'glib2'
|
12
|
+
require 'mkmf-gnome2'
|
13
|
+
%w[rbglib.h rbgtk.h rbpango.h rbatk.h].each do |header|
|
14
|
+
Gem.find_files(header).each do |f|
|
15
|
+
$CFLAGS += " '-I#{File.dirname(f)}'"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
# Look for headers in {gem_root}/ext/{package}
|
20
|
+
if use_gems
|
21
|
+
%w[
|
22
|
+
gdk_pixbuf2 atk gtk2 ].each do |package|
|
23
|
+
require package
|
24
|
+
$CFLAGS += " -I"+Gem.loaded_specs[package].full_gem_path+"/ext/"+package
|
25
|
+
end
|
26
|
+
end
|
27
|
+
if RbConfig::CONFIG.has_key?('rubyhdrdir')
|
28
|
+
$CFLAGS += " -I" + RbConfig::CONFIG['rubyhdrdir']+'/ruby'
|
29
|
+
end
|
30
|
+
|
31
|
+
$CFLAGS += " -I."
|
32
|
+
have_func("rb_errinfo")
|
33
|
+
have_header("cups/cups.h") or exit(-1)
|
34
|
+
have_header("cups/ipp.h") or exit(-1)
|
35
|
+
have_header("ruby.h") or exit(-1)
|
36
|
+
have_header("st.h") or exit(-1)
|
37
|
+
have_library("cups") or exit(-1)
|
38
|
+
$LIBS += " -lcups"
|
39
|
+
|
40
|
+
STDOUT.print("checking for new allocation framework... ") # for ruby-1.7
|
41
|
+
if Object.respond_to? :allocate
|
42
|
+
STDOUT.print "yes
|
43
|
+
"
|
44
|
+
$defs << "-DHAVE_OBJECT_ALLOCATE"
|
45
|
+
else
|
46
|
+
STDOUT.print "no
|
47
|
+
"
|
48
|
+
end
|
49
|
+
|
50
|
+
top = File.expand_path(File.dirname(__FILE__) + '/..') # XXX
|
51
|
+
$CFLAGS += " " + ['glib/src'].map{|d|
|
52
|
+
"-I" + File.join(top, d)
|
53
|
+
}.join(" ")
|
54
|
+
|
55
|
+
have_func("rb_define_alloc_func") # for ruby-1.8
|
56
|
+
|
57
|
+
#set_output_lib('libruby-noggin.a')
|
58
|
+
if /cygwin|mingw/ =~ RUBY_PLATFORM
|
59
|
+
top = "../.."
|
60
|
+
[
|
61
|
+
["glib/src", "ruby-glib2"],
|
62
|
+
].each{|d,l|
|
63
|
+
$LDFLAGS << sprintf(" -L%s/%s", top, d)
|
64
|
+
$libs << sprintf(" -l%s", l)
|
65
|
+
}
|
66
|
+
end
|
67
|
+
begin
|
68
|
+
srcdir = File.expand_path(File.dirname($0))
|
69
|
+
|
70
|
+
begin
|
71
|
+
|
72
|
+
obj_ext = "."+$OBJEXT
|
73
|
+
|
74
|
+
$libs = $libs.split(/ /).uniq.join(' ')
|
75
|
+
$source_files = Dir.glob(sprintf("%s/*.c", srcdir)).map{|fname|
|
76
|
+
fname[0, srcdir.length+1] = ''
|
77
|
+
fname
|
78
|
+
}
|
79
|
+
$objs = $source_files.collect do |item|
|
80
|
+
item.gsub(/.c$/, obj_ext)
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# create Makefile
|
85
|
+
#
|
86
|
+
$defs << "-DRUBY_NOGGIN_COMPILATION"
|
87
|
+
# $CFLAGS << $defs.join(' ')
|
88
|
+
create_makefile("noggin", srcdir)
|
89
|
+
raise Interrupt if not FileTest.exist? "Makefile"
|
90
|
+
|
91
|
+
File.open("Makefile", "a") do |mfile|
|
92
|
+
$source_files.each do |e|
|
93
|
+
mfile.print sprintf("%s: %s
|
94
|
+
", e.gsub(/.c$/, obj_ext), e)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
ensure
|
98
|
+
#Dir.chdir ".."
|
99
|
+
end
|
100
|
+
|
101
|
+
#create_top_makefile()
|
102
|
+
rescue Interrupt
|
103
|
+
print " [error] " + $!.to_s + "
|
104
|
+
"
|
105
|
+
end
|
106
|
+
|
data/ext/noggin/noggin.c
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
2
|
+
/* Includes */
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include "cups/cups.h"
|
8
|
+
#include "cups/ipp.h"
|
9
|
+
#include "ruby.h"
|
10
|
+
#include "st.h"
|
11
|
+
|
12
|
+
/* Setup types */
|
13
|
+
/* Try not to clash with other definitions of bool... */
|
14
|
+
typedef int rubber_bool;
|
15
|
+
#define bool rubber_bool
|
16
|
+
|
17
|
+
/* Prototypes */
|
18
|
+
static VALUE mNoggin;
|
19
|
+
static VALUE
|
20
|
+
Noggin_CLASS_destinations(VALUE self);
|
21
|
+
static VALUE
|
22
|
+
Noggin_CLASS_jobs(VALUE self, VALUE printer, VALUE __v_mine, VALUE __v_whichjobs);
|
23
|
+
static VALUE
|
24
|
+
Noggin_CLASS_ippRequest(VALUE self, VALUE __v_operation, VALUE request_attributes);
|
25
|
+
static VALUE mJob;
|
26
|
+
static VALUE
|
27
|
+
Job_CLASS_cancel(VALUE self, VALUE __v_printer, VALUE __v_job_id);
|
28
|
+
static VALUE mIPP;
|
29
|
+
|
30
|
+
/* Inline C code */
|
31
|
+
|
32
|
+
|
33
|
+
VALUE inline as_string(const char *string) { return string ? rb_str_new2(string) : Qnil; }
|
34
|
+
|
35
|
+
#define TO_STRING(v) ((v) ? rb_str_new2((v)) : Qnil)
|
36
|
+
|
37
|
+
VALUE job_state(ipp_jstate_t state) {
|
38
|
+
switch(state) {
|
39
|
+
case IPP_JOB_ABORTED:
|
40
|
+
return ID2SYM(rb_intern("aborted"));
|
41
|
+
case IPP_JOB_CANCELED:
|
42
|
+
return ID2SYM(rb_intern("cancelled"));
|
43
|
+
case IPP_JOB_COMPLETED:
|
44
|
+
return ID2SYM(rb_intern("completed"));
|
45
|
+
case IPP_JOB_HELD:
|
46
|
+
return ID2SYM(rb_intern("held"));
|
47
|
+
case IPP_JOB_PENDING:
|
48
|
+
return ID2SYM(rb_intern("pending"));
|
49
|
+
case IPP_JOB_PROCESSING:
|
50
|
+
return ID2SYM(rb_intern("processing"));
|
51
|
+
case IPP_JOB_STOPPED:
|
52
|
+
return ID2SYM(rb_intern("stopped"));
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
VALUE rb_ipp_value(ipp_attribute_t* attr) {
|
57
|
+
char *lang = NULL;
|
58
|
+
switch (ippGetValueTag(attr)) {
|
59
|
+
case IPP_TAG_INTEGER:
|
60
|
+
return INT2NUM(ippGetInteger(attr, 0));
|
61
|
+
case IPP_TAG_TEXT:
|
62
|
+
case IPP_TAG_NAME:
|
63
|
+
case IPP_TAG_URI:
|
64
|
+
case IPP_TAG_URISCHEME:
|
65
|
+
return as_string(ippGetString(attr, 0, &lang));
|
66
|
+
case IPP_TAG_BOOLEAN:
|
67
|
+
return ippGetBoolean(attr, 0) ? Qtrue : Qfalse;
|
68
|
+
}
|
69
|
+
return Qnil;
|
70
|
+
|
71
|
+
}
|
72
|
+
int add_to_request_iterator(VALUE key, VALUE val, VALUE data) {
|
73
|
+
ipp_t *request = (ipp_t*) data;
|
74
|
+
char *name = RSTRING_PTR(key);
|
75
|
+
|
76
|
+
switch(TYPE(val)) {
|
77
|
+
case T_FIXNUM:
|
78
|
+
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, name, NUM2INT(val));
|
79
|
+
break;
|
80
|
+
case T_STRING:
|
81
|
+
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, name, NULL, RSTRING_PTR(val));
|
82
|
+
break;
|
83
|
+
case T_TRUE:
|
84
|
+
case T_FALSE:
|
85
|
+
ippAddBoolean(request, IPP_TAG_OPERATION, name, (val) ? 1 : 0);
|
86
|
+
break;
|
87
|
+
}
|
88
|
+
return ST_CONTINUE;
|
89
|
+
}
|
90
|
+
|
91
|
+
|
92
|
+
/* Code */
|
93
|
+
static VALUE
|
94
|
+
Noggin_CLASS_destinations(VALUE self)
|
95
|
+
{
|
96
|
+
VALUE __p_retval = Qnil;
|
97
|
+
|
98
|
+
#line 96 "/home/geoff/Projects/noggin/ext/noggin/noggin.cr"
|
99
|
+
|
100
|
+
do {
|
101
|
+
VALUE list =
|
102
|
+
Qnil;
|
103
|
+
cups_dest_t * dests ;
|
104
|
+
int num_dests = cupsGetDests(&dests);
|
105
|
+
cups_dest_t * dest ;
|
106
|
+
int i ;
|
107
|
+
const char * value ;
|
108
|
+
int j ;
|
109
|
+
list = rb_ary_new2(num_dests);
|
110
|
+
for (i = num_dests, dest = dests;
|
111
|
+
i > 0;
|
112
|
+
i --, dest ++) { VALUE hash =
|
113
|
+
rb_hash_new(), options = rb_hash_new();
|
114
|
+
rb_hash_aset(hash, rb_str_new2("name"), as_string(dest->name));
|
115
|
+
rb_hash_aset(hash, rb_str_new2("instance"), as_string(dest->instance));
|
116
|
+
rb_hash_aset(hash, rb_str_new2("is_default"), INT2NUM(dest->is_default));
|
117
|
+
rb_hash_aset(hash, rb_str_new2("options"), options);
|
118
|
+
for (j = 0;
|
119
|
+
j < dest->num_options;
|
120
|
+
j++) { rb_hash_aset(options, as_string(dest->options[j].name), as_string(dest->options[j].value));
|
121
|
+
} rb_ary_push(list, hash);
|
122
|
+
} cupsFreeDests(num_dests, dests);
|
123
|
+
do { __p_retval = list; goto out; } while(0);
|
124
|
+
|
125
|
+
} while(0);
|
126
|
+
|
127
|
+
out:
|
128
|
+
return __p_retval;
|
129
|
+
}
|
130
|
+
|
131
|
+
static VALUE
|
132
|
+
Noggin_CLASS_jobs(VALUE self, VALUE printer, VALUE __v_mine, VALUE __v_whichjobs)
|
133
|
+
{
|
134
|
+
VALUE __p_retval = Qnil;
|
135
|
+
bool mine; bool __orig_mine;
|
136
|
+
int whichjobs; int __orig_whichjobs;
|
137
|
+
if (! ((TYPE(printer) == T_NIL) || (TYPE(printer) == T_STRING)) )
|
138
|
+
rb_raise(rb_eArgError, "printer argument must be one of Nil, String");
|
139
|
+
__orig_mine = mine = RTEST(__v_mine);
|
140
|
+
__orig_whichjobs = whichjobs = NUM2INT(__v_whichjobs);
|
141
|
+
|
142
|
+
#line 126 "/home/geoff/Projects/noggin/ext/noggin/noggin.cr"
|
143
|
+
|
144
|
+
do {
|
145
|
+
VALUE list =
|
146
|
+
Qnil;
|
147
|
+
cups_job_t *jobs, *job;
|
148
|
+
int num_jobs, i;
|
149
|
+
num_jobs = cupsGetJobs(&jobs, (NIL_P(printer) ? (char*)0 : RSTRING_PTR(printer)), (mine ? 1 : 0), whichjobs);
|
150
|
+
list = rb_ary_new2(num_jobs);
|
151
|
+
for (i = num_jobs, job = jobs;
|
152
|
+
i > 0;
|
153
|
+
i --, job ++) { VALUE hash =
|
154
|
+
rb_hash_new();
|
155
|
+
rb_hash_aset(hash, rb_str_new2("completed_time"), rb_time_new(job->completed_time, 0));
|
156
|
+
rb_hash_aset(hash, rb_str_new2("creation_time"), rb_time_new(job->creation_time, 0));
|
157
|
+
rb_hash_aset(hash, rb_str_new2("dest"), as_string(job->dest));
|
158
|
+
rb_hash_aset(hash, rb_str_new2("format"), as_string(job->format));
|
159
|
+
rb_hash_aset(hash, rb_str_new2("id"), INT2NUM(job->id));
|
160
|
+
rb_hash_aset(hash, rb_str_new2("priority"), INT2NUM(job->priority));
|
161
|
+
rb_hash_aset(hash, rb_str_new2("processing_time"), rb_time_new(job->processing_time, 0));
|
162
|
+
rb_hash_aset(hash, rb_str_new2("size"), INT2NUM(job->size));
|
163
|
+
rb_hash_aset(hash, rb_str_new2("title"), as_string(job->title));
|
164
|
+
rb_hash_aset(hash, rb_str_new2("user"), as_string(job->user));
|
165
|
+
rb_hash_aset(hash, rb_str_new2("state"), job_state(job->state));
|
166
|
+
rb_ary_push(list, hash);
|
167
|
+
} cupsFreeJobs(num_jobs, jobs);
|
168
|
+
do { __p_retval = list; goto out; } while(0);
|
169
|
+
|
170
|
+
} while(0);
|
171
|
+
|
172
|
+
out:
|
173
|
+
return __p_retval;
|
174
|
+
}
|
175
|
+
|
176
|
+
static VALUE
|
177
|
+
Noggin_CLASS_ippRequest(VALUE self, VALUE __v_operation, VALUE request_attributes)
|
178
|
+
{
|
179
|
+
VALUE __p_retval = Qnil;
|
180
|
+
int operation; int __orig_operation;
|
181
|
+
__orig_operation = operation = NUM2INT(__v_operation);
|
182
|
+
|
183
|
+
#line 158 "/home/geoff/Projects/noggin/ext/noggin/noggin.cr"
|
184
|
+
|
185
|
+
do {
|
186
|
+
VALUE resp =
|
187
|
+
Qnil;
|
188
|
+
ipp_t * request =
|
189
|
+
NULL , *response = NULL;
|
190
|
+
ipp_attribute_t * attr =
|
191
|
+
NULL;
|
192
|
+
request = ippNewRequest(operation);
|
193
|
+
rb_hash_foreach(request_attributes, add_to_request_iterator, (VALUE)request);
|
194
|
+
response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/");
|
195
|
+
resp = rb_hash_new();
|
196
|
+
for (attr = ippFirstAttribute(response);
|
197
|
+
attr != NULL;
|
198
|
+
attr = ippNextAttribute(response)) { rb_hash_aset(resp, as_string(ippGetName(attr)), rb_ipp_value(attr));
|
199
|
+
} do { __p_retval = resp; goto out; } while(0);
|
200
|
+
|
201
|
+
} while(0);
|
202
|
+
|
203
|
+
out:
|
204
|
+
return __p_retval;
|
205
|
+
}
|
206
|
+
|
207
|
+
static VALUE
|
208
|
+
Job_CLASS_cancel(VALUE self, VALUE __v_printer, VALUE __v_job_id)
|
209
|
+
{
|
210
|
+
char * printer; char * __orig_printer;
|
211
|
+
int job_id; int __orig_job_id;
|
212
|
+
__orig_printer = printer = ( NIL_P(__v_printer) ? NULL : StringValuePtr(__v_printer) );
|
213
|
+
__orig_job_id = job_id = NUM2INT(__v_job_id);
|
214
|
+
|
215
|
+
#line 87 "/home/geoff/Projects/noggin/ext/noggin/noggin.cr"
|
216
|
+
if (cupsCancelJob(printer, job_id) == 0) { rb_raise(rb_eRuntimeError, "CUPS Error: %d - %s", cupsLastError(), cupsLastErrorString());
|
217
|
+
}
|
218
|
+
return Qnil;
|
219
|
+
}
|
220
|
+
|
221
|
+
/* Init */
|
222
|
+
void
|
223
|
+
Init_noggin(void)
|
224
|
+
{
|
225
|
+
|
226
|
+
mNoggin = rb_define_module("Noggin");
|
227
|
+
rb_define_singleton_method(mNoggin, "destinations", Noggin_CLASS_destinations, 0);
|
228
|
+
rb_define_singleton_method(mNoggin, "jobs", Noggin_CLASS_jobs, 3);
|
229
|
+
rb_define_singleton_method(mNoggin, "ippRequest", Noggin_CLASS_ippRequest, 2);
|
230
|
+
rb_define_const(mNoggin, "WHICHJOBS_ALL", INT2NUM(CUPS_WHICHJOBS_ALL));
|
231
|
+
rb_define_const(mNoggin, "WHICHJOBS_ACTIVE", INT2NUM(CUPS_WHICHJOBS_ACTIVE));
|
232
|
+
rb_define_const(mNoggin, "WHICHJOBS_COMPLETED", INT2NUM(CUPS_WHICHJOBS_COMPLETED));
|
233
|
+
mJob = rb_define_module_under(mNoggin, "Job");
|
234
|
+
rb_define_singleton_method(mJob, "cancel", Job_CLASS_cancel, 2);
|
235
|
+
rb_define_const(mJob, "CURRENT", INT2NUM(CUPS_JOBID_CURRENT));
|
236
|
+
rb_define_const(mJob, "ALL", INT2NUM(CUPS_JOBID_ALL));
|
237
|
+
mIPP = rb_define_module_under(mNoggin, "IPP");
|
238
|
+
rb_define_const(mIPP, "GET_JOBS", INT2NUM(IPP_GET_JOBS));
|
239
|
+
}
|
@@ -0,0 +1,176 @@
|
|
1
|
+
%name noggin
|
2
|
+
|
3
|
+
%include cups/cups.h
|
4
|
+
%include cups/ipp.h
|
5
|
+
%include ruby.h
|
6
|
+
%include st.h
|
7
|
+
%lib cups
|
8
|
+
|
9
|
+
%{
|
10
|
+
|
11
|
+
VALUE inline as_string(const char *string) { return string ? rb_str_new2(string) : Qnil; }
|
12
|
+
|
13
|
+
#define TO_STRING(v) ((v) ? rb_str_new2((v)) : Qnil)
|
14
|
+
|
15
|
+
VALUE job_state(ipp_jstate_t state) {
|
16
|
+
switch(state) {
|
17
|
+
case IPP_JOB_ABORTED:
|
18
|
+
return ID2SYM(rb_intern("aborted"));
|
19
|
+
case IPP_JOB_CANCELED:
|
20
|
+
return ID2SYM(rb_intern("cancelled"));
|
21
|
+
case IPP_JOB_COMPLETED:
|
22
|
+
return ID2SYM(rb_intern("completed"));
|
23
|
+
case IPP_JOB_HELD:
|
24
|
+
return ID2SYM(rb_intern("held"));
|
25
|
+
case IPP_JOB_PENDING:
|
26
|
+
return ID2SYM(rb_intern("pending"));
|
27
|
+
case IPP_JOB_PROCESSING:
|
28
|
+
return ID2SYM(rb_intern("processing"));
|
29
|
+
case IPP_JOB_STOPPED:
|
30
|
+
return ID2SYM(rb_intern("stopped"));
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
VALUE rb_ipp_value(ipp_attribute_t* attr) {
|
35
|
+
char *lang = NULL;
|
36
|
+
switch (ippGetValueTag(attr)) {
|
37
|
+
case IPP_TAG_INTEGER:
|
38
|
+
return INT2NUM(ippGetInteger(attr, 0));
|
39
|
+
case IPP_TAG_TEXT:
|
40
|
+
case IPP_TAG_NAME:
|
41
|
+
case IPP_TAG_URI:
|
42
|
+
case IPP_TAG_URISCHEME:
|
43
|
+
return as_string(ippGetString(attr, 0, &lang));
|
44
|
+
case IPP_TAG_BOOLEAN:
|
45
|
+
return ippGetBoolean(attr, 0) ? Qtrue : Qfalse;
|
46
|
+
}
|
47
|
+
return Qnil;
|
48
|
+
|
49
|
+
}
|
50
|
+
int add_to_request_iterator(VALUE key, VALUE val, VALUE data) {
|
51
|
+
ipp_t *request = (ipp_t*) data;
|
52
|
+
char *name = RSTRING_PTR(key);
|
53
|
+
|
54
|
+
switch(TYPE(val)) {
|
55
|
+
case T_FIXNUM:
|
56
|
+
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, name, NUM2INT(val));
|
57
|
+
break;
|
58
|
+
case T_STRING:
|
59
|
+
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, name, NULL, RSTRING_PTR(val));
|
60
|
+
break;
|
61
|
+
case T_TRUE:
|
62
|
+
case T_FALSE:
|
63
|
+
ippAddBoolean(request, IPP_TAG_OPERATION, name, (val) ? 1 : 0);
|
64
|
+
break;
|
65
|
+
}
|
66
|
+
return ST_CONTINUE;
|
67
|
+
}
|
68
|
+
|
69
|
+
%}
|
70
|
+
|
71
|
+
%pre_init{
|
72
|
+
%}
|
73
|
+
|
74
|
+
%map ruby - (char *) => (VALUE): rb_str_new2(#0)
|
75
|
+
%map string - (VALUE) => (char *): RSTRING_PTR(%%)
|
76
|
+
|
77
|
+
%option glib=no
|
78
|
+
|
79
|
+
module Noggin
|
80
|
+
int WHICHJOBS_ALL = CUPS_WHICHJOBS_ALL
|
81
|
+
int WHICHJOBS_ACTIVE = CUPS_WHICHJOBS_ACTIVE
|
82
|
+
int WHICHJOBS_COMPLETED = CUPS_WHICHJOBS_COMPLETED
|
83
|
+
|
84
|
+
module Job
|
85
|
+
int CURRENT = CUPS_JOBID_CURRENT
|
86
|
+
int ALL = CUPS_JOBID_ALL
|
87
|
+
def int:self.cancel(char * printer, int job_id)
|
88
|
+
if (cupsCancelJob(printer, job_id) == 0) {
|
89
|
+
rb_raise(rb_eRuntimeError, "CUPS Error: %d - %s", cupsLastError(), cupsLastErrorString());
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
module IPP
|
94
|
+
int GET_JOBS = IPP_GET_JOBS
|
95
|
+
end
|
96
|
+
def self.destinations
|
97
|
+
VALUE list = Qnil;
|
98
|
+
cups_dest_t *dests;
|
99
|
+
int num_dests = cupsGetDests(&dests);
|
100
|
+
cups_dest_t *dest;
|
101
|
+
int i;
|
102
|
+
const char *value;
|
103
|
+
int j;
|
104
|
+
|
105
|
+
list = rb_ary_new2(num_dests);
|
106
|
+
for (i = num_dests, dest = dests; i > 0; i --, dest ++)
|
107
|
+
{
|
108
|
+
VALUE hash = rb_hash_new(), options = rb_hash_new();
|
109
|
+
rb_hash_aset(hash, rb_str_new2("name"), as_string(dest->name));
|
110
|
+
rb_hash_aset(hash, rb_str_new2("instance"), as_string(dest->instance));
|
111
|
+
rb_hash_aset(hash, rb_str_new2("is_default"), INT2NUM(dest->is_default));
|
112
|
+
rb_hash_aset(hash, rb_str_new2("options"), options);
|
113
|
+
|
114
|
+
for (j = 0; j < dest->num_options; j++) {
|
115
|
+
rb_hash_aset(options, as_string(dest->options[j].name), as_string(dest->options[j].value));
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
rb_ary_push(list, hash);
|
120
|
+
}
|
121
|
+
|
122
|
+
cupsFreeDests(num_dests, dests);
|
123
|
+
|
124
|
+
return list;
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.jobs(T_NIL|T_STRING printer, bool mine, int whichjobs)
|
128
|
+
VALUE list = Qnil;
|
129
|
+
cups_job_t *jobs, *job;
|
130
|
+
int num_jobs, i;
|
131
|
+
|
132
|
+
num_jobs = cupsGetJobs(&jobs, (NIL_P(printer) ? (char*)0 : RSTRING_PTR(printer)), (mine ? 1 : 0), whichjobs);
|
133
|
+
|
134
|
+
list = rb_ary_new2(num_jobs);
|
135
|
+
for (i = num_jobs, job = jobs; i > 0; i --, job ++)
|
136
|
+
{
|
137
|
+
VALUE hash = rb_hash_new();
|
138
|
+
rb_hash_aset(hash, rb_str_new2("completed_time"), rb_time_new(job->completed_time, 0));
|
139
|
+
rb_hash_aset(hash, rb_str_new2("creation_time"), rb_time_new(job->creation_time, 0));
|
140
|
+
rb_hash_aset(hash, rb_str_new2("dest"), as_string(job->dest));
|
141
|
+
rb_hash_aset(hash, rb_str_new2("format"), as_string(job->format));
|
142
|
+
rb_hash_aset(hash, rb_str_new2("id"), INT2NUM(job->id));
|
143
|
+
rb_hash_aset(hash, rb_str_new2("priority"), INT2NUM(job->priority));
|
144
|
+
rb_hash_aset(hash, rb_str_new2("processing_time"), rb_time_new(job->processing_time, 0));
|
145
|
+
rb_hash_aset(hash, rb_str_new2("size"), INT2NUM(job->size));
|
146
|
+
rb_hash_aset(hash, rb_str_new2("title"), as_string(job->title));
|
147
|
+
rb_hash_aset(hash, rb_str_new2("user"), as_string(job->user));
|
148
|
+
rb_hash_aset(hash, rb_str_new2("state"), job_state(job->state));
|
149
|
+
|
150
|
+
rb_ary_push(list, hash);
|
151
|
+
}
|
152
|
+
|
153
|
+
cupsFreeJobs(num_jobs, jobs);
|
154
|
+
|
155
|
+
return list;
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.ippRequest(int operation, VALUE request_attributes)
|
159
|
+
VALUE resp = Qnil;
|
160
|
+
ipp_t *request = NULL , *response = NULL;
|
161
|
+
ipp_attribute_t *attr = NULL;
|
162
|
+
|
163
|
+
request = ippNewRequest(operation);
|
164
|
+
rb_hash_foreach(request_attributes, add_to_request_iterator, (VALUE)request);
|
165
|
+
|
166
|
+
response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/");
|
167
|
+
|
168
|
+
resp = rb_hash_new();
|
169
|
+
|
170
|
+
for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) {
|
171
|
+
rb_hash_aset(resp, as_string(ippGetName(attr)), rb_ipp_value(attr));
|
172
|
+
}
|
173
|
+
|
174
|
+
return resp;
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
= module Noggin
|
2
|
+
--- Noggin.destinations()
|
3
|
+
|
4
|
+
|
5
|
+
--- Noggin.jobs(String printer, Boolean mine, Integer whichjobs)
|
6
|
+
|
7
|
+
|
8
|
+
--- Noggin.ippRequest(Integer operation, request_attributes)
|
9
|
+
|
10
|
+
|
11
|
+
== Noggin::WHICHJOBS_ALL
|
12
|
+
== Noggin::WHICHJOBS_ACTIVE
|
13
|
+
== Noggin::WHICHJOBS_COMPLETED
|
14
|
+
== module Noggin::Job
|
15
|
+
--- Noggin::Job.cancel(String printer, Integer job_id)
|
16
|
+
|
17
|
+
|
18
|
+
=== Noggin::Job::CURRENT
|
19
|
+
=== Noggin::Job::ALL
|
20
|
+
== module Noggin::IPP
|
21
|
+
=== Noggin::IPP::GET_JOBS
|
data/lib/noggin.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: noggin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Geoff Youngs
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-08-23 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rubber-generate
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 61
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
- 17
|
33
|
+
version: 0.0.17
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: |
|
37
|
+
smb
|
38
|
+
|
39
|
+
email: git@intersect-uk.co.uk
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions:
|
43
|
+
- ext/noggin/extconf.rb
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
46
|
+
files:
|
47
|
+
- ext/noggin/noggin.c
|
48
|
+
- ext/noggin/noggin.cr
|
49
|
+
- ext/noggin/noggin.rd
|
50
|
+
- Rakefile
|
51
|
+
- README.md
|
52
|
+
- lib/noggin.rb
|
53
|
+
- lib/noggin/version.rb
|
54
|
+
- ext/noggin/extconf.rb
|
55
|
+
homepage: http://github.com/geoffyoungs/noggin
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.8.15
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: libcups bindings for ruby
|
88
|
+
test_files: []
|
89
|
+
|