-
-
Save n8felton/145d9f77692e0938e5cd0e24afd84a22 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# As written, this requires the following: | |
# - OS X 10.6+ (tested on 10.12.6 and 10.14.3) | |
# - python 2.6 or 2.7 (for collections.namedtuple usage, should be fine as default python in 10.6 is 2.6) | |
# - pyObjC (as such, recommended to be used with native OS X python install) | |
# Run with root | |
import objc, ctypes.util, os.path, collections | |
from Foundation import NSOrderedSet | |
from time import sleep | |
# List of preferred SSIDs in priority order - edit/add/delete as needed | |
PreferredSSIDs = ["RIT","eduroam"] | |
RemoveSSIDs = ["ritwpa2","rit","rit_guest","RIT-Legacy","RIT-Guest"] | |
def load_objc_framework(framework_name): | |
# Utility function that loads a Framework bundle and creates a namedtuple where the attributes are the loaded classes from the Framework bundle | |
loaded_classes = dict() | |
framework_bundle = objc.loadBundle(framework_name, bundle_path=os.path.dirname(ctypes.util.find_library(framework_name)), module_globals=loaded_classes) | |
return collections.namedtuple('AttributedFramework', loaded_classes.keys())(**loaded_classes) | |
# Load the CoreWLAN.framework (10.6+) | |
CoreWLAN = load_objc_framework('CoreWLAN') | |
# Load all available wifi interfaces | |
interfaces = dict() | |
for i in CoreWLAN.CWInterface.interfaceNames(): | |
interfaces[i] = CoreWLAN.CWInterface.interfaceWithName_(i) | |
# Repeat the configuration with every wifi interface | |
for i in interfaces.keys(): | |
# Turn off the Wi-Fi interface while we reconfigure it | |
power_off_result = interfaces[i].setPower_error_(False, None) | |
# Grab a mutable copy of this interface's configuration | |
configuration_copy = CoreWLAN.CWMutableConfiguration.alloc().initWithConfiguration_(interfaces[i].configuration()) | |
# Find all the preferred/remembered network profiles | |
profiles = list(configuration_copy.networkProfiles()) | |
# Grab all the SSIDs, in order | |
SSIDs = [x.ssid() for x in profiles] | |
# Remove profiles that match the RemoveSSIDs list. | |
profiles = [x for x in profiles if x.ssid() not in RemoveSSIDs] | |
# Loop through PreferredSSIDs list in reverse order sorting each entry to the front of profiles array so it | |
# ends up sorted with PreferredSSIDs as the first items. | |
# Order is preserved for other SSIDs, example where PreferredSSIDs is [ssid3, ssid4]: | |
# Original: [ssid1, ssid2, ssid3, ssid4] | |
# New order: [ssid3, ssid4, ssid1, ssid2] | |
for aSSID in reversed(PreferredSSIDs): | |
profiles.sort(key=lambda x: x.ssid() == aSSID, reverse=True) | |
# Now we have to update the mutable configuration | |
# First convert it back to a NSOrderedSet | |
profile_set = NSOrderedSet.orderedSetWithArray_(profiles) | |
# Then set/overwrite the configuration copy's networkProfiles | |
configuration_copy.setNetworkProfiles_(profile_set) | |
# Then update the network interface configuration | |
result = interfaces[i].commitConfiguration_authorization_error_(configuration_copy, None, None) | |
# Turn the Wi-Fi interface on again | |
while not interfaces[i].powerOn(): | |
sleep(0.1) | |
power_on_result = interfaces[i].setPower_error_(True, None) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment