gphoto4ruby 0.1.0 → 0.1.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/CHANGELOG.rdoc +12 -0
- data/README.rdoc +38 -0
- data/Rakefile +16 -0
- data/example.rb +40 -0
- data/ext/gphoto4ruby.c +370 -11
- data/ext/gphoto4ruby.h +41 -3
- metadata +22 -11
- data/README +0 -23
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
== master
|
2
|
+
|
3
|
+
* Added rdoc comments
|
4
|
+
* Added saving captured image to specified folder
|
5
|
+
* Added folders browsing
|
6
|
+
* Added folders and files listing
|
7
|
+
|
8
|
+
== 0.1.0
|
9
|
+
|
10
|
+
* Initial import
|
11
|
+
* Camera configuration (limited to radio-button and float type of items)
|
12
|
+
* Camera capture image command
|
data/README.rdoc
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
= GPhoto4Ruby
|
2
|
+
|
3
|
+
== Summary
|
4
|
+
|
5
|
+
GPhoto4Ruby is Ruby wrapping around libgphoto2 C library
|
6
|
+
(See http://gphoto.org for more information on libgphoto2 and gphoto2).
|
7
|
+
It maps a digital camera to Ruby object and allows operating it by
|
8
|
+
calling object methods.
|
9
|
+
|
10
|
+
c = GPhoto2::Camera.new
|
11
|
+
c[:exptime] = "0.010" # you can list values with c[:exptime, :all]
|
12
|
+
c["f-number"] = "f/4.5"
|
13
|
+
c.capture
|
14
|
+
|
15
|
+
== Installation
|
16
|
+
|
17
|
+
* First of all you'll need the original gphoto2 C library installed. For
|
18
|
+
installation instructions goto http://gphoto.org.
|
19
|
+
|
20
|
+
* Apparently this GitHub will not build this Gem due to "$SAFE problem".
|
21
|
+
So you can download it from http://rubyforge.org/projects/gphoto4ruby/
|
22
|
+
and install it with:
|
23
|
+
|
24
|
+
sudo gem install gphoto4ruby-version.gem
|
25
|
+
|
26
|
+
* Plug your digital camera through usb and run:
|
27
|
+
|
28
|
+
ruby example.rb
|
29
|
+
|
30
|
+
== Usage
|
31
|
+
|
32
|
+
See example.rb
|
33
|
+
|
34
|
+
== Contact
|
35
|
+
|
36
|
+
neq4 company:: http://neq4.com
|
37
|
+
Sergey Kruk:: sergey.kruk@gmail.com
|
38
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake"
|
3
|
+
require "rake/rdoctask"
|
4
|
+
|
5
|
+
desc "Generate RDoc documentation for gphoto4ruby gem."
|
6
|
+
|
7
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
8
|
+
rdoc.rdoc_files.include("README.rdoc", "LICENSE", "CHANGELOG.rdoc").
|
9
|
+
include("docs/COPYING", "docs/COPYING.LESSER").
|
10
|
+
include("ext/gphoto4ruby.c")
|
11
|
+
rdoc.main = "README.rdoc"
|
12
|
+
rdoc.title = "GPhoto4Ruby documentation"
|
13
|
+
rdoc.rdoc_dir = "docs"
|
14
|
+
rdoc.options << "--charset=UTF-8"
|
15
|
+
rdoc.options << "--webcvs=http://github.com/lonelyelk/gphoto4ruby/tree/master"
|
16
|
+
end
|
data/example.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "gphoto4ruby"
|
3
|
+
|
4
|
+
ports = GPhoto2::Camera.ports
|
5
|
+
if ports.empty?
|
6
|
+
# ports array can be empty if there is only one camera plugged in
|
7
|
+
# or there are no cameras connected to the computer
|
8
|
+
# assuming there is one
|
9
|
+
c = GPhoto2::Camera.new()
|
10
|
+
c.configs.each do |cfg|
|
11
|
+
puts cfg + " value is: " + c[cfg].to_s
|
12
|
+
puts "values available are: " + c[cfg, :all].inspect
|
13
|
+
end
|
14
|
+
c.capture
|
15
|
+
puts "files on camera: " + c.files.inspect
|
16
|
+
puts "some folder stuff: " + c.folder_up.subfolders.inspect
|
17
|
+
else
|
18
|
+
puts ports.length.to_s + "cameras connected"
|
19
|
+
cams = []
|
20
|
+
ports.each do |port|
|
21
|
+
c = GPhoto2::Camera.new(port)
|
22
|
+
puts "camera in port: " + port
|
23
|
+
c.configs.each do |cfg|
|
24
|
+
puts cfg + " value is: " + c[cfg].to_s
|
25
|
+
puts "values available are: " + c[cfg, :all].inspect
|
26
|
+
end
|
27
|
+
c.capture
|
28
|
+
puts "files on camera: " + c.files.inspect
|
29
|
+
puts "some folder stuff: " + c.folder_up.subfolders.inspect
|
30
|
+
cams.push c
|
31
|
+
end
|
32
|
+
# to capture image with all attached cameras at a time use:
|
33
|
+
cams.each_index do |index|
|
34
|
+
if index < cams.length - 1
|
35
|
+
fork {cams[index].capture; exit!}
|
36
|
+
else
|
37
|
+
cams[index].capture
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/ext/gphoto4ruby.c
CHANGED
@@ -22,18 +22,12 @@
|
|
22
22
|
|
23
23
|
#include <stdlib.h>
|
24
24
|
#include <stdio.h>
|
25
|
+
#include <fcntl.h>
|
25
26
|
#include <string.h>
|
26
27
|
#include <gphoto2/gphoto2.h>
|
27
28
|
#include <ruby.h>
|
28
29
|
#include "gphoto4ruby.h"
|
29
30
|
|
30
|
-
|
31
|
-
static VALUE rb_mGPhoto2;
|
32
|
-
static VALUE rb_cGPhoto2Camera;
|
33
|
-
static VALUE rb_cGPhoto2Exception;
|
34
|
-
static VALUE rb_cGPhoto2ConfigurationError;
|
35
|
-
static VALUE rb_cGPhoto2ProgrammerError;
|
36
|
-
|
37
31
|
static void rb_raise_gp_result(int retval) {
|
38
32
|
rb_raise(rb_cGPhoto2Exception, "LibGPhoto2 function returned: %s", gp_result_as_string(retval));
|
39
33
|
}
|
@@ -208,7 +202,10 @@ static void camera_free(GPhoto2Camera *c) {
|
|
208
202
|
int retval;
|
209
203
|
retval = gp_camera_exit(c->camera, c->context);
|
210
204
|
retval = gp_widget_free(c->config);
|
205
|
+
retval = gp_list_free(c->list);
|
206
|
+
retval = gp_file_free(c->file);
|
211
207
|
retval = gp_camera_free(c->camera);
|
208
|
+
free(c->virtFolder);
|
212
209
|
free(c->context);
|
213
210
|
free(c);
|
214
211
|
}
|
@@ -217,18 +214,40 @@ static VALUE camera_allocate(VALUE klass) {
|
|
217
214
|
int retval;
|
218
215
|
GPhoto2Camera *c;
|
219
216
|
c = (GPhoto2Camera*) malloc(sizeof(GPhoto2Camera));
|
217
|
+
c->virtFolder = (char*) malloc(sizeof(char)*100);
|
218
|
+
strcpy(c->virtFolder, "/");//store_00010001/DCIM/100NCD80/");
|
219
|
+
// c->path = "/store_00010001";
|
220
220
|
c->context = gp_context_new();
|
221
221
|
retval = gp_camera_new(&(c->camera));
|
222
222
|
if (retval == GP_OK) {
|
223
|
-
retval =
|
223
|
+
retval = gp_list_new(&(c->list));
|
224
224
|
if (retval == GP_OK) {
|
225
|
-
|
225
|
+
retval = gp_camera_get_config(c->camera, &(c->config), c->context);
|
226
|
+
if (retval == GP_OK) {
|
227
|
+
retval = gp_file_new(&(c->file));
|
228
|
+
if (retval == GP_OK) {
|
229
|
+
return Data_Wrap_Struct(klass, camera_mark, camera_free, c);
|
230
|
+
}
|
231
|
+
}
|
226
232
|
}
|
227
233
|
}
|
228
234
|
rb_raise_gp_result(retval);
|
229
235
|
return Qnil;
|
230
236
|
}
|
231
237
|
|
238
|
+
/*
|
239
|
+
* call-seq:
|
240
|
+
* GPhoto2::Camera.new(port=nil)
|
241
|
+
*
|
242
|
+
* Returns camera object. Camera should be connected at a time constructor
|
243
|
+
* is called. If there is more than one camera connected through usb ports,
|
244
|
+
* port parameter can be passed to specify which camera is addressed with
|
245
|
+
* object.
|
246
|
+
*
|
247
|
+
* GPhoto2::Camera.new
|
248
|
+
* GPhoto2::Capera.new(GPhoto2::Camera.ports[0])
|
249
|
+
*
|
250
|
+
*/
|
232
251
|
static VALUE camera_initialize(int argc, VALUE *argv, VALUE self) {
|
233
252
|
switch (argc) {
|
234
253
|
case 0:
|
@@ -270,6 +289,19 @@ static VALUE camera_initialize(int argc, VALUE *argv, VALUE self) {
|
|
270
289
|
}
|
271
290
|
}
|
272
291
|
|
292
|
+
/*
|
293
|
+
* call-seq:
|
294
|
+
* GPhoto2::Camera.ports => array
|
295
|
+
*
|
296
|
+
* Returns an array of usb port paths with cameras. If only one camera
|
297
|
+
* is connected, returned array is empty.
|
298
|
+
*
|
299
|
+
* # with one camera connected
|
300
|
+
* GPhoto2::Camera.ports #=> []
|
301
|
+
* # with two cameras connected
|
302
|
+
* GPhoto2::Camera.ports #=> ["usb:005,004", "usb:005,006"]
|
303
|
+
*
|
304
|
+
*/
|
273
305
|
static VALUE camera_class_ports(VALUE klass) {
|
274
306
|
int retval, i, portsTotal;
|
275
307
|
GPPortInfoList *portInfoList;
|
@@ -298,15 +330,26 @@ static VALUE camera_class_ports(VALUE klass) {
|
|
298
330
|
return Qnil;
|
299
331
|
}
|
300
332
|
|
333
|
+
/*
|
334
|
+
* call-seq:
|
335
|
+
* capture => camera
|
336
|
+
*
|
337
|
+
* Sends command to camera to capture image with current configuration
|
338
|
+
*
|
339
|
+
* c = GPhoto2::Camera.new
|
340
|
+
* c.capture
|
341
|
+
*
|
342
|
+
*/
|
301
343
|
static VALUE camera_capture(VALUE self) {
|
302
344
|
int retval;
|
303
345
|
GPhoto2Camera *c;
|
304
346
|
|
305
347
|
Data_Get_Struct(self, GPhoto2Camera, c);
|
306
348
|
|
307
|
-
retval = gp_camera_capture(c->camera, GP_CAPTURE_IMAGE, &(c->
|
349
|
+
retval = gp_camera_capture(c->camera, GP_CAPTURE_IMAGE, &(c->path), c->context);
|
308
350
|
if (retval == GP_OK) {
|
309
|
-
|
351
|
+
strcpy(c->virtFolder, c->path.folder);
|
352
|
+
printf("captured: %s/%s\n", c->path.folder, c->path.name);
|
310
353
|
return self;
|
311
354
|
} else {
|
312
355
|
rb_raise_gp_result(retval);
|
@@ -314,6 +357,89 @@ static VALUE camera_capture(VALUE self) {
|
|
314
357
|
}
|
315
358
|
}
|
316
359
|
|
360
|
+
/*
|
361
|
+
* call-seq:
|
362
|
+
* capture_save(folder="") => camera
|
363
|
+
*
|
364
|
+
* Sends command to camera to capture image with current configuration
|
365
|
+
* and saves file into specified folder with the same filename as on
|
366
|
+
* camera file system.
|
367
|
+
*
|
368
|
+
* c = GPhoto2::Camera.new
|
369
|
+
* c.capture_save "/home"
|
370
|
+
*
|
371
|
+
*/
|
372
|
+
static VALUE camera_capture_save(int argc, VALUE *argv, VALUE self) {
|
373
|
+
int retval;
|
374
|
+
GPhoto2Camera *c;
|
375
|
+
const char *fData;
|
376
|
+
char *fPath;
|
377
|
+
char fName[100];
|
378
|
+
unsigned long int fSize;
|
379
|
+
int fd;
|
380
|
+
|
381
|
+
if (argc > 1) {
|
382
|
+
rb_raise(rb_eArgError, "Wrong number of arguments (%d for 0 or 1)", argc);
|
383
|
+
return Qnil;
|
384
|
+
}
|
385
|
+
|
386
|
+
Data_Get_Struct(self, GPhoto2Camera, c);
|
387
|
+
|
388
|
+
retval = gp_camera_capture(c->camera, GP_CAPTURE_IMAGE, &(c->path), c->context);
|
389
|
+
if (retval == GP_OK) {
|
390
|
+
strcpy(c->virtFolder, c->path.folder);
|
391
|
+
if (retval == GP_OK) {
|
392
|
+
retval = gp_camera_file_get(c->camera, c->path.folder, c->path.name, GP_FILE_TYPE_NORMAL, c->file, c->context);
|
393
|
+
if (retval == GP_OK) {
|
394
|
+
retval = gp_file_get_data_and_size(c->file, &fData, &fSize);
|
395
|
+
if (retval == GP_OK) {
|
396
|
+
if (argc == 1) {
|
397
|
+
fPath = RSTRING(argv[0])->ptr;
|
398
|
+
if (strlen(fPath) == 0) {
|
399
|
+
strcpy(fName, c->path.name);
|
400
|
+
} else if (fPath[strlen(fPath)] == '/') {
|
401
|
+
strcpy(fName, fPath);
|
402
|
+
strcat(fName, c->path.name);
|
403
|
+
} else {
|
404
|
+
strcpy(fName, fPath);
|
405
|
+
strcat(fName, "/");
|
406
|
+
strcat(fName, c->path.name);
|
407
|
+
}
|
408
|
+
} else {
|
409
|
+
strcpy(fName, c->path.name);
|
410
|
+
}
|
411
|
+
fd = open(fName, O_CREAT | O_WRONLY, 0644);
|
412
|
+
write(fd, fData, fSize);
|
413
|
+
close(fd);
|
414
|
+
return self;
|
415
|
+
}
|
416
|
+
}
|
417
|
+
}
|
418
|
+
}
|
419
|
+
rb_raise_gp_result(retval);
|
420
|
+
return Qnil;
|
421
|
+
}
|
422
|
+
|
423
|
+
/*
|
424
|
+
* call-seq:
|
425
|
+
* configs => array
|
426
|
+
*
|
427
|
+
* Returns an array of adjustable camera configurations.
|
428
|
+
*
|
429
|
+
* c = GPhoto2::Camera.new
|
430
|
+
* # with Nikon DSC D80
|
431
|
+
* c.configs #=> ["capturetarget", "imgquality",
|
432
|
+
* "imgsize", "whitebalance",
|
433
|
+
* "f-number", "focallength",
|
434
|
+
* "focusmode", "iso",
|
435
|
+
* "exposurebiascompensation",
|
436
|
+
* "exptime", "expprogram",
|
437
|
+
* "capturemode", "focusmetermode",
|
438
|
+
* "exposuremetermode", "flashmode",
|
439
|
+
* "burstnumber", "accessmode",
|
440
|
+
* "channel", "encryption"]
|
441
|
+
*
|
442
|
+
*/
|
317
443
|
static VALUE camera_get_configs(VALUE self) {
|
318
444
|
GPhoto2Camera *c;
|
319
445
|
VALUE arr = rb_ary_new();
|
@@ -325,6 +451,22 @@ static VALUE camera_get_configs(VALUE self) {
|
|
325
451
|
return arr;
|
326
452
|
}
|
327
453
|
|
454
|
+
/*
|
455
|
+
* call-seq:
|
456
|
+
* cam[cfg] => float or string
|
457
|
+
* cam[cfg, :all] => array
|
458
|
+
*
|
459
|
+
* Returns current value of specified camera configuration. Configuration name
|
460
|
+
* (cfg) can be string or symbol and must be in configs method returned array.
|
461
|
+
* When called with directive <b>:all</b> returns an array of allowed values
|
462
|
+
*
|
463
|
+
* c = GPhoto2::Camera.new
|
464
|
+
* # with Nikon DSC D80
|
465
|
+
* c["f-number"] #=> "f/4.5"
|
466
|
+
* c[:focallength] #=> 10.5
|
467
|
+
* c[:focusmode, :all] #=> ["Manual", "AF-S", "AF-C", "AF-A"]
|
468
|
+
*
|
469
|
+
*/
|
328
470
|
static VALUE camera_get_value(int argc, VALUE *argv, VALUE self) {
|
329
471
|
int retval;
|
330
472
|
const char *name;
|
@@ -398,6 +540,18 @@ static VALUE camera_get_value(int argc, VALUE *argv, VALUE self) {
|
|
398
540
|
return Qnil;
|
399
541
|
}
|
400
542
|
|
543
|
+
/*
|
544
|
+
* call-seq:
|
545
|
+
* cam[cfg] = value => float or string
|
546
|
+
*
|
547
|
+
* Sets specified camera configuration to specified value if value is allowed.
|
548
|
+
*
|
549
|
+
* c = GPhoto2::Camera.new
|
550
|
+
* # with Nikon DSC D80
|
551
|
+
* c["f-number"] = "f/4.5" #=> "f/4.5"
|
552
|
+
* c[:focallength] = 10.5 #=> 10.5
|
553
|
+
*
|
554
|
+
*/
|
401
555
|
static VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal) {
|
402
556
|
int retval;
|
403
557
|
const char *name;
|
@@ -443,11 +597,209 @@ static VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal) {
|
|
443
597
|
return Qnil;
|
444
598
|
}
|
445
599
|
|
600
|
+
/*
|
601
|
+
* call-seq:
|
602
|
+
* folder => string
|
603
|
+
*
|
604
|
+
* Returns current camera path. When image is captured, folder changes to
|
605
|
+
* path where files are saved on camera.
|
606
|
+
*
|
607
|
+
* c = GPhoto2::Camera.new
|
608
|
+
* # with Nikon DSC D80
|
609
|
+
* c.folder #=> "/"
|
610
|
+
* c.capture
|
611
|
+
* c.folder #=> "/store_00010001/DCIM/100NCD80"
|
612
|
+
*
|
613
|
+
*/
|
614
|
+
static VALUE camera_folder(VALUE self) {
|
615
|
+
GPhoto2Camera *c;
|
616
|
+
|
617
|
+
Data_Get_Struct(self, GPhoto2Camera, c);
|
618
|
+
|
619
|
+
return rb_str_new2(c->virtFolder);
|
620
|
+
}
|
621
|
+
|
622
|
+
/*
|
623
|
+
* call-seq:
|
624
|
+
* subfolders => array
|
625
|
+
*
|
626
|
+
* Returns an array of subfolder names in current camera path.
|
627
|
+
*
|
628
|
+
* c = GPhoto2::Camera.new
|
629
|
+
* # with Nikon DSC D80
|
630
|
+
* c.folder #=> "/"
|
631
|
+
* c.subfolders #=> ["special", "store_00010001"]
|
632
|
+
*
|
633
|
+
*/
|
634
|
+
static VALUE camera_subfolders(VALUE self) {
|
635
|
+
int retval, i, count;
|
636
|
+
const char *name;
|
637
|
+
GPhoto2Camera *c;
|
638
|
+
VALUE arr;
|
639
|
+
|
640
|
+
Data_Get_Struct(self, GPhoto2Camera, c);
|
641
|
+
|
642
|
+
retval = gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context);
|
643
|
+
if (retval == GP_OK) {
|
644
|
+
count = gp_list_count(c->list);
|
645
|
+
if (count < 0) {
|
646
|
+
rb_raise_gp_result(retval);
|
647
|
+
return Qnil;
|
648
|
+
}
|
649
|
+
arr = rb_ary_new();
|
650
|
+
for (i = 0; i < count; i++) {
|
651
|
+
retval = gp_list_get_name(c->list, i, &name);
|
652
|
+
if (retval == GP_OK) {
|
653
|
+
rb_ary_push(arr, rb_str_new2(name));
|
654
|
+
}
|
655
|
+
}
|
656
|
+
return arr;
|
657
|
+
}
|
658
|
+
rb_raise_gp_result(retval);
|
659
|
+
return Qnil;
|
660
|
+
}
|
661
|
+
|
662
|
+
/*
|
663
|
+
* call-seq:
|
664
|
+
* files => array
|
665
|
+
*
|
666
|
+
* Returns an array of file names in current camera path.
|
667
|
+
*
|
668
|
+
* c = GPhoto2::Camera.new
|
669
|
+
* # with Nikon DSC D80
|
670
|
+
* c.folder #=> "/"
|
671
|
+
* c.files #=> []
|
672
|
+
* c.capture
|
673
|
+
* c.files #=> ["DSC_0001.JPG", "DSC_0002.JPG",
|
674
|
+
* "DSC_0003.JPG", ... ]
|
675
|
+
*
|
676
|
+
*/
|
677
|
+
static VALUE camera_files(VALUE self) {
|
678
|
+
int retval, i, count;
|
679
|
+
const char *name;
|
680
|
+
GPhoto2Camera *c;
|
681
|
+
VALUE arr;
|
682
|
+
|
683
|
+
Data_Get_Struct(self, GPhoto2Camera, c);
|
684
|
+
|
685
|
+
retval = gp_filesystem_reset(c->camera->fs);
|
686
|
+
if (retval == GP_OK) {
|
687
|
+
retval = gp_camera_folder_list_files(c->camera, c->virtFolder, c->list, c->context);
|
688
|
+
if (retval == GP_OK) {
|
689
|
+
count = gp_list_count(c->list);
|
690
|
+
if (count < 0) {
|
691
|
+
rb_raise_gp_result(retval);
|
692
|
+
return Qnil;
|
693
|
+
}
|
694
|
+
arr = rb_ary_new();
|
695
|
+
for (i = 0; i < count; i++) {
|
696
|
+
retval = gp_list_get_name(c->list, i, &name);
|
697
|
+
if (retval == GP_OK) {
|
698
|
+
rb_ary_push(arr, rb_str_new2(name));
|
699
|
+
}
|
700
|
+
}
|
701
|
+
return arr;
|
702
|
+
}
|
703
|
+
}
|
704
|
+
rb_raise_gp_result(retval);
|
705
|
+
return Qnil;
|
706
|
+
}
|
707
|
+
|
708
|
+
/*
|
709
|
+
* call-seq:
|
710
|
+
* folder_up => camera
|
711
|
+
*
|
712
|
+
* Changes current camera path one level up.
|
713
|
+
*
|
714
|
+
* c = GPhoto2::Camera.new
|
715
|
+
* # with Nikon DSC D80
|
716
|
+
* c.folder #=> "/"
|
717
|
+
* c.capture
|
718
|
+
* c.folder #=> "/store_00010001/DCIM/100NCD80"
|
719
|
+
* c.folder_up
|
720
|
+
* c.folder #=> "/store_00010001/DCIM"
|
721
|
+
* c.folder_up.folder_up #=> "/"
|
722
|
+
*
|
723
|
+
*/
|
724
|
+
static VALUE camera_folder_up(VALUE self) {
|
725
|
+
char *pch;
|
726
|
+
GPhoto2Camera *c;
|
727
|
+
|
728
|
+
Data_Get_Struct(self, GPhoto2Camera, c);
|
729
|
+
|
730
|
+
pch = strrchr(c->virtFolder, '/');
|
731
|
+
if ((pch - c->virtFolder) == 0) {
|
732
|
+
c->virtFolder[1] = '\0';
|
733
|
+
} else {
|
734
|
+
c->virtFolder[pch - c->virtFolder] = '\0';
|
735
|
+
}
|
736
|
+
|
737
|
+
return self;
|
738
|
+
}
|
739
|
+
|
740
|
+
/*
|
741
|
+
* call-seq:
|
742
|
+
* folder_down(name) => camera
|
743
|
+
*
|
744
|
+
* Changes current camera path one level down into subfolder with
|
745
|
+
* specified name.
|
746
|
+
*
|
747
|
+
* c = GPhoto2::Camera.new
|
748
|
+
* # with Nikon DSC D80
|
749
|
+
* c.folder #=> "/"
|
750
|
+
* c.folder_down "store_00010001"
|
751
|
+
* c.folder #=> "/store_00010001"
|
752
|
+
* c.folder_down("DCIM").folder_down("100NCD80")
|
753
|
+
* c.folder #=> "/store_00010001/DCIM/100NCD80"
|
754
|
+
*
|
755
|
+
*/
|
756
|
+
static VALUE camera_folder_down(VALUE self, VALUE folder) {
|
757
|
+
Check_Type(folder, T_STRING);
|
758
|
+
int retval;
|
759
|
+
const char *name;
|
760
|
+
int index;
|
761
|
+
GPhoto2Camera *c;
|
762
|
+
|
763
|
+
Data_Get_Struct(self, GPhoto2Camera, c);
|
764
|
+
|
765
|
+
name = RSTRING(folder)->ptr;
|
766
|
+
retval = gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context);
|
767
|
+
if (retval == GP_OK) {
|
768
|
+
retval = gp_list_find_by_name(c->list, &index, name);
|
769
|
+
if (retval == GP_OK) {
|
770
|
+
if (strlen(c->virtFolder) > 1) {
|
771
|
+
strcat(c->virtFolder, "/");
|
772
|
+
}
|
773
|
+
strcat(c->virtFolder, name);
|
774
|
+
}
|
775
|
+
}
|
776
|
+
return self;
|
777
|
+
}
|
778
|
+
|
446
779
|
void Init_gphoto4ruby() {
|
780
|
+
/*
|
781
|
+
* Module contains camera class definition and some exceptions
|
782
|
+
*/
|
447
783
|
rb_mGPhoto2 = rb_define_module("GPhoto2");
|
784
|
+
/*
|
785
|
+
* GPhoto2::Camera object is a Ruby wrapping aroung gphoto2 C library.
|
786
|
+
*/
|
448
787
|
rb_cGPhoto2Camera = rb_define_class_under(rb_mGPhoto2, "Camera", rb_cObject);
|
788
|
+
/*
|
789
|
+
* GPhoto2::Exception is raised when libgphoto2 functions from C core
|
790
|
+
* return any error code
|
791
|
+
*/
|
449
792
|
rb_cGPhoto2Exception = rb_define_class_under(rb_mGPhoto2, "Exception", rb_eStandardError);
|
793
|
+
/*
|
794
|
+
* GPhoto2::ConfigurationError is raised when trying to set configuration
|
795
|
+
* values that are not allowed or trying to access properties that are not
|
796
|
+
* supported
|
797
|
+
*/
|
450
798
|
rb_cGPhoto2ConfigurationError = rb_define_class_under(rb_mGPhoto2, "ConfigurationError", rb_eStandardError);
|
799
|
+
/*
|
800
|
+
* GPhoto2::ProgrammerError is never raised. :) Only when program gets
|
801
|
+
* where it could never get.
|
802
|
+
*/
|
451
803
|
rb_cGPhoto2ProgrammerError = rb_define_class_under(rb_mGPhoto2, "ProgrammerError", rb_eStandardError);
|
452
804
|
rb_define_alloc_func(rb_cGPhoto2Camera, camera_allocate);
|
453
805
|
rb_define_module_function(rb_cGPhoto2Camera, "ports", camera_class_ports, 0);
|
@@ -456,4 +808,11 @@ void Init_gphoto4ruby() {
|
|
456
808
|
rb_define_method(rb_cGPhoto2Camera, "[]", camera_get_value, -1);
|
457
809
|
rb_define_method(rb_cGPhoto2Camera, "[]=", camera_set_value, 2);
|
458
810
|
rb_define_method(rb_cGPhoto2Camera, "capture", camera_capture, 0);
|
811
|
+
rb_define_method(rb_cGPhoto2Camera, "capture_save", camera_capture_save, -1);
|
812
|
+
rb_define_method(rb_cGPhoto2Camera, "folder", camera_folder, 0);
|
813
|
+
rb_define_method(rb_cGPhoto2Camera, "subfolders", camera_subfolders, 0);
|
814
|
+
rb_define_method(rb_cGPhoto2Camera, "files", camera_files, 0);
|
815
|
+
rb_define_method(rb_cGPhoto2Camera, "folder_up", camera_folder_up, 0);
|
816
|
+
rb_define_method(rb_cGPhoto2Camera, "folder_down", camera_folder_down, 1);
|
459
817
|
}
|
818
|
+
|
data/ext/gphoto4ruby.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
*
|
3
|
-
* Copyright 2008 neq4 company
|
4
|
-
* Author: Sergey Kruk
|
3
|
+
* Copyright 2008 neq4 company <http://neq4.com>
|
4
|
+
* Author: Sergey Kruk <sergey.kruk@gmail.com>
|
5
5
|
*
|
6
6
|
* This file is part of GPhoto4Ruby.
|
7
7
|
*
|
@@ -24,7 +24,45 @@ typedef struct {
|
|
24
24
|
Camera *camera;
|
25
25
|
CameraWidget *config;
|
26
26
|
CameraWidget *childConfig;
|
27
|
-
|
27
|
+
CameraList *list;
|
28
|
+
CameraFilePath path;
|
29
|
+
CameraFile *file;
|
28
30
|
GPContext *context;
|
31
|
+
|
32
|
+
char *virtFolder;
|
29
33
|
} GPhoto2Camera;
|
30
34
|
|
35
|
+
static VALUE rb_mGPhoto2;
|
36
|
+
static VALUE rb_cGPhoto2Camera;
|
37
|
+
static VALUE rb_cGPhoto2Exception;
|
38
|
+
static VALUE rb_cGPhoto2ConfigurationError;
|
39
|
+
static VALUE rb_cGPhoto2ProgrammerError;
|
40
|
+
|
41
|
+
static void rb_raise_gp_result(int retval);
|
42
|
+
static void rb_raise_programmer_error(const char* fName);
|
43
|
+
|
44
|
+
static VALUE getRadio(CameraWidget *cc);
|
45
|
+
static VALUE listRadio(CameraWidget *cc);
|
46
|
+
static VALUE setRadio(GPhoto2Camera *c, VALUE newVal);
|
47
|
+
static VALUE getRange(CameraWidget *cc);
|
48
|
+
static VALUE listRange(CameraWidget *cc);
|
49
|
+
static VALUE setRange(GPhoto2Camera *c, VALUE newNum);
|
50
|
+
|
51
|
+
static void populateWithConfigs(CameraWidget *cc, VALUE arr);
|
52
|
+
|
53
|
+
static void camera_mark(GPhoto2Camera *c);
|
54
|
+
static void camera_free(GPhoto2Camera *c);
|
55
|
+
static VALUE camera_allocate(VALUE klass);
|
56
|
+
|
57
|
+
static VALUE camera_initialize(int argc, VALUE *argv, VALUE self);
|
58
|
+
static VALUE camera_class_ports(VALUE klass);
|
59
|
+
static VALUE camera_capture(VALUE self);
|
60
|
+
static VALUE camera_get_configs(VALUE self);
|
61
|
+
static VALUE camera_get_value(int argc, VALUE *argv, VALUE self);
|
62
|
+
static VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal);
|
63
|
+
|
64
|
+
static VALUE camera_folder(VALUE self);
|
65
|
+
static VALUE camera_subfolders(VALUE self);
|
66
|
+
static VALUE camera_files(VALUE self);
|
67
|
+
static VALUE camera_folder_up(VALUE self);
|
68
|
+
static VALUE camera_folder_down(VALUE self, VALUE folder);
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gphoto4ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- heq4 company
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2008-08-
|
13
|
+
date: 2008-08-15 00:00:00 +04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -20,8 +20,11 @@ executables: []
|
|
20
20
|
|
21
21
|
extensions:
|
22
22
|
- ext/extconf.rb
|
23
|
-
extra_rdoc_files:
|
24
|
-
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README.rdoc
|
25
|
+
- LICENSE
|
26
|
+
- CHANGELOG.rdoc
|
27
|
+
- ext/gphoto4ruby.c
|
25
28
|
files:
|
26
29
|
- ext/gphoto4ruby.c
|
27
30
|
- ext/gphoto4ruby.h
|
@@ -29,12 +32,20 @@ files:
|
|
29
32
|
- docs/COPIYNG.LESSER
|
30
33
|
- docs/gphoto4ruby_api_ru.txt
|
31
34
|
- LICENSE
|
32
|
-
-
|
33
|
-
|
34
|
-
|
35
|
+
- CHANGELOG.rdoc
|
36
|
+
- README.rdoc
|
37
|
+
- Rakefile
|
38
|
+
- example.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/lonelyelk/gphoto4ruby
|
35
41
|
post_install_message:
|
36
|
-
rdoc_options:
|
37
|
-
|
42
|
+
rdoc_options:
|
43
|
+
- --main
|
44
|
+
- README.rdoc
|
45
|
+
- --charset
|
46
|
+
- UTF-8
|
47
|
+
- --webcvs
|
48
|
+
- http://github.com/lonelyelk/gphoto4ruby/tree/master
|
38
49
|
require_paths:
|
39
50
|
- lib
|
40
51
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -51,10 +62,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
62
|
version:
|
52
63
|
requirements: []
|
53
64
|
|
54
|
-
rubyforge_project:
|
65
|
+
rubyforge_project: gphoto4ruby
|
55
66
|
rubygems_version: 1.1.1
|
56
67
|
signing_key:
|
57
68
|
specification_version: 2
|
58
|
-
summary: GPhoto4Ruby is Ruby wrapping
|
69
|
+
summary: GPhoto4Ruby is Ruby wrapping around libgphoto2 C library
|
59
70
|
test_files: []
|
60
71
|
|