Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
任意のWiFi接続・切断時に任意のシェルスクリプトを実行するHammerspoonの設定
{
"base": {
"notify": false,
"shell": "/bin/bash",
"with_user_env": true
},
"networks": [
{
"SSID": "ssid1",
"profile": "proxy",
"pre_hook": "hoge.sh",
"post_hook": "fuga.sh"
},
{
"SSID": "ssid2",
"pre_hook": "poyo.sh",
"post_hook": "piyo.sh"
}
]
}
-- init
HOME = os.getenv("HOME")
CONFIG_HOME = HOME .. "/.hammerspoon/"
CONFIG_FILE = CONFIG_HOME .. "config.json"
SCRIPTS_PATH = CONFIG_HOME .. "Scripts/"
PROFILE_CHANGE_SCRIPT = SCRIPTS_PATH .. "nw_profile_changer.sh"
-- key
NETWORKS_KEY = "networks"
SHELL_KEY = "shell"
BASE_CONFIG_KEY = "base"
NOTIFY_KEY = "notify"
USER_ENV_KEY = "with_user_env"
SSID_KEY = "SSID"
PROFILE_KEY = "profile"
PRE_HOOK_KEY = "pre_hook"
POST_HOOK_KEY = "post_hook"
-- default settings
NOTIFY = true
SHELL = "/bin/bash"
USER_ENV = true
DEFAULT_NW_PROFILE = "Automatic"
-- tmp
prevSSID = hs.wifi.currentNetwork()
function hasKey(tbl, key)
for k, v in pairs (tbl) do
if k == key then
return true
end
end
return false
end
function readConfig(files)
-- jsonファイルを開いて一行ずつ読み出し,decode
local fp = io.open(files[1], "r")
local json = fp:read("*a")
fp:close()
local config = hs.json.decode(json)
if hasKey(config, BASE_CONFIG_KEY) then
for k, v in pairs(config[BASE_CONFIG_KEY]) do
hs.settings.set(k, v)
end
end
-- Default valueをセット
if not hasKey(config, NOTIFY_KEY) then
hs.settings.set(NOTIFY_KEY, NOTIFY)
end
if not hasKey(config, SHELL_KEY) then
hs.settings.set(SHELL_KEY, SHELL)
end
if not hasKey(config, USER_ENV_KEY) then
hs.settings.set(USER_ENV_KEY, USER_ENV)
end
-- Networkプロファイルをロード
if hasKey(config, NETWORKS_KEY) then
hs.settings.set(NETWORKS_KEY, config[NETWORKS_KEY])
end
if hs.settings.get(NOTIFY_KEY) then
local notify_msg = string.format("display notification \"Reloaded\" with title \"WLAN Profiles\"")
hs.osascript.applescript(notify_msg)
end
end
function execHook(path)
if path then
local script = SCRIPTS_PATH .. path
local shell = hs.settings.get(SHELL_KEY)
local with_user_env = hs.settings.get(USER_ENV_KEY)
hs.execute(shell .. " " .. script, with_user_env)
end
end
function loadNwProfile(profile_name)
-- ネットワーク環境の切り替え
local command = nil
local shell = hs.settings.get(SHELL_KEY)
local with_user_env = hs.settings.get(USER_ENV_KEY)
if profile_name then
command = shell .. " " .. PROFILE_CHANGE_SCRIPT .. " " .. profile_name
else
command = shell .. " " .. PROFILE_CHANGE_SCRIPT .. " " .. DEFAULT_NW_PROFILE
end
hs.execute(command, with_user_envi)
end
function nwProfileChanger(ssid, profile, connection)
if connection then
-- hookの実行
loadNwProfile(profile[PROFILE_KEY])
if hasKey(profile, PRE_HOOK_KEY) then
execHook(profile[PRE_HOOK_KEY])
end
else
if hasKey(profile, POST_HOOK_KEY) then
execHook(profile[POST_HOOK_KEY])
end
end
end
function ssidChangedCallback(watcher, msg, interface)
local newSSID = hs.wifi.currentNetwork()
if prevSSID ~= newSSID then
for i, nw in ipairs(hs.settings.get(NETWORKS_KEY)) do
if not prevSSID and newSSID and nw[SSID_KEY] == newSSID then
-- 接続時
nwProfileChanger(newSSID, nw, true)
break
elseif prevSSID and not newSSID and nw[SSID_KEY] == prevSSID then
-- 切断時
nwProfileChanger(prevSSID, nw, false)
break
end
end
end
prevSSID = newSSID
end
-- exec
readConfig({CONFIG_FILE})
hs.pathwatcher.new(CONFIG_FILE, readConfig):start()
hs.wifi.watcher.new(ssidChangedCallback):start()
currentlocation=`networksetup -getcurrentlocation`
if test $currentlocation = $1; then
return
fi
scselect `scselect | grep ${1} | cut -b 4-40`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment