gphoto4ruby 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,6 +1,12 @@
1
- == master
1
+ == 0.1.3
2
2
 
3
3
  * Added "delete file from camera" function
4
+ * Directive :type and class constant to determine config type
5
+ * "Configs" is now "config" (method name change)
6
+ * Configs are now cached in instance variable
7
+ * Added config_merge method
8
+ * ProgrammerError removed
9
+ * Removed allowed values check. Values just dont change instead of raising Errors
4
10
 
5
11
  == 0.1.2
6
12
 
data/README.rdoc CHANGED
@@ -41,9 +41,13 @@ calling object methods.
41
41
 
42
42
  == Usage
43
43
 
44
- After installation of this gem rdocs are generated for you. Ruby file
45
- <b>example.rb</b> is installed along with this gem. All examples are tested
46
- on Kubuntu 8.04 and Mac OS X 10.4.11 with digital camera Nikon DSC D80
44
+ After installation of this gem rdocs are generated for you. Or you can generate
45
+ it manually with:
46
+
47
+ rake rdoc
48
+
49
+ Ruby file <b>example.rb</b> is installed along with this gem. All examples are
50
+ tested on Kubuntu 8.04 and Mac OS X 10.4.11 with digital camera Nikon DSC D80
47
51
  connected through usb in PTP mode.
48
52
 
49
53
  <b>example.rb:</b>
@@ -61,9 +65,9 @@ connected through usb in PTP mode.
61
65
 
62
66
  # list available configuration items with current values and lists
63
67
  # of allowed values
64
- c.configs.each do |cfg|
65
- puts cfg + " value is: " + c[cfg].to_s
66
- puts "values available are: " + c[cfg, :all].inspect
68
+ c.config.each_key do |cfg_key|
69
+ puts cfg_key + " value is: " + c.config[cfg_key].to_s # or c[cfg_key].to_s
70
+ puts "values available are: " + c[cfg_key, :all].inspect
67
71
  end
68
72
 
69
73
  # capture image
@@ -88,9 +92,9 @@ connected through usb in PTP mode.
88
92
  ports.each do |port|
89
93
  c = GPhoto2::Camera.new(port)
90
94
  puts "camera in port: " + port
91
- c.configs.each do |cfg|
92
- puts cfg + " value is: " + c[cfg].to_s
93
- puts "values available are: " + c[cfg, :all].inspect
95
+ c.config.each_key do |cfg_key|
96
+ puts cfg_key + " value is: " + c[cfg_key].to_s
97
+ puts "values available are: " + c[cfg_key, :all].inspect
94
98
  end
95
99
  cams.push c
96
100
  end
data/example.rb CHANGED
@@ -11,9 +11,9 @@ if ports.empty?
11
11
 
12
12
  # list available configuration items with current values and lists
13
13
  # of allowed values
14
- c.configs.each do |cfg|
15
- puts cfg + " value is: " + c[cfg].to_s
16
- puts "values available are: " + c[cfg, :all].inspect
14
+ c.config.each_key do |cfg_key|
15
+ puts cfg_key + " value is: " + c.config[cfg_key].to_s # or c[cfg_key].to_s
16
+ puts "values available are: " + c[cfg_key, :all].inspect
17
17
  end
18
18
 
19
19
  # capture image
@@ -38,9 +38,9 @@ else
38
38
  ports.each do |port|
39
39
  c = GPhoto2::Camera.new(port)
40
40
  puts "camera in port: " + port
41
- c.configs.each do |cfg|
42
- puts cfg + " value is: " + c[cfg].to_s
43
- puts "values available are: " + c[cfg, :all].inspect
41
+ c.config.each_key do |cfg_key|
42
+ puts cfg_key + " value is: " + c[cfg_key].to_s
43
+ puts "values available are: " + c[cfg_key, :all].inspect
44
44
  end
45
45
  cams.push c
46
46
  end
data/ext/gphoto4ruby.c CHANGED
@@ -32,166 +32,129 @@ static void rb_raise_gp_result(int retval) {
32
32
  rb_raise(rb_cGPhoto2Exception, "LibGPhoto2 function returned: %s", gp_result_as_string(retval));
33
33
  }
34
34
 
35
- static void rb_raise_programmer_error(const char* fName) {
36
- rb_raise(rb_cGPhoto2ProgrammerError, "Program was not supposed to get here. Function: %s", fName);
35
+ static int gp_result_check(int retval) {
36
+ if (retval < GP_OK) {
37
+ rb_raise_gp_result(retval);
38
+ }
39
+ return retval;
37
40
  }
38
41
 
39
42
  static VALUE getRadio(CameraWidget *cc) {
40
- int retval;
41
43
  const char *val;
42
- retval = gp_widget_get_value(cc, &val);
43
- if (retval == GP_OK) {
44
- return rb_str_new2(val);
45
- } else {
46
- rb_raise_gp_result(retval);
47
- return Qnil;
48
- }
44
+ gp_result_check(gp_widget_get_value(cc, &val));
45
+ return rb_str_new2(val);
49
46
  }
50
47
 
51
48
  static VALUE listRadio(CameraWidget *cc) {
52
- int retval, i, choicesTotal;
49
+ int i, choicesTotal;
53
50
  const char *choice;
54
51
  VALUE arr;
55
52
 
56
- choicesTotal = gp_widget_count_choices(cc);
53
+ choicesTotal = gp_result_check(gp_widget_count_choices(cc));
57
54
  arr = rb_ary_new();
58
55
  for (i = 0; i < choicesTotal; i++) {
59
- retval = gp_widget_get_choice(cc, i, &choice);
60
- if (retval == GP_OK) {
61
- rb_ary_push(arr, rb_str_new2(choice));
62
- } else {
63
- rb_raise_gp_result(retval);
64
- return Qnil;
65
- }
56
+ gp_result_check(gp_widget_get_choice(cc, i, &choice));
57
+ rb_ary_push(arr, rb_str_new2(choice));
66
58
  }
67
59
  return arr;
68
60
 
69
- static VALUE setRadio(GPhoto2Camera *c, VALUE newVal) {
70
- int retval, i, choicesTotal;
71
- const char *choice;
61
+ static VALUE setRadio(VALUE self, GPhoto2Camera *c, VALUE newVal, int save) {
62
+ int i, choicesTotal;
72
63
  const char *val;
73
64
 
74
65
  Check_Type(newVal, T_STRING);
75
66
  val = RSTRING(newVal)->ptr;
76
67
 
77
- choicesTotal = gp_widget_count_choices(c->childConfig);
78
- for (i = 0; i < choicesTotal; i++) {
79
- gp_widget_get_choice(c->childConfig, i, &choice);
80
- if (strcmp(choice, val) == 0) {
81
- retval = gp_widget_set_value(c->childConfig, val);
82
- if (retval == GP_OK) {
83
- retval = gp_camera_set_config(c->camera, c->config, c->context);
84
- if (retval == GP_OK) {
85
- return newVal;
86
- }
87
- }
88
- }
89
- }
90
- if (retval != GP_OK) {
91
- rb_raise_gp_result(retval);
92
- } else {
93
- rb_raise(rb_cGPhoto2ConfigurationError, "Value '%s' is not allowed", val);
68
+ gp_result_check(gp_widget_set_value(c->childConfig, val));
69
+ if (save) {
70
+ saveConfigs(self, c);
94
71
  }
95
- return Qnil;
72
+ return newVal;
96
73
  }
97
74
 
98
75
  static VALUE getRange(CameraWidget *cc) {
99
- int retval;
100
76
  float val;
101
- retval = gp_widget_get_value(cc, &val);
102
- if (retval == GP_OK) {
103
- return rb_float_new(val);
104
- } else {
105
- rb_raise_gp_result(retval);
106
- return Qnil;
107
- }
77
+ gp_result_check(gp_widget_get_value(cc, &val));
78
+ return rb_float_new(val);
108
79
  }
109
80
 
110
81
  static VALUE listRange(CameraWidget *cc) {
111
- int retval;
112
82
  float min, max, inc, i;
113
83
  VALUE arr;
114
84
 
115
- retval = gp_widget_get_range(cc, &min, &max, &inc);
116
- if ((retval == GP_OK) && (inc > 0)) {
117
- arr = rb_ary_new();
85
+ gp_result_check(gp_widget_get_range(cc, &min, &max, &inc));
86
+ arr = rb_ary_new();
87
+ if (inc > 0) {
118
88
  for (i = min; i <= max; i = i + inc) {
119
89
  rb_ary_push(arr, rb_float_new(i));
120
90
  }
121
- return arr;
122
- } else if (retval != GP_OK) {
123
- rb_raise_gp_result(retval);
124
91
  } else {
125
- return rb_ary_new();
92
+ rb_ary_push(arr, rb_float_new(min));
126
93
  }
127
- return Qnil;
94
+ return arr;
128
95
  }
129
96
 
130
- static VALUE setRange(GPhoto2Camera *c, VALUE newNum) {
131
- int retval;
132
- float min, max, inc, i;
97
+ static VALUE setRange(VALUE self, GPhoto2Camera *c, VALUE newNum, int save) {
133
98
  float val;
134
99
 
135
100
  Check_Type(newNum, T_FLOAT);
136
101
  val = NUM2DBL(newNum);
137
102
 
138
- retval = gp_widget_get_range(c->childConfig, &min, &max, &inc);
139
- if ((retval == GP_OK) && (val >= min) && (val <= max) && (inc > 0)) {
140
- for (i = min; i <= max; i = i + inc) {
141
- if ((val >= i) && (val <= (i+inc))) {
142
- if ((val - i) > (inc / 2.0)) {
143
- val = i + inc;
144
- } else {
145
- val = i;
146
- }
147
- retval = gp_widget_set_value(c->childConfig, &val);
148
- if (retval == GP_OK) {
149
- retval = gp_camera_set_config(c->camera, c->config, c->context);
150
- if (retval == GP_OK) {
151
- return rb_float_new(val);
152
- }
153
- }
154
- }
155
- }
156
- }
157
- if (retval != GP_OK) {
158
- rb_raise_gp_result(retval);
159
- } else {
160
- rb_raise(rb_cGPhoto2ConfigurationError, "Value has to be in range: %f .. %f", min, max);
103
+ gp_result_check(gp_widget_set_value(c->childConfig, &val));
104
+ if (save) {
105
+ saveConfigs(self, c);
161
106
  }
162
- return Qnil;
107
+ return newNum;
163
108
  }
164
109
 
165
- static void populateWithConfigs(CameraWidget *cc, VALUE arr) {
166
- int retval, i, childrenTotal;
167
- const char *name;
168
- CameraWidget *child;
110
+ static void saveConfigs(VALUE self, GPhoto2Camera *c) {
111
+ VALUE cfgs, cfg_changed, name;
169
112
  CameraWidgetType widgettype;
170
113
 
171
- retval = gp_widget_get_type(cc, &widgettype);
172
- if (retval == GP_OK) {
114
+ gp_result_check(gp_camera_set_config(c->camera, c->config, c->context));
115
+ gp_result_check(gp_camera_get_config(c->camera, &(c->config), c->context));
116
+ cfg_changed = rb_iv_get(self, "@configs_changed");
117
+ cfgs = rb_iv_get(self, "@configuration");
118
+ name = rb_ary_shift(cfg_changed);
119
+ while (TYPE(name) != T_NIL) {
120
+ gp_result_check(gp_widget_get_child_by_name(c->config, RSTRING(name)->ptr, &(c->childConfig)));
121
+ gp_result_check(gp_widget_get_type(c->childConfig, &widgettype));
173
122
  switch (widgettype) {
174
123
  case GP_WIDGET_RADIO:
175
- case GP_WIDGET_RANGE:
176
- retval = gp_widget_get_name(cc, &name);
177
- if (retval == GP_OK) {
178
- rb_ary_push(arr, rb_str_new2(name));
179
- }
124
+ rb_hash_aset(cfgs, name, getRadio(c->childConfig));
180
125
  break;
181
- case GP_WIDGET_WINDOW:
182
- case GP_WIDGET_SECTION:
183
- childrenTotal = gp_widget_count_children(cc);
184
- for (i = 0; i < childrenTotal; i ++) {
185
- retval = gp_widget_get_child(cc, i, &child);
186
- if (retval == GP_OK) {
187
- populateWithConfigs(child, arr);
188
- }
189
- }
126
+ case GP_WIDGET_RANGE:
127
+ rb_hash_aset(cfgs, name, getRange(c->childConfig));
190
128
  break;
191
129
  }
130
+ name = rb_ary_shift(cfg_changed);
192
131
  }
193
- if (retval != GP_OK) {
194
- rb_raise_gp_result(retval);
132
+ }
133
+
134
+ static void populateWithConfigs(CameraWidget *cc, VALUE hash) {
135
+ int i, childrenTotal;
136
+ const char *name;
137
+ CameraWidget *child;
138
+ CameraWidgetType widgettype;
139
+
140
+ gp_result_check(gp_widget_get_type(cc, &widgettype));
141
+ switch (widgettype) {
142
+ case GP_WIDGET_RADIO:
143
+ gp_result_check(gp_widget_get_name(cc, &name));
144
+ rb_hash_aset(hash, rb_str_new2(name), getRadio(cc));
145
+ break;
146
+ case GP_WIDGET_RANGE:
147
+ gp_result_check(gp_widget_get_name(cc, &name));
148
+ rb_hash_aset(hash, rb_str_new2(name), getRange(cc));
149
+ break;
150
+ case GP_WIDGET_WINDOW:
151
+ case GP_WIDGET_SECTION:
152
+ childrenTotal = gp_result_check(gp_widget_count_children(cc));
153
+ for (i = 0; i < childrenTotal; i ++) {
154
+ gp_result_check(gp_widget_get_child(cc, i, &child));
155
+ populateWithConfigs(child, hash);
156
+ }
157
+ break;
195
158
  }
196
159
  }
197
160
 
@@ -199,39 +162,27 @@ static void camera_mark(GPhoto2Camera *c) {
199
162
  }
200
163
 
201
164
  static void camera_free(GPhoto2Camera *c) {
202
- int retval;
203
- retval = gp_camera_exit(c->camera, c->context);
204
- retval = gp_widget_free(c->config);
205
- retval = gp_list_free(c->list);
206
- retval = gp_file_free(c->file);
207
- retval = gp_camera_free(c->camera);
165
+ gp_result_check(gp_camera_exit(c->camera, c->context));
166
+ gp_result_check(gp_widget_free(c->config));
167
+ gp_result_check(gp_list_free(c->list));
168
+ gp_result_check(gp_file_free(c->file));
169
+ gp_result_check(gp_camera_free(c->camera));
208
170
  free(c->virtFolder);
209
171
  free(c->context);
210
172
  free(c);
211
173
  }
212
174
 
213
175
  static VALUE camera_allocate(VALUE klass) {
214
- int retval;
215
176
  GPhoto2Camera *c;
216
177
  c = (GPhoto2Camera*) malloc(sizeof(GPhoto2Camera));
217
178
  c->virtFolder = (char*) malloc(sizeof(char)*100);
218
179
  strcpy(c->virtFolder, "/");
219
180
  c->context = gp_context_new();
220
- retval = gp_camera_new(&(c->camera));
221
- if (retval == GP_OK) {
222
- retval = gp_list_new(&(c->list));
223
- if (retval == GP_OK) {
224
- retval = gp_camera_get_config(c->camera, &(c->config), c->context);
225
- if (retval == GP_OK) {
226
- retval = gp_file_new(&(c->file));
227
- if (retval == GP_OK) {
228
- return Data_Wrap_Struct(klass, camera_mark, camera_free, c);
229
- }
230
- }
231
- }
232
- }
233
- rb_raise_gp_result(retval);
234
- return Qnil;
181
+ gp_result_check(gp_camera_new(&(c->camera)));
182
+ gp_result_check(gp_list_new(&(c->list)));
183
+ gp_result_check(gp_camera_get_config(c->camera, &(c->config), c->context));
184
+ gp_result_check(gp_file_new(&(c->file)));
185
+ return Data_Wrap_Struct(klass, camera_mark, camera_free, c);
235
186
  }
236
187
 
237
188
  /*
@@ -250,44 +201,37 @@ static VALUE camera_allocate(VALUE klass) {
250
201
  *
251
202
  */
252
203
  static VALUE camera_initialize(int argc, VALUE *argv, VALUE self) {
204
+ GPhoto2Camera *c;
205
+ VALUE cfgs;
206
+
207
+ Data_Get_Struct(self, GPhoto2Camera, c);
208
+
253
209
  switch (argc) {
254
210
  case 0:
255
- return self;
256
211
  break;
257
212
  case 1:
258
213
  Check_Type(argv[0], T_STRING);
259
- int retval, portIndex;
214
+ int portIndex;
260
215
  GPPortInfoList *portInfoList;
261
216
  GPPortInfo p;
262
- GPhoto2Camera *c;
263
-
264
- Data_Get_Struct(self, GPhoto2Camera, c);
265
217
 
266
- retval = gp_port_info_list_new(&portInfoList);
267
- if (retval == GP_OK) {
268
- retval = gp_port_info_list_load(portInfoList);
269
- if (retval == GP_OK) {
270
- portIndex = gp_port_info_list_lookup_path(portInfoList, RSTRING(argv[0])->ptr);
271
- if (portIndex >= 0) {
272
- retval = gp_port_info_list_get_info(portInfoList, portIndex, &p);
273
- if (retval == GP_OK) {
274
- retval = gp_camera_set_port_info(c->camera, p);
275
- if (retval == GP_OK) {
276
- return self;
277
- }
278
- }
279
- } else {
280
- rb_raise_gp_result(portIndex);
281
- return Qnil;
282
- }
283
- }
284
- }
285
- rb_raise_gp_result(retval);
286
- return Qnil;
218
+ gp_result_check(gp_port_info_list_new(&portInfoList));
219
+ gp_result_check(gp_port_info_list_load(portInfoList));
220
+ portIndex = gp_result_check(gp_port_info_list_lookup_path(portInfoList, RSTRING(argv[0])->ptr));
221
+ gp_result_check(gp_port_info_list_get_info(portInfoList, portIndex, &p));
222
+ gp_result_check(gp_camera_set_port_info(c->camera, p));
223
+ break;
287
224
  default:
288
225
  rb_raise(rb_eArgError, "Wrong number of arguments (%d for 0 or 1)", argc);
289
226
  return Qnil;
290
227
  }
228
+
229
+ cfgs = rb_hash_new();
230
+ populateWithConfigs(c->config, cfgs);
231
+ rb_iv_set(self, "@configuration", cfgs);
232
+ rb_iv_set(self, "@configs_changed", rb_ary_new());
233
+
234
+ return self;
291
235
  }
292
236
 
293
237
  /*
@@ -306,60 +250,55 @@ static VALUE camera_initialize(int argc, VALUE *argv, VALUE self) {
306
250
  *
307
251
  */
308
252
  static VALUE camera_class_ports(VALUE klass) {
309
- int retval, i, portsTotal;
253
+ int i, portsTotal;
310
254
  GPPortInfoList *portInfoList;
311
255
  GPPortInfo p;
312
256
  VALUE arr;
313
257
 
314
- retval = gp_port_info_list_new(&portInfoList);
315
- if (retval == GP_OK) {
316
- retval = gp_port_info_list_load(portInfoList);
317
- if (retval == GP_OK) {
318
- portsTotal = gp_port_info_list_count(portInfoList);
319
- arr = rb_ary_new();
320
- for(i = 0; i < portsTotal; i++) {
321
- retval = gp_port_info_list_get_info(portInfoList, i, &p);
322
- if ((retval == GP_OK) && (strlen(p.path) > 4) && (strncmp(p.path, "usb:", 4) == 0)) {
323
- rb_ary_push(arr, rb_str_new2(p.path));
324
- }
325
- }
326
- retval = gp_port_info_list_free(portInfoList);
327
- if (retval == GP_OK) {
328
- return arr;
329
- }
258
+ gp_result_check(gp_port_info_list_new(&portInfoList));
259
+ gp_result_check(gp_port_info_list_load(portInfoList));
260
+ portsTotal = gp_result_check(gp_port_info_list_count(portInfoList));
261
+ arr = rb_ary_new();
262
+ for(i = 0; i < portsTotal; i++) {
263
+ gp_result_check(gp_port_info_list_get_info(portInfoList, i, &p));
264
+ if ((strlen(p.path) > 4) && (strncmp(p.path, "usb:", 4) == 0)) {
265
+ rb_ary_push(arr, rb_str_new2(p.path));
330
266
  }
331
267
  }
332
- rb_raise_gp_result(retval);
333
- return Qnil;
268
+ gp_result_check(gp_port_info_list_free(portInfoList));
269
+ return arr;
334
270
  }
335
271
 
336
272
  /*
337
273
  * call-seq:
338
- * capture => camera
274
+ * capture(config={}) => camera
339
275
  *
340
- * Sends command to camera to capture image with current configuration
276
+ * Sends command to camera to capture image with current or provided
277
+ * configuration. Provided configuration is kept after capture.
341
278
  *
342
279
  * Examples:
343
280
  *
344
281
  * c = GPhoto2::Camera.new
345
282
  * c.capture
283
+ * c.capture "exptime" => "0.010", "iso" => "400"
346
284
  *
347
285
  */
348
- static VALUE camera_capture(VALUE self) {
349
- int retval;
286
+ static VALUE camera_capture(int argc, VALUE *argv, VALUE self) {
350
287
  GPhoto2Camera *c;
351
288
 
352
289
  Data_Get_Struct(self, GPhoto2Camera, c);
353
-
354
- retval = gp_camera_capture(c->camera, GP_CAPTURE_IMAGE, &(c->path), c->context);
355
- if (retval == GP_OK) {
356
- strcpy(c->virtFolder, c->path.folder);
357
- printf("captured: %s/%s\n", c->path.folder, c->path.name);
358
- return self;
359
- } else {
360
- rb_raise_gp_result(retval);
290
+
291
+ if (argc == 1) {
292
+ camera_config_merge(self, argv[0]);
293
+ } else if (argc != 0) {
294
+ rb_raise(rb_eArgError, "Wrong number of arguments (%d for 0 or 1)", argc);
361
295
  return Qnil;
362
296
  }
297
+
298
+ gp_result_check(gp_camera_capture(c->camera, GP_CAPTURE_IMAGE, &(c->path), c->context));
299
+ strcpy(c->virtFolder, c->path.folder);
300
+ // printf("captured: %s/%s\n", c->path.folder, c->path.name);
301
+ return self;
363
302
  }
364
303
 
365
304
  /*
@@ -388,7 +327,7 @@ static VALUE camera_capture(VALUE self) {
388
327
  *
389
328
  */
390
329
  static VALUE camera_save(int argc, VALUE *argv, VALUE self) {
391
- int retval, i;
330
+ int i;
392
331
  int newName = -1;
393
332
  CameraFileType fileType = GP_FILE_TYPE_NORMAL;
394
333
  GPhoto2Camera *c;
@@ -467,33 +406,25 @@ static VALUE camera_save(int argc, VALUE *argv, VALUE self) {
467
406
  return Qnil;
468
407
  }
469
408
 
470
- retval = gp_filesystem_reset(c->camera->fs);
471
- if (retval == GP_OK) {
472
- retval = gp_camera_file_get(c->camera, cFolderName, cFileName, fileType, c->file, c->context);
473
- if (retval == GP_OK) {
474
- retval = gp_file_get_data_and_size(c->file, &fData, &fSize);
475
- if (retval == GP_OK) {
476
- if (newName == 0) {
477
- strcat(fName, newNameStr);
478
- pchNew = strrchr(newNameStr, '.');
479
- pchSrc = strrchr(cFileName, '.');
480
- if (pchNew == NULL) {
481
- strcat(fName, pchSrc);
482
- } else if (strcmp(pchNew, pchSrc) != 0) {
483
- strcat(fName, pchSrc);
484
- }
485
- } else {
486
- strcat(fName, cFileName);
487
- }
488
- fd = open(fName, O_CREAT | O_WRONLY, 0644);
489
- write(fd, fData, fSize);
490
- close(fd);
491
- return self;
492
- }
409
+ gp_result_check(gp_filesystem_reset(c->camera->fs));
410
+ gp_result_check(gp_camera_file_get(c->camera, cFolderName, cFileName, fileType, c->file, c->context));
411
+ gp_result_check(gp_file_get_data_and_size(c->file, &fData, &fSize));
412
+ if (newName == 0) {
413
+ strcat(fName, newNameStr);
414
+ pchNew = strrchr(newNameStr, '.');
415
+ pchSrc = strrchr(cFileName, '.');
416
+ if (pchNew == NULL) {
417
+ strcat(fName, pchSrc);
418
+ } else if (strcmp(pchNew, pchSrc) != 0) {
419
+ strcat(fName, pchSrc);
493
420
  }
421
+ } else {
422
+ strcat(fName, cFileName);
494
423
  }
495
- rb_raise_gp_result(retval);
496
- return Qnil;
424
+ fd = open(fName, O_CREAT | O_WRONLY, 0644);
425
+ write(fd, fData, fSize);
426
+ close(fd);
427
+ return self;
497
428
  }
498
429
 
499
430
  /*
@@ -514,7 +445,7 @@ static VALUE camera_save(int argc, VALUE *argv, VALUE self) {
514
445
  *
515
446
  */
516
447
  static VALUE camera_delete(int argc, VALUE *argv, VALUE self) {
517
- int retval, i;
448
+ int i;
518
449
  GPhoto2Camera *c;
519
450
  const char *key;
520
451
  char cFileName[100], cFolderName[100];
@@ -554,28 +485,22 @@ static VALUE camera_delete(int argc, VALUE *argv, VALUE self) {
554
485
  return Qnil;
555
486
  }
556
487
 
557
- retval = gp_filesystem_reset(c->camera->fs);
558
- if (retval == GP_OK) {
559
- retval = gp_camera_file_delete(c->camera, cFolderName, cFileName, c->context);
560
- if (retval == GP_OK) {
561
- return self;
562
- }
563
- }
564
- rb_raise_gp_result(retval);
565
- return Qnil;
488
+ gp_result_check(gp_filesystem_reset(c->camera->fs));
489
+ gp_result_check(gp_camera_file_delete(c->camera, cFolderName, cFileName, c->context));
490
+ return self;
566
491
  }
567
492
 
568
493
  /*
569
494
  * call-seq:
570
- * configs => array
495
+ * config => hash
571
496
  *
572
- * Returns an array of adjustable camera configurations.
497
+ * Returns cached hash of adjustable camera configuration with their values.
573
498
  *
574
499
  * Examples:
575
500
  *
576
501
  * c = GPhoto2::Camera.new
577
502
  * # with Nikon DSC D80
578
- * c.configs #=> ["capturetarget", "imgquality",
503
+ * c.config.keys #=> ["capturetarget", "imgquality",
579
504
  * "imgsize", "whitebalance",
580
505
  * "f-number", "focallength",
581
506
  * "focusmode", "iso",
@@ -587,25 +512,82 @@ static VALUE camera_delete(int argc, VALUE *argv, VALUE self) {
587
512
  * "channel", "encryption"]
588
513
  *
589
514
  */
590
- static VALUE camera_get_configs(VALUE self) {
515
+ static VALUE camera_get_config(VALUE self) {
516
+ return rb_iv_get(self, "@configuration");
517
+ }
518
+
519
+ /*
520
+ * call-seq:
521
+ * config_merge(hash) => hash
522
+ *
523
+ * Adjusts camera configuration with given values.
524
+ *
525
+ * Examples:
526
+ *
527
+ * c = GPhoto2::Camera.new
528
+ * # with Nikon DSC D80
529
+ * c.config_merge "f-number" => "f/4", "exptime" => "0.010", "iso" => "200"
530
+ *
531
+ */
532
+ static VALUE camera_config_merge(VALUE self, VALUE hash) {
533
+ Check_Type(hash, T_HASH);
534
+
535
+ int i;
536
+ const char *key;
591
537
  GPhoto2Camera *c;
592
- VALUE arr = rb_ary_new();
538
+ CameraWidgetType widgettype;
539
+ VALUE arr, cfgs, cfg_changed;
593
540
 
594
541
  Data_Get_Struct(self, GPhoto2Camera, c);
595
542
 
596
- populateWithConfigs(c->config, arr);
597
-
598
- return arr;
543
+ arr = rb_funcall(hash, rb_intern("keys"), 0);
544
+ cfgs = rb_iv_get(self, "@configuration");
545
+ cfg_changed = rb_iv_get(self, "@configs_changed");
546
+ for (i = 0; i < RARRAY(arr)->len; i++) {
547
+ switch(TYPE(RARRAY(arr)->ptr[i])) {
548
+ case T_STRING:
549
+ key = RSTRING(RARRAY(arr)->ptr[i])->ptr;
550
+ break;
551
+ case T_SYMBOL:
552
+ key = rb_id2name(rb_to_id(RARRAY(arr)->ptr[i]));
553
+ break;
554
+ default:
555
+ rb_raise(rb_eTypeError, "Not valid key type");
556
+ return Qnil;
557
+ }
558
+ if (TYPE(rb_funcall(cfgs, rb_intern("has_key?"), 1, rb_str_new2(key))) == T_TRUE) {
559
+ gp_result_check(gp_widget_get_child_by_name(c->config, key, &(c->childConfig)));
560
+ gp_result_check(gp_widget_get_type(c->childConfig, &widgettype));
561
+ switch (widgettype) {
562
+ case GP_WIDGET_RADIO:
563
+ rb_ary_push(cfg_changed, rb_str_new2(key));
564
+ setRadio(self, c, rb_hash_aref(hash, RARRAY(arr)->ptr[i]), 0);
565
+ break;
566
+ case GP_WIDGET_RANGE:
567
+ rb_ary_push(cfg_changed, rb_str_new2(key));
568
+ setRange(self, c, rb_hash_aref(hash, RARRAY(arr)->ptr[i]), 0);
569
+ break;
570
+ }
571
+ }
572
+ }
573
+ saveConfigs(self, c);
574
+ return cfgs;
599
575
  }
600
576
 
601
577
  /*
602
578
  * call-seq:
603
579
  * cam[cfg] => float or string
604
580
  * cam[cfg, :all] => array
581
+ * cam[cfg, :type] => fixnum
605
582
  *
606
583
  * Returns current value of specified camera configuration. Configuration name
607
584
  * (cfg) can be string or symbol and must be in configs method returned array.
608
- * When called with directive <b>:all</b> returns an array of allowed values
585
+ * Configuration is cached in @configuration instance variable.
586
+ *
587
+ * Possible directives:
588
+ * * <b>:no_cache</b> doesn't use cached configuration value
589
+ * * <b>:all</b> returns an array of allowed values;
590
+ * * <b>:type</b> returns one of available CONFIG_TYPE constats
609
591
  *
610
592
  * Examples:
611
593
  *
@@ -614,14 +596,15 @@ static VALUE camera_get_configs(VALUE self) {
614
596
  * c["f-number"] #=> "f/4.5"
615
597
  * c[:focallength] #=> 10.5
616
598
  * c[:focusmode, :all] #=> ["Manual", "AF-S", "AF-C", "AF-A"]
599
+ * c[:exptime, :type] == GPhoto2::Camera::CONFIG_TYPE_RADIO
600
+ * #=> true
617
601
  *
618
602
  */
619
603
  static VALUE camera_get_value(int argc, VALUE *argv, VALUE self) {
620
- int retval;
621
604
  const char *name;
622
605
  GPhoto2Camera *c;
623
606
  CameraWidgetType widgettype;
624
- VALUE str, dir;
607
+ VALUE str, dir, cfgs;
625
608
 
626
609
  switch (argc) {
627
610
  case 1:
@@ -630,6 +613,7 @@ static VALUE camera_get_value(int argc, VALUE *argv, VALUE self) {
630
613
  case 2:
631
614
  str = argv[0];
632
615
  dir = argv[1];
616
+ Check_Type(dir, T_SYMBOL);
633
617
  break;
634
618
  default:
635
619
  rb_raise(rb_eArgError, "Wrong number of arguments (%d for 1 or 2)", argc);
@@ -648,45 +632,43 @@ static VALUE camera_get_value(int argc, VALUE *argv, VALUE self) {
648
632
  return Qnil;
649
633
  }
650
634
 
651
- Data_Get_Struct(self, GPhoto2Camera, c);
635
+ if (argc == 1) {
636
+ return rb_hash_aref(rb_iv_get(self, "@configuration"), rb_str_new2(name));
637
+ } else {
638
+ Data_Get_Struct(self, GPhoto2Camera, c);
652
639
 
653
- retval = gp_widget_get_child_by_name(c->config, name, &(c->childConfig));
654
- if (retval == GP_OK) {
655
- retval = gp_widget_get_type(c->childConfig, &widgettype);
656
- if (retval == GP_OK) {
657
- switch (widgettype) {
658
- case GP_WIDGET_RADIO:
659
- if (argc == 1) {
660
- return getRadio(c->childConfig);
661
- } else if (strcmp(rb_id2name(rb_to_id(dir)), "all") == 0) {
662
- return listRadio(c->childConfig);
663
- } else {
664
- rb_raise(rb_cGPhoto2ConfigurationError, "Second parameter not valid");
665
- return Qnil;
666
- }
667
- break;
668
- case GP_WIDGET_RANGE:
669
- if (argc == 1) {
670
- return getRange(c->childConfig);
671
- } else if (strcmp(rb_id2name(rb_to_id(dir)), "all") == 0) {
672
- return listRange(c->childConfig);
673
- } else {
674
- rb_raise(rb_cGPhoto2ConfigurationError, "Second parameter not valid");
675
- return Qnil;
676
- }
677
- break;
678
- default:
679
- rb_raise(rb_cGPhoto2ConfigurationError, "Not supported yet");
640
+ gp_result_check(gp_widget_get_child_by_name(c->config, name, &(c->childConfig)));
641
+ gp_result_check(gp_widget_get_type(c->childConfig, &widgettype));
642
+ switch (widgettype) {
643
+ case GP_WIDGET_RADIO:
644
+ if (strcmp(rb_id2name(rb_to_id(dir)), "no_cache") == 0) {
645
+ return getRadio(c->childConfig);
646
+ } else if (strcmp(rb_id2name(rb_to_id(dir)), "all") == 0) {
647
+ return listRadio(c->childConfig);
648
+ } else if (strcmp(rb_id2name(rb_to_id(dir)), "type") == 0) {
649
+ return INT2FIX(GP_WIDGET_RADIO);
650
+ } else {
651
+ rb_raise(rb_cGPhoto2ConfigurationError, "Unknown directive '%s'", rb_id2name(rb_to_id(dir)));
680
652
  return Qnil;
681
- }
653
+ }
654
+ break;
655
+ case GP_WIDGET_RANGE:
656
+ if (strcmp(rb_id2name(rb_to_id(dir)), "no_cache") == 0) {
657
+ return getRange(c->childConfig);
658
+ } else if (strcmp(rb_id2name(rb_to_id(dir)), "all") == 0) {
659
+ return listRange(c->childConfig);
660
+ } else if (strcmp(rb_id2name(rb_to_id(dir)), "type") == 0) {
661
+ return INT2FIX(GP_WIDGET_RANGE);
662
+ } else {
663
+ rb_raise(rb_cGPhoto2ConfigurationError, "Unknown directive '%s'", rb_id2name(rb_to_id(dir)));
664
+ return Qnil;
665
+ }
666
+ break;
667
+ default:
668
+ rb_raise(rb_cGPhoto2ConfigurationError, "Not supported yet");
669
+ return Qnil;
682
670
  }
683
671
  }
684
- if (retval != GP_OK) {
685
- rb_raise_gp_result(retval);
686
- } else {
687
- rb_raise_programmer_error("camera_get_value");
688
- }
689
- return Qnil;
690
672
  }
691
673
 
692
674
  /*
@@ -704,10 +686,10 @@ static VALUE camera_get_value(int argc, VALUE *argv, VALUE self) {
704
686
  *
705
687
  */
706
688
  static VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal) {
707
- int retval;
708
689
  const char *name;
709
690
  GPhoto2Camera *c;
710
691
  CameraWidgetType widgettype;
692
+ VALUE cfg_changed;
711
693
 
712
694
  switch (TYPE(str)) {
713
695
  case T_STRING:
@@ -723,29 +705,23 @@ static VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal) {
723
705
 
724
706
  Data_Get_Struct(self, GPhoto2Camera, c);
725
707
 
726
- retval = gp_widget_get_child_by_name(c->config, name, &(c->childConfig));
727
- if (retval == GP_OK) {
728
- retval = gp_widget_get_type(c->childConfig, &widgettype);
729
- if (retval == GP_OK) {
730
- switch (widgettype) {
731
- case GP_WIDGET_RADIO:
732
- return setRadio(c, newVal);
733
- break;
734
- case GP_WIDGET_RANGE:
735
- return setRange(c, newVal);
736
- break;
737
- default:
738
- rb_raise(rb_cGPhoto2ConfigurationError, "Cannot access this setting");
739
- return Qnil;
740
- }
741
- }
742
- }
743
- if (retval != GP_OK) {
744
- rb_raise_gp_result(retval);
745
- } else {
746
- rb_raise_programmer_error("camera_set_value");
708
+ gp_result_check(gp_widget_get_child_by_name(c->config, name, &(c->childConfig)));
709
+ gp_result_check(gp_widget_get_type(c->childConfig, &widgettype));
710
+ switch (widgettype) {
711
+ case GP_WIDGET_RADIO:
712
+ cfg_changed = rb_iv_get(self, "@configs_changed");
713
+ rb_ary_push(cfg_changed, rb_str_new2(name));
714
+ return setRadio(self, c, newVal, 1);
715
+ break;
716
+ case GP_WIDGET_RANGE:
717
+ cfg_changed = rb_iv_get(self, "@configs_changed");
718
+ rb_ary_push(cfg_changed, rb_str_new2(name));
719
+ return setRange(self, c, newVal, 1);
720
+ break;
721
+ default:
722
+ rb_raise(rb_cGPhoto2ConfigurationError, "Cannot access this setting");
723
+ return Qnil;
747
724
  }
748
- return Qnil;
749
725
  }
750
726
 
751
727
  /*
@@ -787,31 +763,21 @@ static VALUE camera_folder(VALUE self) {
787
763
  *
788
764
  */
789
765
  static VALUE camera_subfolders(VALUE self) {
790
- int retval, i, count;
766
+ int i, count;
791
767
  const char *name;
792
768
  GPhoto2Camera *c;
793
769
  VALUE arr;
794
770
 
795
771
  Data_Get_Struct(self, GPhoto2Camera, c);
796
772
 
797
- retval = gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context);
798
- if (retval == GP_OK) {
799
- count = gp_list_count(c->list);
800
- if (count < 0) {
801
- rb_raise_gp_result(retval);
802
- return Qnil;
803
- }
804
- arr = rb_ary_new();
805
- for (i = 0; i < count; i++) {
806
- retval = gp_list_get_name(c->list, i, &name);
807
- if (retval == GP_OK) {
808
- rb_ary_push(arr, rb_str_new2(name));
809
- }
810
- }
811
- return arr;
773
+ gp_result_check(gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context));
774
+ count = gp_result_check(gp_list_count(c->list));
775
+ arr = rb_ary_new();
776
+ for (i = 0; i < count; i++) {
777
+ gp_result_check(gp_list_get_name(c->list, i, &name));
778
+ rb_ary_push(arr, rb_str_new2(name));
812
779
  }
813
- rb_raise_gp_result(retval);
814
- return Qnil;
780
+ return arr;
815
781
  }
816
782
 
817
783
  /*
@@ -832,34 +798,22 @@ static VALUE camera_subfolders(VALUE self) {
832
798
  *
833
799
  */
834
800
  static VALUE camera_files(VALUE self) {
835
- int retval, i, count;
801
+ int i, count;
836
802
  const char *name;
837
803
  GPhoto2Camera *c;
838
804
  VALUE arr;
839
805
 
840
806
  Data_Get_Struct(self, GPhoto2Camera, c);
841
807
 
842
- retval = gp_filesystem_reset(c->camera->fs);
843
- if (retval == GP_OK) {
844
- retval = gp_camera_folder_list_files(c->camera, c->virtFolder, c->list, c->context);
845
- if (retval == GP_OK) {
846
- count = gp_list_count(c->list);
847
- if (count < 0) {
848
- rb_raise_gp_result(retval);
849
- return Qnil;
850
- }
851
- arr = rb_ary_new();
852
- for (i = 0; i < count; i++) {
853
- retval = gp_list_get_name(c->list, i, &name);
854
- if (retval == GP_OK) {
855
- rb_ary_push(arr, rb_str_new2(name));
856
- }
857
- }
858
- return arr;
859
- }
808
+ gp_result_check(gp_filesystem_reset(c->camera->fs));
809
+ gp_result_check(gp_camera_folder_list_files(c->camera, c->virtFolder, c->list, c->context));
810
+ count = gp_result_check(gp_list_count(c->list));
811
+ arr = rb_ary_new();
812
+ for (i = 0; i < count; i++) {
813
+ gp_result_check(gp_list_get_name(c->list, i, &name));
814
+ rb_ary_push(arr, rb_str_new2(name));
860
815
  }
861
- rb_raise_gp_result(retval);
862
- return Qnil;
816
+ return arr;
863
817
  }
864
818
 
865
819
  /*
@@ -916,7 +870,7 @@ static VALUE camera_folder_up(VALUE self) {
916
870
  */
917
871
  static VALUE camera_folder_down(VALUE self, VALUE folder) {
918
872
  Check_Type(folder, T_STRING);
919
- int retval;
873
+
920
874
  const char *name;
921
875
  int index;
922
876
  GPhoto2Camera *c;
@@ -924,16 +878,12 @@ static VALUE camera_folder_down(VALUE self, VALUE folder) {
924
878
  Data_Get_Struct(self, GPhoto2Camera, c);
925
879
 
926
880
  name = RSTRING(folder)->ptr;
927
- retval = gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context);
928
- if (retval == GP_OK) {
929
- retval = gp_list_find_by_name(c->list, &index, name);
930
- if (retval == GP_OK) {
931
- if (strlen(c->virtFolder) > 1) {
932
- strcat(c->virtFolder, "/");
933
- }
934
- strcat(c->virtFolder, name);
935
- }
881
+ gp_result_check(gp_camera_folder_list_folders(c->camera, c->virtFolder, c->list, c->context));
882
+ gp_result_check(gp_list_find_by_name(c->list, &index, name));
883
+ if (strlen(c->virtFolder) > 1) {
884
+ strcat(c->virtFolder, "/");
936
885
  }
886
+ strcat(c->virtFolder, name);
937
887
  return self;
938
888
  }
939
889
 
@@ -957,18 +907,18 @@ void Init_gphoto4ruby() {
957
907
  * supported
958
908
  */
959
909
  rb_cGPhoto2ConfigurationError = rb_define_class_under(rb_mGPhoto2, "ConfigurationError", rb_eStandardError);
960
- /*
961
- * GPhoto2::ProgrammerError is never raised. :) Only when program gets
962
- * where it could never get.
963
- */
964
- rb_cGPhoto2ProgrammerError = rb_define_class_under(rb_mGPhoto2, "ProgrammerError", rb_eStandardError);
910
+
911
+ rb_define_const(rb_cGPhoto2Camera, "CONFIG_TYPE_RADIO", INT2FIX(GP_WIDGET_RADIO));
912
+ rb_define_const(rb_cGPhoto2Camera, "CONFIG_TYPE_RANGE", INT2FIX(GP_WIDGET_RANGE));
913
+
965
914
  rb_define_alloc_func(rb_cGPhoto2Camera, camera_allocate);
966
915
  rb_define_module_function(rb_cGPhoto2Camera, "ports", camera_class_ports, 0);
967
916
  rb_define_method(rb_cGPhoto2Camera, "initialize", camera_initialize, -1);
968
- rb_define_method(rb_cGPhoto2Camera, "configs", camera_get_configs, 0);
917
+ rb_define_method(rb_cGPhoto2Camera, "config", camera_get_config, 0);
918
+ rb_define_method(rb_cGPhoto2Camera, "config_merge", camera_config_merge, 1);
969
919
  rb_define_method(rb_cGPhoto2Camera, "[]", camera_get_value, -1);
970
920
  rb_define_method(rb_cGPhoto2Camera, "[]=", camera_set_value, 2);
971
- rb_define_method(rb_cGPhoto2Camera, "capture", camera_capture, 0);
921
+ rb_define_method(rb_cGPhoto2Camera, "capture", camera_capture, -1);
972
922
  rb_define_method(rb_cGPhoto2Camera, "save", camera_save, -1);
973
923
  rb_define_method(rb_cGPhoto2Camera, "delete", camera_delete, -1);
974
924
  rb_define_method(rb_cGPhoto2Camera, "folder", camera_folder, 0);
data/ext/gphoto4ruby.h CHANGED
@@ -36,17 +36,17 @@ static VALUE rb_mGPhoto2;
36
36
  static VALUE rb_cGPhoto2Camera;
37
37
  static VALUE rb_cGPhoto2Exception;
38
38
  static VALUE rb_cGPhoto2ConfigurationError;
39
- static VALUE rb_cGPhoto2ProgrammerError;
40
39
 
41
40
  static void rb_raise_gp_result(int retval);
42
41
  static void rb_raise_programmer_error(const char* fName);
43
42
 
44
43
  static VALUE getRadio(CameraWidget *cc);
45
44
  static VALUE listRadio(CameraWidget *cc);
46
- static VALUE setRadio(GPhoto2Camera *c, VALUE newVal);
45
+ static VALUE setRadio(VALUE self, GPhoto2Camera *c, VALUE newVal, int save);
47
46
  static VALUE getRange(CameraWidget *cc);
48
47
  static VALUE listRange(CameraWidget *cc);
49
- static VALUE setRange(GPhoto2Camera *c, VALUE newNum);
48
+ static VALUE setRange(VALUE self, GPhoto2Camera *c, VALUE newNum, int save);
49
+ static void saveConfigs(VALUE self, GPhoto2Camera *c);
50
50
 
51
51
  static void populateWithConfigs(CameraWidget *cc, VALUE arr);
52
52
 
@@ -57,11 +57,13 @@ static VALUE camera_allocate(VALUE klass);
57
57
  static VALUE camera_initialize(int argc, VALUE *argv, VALUE self);
58
58
  static VALUE camera_class_ports(VALUE klass);
59
59
 
60
- static VALUE camera_capture(VALUE self);
60
+ static VALUE camera_capture(int argc, VALUE *argv, VALUE self);
61
61
 
62
62
  static VALUE camera_save(int argc, VALUE *argv, VALUE self);
63
63
 
64
- static VALUE camera_get_configs(VALUE self);
64
+ static VALUE camera_get_config(VALUE self);
65
+ static VALUE camera_config_merge(VALUE self, VALUE hash);
66
+
65
67
  static VALUE camera_get_value(int argc, VALUE *argv, VALUE self);
66
68
  static VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal);
67
69
 
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.2
4
+ version: 0.1.3
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-19 00:00:00 +04:00
13
+ date: 2008-08-26 00:00:00 +04:00
14
14
  default_executable:
15
15
  dependencies: []
16
16