ffi-gphoto2 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/examples/record_movie.rb +30 -0
- data/lib/ffi/gphoto2.rb +1 -0
- data/lib/gphoto2/camera.rb +63 -11
- data/lib/gphoto2/camera_event.rb +10 -0
- data/lib/gphoto2/camera_file.rb +4 -0
- data/lib/gphoto2/camera_file_path.rb +2 -2
- data/lib/gphoto2/version.rb +1 -1
- data/lib/gphoto2.rb +1 -0
- data/spec/gphoto2/camera_file_spec.rb +8 -0
- data/spec/gphoto2/camera_spec.rb +31 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b41989c0a0a69883e01f7f220c8afc02a7f14a6
|
4
|
+
data.tar.gz: 437b613df85ec51ef13c28b160e0614bd84019ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b0ad2ed9e8ca01acbbee01466196f787e12c2472eefbe5dc51b56ae8abafa1598546310a7dca52eb464d681f688790c8650b950d1459ce40157fc0233430e48
|
7
|
+
data.tar.gz: 9030436814f22ad5d8af8065cb8918c8f7503968afa44d745dd81720a2e4a38097ea21af371b42aa5c75289931cd13704fde8a83136211dd9a0504b57bf62f19
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ canonical Ruby way.
|
|
9
9
|
### Prerequisites
|
10
10
|
|
11
11
|
* Ruby >= 1.9
|
12
|
-
* libgphoto2 >= 2.5.0
|
12
|
+
* libgphoto2 >= 2.5.0
|
13
13
|
|
14
14
|
### Gem
|
15
15
|
|
@@ -79,7 +79,11 @@ canonical Ruby way.
|
|
79
79
|
=> ["DSC_0001.JPG", "DSC_0002.JPG", ...]
|
80
80
|
|
81
81
|
# save a file
|
82
|
-
files.first
|
82
|
+
file = files.first
|
83
|
+
file.save
|
84
|
+
|
85
|
+
# and delete it
|
86
|
+
file.delete
|
83
87
|
|
84
88
|
# close the camera
|
85
89
|
camera.finalize
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# The camera must have a `movie` config key for this to work.
|
2
|
+
#
|
3
|
+
# Unlike capturing photos, which typically save to internal memory, videos
|
4
|
+
# save to the memory card. The next `file_added` event from the camera after
|
5
|
+
# stopping the recording will contain data pointing to the video file.
|
6
|
+
|
7
|
+
require 'gphoto2'
|
8
|
+
|
9
|
+
camera = GPhoto2::Camera.first
|
10
|
+
|
11
|
+
begin
|
12
|
+
# start recording
|
13
|
+
camera.update(movie: true)
|
14
|
+
|
15
|
+
# record for ~10 seconds
|
16
|
+
sleep 10
|
17
|
+
|
18
|
+
# stop recording
|
19
|
+
camera.update(movie: false)
|
20
|
+
|
21
|
+
# wait for the camera to finish with the file
|
22
|
+
begin
|
23
|
+
event = camera.wait
|
24
|
+
end until event.type == :file_added
|
25
|
+
|
26
|
+
# the event data has a camera file that can be saved
|
27
|
+
event.data.save
|
28
|
+
ensure
|
29
|
+
camera.finalize
|
30
|
+
end
|
data/lib/ffi/gphoto2.rb
CHANGED
@@ -52,6 +52,7 @@ module FFI
|
|
52
52
|
attach_function :gp_camera_folder_list_files, [Camera.by_ref, :string, CameraList.by_ref, GPContext.by_ref], :int
|
53
53
|
attach_function :gp_camera_folder_list_folders, [Camera.by_ref, :string, CameraList.by_ref, GPContext.by_ref], :int
|
54
54
|
attach_function :gp_camera_file_get, [Camera.by_ref, :string, :string, CameraFileType, CameraFile.by_ref, GPContext.by_ref], :int
|
55
|
+
attach_function :gp_camera_file_delete, [Camera.by_ref, :string, :string, GPContext.by_ref], :int
|
55
56
|
|
56
57
|
# gphoto2/gphoto2-context.h
|
57
58
|
attach_function :gp_context_new, [], :pointer
|
data/lib/gphoto2/camera.rb
CHANGED
@@ -2,15 +2,18 @@ module GPhoto2
|
|
2
2
|
class Camera
|
3
3
|
include FFI::GPhoto2
|
4
4
|
|
5
|
-
attr_reader :context, :
|
5
|
+
attr_reader :context, :port
|
6
6
|
|
7
7
|
def self.all
|
8
8
|
context = Context.new
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
abilities = CameraAbilitiesList.new(context)
|
11
|
+
cameras = abilities.detect
|
12
12
|
|
13
|
-
entries =
|
13
|
+
entries = cameras.to_a.map do |entry|
|
14
|
+
model, port = entry.name, entry.value
|
15
|
+
Camera.new(port, model)
|
16
|
+
end
|
14
17
|
|
15
18
|
context.finalize
|
16
19
|
|
@@ -23,8 +26,8 @@ module GPhoto2
|
|
23
26
|
entries.first
|
24
27
|
end
|
25
28
|
|
26
|
-
def self.open(
|
27
|
-
camera = new(
|
29
|
+
def self.open(port, model = nil)
|
30
|
+
camera = new(port, model)
|
28
31
|
|
29
32
|
if block_given?
|
30
33
|
begin
|
@@ -41,8 +44,8 @@ module GPhoto2
|
|
41
44
|
all.select { |c| c.model.match(pattern) }
|
42
45
|
end
|
43
46
|
|
44
|
-
def initialize(
|
45
|
-
@
|
47
|
+
def initialize(port, model = nil)
|
48
|
+
@port, @model = port, model
|
46
49
|
@dirty = false
|
47
50
|
end
|
48
51
|
|
@@ -73,6 +76,19 @@ module GPhoto2
|
|
73
76
|
wait_for_event(timeout)
|
74
77
|
end
|
75
78
|
|
79
|
+
def model
|
80
|
+
@model ||= begin
|
81
|
+
abilities = CameraAbilitiesList.new(context).detect
|
82
|
+
cameras = abilities.detect
|
83
|
+
|
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
|
90
|
+
end
|
91
|
+
|
76
92
|
def ptr
|
77
93
|
@ptr || (init && @ptr)
|
78
94
|
end
|
@@ -107,8 +123,12 @@ module GPhoto2
|
|
107
123
|
file_get(file)
|
108
124
|
end
|
109
125
|
|
126
|
+
def delete(file)
|
127
|
+
file_delete(file)
|
128
|
+
end
|
129
|
+
|
110
130
|
def [](key)
|
111
|
-
config[key]
|
131
|
+
config[key.to_s]
|
112
132
|
end
|
113
133
|
|
114
134
|
def []=(key, value)
|
@@ -117,6 +137,14 @@ module GPhoto2
|
|
117
137
|
value
|
118
138
|
end
|
119
139
|
|
140
|
+
def update(attributes = {})
|
141
|
+
attributes.each do |key, value|
|
142
|
+
self[key] = value
|
143
|
+
end
|
144
|
+
|
145
|
+
save
|
146
|
+
end
|
147
|
+
|
120
148
|
def dirty?
|
121
149
|
@dirty
|
122
150
|
end
|
@@ -197,6 +225,11 @@ module GPhoto2
|
|
197
225
|
file
|
198
226
|
end
|
199
227
|
|
228
|
+
def file_delete(file)
|
229
|
+
rc = gp_camera_file_delete(ptr, file.folder, file.name, context.ptr)
|
230
|
+
GPhoto2.check!(rc)
|
231
|
+
end
|
232
|
+
|
200
233
|
def unref
|
201
234
|
rc = gp_camera_unref(ptr)
|
202
235
|
GPhoto2.check!(rc)
|
@@ -210,10 +243,29 @@ module GPhoto2
|
|
210
243
|
data_ptr = FFI::MemoryPointer.new(:pointer)
|
211
244
|
data_ptr.write_pointer(data)
|
212
245
|
|
213
|
-
rc = gp_camera_wait_for_event(ptr, timeout, type,
|
246
|
+
rc = gp_camera_wait_for_event(ptr, timeout, type, data_ptr, context.ptr)
|
214
247
|
GPhoto2.check!(rc)
|
215
248
|
|
216
|
-
CameraEventType[type.read_int]
|
249
|
+
type = CameraEventType[type.read_int]
|
250
|
+
data = data_ptr.read_pointer
|
251
|
+
|
252
|
+
data =
|
253
|
+
case type
|
254
|
+
when :unknown
|
255
|
+
data.null? ? nil : data.read_string
|
256
|
+
when :file_added
|
257
|
+
path_ptr = FFI::GPhoto2::CameraFilePath.new(data)
|
258
|
+
path = CameraFilePath.new(path_ptr)
|
259
|
+
CameraFile.new(self, path.folder, path.name)
|
260
|
+
when :folder_added
|
261
|
+
path_ptr = FFI::GPhoto2::CameraFilePath.new(data)
|
262
|
+
path = CameraFilePath.new(path_ptr)
|
263
|
+
CameraFolder.new(self, '%s/%s' % [path.folder, path.name])
|
264
|
+
else
|
265
|
+
nil
|
266
|
+
end
|
267
|
+
|
268
|
+
CameraEvent.new(type, data)
|
217
269
|
end
|
218
270
|
end
|
219
271
|
end
|
data/lib/gphoto2/camera_file.rb
CHANGED
data/lib/gphoto2/version.rb
CHANGED
data/lib/gphoto2.rb
CHANGED
@@ -17,6 +17,7 @@ require 'gphoto2/camera_widgets/window_camera_widget'
|
|
17
17
|
require 'gphoto2/camera'
|
18
18
|
require 'gphoto2/camera_abilities'
|
19
19
|
require 'gphoto2/camera_abilities_list'
|
20
|
+
require 'gphoto2/camera_event'
|
20
21
|
require 'gphoto2/camera_file'
|
21
22
|
require 'gphoto2/camera_file_path'
|
22
23
|
require 'gphoto2/camera_folder'
|
@@ -52,6 +52,14 @@ module GPhoto2
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
describe '#delete' do
|
56
|
+
it 'delegates the deletion of the file to the camera' do
|
57
|
+
file = CameraFile.new(camera, folder, name)
|
58
|
+
expect(camera).to receive(:delete).with(file)
|
59
|
+
file.delete
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
55
63
|
describe '#data' do
|
56
64
|
it 'returns the data of the camera file' do
|
57
65
|
file = CameraFile.new(camera, folder, name)
|
data/spec/gphoto2/camera_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module GPhoto2
|
4
4
|
describe Camera do
|
5
|
-
let(:port) {
|
5
|
+
let(:port) { 'usb:250,006' }
|
6
6
|
|
7
7
|
describe '.all' do
|
8
8
|
let(:abilities_list) { double('camera_abilities_list') }
|
@@ -13,7 +13,7 @@ module GPhoto2
|
|
13
13
|
Context.stub(:stub)
|
14
14
|
CameraAbilitiesList.stub(:new).and_return(abilities_list)
|
15
15
|
abilities_list.stub(:detect).and_return(camera_list)
|
16
|
-
camera_list.
|
16
|
+
camera_list.stub_chain(:to_a, :map).and_return([camera])
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'returns a list of device entries' do
|
@@ -192,6 +192,15 @@ module GPhoto2
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
+
describe '#delete' do
|
196
|
+
it 'deletes a file from the camera' do
|
197
|
+
camera = Camera.new(port)
|
198
|
+
camera.stub(:file_delete)
|
199
|
+
expect(camera).to receive(:file_delete)
|
200
|
+
camera.delete(double('camera_file'))
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
195
204
|
describe '#[]' do
|
196
205
|
let(:window) { double('camera_widget') }
|
197
206
|
|
@@ -227,7 +236,7 @@ module GPhoto2
|
|
227
236
|
camera
|
228
237
|
end
|
229
238
|
|
230
|
-
it "
|
239
|
+
it "sets a widget's value" do
|
231
240
|
camera['iso'] = 400
|
232
241
|
end
|
233
242
|
|
@@ -241,6 +250,25 @@ module GPhoto2
|
|
241
250
|
end
|
242
251
|
end
|
243
252
|
|
253
|
+
describe '#update' do
|
254
|
+
let(:camera) do
|
255
|
+
camera = Camera.new(port)
|
256
|
+
camera.stub(:[]=)
|
257
|
+
camera.stub(:save)
|
258
|
+
camera
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'sets one or more camera setting' do
|
262
|
+
expect(camera).to receive(:[]=).exactly(2).times
|
263
|
+
camera.update('iso' => 400, 'shutterspeed2' => '1/30')
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'immediately saves the settings to the camera' do
|
267
|
+
expect(camera).to receive(:save)
|
268
|
+
camera.update
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
244
272
|
describe '#dirty?' do
|
245
273
|
context 'when the configuration changed' do
|
246
274
|
it 'returns true' do
|
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.
|
4
|
+
version: 0.3.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-
|
11
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- Rakefile
|
82
82
|
- examples/intervalometer.rb
|
83
83
|
- examples/live_view.rb
|
84
|
+
- examples/record_movie.rb
|
84
85
|
- ffi-gphoto2.gemspec
|
85
86
|
- lib/ffi/gphoto2.rb
|
86
87
|
- lib/ffi/gphoto2/camera.rb
|
@@ -111,6 +112,7 @@ files:
|
|
111
112
|
- lib/gphoto2/camera.rb
|
112
113
|
- lib/gphoto2/camera_abilities.rb
|
113
114
|
- lib/gphoto2/camera_abilities_list.rb
|
115
|
+
- lib/gphoto2/camera_event.rb
|
114
116
|
- lib/gphoto2/camera_file.rb
|
115
117
|
- lib/gphoto2/camera_file_path.rb
|
116
118
|
- lib/gphoto2/camera_folder.rb
|