mac-wifi 2.0.0 → 2.1.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.
- checksums.yaml +5 -5
- data/README.md +67 -59
- data/RELEASE_NOTES.md +8 -0
- data/exe/mac-wifi +1 -1052
- data/lib/mac-wifi/base_model.rb +221 -0
- data/lib/mac-wifi/command_line_interface.rb +417 -0
- data/lib/mac-wifi/mac_os_model.rb +297 -0
- data/lib/mac-wifi/main.rb +69 -0
- data/lib/mac-wifi/version.rb +5 -0
- data/lib/mac-wifi.rb +3 -0
- data/mac-wifi.gemspec +8 -4
- metadata +9 -3
@@ -0,0 +1,221 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require_relative '../mac-wifi'
|
3
|
+
|
4
|
+
module MacWifi
|
5
|
+
|
6
|
+
class BaseModel
|
7
|
+
|
8
|
+
class OsCommandError < RuntimeError
|
9
|
+
attr_reader :exitstatus, :command, :text
|
10
|
+
|
11
|
+
def initialize(exitstatus, command, text)
|
12
|
+
@exitstatus = exitstatus
|
13
|
+
@command = command
|
14
|
+
@text = text
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def initialize(verbose = false)
|
20
|
+
@verbose_mode = verbose
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def run_os_command(command)
|
25
|
+
output = `#{command} 2>&1` # join stderr with stdout
|
26
|
+
if $?.exitstatus != 0
|
27
|
+
raise OsCommandError.new($?.exitstatus, command, output)
|
28
|
+
end
|
29
|
+
if @verbose_mode
|
30
|
+
puts "\n\n#{'-' * 79}\nCommand: #{command}\n\nOutput:\n#{output}#{'-' * 79}\n\n"
|
31
|
+
end
|
32
|
+
output
|
33
|
+
end
|
34
|
+
private :run_os_command
|
35
|
+
|
36
|
+
|
37
|
+
# This method returns whether or not there is a working Internet connection.
|
38
|
+
# Because of a Mac issue which causes a request to hang if the network is turned
|
39
|
+
# off during its lifetime, we give it only 5 seconds per try,
|
40
|
+
# and limit the number of tries to 3.
|
41
|
+
#
|
42
|
+
# This implementation will probably strike you as overly complex. The following
|
43
|
+
# code looks like it is all that should be necessary, but unfortunately
|
44
|
+
# this implementation often hangs when wifi is turned off while curl is active
|
45
|
+
#
|
46
|
+
# def connected_to_internet?
|
47
|
+
# script = "curl --silent --head http://www.google.com/ > /dev/null ; echo $?"
|
48
|
+
# result = `#{script}`.chomp
|
49
|
+
# puts result
|
50
|
+
# result == '0'
|
51
|
+
# end
|
52
|
+
|
53
|
+
# TODO Investigate using Curl options: --connect-timeout 1 --max-time 2 --retry 0
|
54
|
+
# to greatly simplify this method.
|
55
|
+
def connected_to_internet?
|
56
|
+
|
57
|
+
tempfile = Tempfile.open('mac-wifi-')
|
58
|
+
|
59
|
+
begin
|
60
|
+
start_status_script = -> do
|
61
|
+
script = "curl --silent --head http://www.google.com/ > /dev/null ; echo $? > #{tempfile.path} &"
|
62
|
+
pid = Process.spawn(script)
|
63
|
+
Process.detach(pid)
|
64
|
+
pid
|
65
|
+
end
|
66
|
+
|
67
|
+
process_is_running = ->(pid) do
|
68
|
+
script = %Q{ps -p #{pid} > /dev/null; echo $?}
|
69
|
+
output = `#{script}`.chomp
|
70
|
+
output == "0"
|
71
|
+
end
|
72
|
+
|
73
|
+
get_connected_state_from_curl = -> do
|
74
|
+
tempfile.close
|
75
|
+
File.read(tempfile.path).chomp == '0'
|
76
|
+
end
|
77
|
+
|
78
|
+
# Do one run, iterating during the timeout period to see if the command has completed
|
79
|
+
do_one_run = -> do
|
80
|
+
end_time = Time.now + 3
|
81
|
+
pid = start_status_script.()
|
82
|
+
while Time.now < end_time
|
83
|
+
if process_is_running.(pid)
|
84
|
+
sleep 0.5
|
85
|
+
else
|
86
|
+
return get_connected_state_from_curl.()
|
87
|
+
end
|
88
|
+
end
|
89
|
+
Process.kill('KILL', pid) if process_is_running.(pid)
|
90
|
+
:hung
|
91
|
+
end
|
92
|
+
|
93
|
+
3.times do
|
94
|
+
connected = do_one_run.()
|
95
|
+
return connected if connected != :hung
|
96
|
+
end
|
97
|
+
|
98
|
+
raise "Could not determine Internet status."
|
99
|
+
|
100
|
+
ensure
|
101
|
+
tempfile.unlink
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Turns wifi off and then on, reconnecting to the originally connecting network.
|
108
|
+
def cycle_network
|
109
|
+
# TODO: Make this network name saving and restoring conditional on it not having a password.
|
110
|
+
# If the disabled code below is enabled, an error will be raised if a password is required,
|
111
|
+
# even though it is stored.
|
112
|
+
# network_name = current_network
|
113
|
+
wifi_off
|
114
|
+
wifi_on
|
115
|
+
# connect(network_name) if network_name
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
def connected_to?(network_name)
|
120
|
+
network_name == connected_network_name
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# Connects to the passed network name, optionally with password.
|
125
|
+
# Turns wifi on first, in case it was turned off.
|
126
|
+
# Relies on subclass implementation of os_level_connect().
|
127
|
+
def connect(network_name, password = nil)
|
128
|
+
# Allow symbols and anything responding to to_s for user convenience
|
129
|
+
network_name = network_name.to_s if network_name
|
130
|
+
password = password.to_s if password
|
131
|
+
|
132
|
+
if network_name.nil? || network_name.empty?
|
133
|
+
raise "A network name is required but was not provided."
|
134
|
+
end
|
135
|
+
wifi_on
|
136
|
+
os_level_connect(network_name, password)
|
137
|
+
|
138
|
+
# Verify that the network is now connected:
|
139
|
+
actual_network_name = connected_network_name
|
140
|
+
unless actual_network_name == network_name
|
141
|
+
message = %Q{Expected to connect to "#{network_name}" but }
|
142
|
+
if actual_network_name
|
143
|
+
message << %Q{connected to "#{connected_network_name}" instead.}
|
144
|
+
else
|
145
|
+
message << "unable to connect to any network. Did you "
|
146
|
+
end
|
147
|
+
message << (password ? "provide the correct password?" : "need to provide a password?")
|
148
|
+
raise message
|
149
|
+
end
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
# Removes the specified network(s) from the preferred network list.
|
155
|
+
# @param network_names names of networks to remove; may be empty or contain nonexistent networks
|
156
|
+
# @return names of the networks that were removed (excludes non-preexisting networks)
|
157
|
+
def remove_preferred_networks(*network_names)
|
158
|
+
networks_to_remove = network_names & preferred_networks # exclude any nonexistent networks
|
159
|
+
networks_to_remove.each { |name| remove_preferred_network(name) }
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
def preferred_network_password(preferred_network_name)
|
164
|
+
preferred_network_name = preferred_network_name.to_s
|
165
|
+
if preferred_networks.include?(preferred_network_name)
|
166
|
+
os_level_preferred_network_password(preferred_network_name)
|
167
|
+
else
|
168
|
+
raise "Network #{preferred_network_name} not in preferred networks list."
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
# Waits for the Internet connection to be in the desired state.
|
174
|
+
# @param target_status must be in [:conn, :disc, :off, :on]; waits for that state
|
175
|
+
# @param wait_interval_in_secs sleeps this interval between retries; if nil or absent,
|
176
|
+
# a default will be provided
|
177
|
+
#
|
178
|
+
def till(target_status, wait_interval_in_secs = nil)
|
179
|
+
|
180
|
+
# One might ask, why not just put the 0.5 up there as the default argument.
|
181
|
+
# We could do that, but we'd still need the line below in case nil
|
182
|
+
# was explicitly specified. The default argument of nil above emphasizes that
|
183
|
+
# the absence of an argument and a specification of nil will behave identically.
|
184
|
+
wait_interval_in_secs ||= 0.5
|
185
|
+
|
186
|
+
finished_predicates = {
|
187
|
+
conn: -> { connected_to_internet? },
|
188
|
+
disc: -> { ! connected_to_internet? },
|
189
|
+
on: -> { wifi_on? },
|
190
|
+
off: -> { ! wifi_on? }
|
191
|
+
}
|
192
|
+
|
193
|
+
finished_predicate = finished_predicates[target_status]
|
194
|
+
|
195
|
+
if finished_predicate.nil?
|
196
|
+
raise ArgumentError.new(
|
197
|
+
"Option must be one of #{finished_predicates.keys.inspect}. Was: #{target_status.inspect}")
|
198
|
+
end
|
199
|
+
|
200
|
+
loop do
|
201
|
+
return if finished_predicate.()
|
202
|
+
sleep(wait_interval_in_secs)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
# Tries an OS command until the stop condition is true.
|
208
|
+
# @command the command to run in the OS
|
209
|
+
# @stop_condition a lambda taking the commands stdout as its sole parameter
|
210
|
+
# @return the stdout produced by the command
|
211
|
+
def try_os_command_until(command, stop_condition, max_tries = 100)
|
212
|
+
max_tries.times do
|
213
|
+
stdout = run_os_command(command)
|
214
|
+
if stop_condition.(stdout)
|
215
|
+
return stdout
|
216
|
+
end
|
217
|
+
end
|
218
|
+
nil
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,417 @@
|
|
1
|
+
require_relative 'mac_os_model'
|
2
|
+
|
3
|
+
module MacWifi
|
4
|
+
|
5
|
+
class CommandLineInterface
|
6
|
+
|
7
|
+
attr_reader :model, :interactive_mode, :options
|
8
|
+
|
9
|
+
class Command < Struct.new(:min_string, :max_string, :action); end
|
10
|
+
|
11
|
+
|
12
|
+
class BadCommandError < RuntimeError
|
13
|
+
def initialize(error_message)
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Help text to be used when requested by 'h' command, in case of unrecognized or nonexistent command, etc.
|
20
|
+
HELP_TEXT = "
|
21
|
+
Command Line Switches: [mac-wifi version #{MacWifi::VERSION}]
|
22
|
+
|
23
|
+
-o[i,j,p,y] - outputs data in inspect, JSON, puts, or YAML format when not in shell mode
|
24
|
+
-s - run in shell mode
|
25
|
+
-v - verbose mode (prints OS commands and their outputs)
|
26
|
+
|
27
|
+
Commands:
|
28
|
+
|
29
|
+
a[vail_nets] - array of names of the available networks
|
30
|
+
ci - connected to Internet (not just wifi on)?
|
31
|
+
co[nnect] network-name - turns wifi on, connects to network-name
|
32
|
+
cy[cle] - turns wifi off, then on, preserving network selection
|
33
|
+
d[isconnect] - disconnects from current network, does not turn off wifi
|
34
|
+
h[elp] - prints this help
|
35
|
+
i[nfo] - a hash of wifi-related information
|
36
|
+
l[s_avail_nets] - details about available networks
|
37
|
+
n[etwork_name] - name (SSID) of currently connected network
|
38
|
+
on - turns wifi on
|
39
|
+
of[f] - turns wifi off
|
40
|
+
pa[ssword] network-name - password for preferred network-name
|
41
|
+
pr[ef_nets] - preferred (not necessarily available) networks
|
42
|
+
q[uit] - exits this program (interactive shell mode only) (see also 'x')
|
43
|
+
r[m_pref_nets] network-name - removes network-name from the preferred networks list
|
44
|
+
(can provide multiple names separated by spaces)
|
45
|
+
s[hell] - opens an interactive pry shell (command line only)
|
46
|
+
t[ill] - returns when the desired Internet connection state is true. Options:
|
47
|
+
1) 'on'/:on, 'off'/:off, 'conn'/:conn, or 'disc'/:disc
|
48
|
+
2) wait interval, in seconds (optional, defaults to 0.5 seconds)
|
49
|
+
w[ifion] - is the wifi on?
|
50
|
+
x[it] - exits this program (interactive shell mode only) (see also 'q')
|
51
|
+
|
52
|
+
When in interactive shell mode:
|
53
|
+
* use quotes for string parameters such as method names.
|
54
|
+
* for pry commands, use prefix `%`.
|
55
|
+
|
56
|
+
"
|
57
|
+
|
58
|
+
|
59
|
+
def initialize(options)
|
60
|
+
@options = options
|
61
|
+
@model = MacOsModel.new(verbose_mode)
|
62
|
+
@interactive_mode = !!(options.interactive_mode)
|
63
|
+
run_shell if @interactive_mode
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Until command line option parsing is added, the only way to specify
|
68
|
+
# verbose mode is in the environment variable MAC_WIFI_OPTS.
|
69
|
+
def verbose_mode
|
70
|
+
options.verbose
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def print_help
|
75
|
+
puts HELP_TEXT
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# @return true if awesome_print is available (after requiring it), else false after requiring 'pp'.
|
80
|
+
# We'd like to use awesome_print if it is available, but not require it.
|
81
|
+
# So, we try to require it, but if that fails, we fall back to using pp (pretty print),
|
82
|
+
# which is included in Ruby distributions without the need to install a gem.
|
83
|
+
def awesome_print_available?
|
84
|
+
if @awesome_print_available.nil? # first time here
|
85
|
+
begin
|
86
|
+
require 'awesome_print'
|
87
|
+
@awesome_print_available = true
|
88
|
+
rescue LoadError
|
89
|
+
require 'pp'
|
90
|
+
@awesome_print_available = false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
@awesome_print_available
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def fancy_string(object)
|
99
|
+
awesome_print_available? ? object.ai : object.pretty_inspect
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def fancy_puts(object)
|
104
|
+
puts fancy_string(object)
|
105
|
+
end
|
106
|
+
alias_method :fp, :fancy_puts
|
107
|
+
|
108
|
+
|
109
|
+
# Asserts that a command has been passed on the command line.
|
110
|
+
def validate_command_line
|
111
|
+
if ARGV.empty?
|
112
|
+
puts "Syntax is: #{__FILE__} [options] command [command_options]"
|
113
|
+
print_help
|
114
|
+
exit(-1)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# Pry will output the content of the method from which it was called.
|
120
|
+
# This small method exists solely to reduce the amount of pry's output
|
121
|
+
# that is not needed here.
|
122
|
+
def run_pry
|
123
|
+
binding.pry
|
124
|
+
|
125
|
+
# the seemingly useless line below is needed to avoid pry's exiting
|
126
|
+
# (see https://github.com/deivid-rodriguez/pry-byebug/issues/45)
|
127
|
+
_a = nil
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
# Runs a pry session in the context of this object.
|
132
|
+
# Commands and options specified on the command line can also be specified in the shell.
|
133
|
+
def run_shell
|
134
|
+
begin
|
135
|
+
require 'pry'
|
136
|
+
rescue LoadError
|
137
|
+
puts "The 'pry' gem and/or one of its prerequisites, required for running the shell, was not found." +
|
138
|
+
" Please `gem install pry`."
|
139
|
+
exit(-1)
|
140
|
+
end
|
141
|
+
|
142
|
+
print_help
|
143
|
+
|
144
|
+
# Enable the line below if you have any problems with pry configuration being loaded
|
145
|
+
# that is messing up this runtime use of pry:
|
146
|
+
# Pry.config.should_load_rc = false
|
147
|
+
|
148
|
+
# Strangely, this is the only thing I have found that successfully suppresses the
|
149
|
+
# code context output, which is not useful here. Anyway, this will differentiate
|
150
|
+
# a pry command from a DSL command, which _is_ useful here.
|
151
|
+
Pry.config.command_prefix = '%'
|
152
|
+
|
153
|
+
run_pry
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
# For use by the shell; when typing a command and options, it is passed to process_command_line
|
158
|
+
def method_missing(method_name, *options)
|
159
|
+
method_name = method_name.to_s
|
160
|
+
method_exists = !! find_command_action(method_name)
|
161
|
+
if method_exists
|
162
|
+
process_command_line(method_name, options)
|
163
|
+
else
|
164
|
+
puts(%Q{"#{method_name}" is not a valid command or option. If you intend for this to be a string literal, use quotes or %q/Q{}.})
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
# Processes the command (ARGV[0]) and any relevant options (ARGV[1..-1]).
|
170
|
+
#
|
171
|
+
# CAUTION! In interactive mode, any strings entered (e.g. a network name) MUST
|
172
|
+
# be in a form that the Ruby interpreter will recognize as a string,
|
173
|
+
# i.e. single or double quotes, %q, %Q, etc.
|
174
|
+
# Otherwise it will assume it's a method name and pass it to method_missing!
|
175
|
+
def process_command_line(command, options)
|
176
|
+
action = find_command_action(command)
|
177
|
+
if action
|
178
|
+
action.(*options)
|
179
|
+
else
|
180
|
+
print_help
|
181
|
+
raise BadCommandError.new(
|
182
|
+
%Q{Unrecognized command. Command was "#{command}" and options were #{options.inspect}.})
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
def quit
|
188
|
+
if interactive_mode
|
189
|
+
exit(0)
|
190
|
+
else
|
191
|
+
puts "This command can only be run in shell mode."
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
|
196
|
+
def cmd_a
|
197
|
+
info = model.available_network_names
|
198
|
+
if interactive_mode
|
199
|
+
info
|
200
|
+
else
|
201
|
+
if post_processor
|
202
|
+
puts post_processor.(info)
|
203
|
+
else
|
204
|
+
message = if model.wifi_on?
|
205
|
+
"Available networks are:\n\n#{fancy_string(info)}"
|
206
|
+
else
|
207
|
+
"Wifi is off, cannot see available networks."
|
208
|
+
end
|
209
|
+
puts(message)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
def cmd_ci
|
216
|
+
connected = model.connected_to_internet?
|
217
|
+
if interactive_mode
|
218
|
+
connected
|
219
|
+
else
|
220
|
+
puts (post_processor ? post_processor.(connected) : "Connected to Internet: #{connected}")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
def cmd_co(network, password = nil)
|
226
|
+
model.connect(network, password)
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
def cmd_cy
|
231
|
+
model.cycle_network
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
def cmd_d
|
236
|
+
model.disconnect
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
def cmd_h
|
241
|
+
print_help
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
def cmd_i
|
246
|
+
info = model.wifi_info
|
247
|
+
if interactive_mode
|
248
|
+
info
|
249
|
+
else
|
250
|
+
if post_processor
|
251
|
+
puts post_processor.(info)
|
252
|
+
else
|
253
|
+
puts fancy_string(info)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
|
259
|
+
def cmd_lsa
|
260
|
+
info = model.available_network_info
|
261
|
+
if interactive_mode
|
262
|
+
info
|
263
|
+
else
|
264
|
+
if post_processor
|
265
|
+
puts post_processor.(info)
|
266
|
+
else
|
267
|
+
message = model.wifi_on? ? fancy_string(info) : "Wifi is off, cannot see available networks."
|
268
|
+
puts(message)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
def cmd_n
|
275
|
+
name = model.connected_network_name
|
276
|
+
if interactive_mode
|
277
|
+
name
|
278
|
+
else
|
279
|
+
display_name = name ? name : '[none]'
|
280
|
+
puts (post_processor ? post_processor.(name) : %Q{Network (SSID) name: "#{display_name}"})
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
|
285
|
+
def cmd_of
|
286
|
+
model.wifi_off
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
def cmd_on
|
291
|
+
model.wifi_on
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
def cmd_pa(network)
|
296
|
+
password = model.preferred_network_password(network)
|
297
|
+
|
298
|
+
if interactive_mode
|
299
|
+
password
|
300
|
+
else
|
301
|
+
if post_processor
|
302
|
+
puts post_processor.(password)
|
303
|
+
else
|
304
|
+
output = %Q{Preferred network "#{model.connected_network_name}" }
|
305
|
+
output << (password ? %Q{stored password is "#{password}".} : "has no stored password.")
|
306
|
+
puts output
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
|
312
|
+
def cmd_pr
|
313
|
+
networks = model.preferred_networks
|
314
|
+
if interactive_mode
|
315
|
+
networks
|
316
|
+
else
|
317
|
+
puts (post_processor ? post_processor.(networks) : fancy_string(networks))
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
|
322
|
+
def cmd_q
|
323
|
+
quit
|
324
|
+
end
|
325
|
+
|
326
|
+
|
327
|
+
def cmd_r(*options)
|
328
|
+
removed_networks = model.remove_preferred_networks(*options)
|
329
|
+
if interactive_mode
|
330
|
+
removed_networks
|
331
|
+
else
|
332
|
+
puts (post_processor ? post_processor.(removed_networks) : "Removed networks: #{removed_networks.inspect}")
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
def cmd_t(*options)
|
338
|
+
target_status = options[0].to_sym
|
339
|
+
wait_interval_in_secs = (options[1] ? Float(options[1]) : nil)
|
340
|
+
model.till(target_status, wait_interval_in_secs)
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
def cmd_w
|
345
|
+
on = model.wifi_on?
|
346
|
+
if interactive_mode
|
347
|
+
on
|
348
|
+
else
|
349
|
+
puts (post_processor ? post_processor.(on) : "Wifi on: #{on}")
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
def cmd_x
|
355
|
+
quit
|
356
|
+
end
|
357
|
+
|
358
|
+
|
359
|
+
def commands
|
360
|
+
@commands_ ||= [
|
361
|
+
Command.new('a', 'avail_nets', -> (*_options) { cmd_a }),
|
362
|
+
Command.new('ci', 'ci', -> (*_options) { cmd_ci }),
|
363
|
+
Command.new('co', 'connect', -> (*options) { cmd_co(*options) }),
|
364
|
+
Command.new('cy', 'cycle', -> (*_options) { cmd_cy }),
|
365
|
+
Command.new('d', 'disconnect', -> (*_options) { cmd_d }),
|
366
|
+
Command.new('h', 'help', -> (*_options) { cmd_h }),
|
367
|
+
Command.new('i', 'info', -> (*_options) { cmd_i }),
|
368
|
+
Command.new('l', 'ls_avail_nets', -> (*_options) { cmd_lsa }),
|
369
|
+
Command.new('n', 'network_name', -> (*_options) { cmd_n }),
|
370
|
+
Command.new('of', 'off', -> (*_options) { cmd_of }),
|
371
|
+
Command.new('on', 'on', -> (*_options) { cmd_on }),
|
372
|
+
Command.new('pa', 'password', -> (*options) { cmd_pa(*options) }),
|
373
|
+
Command.new('pr', 'pref_nets', -> (*_options) { cmd_pr }),
|
374
|
+
Command.new('q', 'quit', -> (*_options) { cmd_q }),
|
375
|
+
Command.new('r', 'rm_pref_nets', -> (*options) { cmd_r(*options) }),
|
376
|
+
Command.new('t', 'till', -> (*options) { cmd_t(*options) }),
|
377
|
+
Command.new('w', 'wifion', -> (*_options) { cmd_w }),
|
378
|
+
Command.new('x', 'xit', -> (*_options) { cmd_x })
|
379
|
+
]
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
def find_command_action(command_string)
|
384
|
+
result = commands.detect do |cmd|
|
385
|
+
cmd.max_string.start_with?(command_string) \
|
386
|
+
&& \
|
387
|
+
command_string.length >= cmd.min_string.length # e.g. 'c' by itself should not work
|
388
|
+
end
|
389
|
+
|
390
|
+
result ? result.action : nil
|
391
|
+
end
|
392
|
+
|
393
|
+
|
394
|
+
# If a post-processor has been configured (e.g. YAML or JSON), use it.
|
395
|
+
def post_process(object)
|
396
|
+
post_processor ? post_processor.(object) : object
|
397
|
+
end
|
398
|
+
|
399
|
+
|
400
|
+
|
401
|
+
def post_processor
|
402
|
+
options.post_processor
|
403
|
+
end
|
404
|
+
|
405
|
+
|
406
|
+
def call
|
407
|
+
validate_command_line
|
408
|
+
begin
|
409
|
+
process_command_line(ARGV[0], ARGV[1..-1])
|
410
|
+
rescue BadCommandError => error
|
411
|
+
separator_line = "! #{'-' * 75} !\n"
|
412
|
+
puts '' << separator_line << error.to_s << "\n" << separator_line
|
413
|
+
exit(-1)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|