wifi-wand 2.16.1 → 2.17.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa4d72d84399a3545afdc8a93bae85c4b908c4241e9f6b81611525dd16bb60c6
4
- data.tar.gz: 395a8c9a5f33fdc7560a1c77e9cf034dc71257001c6b83947e609e66c039289f
3
+ metadata.gz: 71b05a8e0debe969871ce1c44e2a5497458b970f7cf6d666d2035448636f194b
4
+ data.tar.gz: 3decf9e34a5aaca2b0d1de7ccb91a93138b002d755c648d0975ca0164a48624d
5
5
  SHA512:
6
- metadata.gz: b22b21c170675dc09b88d0e27602f36c6d347202222cc89f26fec49527f72b4aa30788ae88234a5d03d0bbd98de024f3999c6b1f5898cdc77d538ea1f9003976
7
- data.tar.gz: 6bd48d2bf96327d2b330f88bc9cf48136535ae787a49bf9ebccfe53b0023e1e5699a55e16dabd7c16227f5c056e7ab6674529b736246faae3e0158370fb65190
6
+ metadata.gz: 57fa874a6588a7a03862a2397f172374a3203e27fb0694623a6385a1743d195e1899393705cb6ef2133448e402fdf09a8fd4cebb19dfd67fa16d367addaa9a99
7
+ data.tar.gz: 37b6a84124163b57e1a6922f7703dac69bb8ebcddf6c3ac5d4e056404b4a224b27f1a98505f09c798586df6e0a8cd6a6564664775f48742dd28d90d8dbf6f00a
data/README.md CHANGED
@@ -32,7 +32,7 @@ $ wifi-wand -h
32
32
  Command Line Switches: [wifi-wand version 2.14.0 at https://github.com/keithrbennett/wifiwand]
33
33
 
34
34
  -o {i,j,k,p,y} - outputs data in inspect, JSON, pretty JSON, puts, or YAML format when not in shell mode
35
- -p wifi_port_name - override automatic detection of port name with this name
35
+ -p wifi_interface_name - override automatic detection of interface name with this name
36
36
  -s - run in shell mode
37
37
  -v - verbose mode (prints OS commands and their outputs)
38
38
 
@@ -44,17 +44,18 @@ co[nnect] network-name - turns wifi on, connects to network-name
44
44
  cy[cle] - turns wifi off, then on, preserving network selection
45
45
  d[isconnect] - disconnects from current network, does not turn off wifi
46
46
  f[orget] name1 [..name_n] - removes network-name(s) from the preferred networks list
47
+ in interactive mode, can be a single array of names, e.g. returned by `pref_nets`
47
48
  h[elp] - prints this help
48
49
  i[nfo] - a hash of wifi-related information
49
- l[s_avail_nets] - details about available networks in descending order of signal strength
50
- na[meservers] - nameservers: 'show' or no arg to show, 'clear' to clear, or IP addresses to set, e.g. '9.9.9.9 8.8.8.8'
50
+ na[meservers] - nameservers: 'show' or no arg to show, 'clear' to clear,
51
+ or IP addresses to set, e.g. '9.9.9.9 8.8.8.8'
51
52
  ne[twork_name] - name (SSID) of currently connected network
52
53
  on - turns wifi on
53
54
  of[f] - turns wifi off
54
55
  pa[ssword] network-name - password for preferred network-name
55
56
  pr[ef_nets] - preferred (saved) networks
56
57
  q[uit] - exits this program (interactive shell mode only) (see also 'x')
57
- ro[pen] - open resource ('ipl' (IP Location), 'ipw' (What is My IP), 'spe' (Speed Test), 'this' (wifi-wand home page))
58
+ ro[pen] - open resource ('cap' (Portal Logins), 'ipl' (IP Location), 'ipw' (What is My IP), 'libre' (LibreSpeed), 'spe' (Speed Test), 'this' (wifi-wand home page))
58
59
  t[ill] - returns when the desired Internet connection state is true. Options:
59
60
  1) 'on'/:on, 'off'/:off, 'conn'/:conn, or 'disc'/:disc
60
61
  2) wait interval between tests, in seconds (optional, defaults to 0.5 seconds)
@@ -203,7 +204,6 @@ constants or instance variables if you want to create variables in your shell.
203
204
  ```
204
205
  wifi-wand i # prints out wifi info
205
206
  wifi-wand a # prints out names of available networks
206
- wifi-wand lsa # prints available networks detailed information
207
207
  wifi-wand pr # prints preferred networks
208
208
  wifi-wand cy # cycles the wifi off and on
209
209
  wifi-wand co a-network a-password # connects to a network requiring a password
@@ -366,12 +366,14 @@ The following tasks were restored by using `networksetup`:
366
366
  * determining whether or not wifi is on
367
367
  * the name of the currently connected network
368
368
 
369
- The only remaining issue is that we were getting some extended information from airport for each available network.
369
+ The only remaining issue is that we were getting some extended information from airport for each available network. This extended information has now been removed in version 2.17.0.
370
+
371
+ In addition, the extended information about the available networks (`ls_avail_nets`) has been removed in version 2.17.0.
370
372
 
371
373
 
372
374
  ### License
373
375
 
374
- MIT License (see LICENSE.txt)
376
+ Apache 2 License (see LICENSE.txt)
375
377
 
376
378
  ### Logo
377
379
 
data/RELEASE_NOTES.md CHANGED
@@ -1,7 +1,17 @@
1
+ ## v2.17.0
2
+
3
+ * Remove all remaining uses of the 'airport' command.
4
+ * Remove 'available_network_info' command which required the 'airport' command.
5
+ * Remove extended information in the 'info' command output, which required the 'airport' command.
6
+ * Remove unused ModelValidator class.
7
+ * In README, update license reference and make other edits.
8
+
9
+
1
10
  ## v2.16.1
2
11
 
3
12
  * Fix airport deprecations' removal of listing all networks and disconnecting from a network by using Swift scripts.
4
13
 
14
+
5
15
  ## v2.16.0 (2024-04)
6
16
 
7
17
  * Handle deprecation of the `airport` command starting at Mac OS 14.4.
@@ -40,7 +40,7 @@ describe MacOsModel do
40
40
 
41
41
  it 'can list available networks' do
42
42
  subject.wifi_on
43
- subject.available_network_info
43
+ subject.available_network_names
44
44
  end
45
45
  end
46
46
 
@@ -73,7 +73,6 @@ f[orget] name1 [..name_n] - removes network-name(s) from the preferred networks
73
73
  in interactive mode, can be a single array of names, e.g. returned by `pref_nets`
74
74
  h[elp] - prints this help
75
75
  i[nfo] - a hash of wifi-related information
76
- l[s_avail_nets] - details about available networks, in descending order of signal strength
77
76
  na[meservers] - nameservers: 'show' or no arg to show, 'clear' to clear,
78
77
  or IP addresses to set, e.g. '9.9.9.9 8.8.8.8'
79
78
  ne[twork_name] - name (SSID) of currently connected network
@@ -203,7 +202,6 @@ When in interactive shell mode:
203
202
  end
204
203
 
205
204
 
206
-
207
205
  def quit
208
206
  if interactive_mode
209
207
  exit(0)
@@ -272,29 +270,6 @@ When in interactive shell mode:
272
270
  end
273
271
  end
274
272
 
275
-
276
- def cmd_l
277
- info = model.available_network_info
278
-
279
- if interactive_mode
280
- info
281
- else
282
- output = ''
283
- unless model.wifi_on?
284
- output << "Wifi is off, cannot see available networks."
285
- else
286
- if post_processor
287
- output = post_processor.(info)
288
- else
289
- output << "\nAccess points listed in descending order of signal strength (RSSI):\n\n"
290
- output << fancy_string(info)
291
- end
292
- end
293
- puts output
294
- end
295
- end
296
-
297
-
298
273
  # Performs nameserver functionality.
299
274
  # @param subcommand 'get' or no arg to get, 'clear' to clear, and an array of IP addresses to set
300
275
  def cmd_na(*args)
@@ -10,49 +10,11 @@ module WifiWand
10
10
 
11
11
  class MacOsModel < BaseModel
12
12
 
13
- DEFAULT_AIRPORT_FILESPEC = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport'
14
-
15
- attr_reader :airport_deprecated, :mac_os_version_major, :mac_os_version_minor, :mac_os_version_string
16
-
17
13
  # Takes an OpenStruct containing options such as verbose mode and interface name.
18
14
  def initialize(options = OpenStruct.new)
19
15
  super
20
- populate_mac_os_version
21
- @airport_deprecated = @mac_os_version_major > 14 || (@mac_os_version_major == 14 && @mac_os_version_minor >= 4)
22
- end
23
-
24
- # Provides Mac OS major and minor version numbers
25
- def populate_mac_os_version
26
- @mac_os_version_string = `sw_vers --productVersion`.chomp
27
- @mac_os_version_major, @mac_os_version_minor = mac_os_version_string.split('.').map(&:to_i)
28
- [@mac_os_version_major, @mac_os_version_minor]
29
- end
30
-
31
- def airport_deprecated_message
32
- <<~MESSAGE
33
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
34
- This method requires the airport utility which is no longer functional in Mac OS >= 14.4.
35
- You are running Mac OS version #{mac_os_version_string}.
36
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
37
- MESSAGE
38
- end
39
-
40
- # Although at this time the airport command utility is predictable,
41
- # allow putting it elsewhere in the path for overriding and easier fix
42
- # if that location should change.
43
- def airport_command
44
- airport_in_path = `which airport`.chomp
45
-
46
- return airport_in_path unless airport_in_path.empty?
47
-
48
- return DEFAULT_AIRPORT_FILESPEC if File.exist?(DEFAULT_AIRPORT_FILESPEC)
49
-
50
- raise Error.new("Airport command not found.") unless airport_deprecated
51
-
52
- nil # no error, no data
53
16
  end
54
17
 
55
-
56
18
  # Identifies the (first) wireless network hardware interface in the system, e.g. en0 or en1
57
19
  # This may not detect wifi ports with nonstandard names, such as USB wifi devices.
58
20
  def detect_wifi_interface
@@ -78,97 +40,6 @@ class MacOsModel < BaseModel
78
40
  end
79
41
  end
80
42
 
81
-
82
- # Returns data pertaining to available wireless networks.
83
- # For some reason, this often returns no results, so I've put the operation in a loop.
84
- # I was unable to detect a sort strategy in the airport utility's output, so I sort
85
- # the lines alphabetically, to show duplicates and for easier lookup.
86
- #
87
- # Sample Output:
88
- #
89
- # => ["SSID BSSID RSSI CHANNEL HT CC SECURITY (auth/unicast/group)",
90
- # "ByCO-U00tRzUzMEg 64:6c:b2:db:f3:0c -56 6 Y -- NONE",
91
- # "Chancery 0a:18:d6:0b:b9:c3 -82 11 Y -- NONE",
92
- # "Chancery 2a:a4:3c:03:33:99 -59 60,+1 Y -- NONE",
93
- # "DIRECT-sq-BRAVIA 02:71:cc:87:4a:8c -76 6 Y -- WPA2(PSK/AES/AES) ", #
94
- def available_network_info
95
-
96
- raise RuntimeError, airport_deprecated_message if airport_deprecated
97
-
98
- return nil unless wifi_on? # no need to try
99
- command = "#{airport_command} -s | iconv -f macroman -t utf-8"
100
- max_attempts = 50
101
-
102
- reformat_line = ->(line) do
103
- ssid = line[0..31].strip
104
- "%-32.32s%s" % [ssid, line[32..-1]]
105
- end
106
-
107
- signal_strength = ->(line) { (line[50..54] || '').to_i }
108
-
109
- sort_in_place_by_signal_strength = ->(lines) do
110
- lines.sort! { |x,y| signal_strength.(y) <=> signal_strength.(x) }
111
- end
112
-
113
- process_tabular_data = ->(output) do
114
- lines = output.split("\n")
115
- header_line = lines[0]
116
- data_lines = lines[1..-1]
117
- data_lines.map! do |line|
118
- # Reformat the line so that the name is left instead of right justified
119
- reformat_line.(line)
120
- end
121
- sort_in_place_by_signal_strength.(data_lines)
122
- [reformat_line.(header_line)] + data_lines
123
- end
124
-
125
- output = try_os_command_until(command, ->(output) do
126
- ! ([nil, ''].include?(output))
127
- end)
128
-
129
- if output
130
- process_tabular_data.(output)
131
- else
132
- raise Error.new("Unable to get available network information after #{max_attempts} attempts.")
133
- end
134
- end
135
-
136
-
137
- # The Mac OS airport utility (at
138
- # /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport)
139
- # outputs the network names right padded with spaces so there is no way to differentiate a
140
- # network name *with* leading space(s) from one without:
141
- #
142
- # SSID BSSID RSSI CHANNEL HT CC SECURITY (auth/unicast/group)
143
- # ngHub_319442NL0293C 04:a1:51:58:5b:05 -65 11 Y US WPA2(PSK/AES/AES)
144
- # NETGEAR89_2GEXT 9c:3d:cf:11:69:b4 -67 8 Y US NONE
145
- #
146
- # To remedy this, they offer a "-x" option that outputs the information in (pseudo) XML.
147
- # This XML has 'dict' elements that contain many elements. The SSID can be found in the
148
- # XML element <string> which immediately follows an XML element whose text is "SSID_STR".
149
- # Unfortunately, since there is no way to connect the two other than their physical location,
150
- # the key is rather useless for XML parsing.
151
- #
152
- # I tried extracting the arrays of keys and strings, and finding the string element
153
- # at the same position in the string array as the 'SSID_STR' was in the keys array.
154
- # However, not all keys had string elements, so the index in the key array was the wrong index.
155
- # Here is an excerpt from the XML output:
156
- #
157
- # <key>RSSI</key>
158
- # <integer>-91</integer>
159
- # <key>SSID</key>
160
- # <data>
161
- # TkVUR0VBUjY1
162
- # </data>
163
- # <key>SSID_STR</key>
164
- # <string>NETGEAR65</string>
165
- #
166
- # The kludge I came up with was that the ssid was always the 2nd value in the <string> element
167
- # array, so that's what is used here.
168
- #
169
- # But now even that approach has been superseded by the XPath approach now used.
170
- #
171
- # REXML is used here to avoid the need for the user to install Nokogiri.
172
43
  def available_network_names
173
44
  return nil unless wifi_on? # no need to try
174
45
 
@@ -331,13 +202,6 @@ class MacOsModel < BaseModel
331
202
  'timestamp' => Time.now,
332
203
  }
333
204
 
334
- unless airport_deprecated
335
- more_output = run_os_command(airport_command + " -I")
336
- more_info = colon_output_to_hash(more_output)
337
- info.merge!(more_info)
338
- info.delete('AirPort') # will be here if off, but info is already in wifi_on key
339
- end
340
-
341
205
  if info['internet_on'] && (! need_hotspot_login)
342
206
  begin
343
207
  info['public_ip'] = public_ip_address_info
@@ -430,7 +294,21 @@ class MacOsModel < BaseModel
430
294
  output.split("\n")
431
295
  end
432
296
 
297
+ def ensure_swift_and_corewlan_present
298
+ unless swift_and_corewlan_present?
299
+ raise RuntimeError, <<~MESSAGE
300
+ Swift and/or CoreWLAN are not present and are needed by this task.
301
+ This can be fixed by installing XCode.
302
+ MESSAGE
303
+ end
304
+ end
305
+
306
+ def swift_and_corewlan_present?
307
+ system("swift -e 'import CoreWLAN' >/dev/null 2>&1")
308
+ end
309
+
433
310
  def run_swift_command(basename)
311
+ ensure_swift_and_corewlan_present
434
312
  swift_filespec = File.join(
435
313
  File.dirname(__FILE__), "../../../swift/#{basename}.swift"
436
314
  )
@@ -1,3 +1,3 @@
1
1
  module WifiWand
2
- VERSION = '2.16.1' unless defined?(VERSION)
2
+ VERSION = '2.17.0' unless defined?(VERSION)
3
3
  end
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env swift
2
+
1
3
  import Foundation
2
4
  import CoreWLAN
3
5
 
@@ -11,10 +13,9 @@ class NetworkScanner {
11
13
  return nil
12
14
  }
13
15
  self.currentInterface = defaultInterface
14
- self.scanForNetworks()
15
16
  }
16
17
 
17
- func scanForNetworks() {
18
+ func available_networks() {
18
19
  do {
19
20
  let networks = try currentInterface.scanForNetworks(withName: nil)
20
21
  for network in networks {
@@ -23,10 +24,7 @@ class NetworkScanner {
23
24
  } catch let error as NSError {
24
25
  print("Error: \(error.localizedDescription)")
25
26
  }
26
- }
27
+ }
27
28
  }
28
29
 
29
- // Usage
30
- if NetworkScanner() != nil {
31
- // The list of available networks will be printed
32
- }
30
+ NetworkScanner()?.available_networks()
@@ -1,9 +1,13 @@
1
+ #!/usr/bin/env swift
2
+
1
3
  import Foundation
2
4
  import CoreWLAN
3
5
 
4
6
  if let wifiInterface = CWWiFiClient.shared().interface() {
5
7
  wifiInterface.disassociate()
6
8
  print("ok")
9
+ exit(0)
7
10
  } else {
8
11
  print("error")
12
+ exit(1)
9
13
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wifi-wand
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.16.1
4
+ version: 2.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Bennett
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-20 00:00:00.000000000 Z
11
+ date: 2024-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -134,7 +134,6 @@ files:
134
134
  - lib/wifi-wand/models/base_model.rb
135
135
  - lib/wifi-wand/models/helpers/command_output_formatter.rb
136
136
  - lib/wifi-wand/models/mac_os_model.rb
137
- - lib/wifi-wand/models/model_validator.rb
138
137
  - lib/wifi-wand/operating_systems.rb
139
138
  - lib/wifi-wand/os/base_os.rb
140
139
  - lib/wifi-wand/os/imaginary_os.rb
@@ -1,60 +0,0 @@
1
- module WifiWand
2
-
3
- class ModelValidator
4
-
5
- BASE_MODEL_ESSENTIAL_METHODS = [
6
- :connect,
7
- :connected_to?,
8
- :connected_to_internet?,
9
- :cycle_network,
10
- :preferred_network_password,
11
- :public_ip_address_info,
12
- :random_mac_address,
13
- :remove_preferred_networks,
14
- :run_os_command,
15
- :till,
16
- :try_os_command_until,
17
- :verbose_mode,
18
- :verbose_mode=,
19
- :wifi_interface,
20
- :wifi_interface=
21
- ]
22
-
23
-
24
- BASE_MODEL_NONESSENTIAL_METHODS = [
25
- ]
26
-
27
-
28
- MAC_OS_MODEL_ESSENTIAL_METHODS = [
29
- :airport_command,
30
- :available_network_info,
31
- :available_network_names,
32
- :connected_network_name,
33
- :detect_wifi_interface,
34
- :disconnect,
35
- :ip_address,
36
- :is_wifi_interface?,
37
- :mac_address,
38
- :nameservers_using_networksetup,
39
- :nameservers_using_resolv_conf,
40
- :nameservers_using_scutil,
41
- :open_resource,
42
- :os_level_connect,
43
- :os_level_preferred_network_password,
44
- :preferred_networks,
45
- :remove_preferred_network,
46
- :set_nameservers,
47
- :wifi_info,
48
- :wifi_off,
49
- :wifi_on,
50
- :wifi_on?
51
- ]
52
-
53
- MAC_OS_MODEL_ESSENTIAL_METHODS = [
54
- ]
55
-
56
- ALL_MODEL_METHODS = BASE_MODEL_ESSENTIAL_METHODS + MAC_OS_MODEL_ESSENTIAL_METHODS
57
-
58
-
59
- end
60
- end