noggin 0.0.1
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/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
|
+
|