gphoto4ruby 0.4.1 → 0.4.2

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,3 +1,13 @@
1
+ == 0.4.2
2
+
3
+ Pulled changes from Tallak Tveide
4
+
5
+ * Added pthread to keep camera alive when library is available
6
+ * Added several question mark methods (has_config?, has_image_capture? and
7
+ has_preview?) based on gphoto2 camera abilities
8
+ * Added model_name
9
+ * Added dispose method that allows to reuse same code and reinitialize camera
10
+
1
11
  == 0.4.1
2
12
 
3
13
  * Fix for canon cameras to keep "capture=on" between ruby calls. Though it shows
data/README.rdoc CHANGED
@@ -101,6 +101,11 @@ connected through usb in PTP mode and Canon EOS 450D.
101
101
  # it from camera
102
102
  cams.first.capture.save.delete
103
103
  end
104
+
105
+
106
+ On supported systems, instanciating a camera will start a thread that
107
+ prevents the camera from posering off automatically.
108
+
104
109
  == Contact
105
110
 
106
111
  neq4 company:: http://neq4.com
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
data/example.rb CHANGED
@@ -8,6 +8,7 @@ if ports.any?
8
8
  ports.each do |port|
9
9
  c = GPhoto2::Camera.new(port)
10
10
  puts "camera in port: " + port
11
+ puts 'Model: ' + c.model_name
11
12
  c["capture"] = true if c.config.has_key? "capture" # canon? :)
12
13
  c.config(:no_cache).each do |key, value|
13
14
  puts key + " value is: " + value.to_s
data/ext/gphoto2camera.c CHANGED
@@ -20,8 +20,36 @@
20
20
  *
21
21
  */
22
22
 
23
+ /* CAMERA TIMEOUT FUNCTIONALITY COPIED FROM libgphoto2 */
24
+ /*
25
+ * Copyright © 2002 Lutz Müller <lutz@users.sourceforge.net>
26
+ *
27
+ * This library is free software; you can redistribute it and/or
28
+ * modify it under the terms of the GNU Lesser General Public
29
+ * License as published by the Free Software Foundation; either
30
+ * version 2 of the License, or (at your option) any later version.
31
+ *
32
+ * This library is distributed in the hope that it will be useful,
33
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35
+ * Lesser General Public License for more details.
36
+ *
37
+ * You should have received a copy of the GNU Lesser General Public
38
+ * License along with this library; if not, write to the
39
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
40
+ * Boston, MA 02111-1307, USA.
41
+ */
42
+
43
+
44
+
23
45
  #include "gphoto2camera.h"
24
46
 
47
+ #ifdef HAVE_PTHREAD
48
+ #include <time.h>
49
+ #include <pthread.h>
50
+ #endif
51
+
52
+
25
53
  VALUE rb_mGPhoto2;
26
54
  VALUE rb_cGPhoto2Camera;
27
55
 
@@ -49,10 +77,74 @@ VALUE rb_cGPhoto2ConfigurationError;
49
77
  } \
50
78
  }
51
79
 
80
+
81
+
82
+ #ifdef HAVE_PTHREAD
83
+ static void thread_cleanup_func (void *data) {
84
+ ThreadData *td = data;
85
+ free (td);
86
+ }
87
+
88
+ static void * thread_func (void *data) {
89
+ ThreadData *td = data;
90
+ time_t t, last;
91
+ int dummy;
92
+ struct timespec interval, remainder;
93
+ double diff;
94
+
95
+ pthread_cleanup_push (thread_cleanup_func, td);
96
+
97
+ last = time (NULL);
98
+ while (1) {
99
+ /* Sleep first to avoid loop using all CPU */
100
+ t = time (NULL);
101
+ interval.tv_sec = td-> timeout - (t - last);
102
+ interval.tv_nsec = 0;
103
+ pthread_setcanceltype(PTHREAD_CANCEL_ENABLE, &dummy);
104
+ nanosleep(*interval, *remainder);
105
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &dummy);
106
+
107
+ t = time (NULL);
108
+ if (t - last > td->timeout) {
109
+ td->func (td->camera, NULL);
110
+ last = t;
111
+ }
112
+ pthread_testcancel ();
113
+ }
114
+ pthread_cleanup_pop (1);
115
+ }
116
+
117
+ static unsigned int start_timeout_func (Camera *camera, unsigned int timeout, CameraTimeoutFunc func, void __unused__ *data) {
118
+ pthread_t tid;
119
+ ThreadData *td;
120
+
121
+ td = malloc (sizeof (ThreadData));
122
+ if (!td)
123
+ return 0;
124
+ memset (td, 0, sizeof (ThreadData));
125
+ td->camera = camera;
126
+ td->timeout = timeout;
127
+ td->func = func;
128
+
129
+ pthread_create (&tid, NULL, thread_func, td);
130
+
131
+ return (tid);
132
+ }
133
+
134
+ static void stop_timeout_func (Camera __unused__ *camera, unsigned int id, void __unused__ *data) {
135
+ pthread_t tid = id;
136
+ pthread_cancel (tid);
137
+ pthread_join (tid, NULL);
138
+ }
139
+
140
+ #endif
141
+
142
+
52
143
  void camera_mark(GPhoto2Camera *c) {
53
144
  }
54
145
 
55
146
  void camera_free(GPhoto2Camera *c) {
147
+ if (!c->disposed) {
56
148
  gp_result_check(gp_camera_exit(c->camera, c->context));
57
149
  gp_result_check(gp_widget_free(c->config));
58
150
  gp_result_check(gp_camera_unref(c->camera));
@@ -60,7 +152,8 @@ void camera_free(GPhoto2Camera *c) {
60
152
  free(c->virtFolder);
61
153
  free(c->lastName);
62
154
  free(c->context);
63
- free(c);
155
+ }
156
+ free(c);
64
157
  }
65
158
 
66
159
  VALUE camera_allocate(VALUE klass) {
@@ -71,9 +164,11 @@ VALUE camera_allocate(VALUE klass) {
71
164
  strcpy(c->virtFolder, "/");
72
165
  c->lastName[0] = '\0';
73
166
  c->context = gp_context_new();
167
+ c->disposed = 0;
74
168
  gp_result_check(gp_camera_new(&(c->camera)));
75
169
  gp_result_check(gp_camera_get_config(c->camera, &(c->config), c->context));
76
170
  gp_result_check(gp_camera_ref(c->camera));
171
+ gp_result_check(gp_camera_get_abilities (c->camera, &((*c).abilities)));
77
172
  return Data_Wrap_Struct(klass, camera_mark, camera_free, c);
78
173
  }
79
174
 
@@ -122,10 +217,53 @@ VALUE camera_initialize(int argc, VALUE *argv, VALUE self) {
122
217
  populateWithConfigs(c->config, cfgs);
123
218
  rb_iv_set(self, "@configuration", cfgs);
124
219
  rb_iv_set(self, "@configs_changed", rb_ary_new());
220
+
221
+ #ifdef HAVE_PTHREAD
222
+ gp_camera_set_timeout_funcs (c->camera, start_timeout_func, stop_timeout_func, NULL);
223
+ #endif
224
+
225
+
125
226
 
126
227
  return self;
127
228
  }
128
229
 
230
+
231
+ /*
232
+ * call-seq:
233
+ * dispose => nil
234
+ *
235
+ * Releases resources aquired by the Camera class so that is will be possible
236
+ * to connect to the camera again even before Ruby garbage collection has
237
+ * released the Camera from memory
238
+ *
239
+ * Examples:
240
+ *
241
+ * c = GPhoto2::Camera.new
242
+ * begin
243
+ * c.capture
244
+ * ensure
245
+ * c.dispose # if capture failed, this code may run again in the same process
246
+ * end
247
+ *
248
+ */
249
+ VALUE camera_dispose(VALUE self) {
250
+ GPhoto2Camera *c;
251
+ Data_Get_Struct(self, GPhoto2Camera, c);
252
+ if (!c->disposed) {
253
+ gp_result_check(gp_camera_exit(c->camera, c->context));
254
+ gp_result_check(gp_widget_free(c->config));
255
+ gp_result_check(gp_camera_unref(c->camera));
256
+ gp_result_check(gp_camera_free(c->camera));
257
+ free(c->virtFolder);
258
+ free(c->lastName);
259
+ free(c->context);
260
+ c->disposed = -1;
261
+ return Qtrue;
262
+ } else {
263
+ return Qfalse;
264
+ }
265
+ }
266
+
129
267
  /*
130
268
  * call-seq:
131
269
  * GPhoto2::Camera.ports => array
@@ -211,6 +349,7 @@ VALUE camera_capture(int argc, VALUE *argv, VALUE self) {
211
349
  CameraFilePath path;
212
350
 
213
351
  Data_Get_Struct(self, GPhoto2Camera, c);
352
+ check_disposed(c);
214
353
 
215
354
  if (argc == 1) {
216
355
  camera_config_merge(self, argv[0]);
@@ -271,6 +410,7 @@ VALUE camera_save(int argc, VALUE *argv, VALUE self) {
271
410
  VALUE arr, hVal;
272
411
 
273
412
  Data_Get_Struct(self, GPhoto2Camera, c);
413
+ check_disposed(c);
274
414
 
275
415
  gp_list_new(&list);
276
416
 
@@ -372,19 +512,34 @@ VALUE camera_save(int argc, VALUE *argv, VALUE self) {
372
512
  strcat(fName, newNameStr);
373
513
  pchNew = strrchr(newNameStr, '.');
374
514
  pchSrc = strrchr(cFileName, '.');
515
+ if (fileType == GP_FILE_TYPE_PREVIEW) {
516
+ pchSrc = ".JPG"; /* previews are always jpeg, even if original is RAW/TIF/etc */
517
+ }
375
518
  if (pchNew == NULL) {
376
519
  strcat(fName, pchSrc);
377
- } else if (strcmp(pchNew, pchSrc) != 0) {
520
+ } else if (strcasecmp(pchNew, pchSrc) != 0) {
378
521
  strcat(fName, pchSrc);
379
522
  }
380
523
  } else {
381
- strcat(fName, cFileName);
524
+ pchSrc = strrchr(cFileName, '.');
525
+ if (fileType == GP_FILE_TYPE_PREVIEW && pchSrc) {
526
+ strncat(fName, cFileName, pchSrc - cFileName);
527
+ strcat(fName, ".JPG");
528
+ } else {
529
+ strcat(fName, cFileName);
530
+ }
382
531
  }
383
532
  } else {
384
- strcat(fName, cFileName);
533
+ pchSrc = strrchr(cFileName, '.');
534
+ if (fileType == GP_FILE_TYPE_PREVIEW && pchSrc) {
535
+ strncat(fName, cFileName, pchSrc - cFileName);
536
+ strcat(fName, ".JPG");
537
+ } else {
538
+ strcat(fName, cFileName);
539
+ }
385
540
  }
386
- fd = open(fName, O_CREAT | O_WRONLY, 0644);
387
- retVal = write(fd, fData, fSize);
541
+ fd = open(fName, O_CREAT | O_WRONLY, 0644);
542
+ retVal = write(fd, fData, fSize);
388
543
  close(fd);
389
544
  gp_file_free(file);
390
545
  gp_list_free(list);
@@ -425,6 +580,7 @@ VALUE camera_delete(int argc, VALUE *argv, VALUE self) {
425
580
  VALUE arr;
426
581
 
427
582
  Data_Get_Struct(self, GPhoto2Camera, c);
583
+ check_disposed(c);
428
584
 
429
585
  gp_list_new(&list);
430
586
 
@@ -532,6 +688,7 @@ VALUE camera_get_config(int argc, VALUE *argv, VALUE self) {
532
688
  case 1:
533
689
  Check_Type(argv[0], T_SYMBOL);
534
690
  Data_Get_Struct(self, GPhoto2Camera, c);
691
+ check_disposed(c);
535
692
 
536
693
  if (strcmp(rb_id2name(rb_to_id(argv[0])), "no_cache") == 0) {
537
694
  gp_widget_free(c->config);
@@ -573,6 +730,7 @@ VALUE camera_config_merge(VALUE self, VALUE hash) {
573
730
  VALUE arr, cfgs, cfg_changed;
574
731
 
575
732
  Data_Get_Struct(self, GPhoto2Camera, c);
733
+ check_disposed(c);
576
734
 
577
735
  arr = rb_funcall(hash, rb_intern("keys"), 0);
578
736
  cfgs = rb_iv_get(self, "@configuration");
@@ -677,6 +835,7 @@ VALUE camera_get_value(int argc, VALUE *argv, VALUE self) {
677
835
  dir = argv[1];
678
836
  Check_Type(dir, T_SYMBOL);
679
837
  Data_Get_Struct(self, GPhoto2Camera, c);
838
+ check_disposed(c);
680
839
 
681
840
  if (strcmp(rb_id2name(rb_to_id(dir)), "no_cache") == 0) {
682
841
  gp_widget_free(c->config);
@@ -803,6 +962,7 @@ VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal) {
803
962
  }
804
963
 
805
964
  Data_Get_Struct(self, GPhoto2Camera, c);
965
+ check_disposed(c);
806
966
 
807
967
  gp_result_check(gp_widget_get_child_by_name(c->config, name, &(c->childConfig)));
808
968
  gp_result_check(gp_widget_get_type(c->childConfig, &widgettype));
@@ -838,6 +998,65 @@ VALUE camera_set_value(VALUE self, VALUE str, VALUE newVal) {
838
998
  }
839
999
  }
840
1000
 
1001
+
1002
+
1003
+ /*
1004
+ * call-seq:
1005
+ * model_name => string
1006
+ *
1007
+ * Returns the model name of the camera
1008
+ *
1009
+ */
1010
+ VALUE camera_model_name(VALUE self) {
1011
+ GPhoto2Camera *c;
1012
+ Data_Get_Struct(self, GPhoto2Camera, c);
1013
+ check_disposed(c);
1014
+ return rb_str_new2((*c).abilities.model);
1015
+ }
1016
+
1017
+ /*
1018
+ * call-seq:
1019
+ * has_image_capture? => bool
1020
+ *
1021
+ * Returns true if the camera is capable of image capture
1022
+ *
1023
+ */
1024
+ VALUE camera_has_image_capture(VALUE self) {
1025
+ GPhoto2Camera *c;
1026
+ Data_Get_Struct(self, GPhoto2Camera, c);
1027
+ check_disposed(c);
1028
+ return ((*c).abilities.operations & GP_OPERATION_CAPTURE_IMAGE) ? Qtrue : Qfalse;
1029
+ }
1030
+
1031
+ /*
1032
+ * call-seq:
1033
+ * has_preview? => bool
1034
+ *
1035
+ * Returns true if the camera is capable of generatig image previews
1036
+ *
1037
+ */
1038
+ VALUE camera_has_preview(VALUE self) {
1039
+ GPhoto2Camera *c;
1040
+ Data_Get_Struct(self, GPhoto2Camera, c);
1041
+ check_disposed(c);
1042
+ return ((*c).abilities.operations & GP_OPERATION_CAPTURE_PREVIEW) ? Qtrue : Qfalse;
1043
+ }
1044
+
1045
+ /*
1046
+ * call-seq:
1047
+ * has_config? => bool
1048
+ *
1049
+ * Returns true if the camera has any configuration values
1050
+ *
1051
+ */
1052
+ VALUE camera_has_config(VALUE self) {
1053
+ GPhoto2Camera *c;
1054
+ Data_Get_Struct(self, GPhoto2Camera, c);
1055
+ check_disposed(c);
1056
+ return ((*c).abilities.operations & GP_OPERATION_CONFIG) ? Qtrue : Qfalse;
1057
+ }
1058
+
1059
+
841
1060
  /*
842
1061
  * call-seq:
843
1062
  * folder => string
@@ -858,6 +1077,7 @@ VALUE camera_folder(VALUE self) {
858
1077
  GPhoto2Camera *c;
859
1078
 
860
1079
  Data_Get_Struct(self, GPhoto2Camera, c);
1080
+ check_disposed(c);
861
1081
 
862
1082
  return rb_str_new2(c->virtFolder);
863
1083
  }
@@ -887,6 +1107,7 @@ VALUE camera_subfolders(VALUE self) {
887
1107
  VALUE arr;
888
1108
 
889
1109
  Data_Get_Struct(self, GPhoto2Camera, c);
1110
+ check_disposed(c);
890
1111
 
891
1112
  gp_list_new(&list);
892
1113
 
@@ -940,6 +1161,7 @@ VALUE camera_files(int argc, VALUE *argv, VALUE self) {
940
1161
  }
941
1162
 
942
1163
  Data_Get_Struct(self, GPhoto2Camera, c);
1164
+ check_disposed(c);
943
1165
 
944
1166
  gp_list_new(&list);
945
1167
 
@@ -985,6 +1207,7 @@ VALUE camera_files_count(VALUE self) {
985
1207
  CameraList *list;
986
1208
 
987
1209
  Data_Get_Struct(self, GPhoto2Camera, c);
1210
+ check_disposed(c);
988
1211
 
989
1212
  gp_list_new(&list);
990
1213
 
@@ -1020,6 +1243,7 @@ VALUE camera_folder_up(VALUE self) {
1020
1243
  GPhoto2Camera *c;
1021
1244
 
1022
1245
  Data_Get_Struct(self, GPhoto2Camera, c);
1246
+ check_disposed(c);
1023
1247
 
1024
1248
  pch = strrchr(c->virtFolder, '/');
1025
1249
  if ((pch - c->virtFolder) == 0) {
@@ -1060,6 +1284,7 @@ VALUE camera_folder_down(VALUE self, VALUE folder) {
1060
1284
  GPhoto2Camera *c;
1061
1285
 
1062
1286
  Data_Get_Struct(self, GPhoto2Camera, c);
1287
+ check_disposed(c);
1063
1288
 
1064
1289
  gp_list_new(&list);
1065
1290
 
@@ -1094,6 +1319,7 @@ VALUE camera_create_folder(VALUE self, VALUE folder) {
1094
1319
  GPhoto2Camera *c;
1095
1320
 
1096
1321
  Data_Get_Struct(self, GPhoto2Camera, c);
1322
+ check_disposed(c);
1097
1323
 
1098
1324
  name = RSTRING_PTR(folder);
1099
1325
  gp_result_check(gp_camera_folder_make_dir(c->camera, c->virtFolder, name, c->context));
@@ -1156,6 +1382,7 @@ VALUE camera_wait(int argc, VALUE *argv, VALUE self) {
1156
1382
  }
1157
1383
 
1158
1384
  Data_Get_Struct(self, GPhoto2Camera, c);
1385
+ check_disposed(c);
1159
1386
  ce = (GPhoto2CameraEvent*) ALLOC(GPhoto2CameraEvent);
1160
1387
 
1161
1388
  // RESULT_CHECK_EVENT(gp_filesystem_reset(c->camera->fs), ce);
data/ext/gphoto2camera.h CHANGED
@@ -42,7 +42,11 @@ void camera_mark(GPhoto2Camera *c);
42
42
  void camera_free(GPhoto2Camera *c);
43
43
  VALUE camera_allocate(VALUE klass);
44
44
 
45
+
46
+
47
+
45
48
  VALUE camera_initialize(int argc, VALUE *argv, VALUE self);
49
+ VALUE camera_dispose(VALUE self);
46
50
  VALUE camera_class_ports(VALUE klass);
47
51
 
48
52
  VALUE camera_capture(int argc, VALUE *argv, VALUE self);
@@ -66,4 +70,9 @@ VALUE camera_create_folder(VALUE self, VALUE folder);
66
70
 
67
71
  VALUE camera_wait(int argc, VALUE *argv, VALUE self);
68
72
 
73
+ VALUE camera_model_name(VALUE self);
74
+ VALUE camera_has_image_capture(VALUE self);
75
+ VALUE camera_has_preview(VALUE self);
76
+ VALUE camera_has_config(VALUE self);
77
+
69
78
  #endif /* _INC_CAMERA */
@@ -35,6 +35,13 @@ int gp_result_check(int retval) {
35
35
  return retval;
36
36
  }
37
37
 
38
+ void check_disposed(GPhoto2Camera* c) {
39
+ if ((*c).disposed) {
40
+ rb_raise(rb_cGPhoto2Exception, "Camera has been disposed");
41
+ }
42
+ }
43
+
44
+
38
45
  VALUE getRadio(CameraWidget *cc) {
39
46
  const char *val;
40
47
 
@@ -272,3 +279,5 @@ void populateWithConfigs(CameraWidget *cc, VALUE hash) {
272
279
  }
273
280
  }
274
281
 
282
+
283
+
@@ -48,12 +48,16 @@ typedef struct {
48
48
 
49
49
  char *virtFolder;
50
50
  char *lastName;
51
+
52
+ CameraAbilities abilities;
53
+ int disposed;
51
54
  } GPhoto2Camera;
52
55
 
53
56
  extern VALUE rb_cGPhoto2Exception;
54
57
 
55
58
  void rb_raise_gp_result(int retval);
56
59
  int gp_result_check(int retval);
60
+ void check_disposed(GPhoto2Camera* c);
57
61
 
58
62
  VALUE getRadio(CameraWidget *cc);
59
63
  VALUE listRadio(CameraWidget *cc);
data/ext/gphoto4ruby.c CHANGED
@@ -85,6 +85,7 @@ void Init_gphoto4ruby() {
85
85
  rb_define_alloc_func(rb_cGPhoto2Camera, camera_allocate);
86
86
  rb_define_module_function(rb_cGPhoto2Camera, "ports", camera_class_ports, 0); /* in gphoto2camera.c */
87
87
  rb_define_method(rb_cGPhoto2Camera, "initialize", camera_initialize, -1); /* in gphoto2camera.c */
88
+ rb_define_method(rb_cGPhoto2Camera, "dispose", camera_dispose, 0); /* in gphoto2camera.c */
88
89
  rb_define_method(rb_cGPhoto2Camera, "config", camera_get_config, -1); /* in gphoto2camera.c */
89
90
  rb_define_method(rb_cGPhoto2Camera, "config_merge", camera_config_merge, 1); /* in gphoto2camera.c */
90
91
  rb_define_method(rb_cGPhoto2Camera, "[]", camera_get_value, -1); /* in gphoto2camera.c */
@@ -103,5 +104,10 @@ void Init_gphoto4ruby() {
103
104
 
104
105
  rb_define_method(rb_cGPhoto2CameraEvent, "type", camera_event_type, 0); /* in gphoto2camera_event.c */
105
106
  rb_define_method(rb_cGPhoto2CameraEvent, "file", camera_event_file, 0); /* in gphoto2camera_event.c */
107
+
108
+ rb_define_method(rb_cGPhoto2Camera, "model_name", camera_model_name, 0); /* in gphoto2camera.c */
109
+ rb_define_method(rb_cGPhoto2Camera, "has_image_capture?", camera_has_image_capture, 0); /* in gphoto2camera.c */
110
+ rb_define_method(rb_cGPhoto2Camera, "has_preview?", camera_has_preview, 0); /* in gphoto2camera.c */
111
+ rb_define_method(rb_cGPhoto2Camera, "has_config?", camera_has_config, 0); /* in gphoto2camera.c */
106
112
  }
107
113
 
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gphoto4ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 4
8
+ - 2
9
+ version: 0.4.2
5
10
  platform: ruby
6
11
  authors:
7
12
  - neq4 company
@@ -10,7 +15,7 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2009-11-06 00:00:00 +03:00
18
+ date: 2010-02-28 00:00:00 +03:00
14
19
  default_executable:
15
20
  dependencies: []
16
21
 
@@ -65,18 +70,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
70
  requirements:
66
71
  - - ">="
67
72
  - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
68
75
  version: "0"
69
- version:
70
76
  required_rubygems_version: !ruby/object:Gem::Requirement
71
77
  requirements:
72
78
  - - ">="
73
79
  - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
74
82
  version: "0"
75
- version:
76
83
  requirements: []
77
84
 
78
85
  rubyforge_project: gphoto4ruby
79
- rubygems_version: 1.3.5
86
+ rubygems_version: 1.3.6
80
87
  signing_key:
81
88
  specification_version: 3
82
89
  summary: GPhoto4Ruby is Ruby wrapping around gphoto2 C library