sony_camera_remote_api 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -3
- data/README.md +4 -5
- data/lib/sony_camera_remote_api/client/main.rb +13 -21
- data/lib/sony_camera_remote_api/client/shelf.rb +222 -0
- data/lib/sony_camera_remote_api/scripts.rb +1 -0
- data/lib/sony_camera_remote_api/shelf.rb +206 -0
- data/lib/sony_camera_remote_api/utils.rb +1 -0
- data/lib/sony_camera_remote_api/version.rb +1 -1
- metadata +4 -3
- data/lib/sony_camera_remote_api/client/config.rb +0 -266
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07641246ad67933b0db1b774054e8370cb2e0a3d
|
4
|
+
data.tar.gz: 53708aaad639d29ab749b946f661627704e13813
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e5907a4ce53ecfb1a4ccddee974ae687cc586a42c733c1bc208e05dbff17a5595bae603b5da4381a7a53dad9e0df246bf3aac51a97a62b458903deb496fa663
|
7
|
+
data.tar.gz: 82456f6634df3edef58d04bcae163492f9879777ad5e0e5d56b6a28036716019d8be1514e9dcaf2f6bb06b40d2e6efccee06fbf226ca064b653f8acb44ac8293
|
data/.gitignore
CHANGED
@@ -42,9 +42,9 @@ build-iPhoneSimulator/
|
|
42
42
|
|
43
43
|
# for a library or gem, you might want to ignore these files since the code is
|
44
44
|
# intended to run in multiple environments; otherwise, check them in:
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
Gemfile.lock
|
46
|
+
.ruby-version
|
47
|
+
.ruby-gemset
|
48
48
|
|
49
49
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
50
50
|
.rvmrc
|
data/README.md
CHANGED
@@ -15,8 +15,8 @@ A Ruby Gem that facilitates the use of Sony Remote Camera API.
|
|
15
15
|
## Backgrounds
|
16
16
|
|
17
17
|
[Sony Camera Remote API](https://developer.sony.com/develop/cameras/) allows us to control a number of Sony cameras, including Sony Action cams, Sony Alpha cameras and Lens Style cameras, wirelessly from another device.
|
18
|
-
|
19
|
-
|
18
|
+
But these APIs are quite low-level, so that we have to implement a lot of sequences while considering many pitfalls, which are less documented in their API reference.
|
19
|
+
This gem is a wrapper library that make it easy to use Sony camera functions for high-level applications.
|
20
20
|
|
21
21
|
|
22
22
|
## Features
|
@@ -52,12 +52,11 @@ Or install it yourself as:
|
|
52
52
|
|
53
53
|
## Usage
|
54
54
|
|
55
|
-
1. Connect to the camera by Direct Wi-Fi
|
55
|
+
1. Connect your PC to the camera by Direct Wi-Fi. If you are using Linux, bundled scripts and its interface method are available.
|
56
56
|
2. Create SonyCameraRemoteAPI::Camera object. It takes a little time because of SSDP search.
|
57
57
|
3. Now you can call not only wrapper methods but also original APIs as a method!
|
58
58
|
|
59
|
-
If you
|
60
|
-
and then If you want to take a picture and save it:
|
59
|
+
If you want to take a picture and save it:
|
61
60
|
|
62
61
|
```ruby
|
63
62
|
require 'sony_camera_remote_api'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'sony_camera_remote_api'
|
2
2
|
require 'sony_camera_remote_api/logging'
|
3
3
|
require 'sony_camera_remote_api/scripts'
|
4
|
-
require 'sony_camera_remote_api/client/
|
4
|
+
require 'sony_camera_remote_api/client/shelf'
|
5
5
|
require 'fileutils'
|
6
6
|
require 'thor'
|
7
7
|
require 'highline/import'
|
@@ -9,7 +9,6 @@ require 'yaml'
|
|
9
9
|
require 'time'
|
10
10
|
require 'pp'
|
11
11
|
|
12
|
-
|
13
12
|
module SonyCameraRemoteAPI
|
14
13
|
# CLI client module
|
15
14
|
module Client
|
@@ -20,9 +19,8 @@ module SonyCameraRemoteAPI
|
|
20
19
|
class Main < Thor
|
21
20
|
include Utils
|
22
21
|
include Scripts
|
23
|
-
include ConfigUtils
|
24
22
|
|
25
|
-
register
|
23
|
+
register ShelfCmd, 'shelf', 'shelf [commands] [options]', 'Managing camera connections'
|
26
24
|
|
27
25
|
# Global options
|
28
26
|
class_option :setting, type: :boolean, desc: 'Show current camera settings'
|
@@ -30,8 +28,6 @@ module SonyCameraRemoteAPI
|
|
30
28
|
class_option :dir, type: :string, desc: 'Output directory', banner: 'DIR'
|
31
29
|
class_option :config, aliases: '-c', type: :string, desc: 'Config file path', banner: 'FILE'
|
32
30
|
class_option :ssid, type: :string, desc: 'SSID of the camera to connect'
|
33
|
-
class_option :pass, type: :string, desc: 'Password of camera to connect'
|
34
|
-
class_option :interface, type: :string, desc: 'Interface by which camera is connected'
|
35
31
|
class_option :verbose, type: :numeric, desc: 'Increase verbosity', banner: 'LEVEL'
|
36
32
|
|
37
33
|
no_tasks do
|
@@ -40,41 +36,37 @@ module SonyCameraRemoteAPI
|
|
40
36
|
end
|
41
37
|
|
42
38
|
def load_camera_config
|
43
|
-
#
|
44
|
-
if
|
45
|
-
|
46
|
-
return { 'ssid' => options[:ssid], 'pass' => options[:pass], 'interface' => options[:interface] }
|
47
|
-
else
|
48
|
-
puts "'--ssid', '--pass', '--interface' must be present all at a time!"
|
49
|
-
return
|
50
|
-
end
|
39
|
+
# If SSID is specified, load the camera config.
|
40
|
+
if options[:ssid]
|
41
|
+
@shelf.get options[:ssid] || @shelf.get_default
|
51
42
|
else
|
52
|
-
|
53
|
-
config
|
43
|
+
@shelf.get_default
|
54
44
|
end
|
55
45
|
end
|
56
46
|
|
57
47
|
# Load camera config and connect
|
58
48
|
def load_and_connect
|
59
49
|
config = load_camera_config
|
60
|
-
|
61
|
-
|
50
|
+
unless config
|
51
|
+
puts 'Failed to load camera config!'
|
52
|
+
exit 1
|
53
|
+
end
|
62
54
|
unless Scripts.connect(config['interface'], config['ssid'], config['pass'])
|
63
55
|
puts 'Failed to connect!'
|
64
|
-
|
56
|
+
exit 1
|
65
57
|
end
|
66
58
|
config
|
67
59
|
end
|
68
60
|
|
69
61
|
# Initialize camera instance
|
70
62
|
def init_camera
|
63
|
+
@shelf = Shelf.new config_file
|
71
64
|
config = load_and_connect
|
72
|
-
exit(1) if config.nil?
|
73
65
|
|
74
66
|
puts 'Initializing camera...'
|
75
67
|
if config['endpoints'].nil?
|
76
68
|
@cam = SonyCameraRemoteAPI::Camera.new reconnect_by: method(:load_and_connect)
|
77
|
-
|
69
|
+
@shelf.set_endpoints config['ssid'], @cam.endpoints
|
78
70
|
puts 'SSDP configuration saved.'
|
79
71
|
else
|
80
72
|
@cam = SonyCameraRemoteAPI::Camera.new endpoints: config['endpoints'],
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'sony_camera_remote_api'
|
2
|
+
require 'sony_camera_remote_api/scripts'
|
3
|
+
require 'sony_camera_remote_api/logging'
|
4
|
+
require 'sony_camera_remote_api/utils'
|
5
|
+
require 'sony_camera_remote_api/shelf'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'thor'
|
8
|
+
require 'highline/import'
|
9
|
+
|
10
|
+
|
11
|
+
module SonyCameraRemoteAPI
|
12
|
+
# CLI client module
|
13
|
+
module Client
|
14
|
+
|
15
|
+
# 'shelf' subcommand class for managing camera connection
|
16
|
+
class ShelfCmd < Thor
|
17
|
+
include Utils
|
18
|
+
include Scripts
|
19
|
+
|
20
|
+
class_option :file, aliases: '-f', type: :string, desc: 'Config file path', banner: 'FILE'
|
21
|
+
|
22
|
+
no_tasks do
|
23
|
+
def config_file
|
24
|
+
options[:file] || GLOBAL_CONFIG_FILE
|
25
|
+
end
|
26
|
+
|
27
|
+
def read_or_create_shelf
|
28
|
+
@shelf = Shelf.new config_file
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_id_or_ssid(id_or_ssid)
|
32
|
+
begin
|
33
|
+
id = Integer(id_or_ssid)
|
34
|
+
specified = @shelf.get_by_index id
|
35
|
+
unless specified
|
36
|
+
puts 'ERROR: Specified ID is invalid!'
|
37
|
+
return
|
38
|
+
end
|
39
|
+
rescue ArgumentError
|
40
|
+
ssid = id_or_ssid
|
41
|
+
specified = @shelf.get(ssid)
|
42
|
+
unless specified
|
43
|
+
puts 'ERROR: Specified SSID is not found or too ambigous!'
|
44
|
+
return
|
45
|
+
end
|
46
|
+
end
|
47
|
+
specified
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
desc 'add <SSID> <password> <interface>', 'Add a new camera connection'
|
53
|
+
def add(ssid, pass, interface)
|
54
|
+
read_or_create_shelf
|
55
|
+
if @shelf.get_all.find { |c| c['ssid'] == ssid }
|
56
|
+
# If SSID is duplicacted, ask user to overwrite or not.
|
57
|
+
answer = $terminal.ask('SSID duplicated! Do you want to overwrite? ') { |q| q.validate = /[yn]/i; q.default = 'n' }
|
58
|
+
if answer == 'y'
|
59
|
+
@shelf.add ssid, pass, interface, overwrite: true
|
60
|
+
else
|
61
|
+
puts 'Entry not changed.'
|
62
|
+
invoke :list, [], options
|
63
|
+
return
|
64
|
+
end
|
65
|
+
else
|
66
|
+
@shelf.add ssid, pass, interface
|
67
|
+
end
|
68
|
+
|
69
|
+
# Ask user to set default or not.
|
70
|
+
if @shelf.get
|
71
|
+
answer = $terminal.ask('Do you want set this camera as default? ') { |q| q.validate = /[yn]/i; q.default = 'y' }
|
72
|
+
if answer == 'y'
|
73
|
+
@shelf.use ssid
|
74
|
+
end
|
75
|
+
else
|
76
|
+
@shelf.use ssid
|
77
|
+
end
|
78
|
+
|
79
|
+
invoke :list, [], options
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
desc 'list', 'List added cameras'
|
84
|
+
def list
|
85
|
+
read_or_create_shelf
|
86
|
+
cameras = @shelf.get_all
|
87
|
+
default = @shelf.get
|
88
|
+
|
89
|
+
# No camera has been added, exit with a message.
|
90
|
+
if cameras.empty?
|
91
|
+
puts 'No camera yet!'
|
92
|
+
puts "Use 'sonycam shelf add' to add a new camera config."
|
93
|
+
return
|
94
|
+
end
|
95
|
+
|
96
|
+
# If default camera is not set, show message.
|
97
|
+
if default
|
98
|
+
default_ssid = default['ssid']
|
99
|
+
else
|
100
|
+
puts 'Default camera is not selected yet!'
|
101
|
+
puts "Use 'sonycam shelf use' command to select camera to use as default."
|
102
|
+
default_ssid = nil
|
103
|
+
end
|
104
|
+
|
105
|
+
# Selected camera is signed by allow
|
106
|
+
cameras.each_with_index do |v, i|
|
107
|
+
if v['ssid'] == default_ssid
|
108
|
+
puts "=> #{i}: SSID : #{v['ssid']} "
|
109
|
+
else
|
110
|
+
puts " #{i}: SSID : #{v['ssid']} "
|
111
|
+
end
|
112
|
+
puts " Password : #{v['pass']} "
|
113
|
+
puts " Interface : #{v['interface']} "
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
desc 'remove <ID or SSID> [options]', 'Remove camera(s) from the shelf'
|
119
|
+
option :all, type: :boolean, desc: 'Remove all cameras'
|
120
|
+
def remove(id_or_ssid = nil)
|
121
|
+
read_or_create_shelf
|
122
|
+
if options[:all]
|
123
|
+
@shelf.remove_all
|
124
|
+
return
|
125
|
+
end
|
126
|
+
|
127
|
+
specified = get_id_or_ssid id_or_ssid
|
128
|
+
@shelf.remove specified['ssid'] if specified
|
129
|
+
|
130
|
+
invoke :list, [], options
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
desc 'use <ID or SSID>', 'Select a camera as default'
|
135
|
+
def use(id_or_ssid)
|
136
|
+
read_or_create_shelf
|
137
|
+
|
138
|
+
specified = get_id_or_ssid id_or_ssid
|
139
|
+
@shelf.use specified['ssid'] if specified
|
140
|
+
|
141
|
+
invoke :list, [], options
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
desc 'interface <if-name> <ssid>', 'Set interface by which the camera is connected.'
|
146
|
+
def interface(if_name, id_or_ssid = nil)
|
147
|
+
read_or_create_shelf
|
148
|
+
|
149
|
+
if id_or_ssid
|
150
|
+
specified = get_id_or_ssid id_or_ssid
|
151
|
+
else
|
152
|
+
specified = @shelf.get
|
153
|
+
unless specified
|
154
|
+
puts 'ERROR: Default camera is not selected yet!'
|
155
|
+
return
|
156
|
+
end
|
157
|
+
end
|
158
|
+
@shelf.set_interface if_name, specified['ssid'] if specified
|
159
|
+
invoke :list, [], options
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
desc 'default', 'Show the default camera currently selected'
|
164
|
+
option :json, type: :boolean, desc: 'output in JSON format'
|
165
|
+
def default
|
166
|
+
read_or_create_shelf
|
167
|
+
|
168
|
+
default = @shelf.get
|
169
|
+
unless default
|
170
|
+
puts 'ERROR: Default camera is not selected yet!'
|
171
|
+
return
|
172
|
+
end
|
173
|
+
|
174
|
+
if options[:json]
|
175
|
+
puts JSON.pretty_generate default
|
176
|
+
else
|
177
|
+
puts "SSID : #{default['ssid']} "
|
178
|
+
puts "Password : #{default['pass']} "
|
179
|
+
puts "Interface : #{default['interface']} "
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
desc 'connect [options]', 'Connect to the default camera'
|
185
|
+
option :restart, aliases: '-r', type: :boolean, desc: 'Restart interface', default: false
|
186
|
+
option :ssid, aliases: '-s', type: :string, desc: 'Specify camera by SSID'
|
187
|
+
def connect
|
188
|
+
read_or_create_shelf
|
189
|
+
|
190
|
+
if options[:ssid]
|
191
|
+
camera = @shelf.get(options[:ssid])
|
192
|
+
unless camera
|
193
|
+
puts 'ERROR: Specified SSID is not found or too ambigous!'
|
194
|
+
return
|
195
|
+
end
|
196
|
+
else
|
197
|
+
camera = @shelf.get
|
198
|
+
unless camera
|
199
|
+
puts 'ERROR: Default camera is not selected yet!'
|
200
|
+
return
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
puts 'Camera to connect:'
|
205
|
+
puts " - SSID : #{camera['ssid']}"
|
206
|
+
puts " - pass : #{camera['pass']}"
|
207
|
+
puts " - inteface : #{camera['interface']}"
|
208
|
+
|
209
|
+
# Connect to camera by external script
|
210
|
+
if options[:restart]
|
211
|
+
result = Scripts.restart_and_connect(camera['interface'], camera['ssid'], camera['pass'])
|
212
|
+
else
|
213
|
+
result = Scripts.connect(camera['interface'], camera['ssid'], camera['pass'])
|
214
|
+
end
|
215
|
+
unless result
|
216
|
+
puts 'Failed to connect!'
|
217
|
+
exit 1
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -16,6 +16,7 @@ module SonyCameraRemoteAPI
|
|
16
16
|
run_external_command "sudo bash #{connection_script} #{interface} #{ssid} #{pass}"
|
17
17
|
end
|
18
18
|
|
19
|
+
|
19
20
|
# Restart the interface and connect to camera by Wi-Fi.
|
20
21
|
# @param [String] interface Interface name, e.g. wlan0
|
21
22
|
# @param [String] ssid SSID of the camera to connect
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'sony_camera_remote_api/utils'
|
2
|
+
require 'sony_camera_remote_api/scripts'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
|
6
|
+
module SonyCameraRemoteAPI
|
7
|
+
class Shelf
|
8
|
+
include Utils
|
9
|
+
|
10
|
+
# Default config file saved in home directory.
|
11
|
+
GLOBAL_CONFIG_FILE = File.expand_path('~/.sonycamconf')
|
12
|
+
|
13
|
+
|
14
|
+
# Create CameraShelf object.
|
15
|
+
# @param [String] config_file The path of config file.
|
16
|
+
def initialize(config_file = GLOBAL_CONFIG_FILE)
|
17
|
+
@config_file = config_file
|
18
|
+
read_or_create
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
# Get a camera config by SSID.
|
23
|
+
# You can use a partial string as long as it is unique.
|
24
|
+
# If SSID is not given, get the default camera config.
|
25
|
+
# @param [String] ssid SSID
|
26
|
+
# @return [Hash, nil] A camera config hash
|
27
|
+
def get(ssid = nil)
|
28
|
+
if ssid.nil?
|
29
|
+
get_default
|
30
|
+
else
|
31
|
+
get_unique(ssid)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Get a camera config by index.
|
37
|
+
# @param [String] index Index
|
38
|
+
# @return [Hash, nil] A camera config hash
|
39
|
+
def get_by_index(index)
|
40
|
+
if index.between? 0, @config['camera'].size - 1
|
41
|
+
@config['camera'][index]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Get all camera configs.
|
47
|
+
# @return [Array<Hash>] An array of camera config hashes
|
48
|
+
def get_all
|
49
|
+
@config['camera']
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Add a camera config.
|
54
|
+
# @param [Boolean] overwrite Overwrite if the same SSID's config is already added.
|
55
|
+
# @return [Boolean] +true+ if successfully added, +false+ otherwise.
|
56
|
+
def add(ssid, pass, interface, overwrite: false)
|
57
|
+
# If input SSID is already registered, ask user to overwrite
|
58
|
+
same_one = @config['camera'].find { |n| n['ssid'] == ssid }
|
59
|
+
if same_one && !overwrite
|
60
|
+
false
|
61
|
+
else
|
62
|
+
@config['camera'].delete_if { |c| c['ssid'] == ssid }
|
63
|
+
@config['camera'] << { 'ssid' => ssid, 'pass' => pass, 'interface' => interface }
|
64
|
+
if @config['camera'].size == 1
|
65
|
+
@config['default'] = ssid
|
66
|
+
end
|
67
|
+
write
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# Remove a camera config.
|
73
|
+
# @return [Boolean] +true+ if successfully removed, +false+ otherwise.
|
74
|
+
def remove(ssid)
|
75
|
+
entry = get_unique(ssid)
|
76
|
+
if @config['camera'].delete entry
|
77
|
+
write
|
78
|
+
else
|
79
|
+
false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# Remove a camera config by index.
|
85
|
+
# @param [String] index Index
|
86
|
+
# @return [Hash, nil] A camera config hash
|
87
|
+
def remove_by_index(index)
|
88
|
+
if index.between? 0, @config['camera'].size - 1
|
89
|
+
@config['camera'].delete_at index
|
90
|
+
write
|
91
|
+
else
|
92
|
+
false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
# Remove all camera configs.
|
98
|
+
# @return [Boolean] +true+ if successfully removed, +false+ otherwise.
|
99
|
+
def remove_all
|
100
|
+
create
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# Select a camera config as default.
|
105
|
+
# @return [Boolean] +true+ if successfully set default camera, +false+ otherwise.
|
106
|
+
def use(ssid)
|
107
|
+
entry = get(ssid)
|
108
|
+
if entry
|
109
|
+
@config['default'] = entry['ssid']
|
110
|
+
write
|
111
|
+
else
|
112
|
+
false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
# Set endpoint information to a camera config.
|
118
|
+
# @return [Boolean] +true+ if successfully set endpoints, +false+ otherwise.
|
119
|
+
def set_endpoints(endpoints, ssid = nil)
|
120
|
+
entry = get(ssid)
|
121
|
+
if entry
|
122
|
+
entry['endpoints'] = endpoints
|
123
|
+
write
|
124
|
+
else
|
125
|
+
false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# Set interface by which the camera is connected.
|
131
|
+
# @return [Boolean] +true+ if successfully set default camera, +false+ otherwise.
|
132
|
+
def set_interface(interface, ssid = nil)
|
133
|
+
entry = get(ssid)
|
134
|
+
if entry
|
135
|
+
entry['interface'] = interface
|
136
|
+
write
|
137
|
+
else
|
138
|
+
false
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
# Connect to the camera.
|
144
|
+
# If SSID is not given, default camera is used.
|
145
|
+
# @param [String] ssid SSID
|
146
|
+
# @return [Boolean] +true+ if successfully connected, +false+ otherwise.
|
147
|
+
def connect(ssid = nil)
|
148
|
+
entry = get(ssid)
|
149
|
+
if entry
|
150
|
+
Scripts.connect entry['interface'], entry['ssid'], entry['pass']
|
151
|
+
else
|
152
|
+
false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
# Get camera whose SSID uniquely matches with specified string.
|
160
|
+
# @param [String] ssid SSID
|
161
|
+
# @return [Hash, nil] A camera config hash
|
162
|
+
def get_unique(ssid)
|
163
|
+
complete_ssid, num = partial_and_unique_match(ssid, @config['camera'].map { |c| c['ssid'] })
|
164
|
+
return unless num == 1
|
165
|
+
@config['camera'].find { |c| c['ssid'] == complete_ssid }
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
# Get the default camera config.
|
170
|
+
# @return [Hash, nil] A camera config hash
|
171
|
+
def get_default
|
172
|
+
@config['camera'].find { |c| c['ssid'] == @config['default'] }
|
173
|
+
end
|
174
|
+
|
175
|
+
# @return [Boolean]
|
176
|
+
def read_or_create
|
177
|
+
unless read
|
178
|
+
create
|
179
|
+
else
|
180
|
+
false
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# @return [Boolean]
|
185
|
+
def create
|
186
|
+
@config = { 'camera' => [] }
|
187
|
+
write
|
188
|
+
end
|
189
|
+
|
190
|
+
# @return [Boolean]
|
191
|
+
def read
|
192
|
+
if File.exists? @config_file
|
193
|
+
@config = YAML.load_file(@config_file)
|
194
|
+
end
|
195
|
+
@config.present? ? true : false
|
196
|
+
end
|
197
|
+
|
198
|
+
# @return [Boolean]
|
199
|
+
def write
|
200
|
+
open(@config_file, 'w') do |e|
|
201
|
+
YAML.dump(@config, e)
|
202
|
+
end
|
203
|
+
true
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sony_camera_remote_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kota65535
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -189,13 +189,14 @@ files:
|
|
189
189
|
- lib/sony_camera_remote_api/camera_api.rb
|
190
190
|
- lib/sony_camera_remote_api/camera_api_group.rb
|
191
191
|
- lib/sony_camera_remote_api/camera_api_group_def.rb
|
192
|
-
- lib/sony_camera_remote_api/client/config.rb
|
193
192
|
- lib/sony_camera_remote_api/client/main.rb
|
193
|
+
- lib/sony_camera_remote_api/client/shelf.rb
|
194
194
|
- lib/sony_camera_remote_api/error.rb
|
195
195
|
- lib/sony_camera_remote_api/logging.rb
|
196
196
|
- lib/sony_camera_remote_api/packet.rb
|
197
197
|
- lib/sony_camera_remote_api/raw_api.rb
|
198
198
|
- lib/sony_camera_remote_api/scripts.rb
|
199
|
+
- lib/sony_camera_remote_api/shelf.rb
|
199
200
|
- lib/sony_camera_remote_api/ssdp.rb
|
200
201
|
- lib/sony_camera_remote_api/utils.rb
|
201
202
|
- lib/sony_camera_remote_api/version.rb
|
@@ -1,266 +0,0 @@
|
|
1
|
-
require 'sony_camera_remote_api'
|
2
|
-
require 'sony_camera_remote_api/scripts'
|
3
|
-
require 'sony_camera_remote_api/logging'
|
4
|
-
require 'sony_camera_remote_api/utils'
|
5
|
-
require 'fileutils'
|
6
|
-
require 'thor'
|
7
|
-
require 'highline/import'
|
8
|
-
require 'yaml'
|
9
|
-
require 'pp'
|
10
|
-
|
11
|
-
module SonyCameraRemoteAPI
|
12
|
-
module Client
|
13
|
-
module ConfigUtils
|
14
|
-
|
15
|
-
module_function
|
16
|
-
|
17
|
-
# Get default selected camera.
|
18
|
-
def default_camera(file)
|
19
|
-
# check default camera in configuration file
|
20
|
-
yaml = read_config_file file
|
21
|
-
unless yaml.key?('default')
|
22
|
-
puts 'Default camera is not selected!'
|
23
|
-
return nil
|
24
|
-
end
|
25
|
-
yaml['camera'].find { |n| n['ssid'] == yaml['default'] }
|
26
|
-
end
|
27
|
-
|
28
|
-
# Save endpoint information to config file if exists
|
29
|
-
def save_ssdp_config(file, endpoints)
|
30
|
-
yaml = read_config_file file
|
31
|
-
config = yaml['camera'].find { |n| n['ssid'] == yaml['default'] }
|
32
|
-
config['endpoints'] = endpoints
|
33
|
-
write_config_file file, yaml
|
34
|
-
end
|
35
|
-
|
36
|
-
# Read config file.
|
37
|
-
# @param [Boolean] assert If +true+, exit when the config file does not exist.
|
38
|
-
# @return [Hash] JSON converted from YAML config file.
|
39
|
-
def read_config_file(file, assert: true)
|
40
|
-
if File.exists? file
|
41
|
-
YAML.load_file(file)
|
42
|
-
else
|
43
|
-
if assert
|
44
|
-
puts 'Configuration file not found!'
|
45
|
-
exit 1
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Write config file
|
51
|
-
def write_config_file(file, yaml)
|
52
|
-
open(file, 'w') do |e|
|
53
|
-
YAML.dump(yaml, e)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
module SonyCameraRemoteAPI
|
64
|
-
# CLI client module
|
65
|
-
module Client
|
66
|
-
|
67
|
-
# 'config' subcommand class for managing camera connection
|
68
|
-
class Config < Thor
|
69
|
-
include Utils
|
70
|
-
include Scripts
|
71
|
-
include ConfigUtils
|
72
|
-
|
73
|
-
class_option :file, aliases: '-f', type: :string, desc: 'Config file path', banner: 'FILE'
|
74
|
-
|
75
|
-
no_tasks do
|
76
|
-
def config_file
|
77
|
-
options[:file] || GLOBAL_CONFIG_FILE
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
|
-
desc 'add <SSID> <password> <interface>', 'Register a new camera connection'
|
83
|
-
def add(ssid, pass, interface)
|
84
|
-
yaml = read_config_file config_file, assert: false
|
85
|
-
if yaml.nil? || !yaml.key?('camera')
|
86
|
-
yaml = { 'camera' => [{ 'ssid' => ssid, 'pass' => pass, 'interface' => interface }] }
|
87
|
-
else
|
88
|
-
# if input SSID is already registered, ask user to overwrite
|
89
|
-
index = yaml['camera'].index { |n| n['ssid'] == ssid }
|
90
|
-
if index
|
91
|
-
answer = $terminal.ask('SSID duplicated! Do you want to overwrite? ') { |q| q.validate = /[yn]/i; q.default = 'n' }
|
92
|
-
if answer == 'y'
|
93
|
-
yaml['camera'][index] = { 'ssid' => ssid, 'pass' => pass, 'interface' => interface }
|
94
|
-
else
|
95
|
-
puts 'Entry not changed.'
|
96
|
-
invoke :list, [], options
|
97
|
-
return
|
98
|
-
end
|
99
|
-
else
|
100
|
-
yaml['camera'] << { 'ssid' => ssid, 'pass' => pass, 'interface' => interface }
|
101
|
-
end
|
102
|
-
end
|
103
|
-
# ask user to select as default
|
104
|
-
answer = $terminal.ask('Do you want set this camera as default? ') { |q| q.validate = /[yn]/i; q.default = 'y' }
|
105
|
-
if answer == 'y'
|
106
|
-
yaml['default'] = ssid
|
107
|
-
end
|
108
|
-
write_config_file config_file, yaml
|
109
|
-
invoke :list, [], options
|
110
|
-
end
|
111
|
-
|
112
|
-
|
113
|
-
desc 'list', 'List registered cameras'
|
114
|
-
def list
|
115
|
-
yaml = read_config_file config_file
|
116
|
-
if yaml['camera'].uniq! { |v| v['ssid'] }
|
117
|
-
puts 'Removed duplicated entries.'
|
118
|
-
write_config_file config_file, yaml
|
119
|
-
end
|
120
|
-
if yaml.key? 'camera'
|
121
|
-
# selected camera is signed by allow
|
122
|
-
yaml['camera'].each_with_index do |v, i|
|
123
|
-
if v['ssid'] == yaml['default']
|
124
|
-
puts "=> #{i}: SSID : #{v['ssid']} "
|
125
|
-
else
|
126
|
-
puts " #{i}: SSID : #{v['ssid']} "
|
127
|
-
end
|
128
|
-
puts " Password : #{v['pass']} "
|
129
|
-
puts " Interface : #{v['interface']} "
|
130
|
-
end
|
131
|
-
else
|
132
|
-
# no camera is registered
|
133
|
-
puts 'No camera!'
|
134
|
-
puts "To add new camera connection, use 'sonycam config add' command."
|
135
|
-
end
|
136
|
-
# default camera is not selected
|
137
|
-
unless yaml.key? 'default'
|
138
|
-
puts 'Currently no camera is selected as default!'
|
139
|
-
puts "To select a camera as default from the list above, use 'sonycam config use' command."
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
desc 'remove [options]', 'Unregister a camera'
|
145
|
-
option :all, type: :boolean, desc: 'Remove all cameras'
|
146
|
-
option :id, aliases: '-i', type: :numeric, desc: "Specify camera by ID, which can be seen by 'config list' command", banner: 'NUMBER'
|
147
|
-
option :ssid, aliases: '-s', type: :string, desc: 'Specify camera by SSID'
|
148
|
-
def remove
|
149
|
-
unless [options[:id], options[:ssid], options[:all]].one?
|
150
|
-
puts "use either option '--all', '--id', '--ssid' to specify camera"
|
151
|
-
return
|
152
|
-
end
|
153
|
-
|
154
|
-
yaml = read_config_file config_file
|
155
|
-
if options[:all]
|
156
|
-
# remove all entries
|
157
|
-
write_config_file config_file, {}
|
158
|
-
return
|
159
|
-
end
|
160
|
-
if options[:id]
|
161
|
-
# remove ID'th entry
|
162
|
-
if 0 <= options[:id] && options[:id] < yaml['camera'].size
|
163
|
-
yaml.delete_if { |k, v| k == 'default' && v == yaml['camera'][options[:id]]['ssid'] }
|
164
|
-
yaml['camera'].delete_at options[:id]
|
165
|
-
write_config_file config_file, yaml
|
166
|
-
else
|
167
|
-
puts 'ERROR: Specified ID is invalid!'
|
168
|
-
end
|
169
|
-
elsif options[:ssid]
|
170
|
-
# find entry that matches specified SSID exactly
|
171
|
-
result, num = partial_and_unique_match(options[:ssid], yaml['camera'].map { |e| e['ssid'] })
|
172
|
-
if result
|
173
|
-
yaml.delete_if { |k, v| k == 'default' && v == result }
|
174
|
-
yaml['camera'].delete_if { |e| e['ssid'] == result }
|
175
|
-
write_config_file config_file, yaml
|
176
|
-
else
|
177
|
-
if num > 1
|
178
|
-
puts 'ERROR: Specified SSID is ambigous!'
|
179
|
-
elsif num == 0
|
180
|
-
puts 'ERROR: Specified SSID is not found!'
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
invoke :list, [], options
|
185
|
-
end
|
186
|
-
|
187
|
-
|
188
|
-
desc 'use <SSID>', 'Select a camera as default'
|
189
|
-
option :id, aliases: '-i', type: :numeric, desc: "Specify camera by ID, which can be seen by 'config list' command", banner: 'NUMBER'
|
190
|
-
option :ssid, aliases: '-s', type: :string, desc: 'Specify camera by SSID'
|
191
|
-
def use
|
192
|
-
unless [options[:id], options[:ssid]].one?
|
193
|
-
puts "use either option '--id' or '--ssid' to specify camera"
|
194
|
-
return
|
195
|
-
end
|
196
|
-
|
197
|
-
yaml = read_config_file config_file
|
198
|
-
|
199
|
-
if options[:id]
|
200
|
-
# select ID'th entry
|
201
|
-
if 0 <= options[:id] && options[:id] < yaml['camera'].size
|
202
|
-
yaml['default'] = yaml['camera'][options[:id]]['ssid']
|
203
|
-
write_config_file config_file, yaml
|
204
|
-
else
|
205
|
-
puts 'ERROR: Specified ID is invalid!'
|
206
|
-
end
|
207
|
-
elsif options[:ssid]
|
208
|
-
# find entry that matches specified SSID exactly
|
209
|
-
result, num = partial_and_unique_match(options[:ssid], yaml['camera'].map { |e| e['ssid'] })
|
210
|
-
if result
|
211
|
-
yaml['default'] = result
|
212
|
-
write_config_file config_file, yaml
|
213
|
-
else
|
214
|
-
# find entry that matches specified SSID partially but identically
|
215
|
-
if num > 1
|
216
|
-
puts 'ERROR: Specified SSID is ambigous!'
|
217
|
-
elsif num == 0
|
218
|
-
puts 'ERROR: Specified SSID is not found!'
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
invoke :list, [], options
|
223
|
-
end
|
224
|
-
|
225
|
-
|
226
|
-
desc 'default', 'Show the current default camera'
|
227
|
-
option :json, type: :boolean, desc: 'output in JSON format'
|
228
|
-
def default
|
229
|
-
config = default_camera config_file
|
230
|
-
return if config.nil?
|
231
|
-
|
232
|
-
if options[:json]
|
233
|
-
puts JSON.pretty_generate config
|
234
|
-
else
|
235
|
-
puts "SSID : #{config['ssid']} "
|
236
|
-
puts "Password : #{config['pass']} "
|
237
|
-
puts "Interface : #{config['interface']} "
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
|
242
|
-
desc 'connect', 'Connect to the current default camera'
|
243
|
-
option :restart, aliases: '-r', type: :boolean, desc: 'Restart interface', default: false
|
244
|
-
def connect
|
245
|
-
config = default_camera config_file
|
246
|
-
return if config.nil?
|
247
|
-
|
248
|
-
puts 'Selected camera:'
|
249
|
-
puts " - SSID : #{config['ssid']}"
|
250
|
-
puts " - pass : #{config['pass']}"
|
251
|
-
puts " - inteface : #{config['interface']}"
|
252
|
-
|
253
|
-
# Connect to camera by external script
|
254
|
-
if options[:restart]
|
255
|
-
result = Scripts.restart_and_connect(config['interface'], config['ssid'], config['pass'])
|
256
|
-
else
|
257
|
-
result = Scripts.connect(config['interface'], config['ssid'], config['pass'])
|
258
|
-
end
|
259
|
-
unless result
|
260
|
-
puts 'Failed to connect!'
|
261
|
-
exit 1
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|