Last active
March 18, 2017 03:42
-
-
Save sdagley/33af78bb216f9ddbf32e90ec9eb63b5b 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 | |
# Modify the Mac's WiFi Preferred Networks list to put specified SSIDs at the top of the list | |
# As written, this requires the following: | |
# - OS X 10.6+ (has been reported working through 10.12.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 | |
# Based on pudquick's reorder_wifi_alt.py - https://gist.github.com/pudquick/fcbdd3924ee230592ab4 | |
# Changed to use array of PreferredSSIDs rather than hard coding 3 SSIDs | |
import objc, ctypes.util, os.path, collections | |
from Foundation import NSOrderedSet | |
# List of preferred SSIDs in priority order - edit/add/delete as needed | |
PreferredSSIDs = ["SSID_1", "SSID_2", "SSID_3"] | |
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(): | |
# 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] | |
# 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment