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