ffi-gphoto2 0.2.0

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +90 -0
  7. data/Rakefile +6 -0
  8. data/examples/intervalometer.rb +12 -0
  9. data/examples/live_view.rb +21 -0
  10. data/ffi-gphoto2.gemspec +30 -0
  11. data/lib/ffi/gphoto2.rb +85 -0
  12. data/lib/ffi/gphoto2/camera.rb +12 -0
  13. data/lib/ffi/gphoto2/camera_abilities.rb +37 -0
  14. data/lib/ffi/gphoto2/camera_abilities_list.rb +15 -0
  15. data/lib/ffi/gphoto2/camera_capture_type.rb +8 -0
  16. data/lib/ffi/gphoto2/camera_driver_status.rb +9 -0
  17. data/lib/ffi/gphoto2/camera_event_type.rb +10 -0
  18. data/lib/ffi/gphoto2/camera_file.rb +28 -0
  19. data/lib/ffi/gphoto2/camera_file_access_type.rb +8 -0
  20. data/lib/ffi/gphoto2/camera_file_operation.rb +11 -0
  21. data/lib/ffi/gphoto2/camera_file_path.rb +9 -0
  22. data/lib/ffi/gphoto2/camera_file_type.rb +11 -0
  23. data/lib/ffi/gphoto2/camera_folder_operation.rb +10 -0
  24. data/lib/ffi/gphoto2/camera_list.rb +15 -0
  25. data/lib/ffi/gphoto2/camera_operation.rb +12 -0
  26. data/lib/ffi/gphoto2/camera_widget.rb +33 -0
  27. data/lib/ffi/gphoto2/camera_widget_type.rb +14 -0
  28. data/lib/ffi/gphoto2/entry.rb +9 -0
  29. data/lib/ffi/gphoto2/gp_context.rb +31 -0
  30. data/lib/ffi/gphoto2/gphoto_device_type.rb +7 -0
  31. data/lib/ffi/gphoto2_port.rb +31 -0
  32. data/lib/ffi/gphoto2_port/gp_port_info.rb +11 -0
  33. data/lib/ffi/gphoto2_port/gp_port_info_list.rb +14 -0
  34. data/lib/ffi/gphoto2_port/gp_port_result.rb +35 -0
  35. data/lib/ffi/gphoto2_port/gp_port_type.rb +12 -0
  36. data/lib/gphoto2.rb +41 -0
  37. data/lib/gphoto2/camera.rb +219 -0
  38. data/lib/gphoto2/camera_abilities.rb +44 -0
  39. data/lib/gphoto2/camera_abilities_list.rb +64 -0
  40. data/lib/gphoto2/camera_file.rb +69 -0
  41. data/lib/gphoto2/camera_file_path.rb +21 -0
  42. data/lib/gphoto2/camera_folder.rb +82 -0
  43. data/lib/gphoto2/camera_list.rb +43 -0
  44. data/lib/gphoto2/camera_widgets/camera_widget.rb +112 -0
  45. data/lib/gphoto2/camera_widgets/date_camera_widget.rb +19 -0
  46. data/lib/gphoto2/camera_widgets/menu_camera_widget.rb +4 -0
  47. data/lib/gphoto2/camera_widgets/radio_camera_widget.rb +41 -0
  48. data/lib/gphoto2/camera_widgets/range_camera_widget.rb +37 -0
  49. data/lib/gphoto2/camera_widgets/section_camera_widget.rb +4 -0
  50. data/lib/gphoto2/camera_widgets/text_camera_widget.rb +14 -0
  51. data/lib/gphoto2/camera_widgets/toggle_camera_widget.rb +18 -0
  52. data/lib/gphoto2/camera_widgets/window_camera_widget.rb +4 -0
  53. data/lib/gphoto2/context.rb +31 -0
  54. data/lib/gphoto2/entry.rb +38 -0
  55. data/lib/gphoto2/port_info.rb +70 -0
  56. data/lib/gphoto2/port_info_list.rb +46 -0
  57. data/lib/gphoto2/port_result.rb +7 -0
  58. data/lib/gphoto2/version.rb +3 -0
  59. data/spec/gphoto2/camera_abilities_list_spec.rb +45 -0
  60. data/spec/gphoto2/camera_abilities_spec.rb +38 -0
  61. data/spec/gphoto2/camera_file_path_spec.rb +27 -0
  62. data/spec/gphoto2/camera_file_spec.rb +71 -0
  63. data/spec/gphoto2/camera_folder_spec.rb +110 -0
  64. data/spec/gphoto2/camera_list_spec.rb +35 -0
  65. data/spec/gphoto2/camera_spec.rb +292 -0
  66. data/spec/gphoto2/camera_widgets/date_camera_widget_spec.rb +15 -0
  67. data/spec/gphoto2/camera_widgets/radio_camera_widget_spec.rb +31 -0
  68. data/spec/gphoto2/camera_widgets/range_camera_widget_spec.rb +27 -0
  69. data/spec/gphoto2/camera_widgets/text_camera_widget_spec.rb +15 -0
  70. data/spec/gphoto2/camera_widgets/toggle_camera_widget_spec.rb +21 -0
  71. data/spec/gphoto2/context_spec.rb +17 -0
  72. data/spec/gphoto2/entry_spec.rb +27 -0
  73. data/spec/gphoto2/port_info_list_spec.rb +33 -0
  74. data/spec/gphoto2/port_info_spec.rb +53 -0
  75. data/spec/spec_helper.rb +12 -0
  76. data/spec/support/shared_examples/camera_widget_examples.rb +89 -0
  77. metadata +194 -0
@@ -0,0 +1,44 @@
1
+ module GPhoto2
2
+ class CameraAbilities
3
+ include FFI::GPhoto2
4
+
5
+ attr_reader :ptr
6
+
7
+ def self.find(model)
8
+ context = Context.new
9
+
10
+ camera_abilities_list = CameraAbilitiesList.new(context)
11
+ index = camera_abilities_list.lookup_model(model)
12
+ abilities = camera_abilities_list[index]
13
+
14
+ context.finalize
15
+
16
+ abilities
17
+ end
18
+
19
+ def initialize(camera_abilities_list, index)
20
+ @camera_abilities_list = camera_abilities_list
21
+ @index = index
22
+ get_abilities
23
+ end
24
+
25
+ def [](field)
26
+ ptr[field]
27
+ end
28
+
29
+ def to_ptr
30
+ @ptr
31
+ end
32
+
33
+ private
34
+
35
+ def get_abilities
36
+ ptr = FFI::GPhoto2::CameraAbilities.new
37
+ rc = gp_abilities_list_get_abilities(@camera_abilities_list.ptr,
38
+ @index,
39
+ ptr)
40
+ GPhoto2.check!(rc)
41
+ @ptr = ptr
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,64 @@
1
+ module GPhoto2
2
+ class CameraAbilitiesList
3
+ include FFI::GPhoto2
4
+
5
+ attr_reader :ptr
6
+
7
+ def initialize(context)
8
+ @context = context
9
+ new
10
+ load
11
+ end
12
+
13
+ def detect
14
+ _detect
15
+ end
16
+
17
+ def lookup_model(model)
18
+ _lookup_model(model)
19
+ end
20
+ alias_method :index, :lookup_model
21
+
22
+ def at(index)
23
+ CameraAbilities.new(self, index)
24
+ end
25
+ alias_method :[], :at
26
+
27
+ def to_ptr
28
+ @ptr
29
+ end
30
+
31
+ private
32
+
33
+ def new
34
+ ptr = FFI::MemoryPointer.new(FFI::GPhoto2::CameraAbilitiesList)
35
+ rc = gp_abilities_list_new(ptr)
36
+ GPhoto2.check!(rc)
37
+ @ptr = FFI::GPhoto2::CameraAbilitiesList.new(ptr.read_pointer)
38
+ end
39
+
40
+ def load
41
+ rc = gp_abilities_list_load(ptr, @context.ptr)
42
+ GPhoto2.check!(rc)
43
+ end
44
+
45
+ def _detect
46
+ port_info_list = PortInfoList.new
47
+ camera_list = CameraList.new
48
+
49
+ rc = gp_abilities_list_detect(ptr,
50
+ port_info_list.ptr,
51
+ camera_list.ptr,
52
+ @context.ptr)
53
+ GPhoto2.check!(rc)
54
+
55
+ camera_list
56
+ end
57
+
58
+ def _lookup_model(model)
59
+ index = rc = gp_abilities_list_lookup_model(ptr, model)
60
+ GPhoto2.check!(rc)
61
+ index
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,69 @@
1
+ module GPhoto2
2
+ class CameraFile
3
+ include FFI::GPhoto2
4
+
5
+ attr_reader :folder, :name, :ptr
6
+
7
+ def initialize(camera, folder = nil, name = nil)
8
+ @camera = camera
9
+ @folder, @name = folder, name
10
+ new
11
+ end
12
+
13
+ def preview?
14
+ @folder.nil? && @name.nil?
15
+ end
16
+
17
+ def save(pathname = default_filename)
18
+ File.binwrite(pathname, data)
19
+ end
20
+
21
+ def data
22
+ data_and_size.first
23
+ end
24
+
25
+ def size
26
+ data_and_size.last
27
+ end
28
+
29
+ def to_ptr
30
+ @ptr
31
+ end
32
+
33
+ private
34
+
35
+ def data_and_size
36
+ @data_and_size ||= begin
37
+ @camera.file(self) unless preview?
38
+ get_data_and_size
39
+ end
40
+ end
41
+
42
+ def default_filename
43
+ # previews are always jpg
44
+ preview? ? 'capture_preview.jpg' : @name
45
+ end
46
+
47
+ def new
48
+ ptr = FFI::MemoryPointer.new(FFI::GPhoto2::CameraFile)
49
+ rc = gp_file_new(ptr)
50
+ GPhoto2.check!(rc)
51
+ @ptr = FFI::GPhoto2::CameraFile.new(ptr.read_pointer)
52
+ end
53
+
54
+ def get_data_and_size
55
+ data = FFI::MemoryPointer.new(:uchar)
56
+ data_ptr = FFI::MemoryPointer.new(:pointer)
57
+ data_ptr.write_pointer(data)
58
+ size = FFI::MemoryPointer.new(:ulong)
59
+
60
+ rc = gp_file_get_data_and_size(ptr, data_ptr, size)
61
+ GPhoto2.check!(rc)
62
+
63
+ size = size.read_ulong
64
+ data = data_ptr.read_pointer.read_bytes(size)
65
+
66
+ [data, size]
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,21 @@
1
+ module GPhoto2
2
+ class CameraFilePath
3
+ attr_reader :ptr
4
+
5
+ def initialize
6
+ @ptr = FFI::GPhoto2::CameraFilePath.new
7
+ end
8
+
9
+ def name
10
+ ptr[:name].to_s
11
+ end
12
+
13
+ def folder
14
+ ptr[:folder].to_s
15
+ end
16
+
17
+ def to_ptr
18
+ @ptr
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ module GPhoto2
2
+ class CameraFolder
3
+ include FFI::GPhoto2
4
+
5
+ attr_reader :path
6
+
7
+ def initialize(camera, path = '/')
8
+ @camera = camera
9
+ @path = path
10
+ end
11
+
12
+ def root?
13
+ @path == '/'
14
+ end
15
+
16
+ def name
17
+ if root?
18
+ '/'
19
+ else
20
+ @path.rpartition('/').last
21
+ end
22
+ end
23
+
24
+ def folders
25
+ folder_list_folders
26
+ end
27
+
28
+ def files
29
+ folder_list_files
30
+ end
31
+
32
+ def cd(name)
33
+ case name
34
+ when '.'
35
+ self
36
+ when '..'
37
+ up
38
+ else
39
+ CameraFolder.new(@camera, File.join(@path, name))
40
+ end
41
+ end
42
+ alias_method :/, :cd
43
+
44
+ def open(name)
45
+ CameraFile.new(@camera, @path, name)
46
+ end
47
+
48
+ def up
49
+ if root?
50
+ self
51
+ else
52
+ parent = @path.rpartition('/').first
53
+ parent = '/' if parent.empty?
54
+ CameraFolder.new(@camera, parent)
55
+ end
56
+ end
57
+
58
+ def to_s
59
+ name
60
+ end
61
+
62
+ private
63
+
64
+ def folder_list_files
65
+ list = CameraList.new
66
+
67
+ rc = gp_camera_folder_list_files(@camera.ptr, @path, list.ptr, @camera.context.ptr)
68
+ GPhoto2.check!(rc)
69
+
70
+ list.to_a.map { |f| open(f.name) }
71
+ end
72
+
73
+ def folder_list_folders
74
+ list = CameraList.new
75
+
76
+ rc = gp_camera_folder_list_folders(@camera.ptr, @path, list.ptr, @camera.context.ptr)
77
+ GPhoto2.check!(rc)
78
+
79
+ list.to_a.map { |f| cd(f.name) }
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,43 @@
1
+ module GPhoto2
2
+ class CameraList
3
+ include FFI::GPhoto2
4
+
5
+ attr_reader :ptr
6
+
7
+ def initialize
8
+ new
9
+ end
10
+
11
+ def finalize
12
+ free
13
+ end
14
+
15
+ def size
16
+ count
17
+ end
18
+ alias_method :length, :size
19
+
20
+ def to_a
21
+ size.times.map { |i| Entry.new(self, i) }
22
+ end
23
+
24
+ def to_ptr
25
+ @ptr
26
+ end
27
+
28
+ private
29
+
30
+ def new
31
+ ptr = FFI::MemoryPointer.new(FFI::GPhoto2::CameraList)
32
+ rc = gp_list_new(ptr)
33
+ GPhoto2.check!(rc)
34
+ @ptr = FFI::GPhoto2::CameraList.new(ptr.read_pointer)
35
+ end
36
+
37
+ def count
38
+ rc = gp_list_count(ptr)
39
+ GPhoto2.check!(rc)
40
+ rc
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,112 @@
1
+ module GPhoto2
2
+ class CameraWidget
3
+ include FFI::GPhoto2
4
+
5
+ attr_reader :ptr
6
+
7
+ def self.factory(ptr, parent = nil)
8
+ # ptr fields are supposed to be private, but we ignore that here
9
+ type = ptr[:type].to_s.split('_').last.capitalize
10
+ klass = GPhoto2.const_get("#{type}CameraWidget")
11
+ klass.new(ptr, parent)
12
+ end
13
+
14
+ def initialize(ptr, parent = nil)
15
+ @ptr = ptr
16
+ @parent = parent
17
+ end
18
+
19
+ def finalize
20
+ free
21
+ end
22
+ alias_method :close, :finalize
23
+
24
+ def name
25
+ get_name
26
+ end
27
+
28
+ def value
29
+ get_value
30
+ end
31
+
32
+ def value=(value)
33
+ set_value(value)
34
+ value
35
+ end
36
+
37
+ def type
38
+ get_type
39
+ end
40
+
41
+ def children
42
+ count_children.times.map { |i| get_child(i) }
43
+ end
44
+
45
+ def flatten(map = {})
46
+ case type
47
+ when :window, :section
48
+ children.each { |child| child.flatten(map) }
49
+ when :menu
50
+ # noop
51
+ else
52
+ map[name] = self
53
+ end
54
+
55
+ map
56
+ end
57
+
58
+ def to_s
59
+ value.to_s
60
+ end
61
+
62
+ def to_ptr
63
+ @ptr
64
+ end
65
+
66
+ private
67
+
68
+ def free
69
+ rc = gp_widget_free(ptr)
70
+ GPhoto2.check!(rc)
71
+ end
72
+
73
+ def get_name
74
+ str = FFI::MemoryPointer.new(:string)
75
+ str_ptr = FFI::MemoryPointer.new(:pointer)
76
+ str_ptr.write_pointer(str)
77
+ rc = gp_widget_get_name(ptr, str_ptr)
78
+ GPhoto2.check!(rc)
79
+ str_ptr.read_pointer.read_string
80
+ end
81
+
82
+ def get_value
83
+ raise NotImplementedError
84
+ end
85
+
86
+ def set_value(value)
87
+ raise NotImplementedError
88
+ end
89
+
90
+ def get_type
91
+ # assume CameraWidgetType is an int
92
+ type = FFI::MemoryPointer.new(:int)
93
+ rc = gp_widget_get_type(ptr, type)
94
+ GPhoto2.check!(rc)
95
+ CameraWidgetType[type.read_int]
96
+ end
97
+
98
+ def count_children
99
+ rc = gp_widget_count_children(ptr)
100
+ GPhoto2.check!(rc)
101
+ rc
102
+ end
103
+
104
+ def get_child(index)
105
+ widget_ptr = FFI::MemoryPointer.new(FFI::GPhoto2::CameraWidget)
106
+ rc = gp_widget_get_child(ptr, index, widget_ptr)
107
+ GPhoto2.check!(rc)
108
+ widget = FFI::GPhoto2::CameraWidget.new(widget_ptr.read_pointer)
109
+ CameraWidget.factory(widget, self)
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,19 @@
1
+ module GPhoto2
2
+ class DateCameraWidget < CameraWidget
3
+ protected
4
+
5
+ def get_value
6
+ val = FFI::MemoryPointer.new(:int)
7
+ rc = gp_widget_get_value(ptr, val)
8
+ GPhoto2.check!(rc)
9
+ Time.at(val.read_int).utc
10
+ end
11
+
12
+ def set_value(date)
13
+ val = FFI::MemoryPointer.new(:int)
14
+ val.write_int(date.to_i)
15
+ rc = gp_widget_set_value(ptr, val)
16
+ GPhoto2.check!(rc)
17
+ end
18
+ end
19
+ end