ffi-gphoto2 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b41989c0a0a69883e01f7f220c8afc02a7f14a6
4
- data.tar.gz: 437b613df85ec51ef13c28b160e0614bd84019ff
3
+ metadata.gz: f540e98f060027da7173c2025502331090f5a24c
4
+ data.tar.gz: 27555b84f07e26724da18c72500e6c7483ec6916
5
5
  SHA512:
6
- metadata.gz: 7b0ad2ed9e8ca01acbbee01466196f787e12c2472eefbe5dc51b56ae8abafa1598546310a7dca52eb464d681f688790c8650b950d1459ce40157fc0233430e48
7
- data.tar.gz: 9030436814f22ad5d8af8065cb8918c8f7503968afa44d745dd81720a2e4a38097ea21af371b42aa5c75289931cd13704fde8a83136211dd9a0504b57bf62f19
6
+ metadata.gz: f7fc0ad08a779b3de0b29a54b2624b367a350b4203b7ab174e1089955fd171a67645943227954fd78730a95eb4754a572bed4a788a35aba51bf654b567aff31f
7
+ data.tar.gz: 355b62d70d3c67322631093a1c4d32ee84bdcfbd5bd2b5ba1eafda2171e99d9e38245c799b1daed6c1e59795d0514f0d6406098c58f9cd7dd92aa3163a013e0a
data/README.md CHANGED
@@ -36,6 +36,10 @@ canonical Ruby way.
36
36
  # ...or even search by model name
37
37
  camera = GPhoto2::Camera.where(/nikon/i).first
38
38
 
39
+ # check camera abilities
40
+ camera.can? :capture_image
41
+ # => true
42
+
39
43
  # list camera configuration names
40
44
  camera.config.keys
41
45
  # => ['autofocusdrive', 'manualfocusdrive', 'controlmode', ...]
@@ -0,0 +1,37 @@
1
+ require 'gphoto2'
2
+
3
+ def visit(widget, level = 0)
4
+ indent = ' ' * level
5
+
6
+ puts "#{indent}#{widget.name}"
7
+
8
+ if widget.type == :window || widget.type == :section
9
+ widget.children.each { |child| visit(child, level + 1) }
10
+ return
11
+ end
12
+
13
+ indent << ' '
14
+
15
+ puts "#{indent}type: #{widget.type}"
16
+
17
+ return if widget.type == :menu
18
+
19
+ puts "#{indent}value: #{widget.value}"
20
+
21
+ case widget.type
22
+ when :range
23
+ range = widget.range
24
+ step = (range.size > 1) ? range[1] - range[0] : 1.0
25
+ puts "#{indent}options: #{range.first}..#{range.last}:step(#{step})"
26
+ when :radio
27
+ puts "#{indent}options: #{widget.choices.inspect}"
28
+ end
29
+ end
30
+
31
+ camera = GPhoto2::Camera.first
32
+
33
+ begin
34
+ visit(camera.window)
35
+ ensure
36
+ camera.finalize
37
+ end
@@ -18,10 +18,8 @@ begin
18
18
  # stop recording
19
19
  camera.update(movie: false)
20
20
 
21
- # wait for the camera to finish with the file
22
- begin
23
- event = camera.wait
24
- end until event.type == :file_added
21
+ # block until the camera finishes with the file
22
+ event = camera.wait_for(:file_added)
25
23
 
26
24
  # the event data has a camera file that can be saved
27
25
  event.data.save
@@ -2,7 +2,7 @@ module GPhoto2
2
2
  class Camera
3
3
  include FFI::GPhoto2
4
4
 
5
- attr_reader :context, :port
5
+ attr_reader :context, :model, :port
6
6
 
7
7
  def self.all
8
8
  context = Context.new
@@ -12,7 +12,7 @@ module GPhoto2
12
12
 
13
13
  entries = cameras.to_a.map do |entry|
14
14
  model, port = entry.name, entry.value
15
- Camera.new(port, model)
15
+ Camera.new(model, port)
16
16
  end
17
17
 
18
18
  context.finalize
@@ -26,8 +26,8 @@ module GPhoto2
26
26
  entries.first
27
27
  end
28
28
 
29
- def self.open(port, model = nil)
30
- camera = new(port, model)
29
+ def self.open(model, port)
30
+ camera = new(model, port)
31
31
 
32
32
  if block_given?
33
33
  begin
@@ -40,12 +40,14 @@ module GPhoto2
40
40
  end
41
41
  end
42
42
 
43
- def self.where(pattern)
44
- all.select { |c| c.model.match(pattern) }
43
+ def self.where(condition)
44
+ name = condition.keys.first
45
+ pattern = condition.values.first
46
+ all.select { |c| c.send(name).match(pattern) }
45
47
  end
46
48
 
47
- def initialize(port, model = nil)
48
- @port, @model = port, model
49
+ def initialize(model, port)
50
+ @model, @port = model, port
49
51
  @dirty = false
50
52
  end
51
53
 
@@ -76,17 +78,12 @@ module GPhoto2
76
78
  wait_for_event(timeout)
77
79
  end
78
80
 
79
- def model
80
- @model ||= begin
81
- abilities = CameraAbilitiesList.new(context).detect
82
- cameras = abilities.detect
81
+ def wait_for(event_type)
82
+ begin
83
+ event = wait
84
+ end until event.type == event_type
83
85
 
84
- entry = cameras.map(&:value).find { |port| port == @port }
85
-
86
- raise RuntimeError, "no camera found on port #{@port}" if entry.nil?
87
-
88
- entry.name
89
- end
86
+ event
90
87
  end
91
88
 
92
89
  def ptr
@@ -149,6 +146,10 @@ module GPhoto2
149
146
  @dirty
150
147
  end
151
148
 
149
+ def can?(operation)
150
+ (abilities[:operations] & CameraOperation[operation]) != 0
151
+ end
152
+
152
153
  def save
153
154
  return false unless dirty?
154
155
  set_config
@@ -41,7 +41,7 @@ module GPhoto2
41
41
  def children
42
42
  count_children.times.map { |i| get_child(i) }
43
43
  end
44
-
44
+
45
45
  def flatten(map = {})
46
46
  case type
47
47
  when :window, :section
@@ -10,5 +10,11 @@ module GPhoto2
10
10
  GPhoto2.check!(rc)
11
11
  val_ptr.read_pointer.read_string
12
12
  end
13
+
14
+ def set_value(text)
15
+ val = FFI::MemoryPointer.from_string(text)
16
+ rc = gp_widget_set_value(ptr, val)
17
+ GPhoto2.check!(rc)
18
+ end
13
19
  end
14
20
  end
@@ -5,6 +5,7 @@ module GPhoto2
5
5
  def get_value
6
6
  val = FFI::MemoryPointer.new(:int)
7
7
  rc = gp_widget_get_value(ptr, val)
8
+ GPhoto2.check!(rc)
8
9
  (val.read_int == 1)
9
10
  end
10
11
 
@@ -1,3 +1,3 @@
1
1
  module GPhoto2
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -2,12 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  module GPhoto2
4
4
  describe Camera do
5
+ let(:model) { 'Nikon DSC D5100 (PTP mode)' }
5
6
  let(:port) { 'usb:250,006' }
6
7
 
7
8
  describe '.all' do
8
9
  let(:abilities_list) { double('camera_abilities_list') }
9
10
  let(:camera_list) { double('camera_list') }
10
- let(:camera) { Camera.new(port) }
11
+ let(:camera) { Camera.new(model, port) }
11
12
 
12
13
  before do
13
14
  Context.stub(:stub)
@@ -26,7 +27,7 @@ module GPhoto2
26
27
  describe '.first' do
27
28
  context 'when devices are automatically detected' do
28
29
  it 'returns a new Camera using the first entry' do
29
- camera = Camera.new(port)
30
+ camera = Camera.new(model, port)
30
31
  Camera.stub(:all).and_return([camera])
31
32
  expect(Camera.first).to be_kind_of(Camera)
32
33
  end
@@ -47,33 +48,51 @@ module GPhoto2
47
48
  context 'when a block is given' do
48
49
  it 'yeilds a new camera instance' do
49
50
  expect(Camera).to receive(:open).and_yield(camera)
50
- Camera.open(port) { |c| }
51
+ Camera.open(model, port) { |c| }
51
52
  end
52
53
 
53
54
  it 'finalizes the camera when the block terminates' do
54
55
  expect(camera).to receive(:finalize)
55
- Camera.open(port) { |c| }
56
+ Camera.open(model, port) { |c| }
56
57
  end
57
58
  end
58
59
 
59
60
  context 'when no block is given' do
60
61
  it 'returns a new camera instance' do
61
- expect(Camera.open(port)).to eq(camera)
62
+ expect(Camera.open(model, port)).to eq(camera)
62
63
  end
63
64
  end
64
65
  end
65
66
 
66
67
  describe '.where' do
67
- it 'filters all detected cameras by model' do
68
- cameras = %w[cheese toast wine].map { |model| double('camera', model: model) }
68
+ let(:cameras) do
69
+ cameras = []
70
+ cameras << double('camera', model: 'Canon EOS 5D Mark III', port: 'usb:250,004')
71
+ cameras << double('camera', model: 'Nikon DSC D800', port: 'usb:250,005')
72
+ cameras << double('camera', model: 'Nikon DSC D5100', port: 'usb:250,006')
73
+ cameras
74
+ end
75
+
76
+ before do
69
77
  Camera.stub(:all).and_return(cameras)
70
- expect(Camera.where(/e/)).to match_array([cameras[0], cameras[2]])
78
+ end
79
+
80
+ it 'filters all detected cameras by model' do
81
+ actual = Camera.where(model: /nikon/i)
82
+ expected = [cameras[1], cameras[2]]
83
+ expect(actual).to match_array(expected)
84
+ end
85
+
86
+ it 'filters all detected cameras by port' do
87
+ actual = Camera.where(port: 'usb:250,004')
88
+ expected = [cameras[0]]
89
+ expect(actual).to match_array(expected)
71
90
  end
72
91
  end
73
92
 
74
93
  describe '#exit' do
75
94
  it 'closes the camera connection' do
76
- camera = Camera.new(port)
95
+ camera = Camera.new(model, port)
77
96
  camera.stub(:_exit)
78
97
  expect(camera).to receive(:_exit)
79
98
  camera.exit
@@ -81,7 +100,7 @@ module GPhoto2
81
100
  end
82
101
 
83
102
  describe '#capture' do
84
- let(:camera) { Camera.new(port) }
103
+ let(:camera) { Camera.new(model, port) }
85
104
  let(:path) { double('camera_file_path', folder: 'folder', name: 'name') }
86
105
 
87
106
  before do
@@ -100,7 +119,7 @@ module GPhoto2
100
119
  end
101
120
 
102
121
  describe '#preview' do
103
- let(:camera) { Camera.new(port) }
122
+ let(:camera) { Camera.new(model, port) }
104
123
  let(:file) { double('camera_file') }
105
124
 
106
125
  before do
@@ -119,8 +138,8 @@ module GPhoto2
119
138
  end
120
139
 
121
140
  describe '#wait' do
122
- let(:camera) { Camera.new(port) }
123
- let(:event) { :capture_complete }
141
+ let(:camera) { Camera.new(model, port) }
142
+ let(:event) { double('camera_event') }
124
143
 
125
144
  before do
126
145
  camera.stub(:wait_for_event).and_return(event)
@@ -136,8 +155,26 @@ module GPhoto2
136
155
  end
137
156
  end
138
157
 
158
+ describe '#wait_for' do
159
+ let(:camera) { Camera.new(model, port) }
160
+ let(:event) { double('camera_event', type: :capture_complete) }
161
+
162
+ before do
163
+ camera.stub(:wait).and_return(event)
164
+ end
165
+
166
+ it 'blocks until a given event is returned from #wait' do
167
+ expect(camera).to receive(:wait)
168
+ camera.wait_for(:capture_complete)
169
+ end
170
+
171
+ it 'returns the first event of the given type' do
172
+ expect(camera.wait_for(:capture_complete)).to eq(event)
173
+ end
174
+ end
175
+
139
176
  describe '#window' do
140
- let(:camera) { Camera.new(port) }
177
+ let(:camera) { Camera.new(model, port) }
141
178
  let(:window) { double('camera_widget') }
142
179
 
143
180
  it 'always returns the same CameraWidget instance' do
@@ -149,7 +186,7 @@ module GPhoto2
149
186
 
150
187
  describe '#config' do
151
188
  it 'returns a map of configuration widgets' do
152
- camera = Camera.new(port)
189
+ camera = Camera.new(model, port)
153
190
  window = double('camera_widget')
154
191
  camera.stub(:window).and_return(window)
155
192
  window.stub(:flatten).and_return({ 'iso' => window })
@@ -159,7 +196,7 @@ module GPhoto2
159
196
  end
160
197
 
161
198
  describe '#filesystem' do
162
- let(:camera) { Camera.new(port) }
199
+ let(:camera) { Camera.new(model, port) }
163
200
 
164
201
  context 'when a path is passed' do
165
202
  let(:path) { '/store_00010001' }
@@ -185,7 +222,7 @@ module GPhoto2
185
222
 
186
223
  describe '#file' do
187
224
  it 'retrieves a file from the camera' do
188
- camera = Camera.new(port)
225
+ camera = Camera.new(model, port)
189
226
  camera.stub(:file_get)
190
227
  expect(camera).to receive(:file_get)
191
228
  camera.file(double('camera_file'))
@@ -194,7 +231,7 @@ module GPhoto2
194
231
 
195
232
  describe '#delete' do
196
233
  it 'deletes a file from the camera' do
197
- camera = Camera.new(port)
234
+ camera = Camera.new(model, port)
198
235
  camera.stub(:file_delete)
199
236
  expect(camera).to receive(:file_delete)
200
237
  camera.delete(double('camera_file'))
@@ -205,7 +242,7 @@ module GPhoto2
205
242
  let(:window) { double('camera_widget') }
206
243
 
207
244
  let(:camera) do
208
- camera = Camera.new(port)
245
+ camera = Camera.new(model, port)
209
246
  camera.stub(:config).and_return({ 'iso' => window })
210
247
  camera
211
248
  end
@@ -231,7 +268,7 @@ module GPhoto2
231
268
  end
232
269
 
233
270
  let(:camera) do
234
- camera = Camera.new(port)
271
+ camera = Camera.new(model, port)
235
272
  camera.stub(:[]).and_return(window)
236
273
  camera
237
274
  end
@@ -252,7 +289,7 @@ module GPhoto2
252
289
 
253
290
  describe '#update' do
254
291
  let(:camera) do
255
- camera = Camera.new(port)
292
+ camera = Camera.new(model, port)
256
293
  camera.stub(:[]=)
257
294
  camera.stub(:save)
258
295
  camera
@@ -272,7 +309,7 @@ module GPhoto2
272
309
  describe '#dirty?' do
273
310
  context 'when the configuration changed' do
274
311
  it 'returns true' do
275
- camera = Camera.new(port)
312
+ camera = Camera.new(model, port)
276
313
  camera.stub_chain(:[], :value=)
277
314
 
278
315
  camera['iso'] = 400
@@ -283,15 +320,38 @@ module GPhoto2
283
320
 
284
321
  context 'when the configuration has not changed' do
285
322
  it 'returns false' do
286
- camera = Camera.new(port)
323
+ camera = Camera.new(model, port)
287
324
  expect(camera).not_to be_dirty
288
325
  end
289
326
  end
290
327
  end
291
328
 
329
+ describe '#can?' do
330
+ let(:camera) { Camera.new(model, port) }
331
+ let(:operations) { FFI::GPhoto2::CameraOperation[:capture_image] }
332
+
333
+ before do
334
+ camera.stub_chain(:abilities, :[])
335
+ .with(:operations)
336
+ .and_return(operations)
337
+ end
338
+
339
+ context 'when the camera does not have the ability perform an operation' do
340
+ it 'return false' do
341
+ expect(camera.can?(:capture_audio)).to be_false
342
+ end
343
+ end
344
+
345
+ context 'when the camera does have the ability to perform an operation' do
346
+ it 'returns true' do
347
+ expect(camera.can?(:capture_image)).to be_true
348
+ end
349
+ end
350
+ end
351
+
292
352
  describe '#save' do
293
353
  let(:camera) do
294
- camera = Camera.new(port)
354
+ camera = Camera.new(model, port)
295
355
  camera.stub_chain(:[], :value=)
296
356
  camera.stub(:set_config)
297
357
  camera
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-gphoto2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Macias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-05 00:00:00.000000000 Z
11
+ date: 2013-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,7 @@ files:
80
80
  - README.md
81
81
  - Rakefile
82
82
  - examples/intervalometer.rb
83
+ - examples/list_config.rb
83
84
  - examples/live_view.rb
84
85
  - examples/record_movie.rb
85
86
  - ffi-gphoto2.gemspec
@@ -171,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
172
  requirements:
172
173
  - libgphoto2 >= 2.5.0
173
174
  rubyforge_project:
174
- rubygems_version: 2.0.3
175
+ rubygems_version: 2.0.7
175
176
  signing_key:
176
177
  specification_version: 4
177
178
  summary: A Ruby FFI for common functions in libgphoto2