gphoto4ruby 0.1.2 → 0.1.3

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 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