wifi-wand 2.19.1 → 2.20.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
  SHA256:
3
- metadata.gz: b9da3f2d69b3deb5046f7ea3394a43235733d9784c41bf372febdcca09c5d15d
4
- data.tar.gz: 63f83f663cb0ad11f8fe5087aeda730e8dcd4a5108dad4b84c653d37cd2cd21e
3
+ metadata.gz: f6064b0904166cac0ccc9768c6bd385f422616d42418e6c42db8f38235fde354
4
+ data.tar.gz: 07a0a469d659dd82a5fbb80562dfbef16629aa2344ca22134e1f92c585717cac
5
5
  SHA512:
6
- metadata.gz: 0be501742d8ad2e8ac317bf622b6f448af53293a8b90e563768aba12cf49a79488b3e8897928300be1150c6d021aa531c2fb809db0e9ff1346813268b347693c
7
- data.tar.gz: a645d6e65afb64c19bbca0dd3443fc1b92067084897384df8da330df876093bfd5906b754dc18826b59810aeab65050dc9a64918692a4f291361ada7f87a9b2c
6
+ metadata.gz: 4366219cfc3d754a69f21055ee489e2e458d7d969f6103353b203acbf8bc2d3419389288e90dc039c350f77bb8dbe90d8821e61e884fa8098483036810a7f9eb
7
+ data.tar.gz: cd4fe96013c357f5cea0e09d740ef723a460c046b0f8f48d2726b957675e87f305455a6f46f91d38d50b49c27ba87c8a7b7cdb39c55333a02e60cd689b0dc1b7
data/RELEASE_NOTES.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## v2.20.0
2
+
3
+ * Change detect_wifi_interface and available_network_names to use system_profiler JSON output.
4
+ * Previously, detect_wifi_interface parsed human readable text; parsing JSON is more reliable.
5
+ * Previously, available_network_names used Swift and CoreLAN and required XCode installation.
6
+
7
+
1
8
  ## v2.19.1
2
9
 
3
10
  * Fix connected_network_name when wifi is on but no network is connected.
@@ -219,9 +219,17 @@ When in interactive shell mode:
219
219
  if post_processor
220
220
  puts post_processor.(info)
221
221
  else
222
- puts model.wifi_on? \
223
- ? "Available networks are:\n\n#{fancy_string(info)}" \
224
- : "Wifi is off, cannot see available networks."
222
+ message = if model.wifi_on?
223
+ <<~MESSAGE
224
+ Available networks, in descending signal strength order,
225
+ and not including any currently connected network, are:
226
+
227
+ #{fancy_string(info)}"
228
+ MESSAGE
229
+ else
230
+ "Wifi is off, cannot see available networks."
231
+ end
232
+ puts message
225
233
  end
226
234
  end
227
235
  end
@@ -14,17 +14,16 @@ class BaseModel
14
14
  def initialize(options)
15
15
  @verbose_mode = options.verbose
16
16
 
17
- if options.wifi_interface && (! is_wifi_interface?(options.wifi_interface))
18
- raise Error.new("#{options.wifi_interface} is not a Wi-Fi interface.")
17
+ if options.wifi_interface
18
+ if is_wifi_interface?(options.wifi_interface)
19
+ @wifi_interface = options.wifi_interface
20
+ else
21
+ raise Error.new("#{options.wifi_interface} is not a Wi-Fi interface.")
22
+ end
19
23
  end
20
- @wifi_interface = options.wifi_interface
21
24
  end
22
25
 
23
-
24
-
25
-
26
26
  def run_os_command(command, raise_on_error = true)
27
-
28
27
  if verbose_mode
29
28
  puts CommandOutputFormatter.command_attempt_as_string(command)
30
29
  end
@@ -46,16 +45,15 @@ class BaseModel
46
45
 
47
46
 
48
47
  # This method returns whether or not there is a working Internet connection,
49
- # which is defined as name resolution and HTTP get being successful.
50
- # Domains attempted are google.com and baidu.com. Success is either being successful.
48
+ # which is defined as success for both name resolution and an HTTP get.
49
+ # Domains attempted are google.com and baidu.com.
50
+ # Success is defined as either being successful.
51
51
  # Commands for the multiple sites are run in parallel, in threads, to save time.
52
52
  def connected_to_internet?
53
- return nil unless wifi_on? # no need to try
53
+ return false unless wifi_on? # no need to try
54
54
 
55
55
  # We cannot use run_os_command for the running of external processes here,
56
56
  # because they are multithreaded, and the output will get mixed up.
57
-
58
- # First pass to fail quickly if name resolving does not work.
59
57
  test_using_dig = -> do
60
58
  domains = %w(google.com baidu.com)
61
59
  puts "Calling dig on domains #{domains}..." if verbose_mode
@@ -185,8 +183,8 @@ class BaseModel
185
183
  # @param wait_interval_in_secs sleeps this interval between retries; if nil or absent,
186
184
  # a default will be provided
187
185
  #
186
+ # Connected is defined as being able to connect to an external web site.
188
187
  def till(target_status, wait_interval_in_secs = nil)
189
-
190
188
  # One might ask, why not just put the 0.5 up there as the default argument.
191
189
  # We could do that, but we'd still need the line below in case nil
192
190
  # was explicitly specified. The default argument of nil above emphasizes that
@@ -217,7 +215,7 @@ class BaseModel
217
215
  # Tries an OS command until the stop condition is true.
218
216
  # @command the command to run in the OS
219
217
  # @stop_condition a lambda taking the command's stdout as its sole parameter
220
- # @return the stdout produced by the command
218
+ # @return the stdout produced by the command, or nil if max_tries was reached
221
219
  def try_os_command_until(command, stop_condition, max_tries = 100)
222
220
 
223
221
  report_attempt_count = ->(attempt_count) do
@@ -225,10 +223,10 @@ class BaseModel
225
223
  end
226
224
 
227
225
  max_tries.times do |n|
228
- stdout = run_os_command(command)
229
- if stop_condition.(stdout)
226
+ stdout_text = run_os_command(command)
227
+ if stop_condition.(stdout_text)
230
228
  report_attempt_count.(n + 1)
231
- return stdout
229
+ return stdout_text
232
230
  end
233
231
  end
234
232
 
@@ -16,7 +16,7 @@ class MacOsModel < BaseModel
16
16
 
17
17
  # Identifies the (first) wireless network hardware interface in the system, e.g. en0 or en1
18
18
  # This may not detect wifi ports with nonstandard names, such as USB wifi devices.
19
- def detect_wifi_interface
19
+ def detect_wifi_interface_using_networksetup
20
20
 
21
21
  lines = run_os_command("networksetup -listallhardwareports").split("\n")
22
22
  # Produces something like this:
@@ -39,10 +39,34 @@ class MacOsModel < BaseModel
39
39
  end
40
40
  end
41
41
 
42
+ # Identifies the (first) wireless network hardware interface in the system, e.g. en0 or en1
43
+ # This may not detect wifi ports with nonstandard names, such as USB wifi devices.
44
+ def detect_wifi_interface
45
+ json_text = run_os_command('system_profiler -json SPNetworkDataType')
46
+ net_data = JSON.parse(json_text)
47
+ nets = net_data['SPNetworkDataType']
48
+ wifi = nets.detect { |net| net['_name'] == 'Wi-Fi'}
49
+ wifi['interface']
50
+ end
51
+
52
+ # Returns the network names sorted in descending order of signal strength.
42
53
  def available_network_names
43
54
  return nil unless wifi_on? # no need to try
44
55
 
45
- run_swift_command('AvailableWifiNetworkLister').split("\n")
56
+ # run_swift_command('AvailableWifiNetworkLister').split("\n").uniq
57
+
58
+ json_text = run_os_command('system_profiler -json SPAirPortDataType')
59
+ data = JSON.parse(json_text)
60
+
61
+ inner_key = connected_network_name ? 'spairport_airport_other_local_wireless_networks' : 'spairport_airport_local_wireless_networks'
62
+
63
+ nets = data['SPAirPortDataType'] \
64
+ .detect { |h| h.key?('spairport_airport_interfaces') } \
65
+ ['spairport_airport_interfaces'] \
66
+ .detect { |h| h['_name'] == wifi_interface } \
67
+ [inner_key] \
68
+ .sort_by { |net| -net['spairport_signal_noise'].split('/').first.to_i }
69
+ nets.map { |h| h['_name']}.uniq
46
70
  end
47
71
 
48
72
 
@@ -1,3 +1,3 @@
1
1
  module WifiWand
2
- VERSION = '2.19.1' unless defined?(VERSION)
2
+ VERSION = '2.20.0' unless defined?(VERSION)
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wifi-wand
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.19.1
4
+ version: 2.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Bennett