Initial commit of Hammerspoon config
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
local obj = {}
|
||||
obj.__index = obj
|
||||
obj.__name = "seal_vpn"
|
||||
|
||||
function obj:commands()
|
||||
return {vpn = {
|
||||
cmd = "vpn",
|
||||
fn = obj.choicesVPNCommand,
|
||||
name = "VPN",
|
||||
description = "Manage VPN connections",
|
||||
plugin = obj.__name
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function obj:bare()
|
||||
return nil
|
||||
end
|
||||
|
||||
function obj.getVPNConnections()
|
||||
connections = {}
|
||||
code, output, descriptor = hs.osascript.applescript([[
|
||||
set output to ""
|
||||
|
||||
on join_list(the_list, delimiter)
|
||||
set the_string to ""
|
||||
set old_delims to AppleScript's text item delimiters
|
||||
repeat with the_item in the_list
|
||||
if the_string is equal to "" then
|
||||
set the_string to the_string & the_item
|
||||
else
|
||||
set the_string to the_string & delimiter & the_item
|
||||
end if
|
||||
end repeat
|
||||
set AppleScript's text item delimiters to old_delims
|
||||
return the_string
|
||||
end join_list
|
||||
|
||||
set vpn_connections to {}
|
||||
|
||||
tell application "Viscosity"
|
||||
repeat with the_connection in connections
|
||||
set the end of vpn_connections to (name of the_connection) & tab & (state of the_connection) & tab & "Viscosity"
|
||||
end repeat
|
||||
end tell
|
||||
|
||||
tell application "System Events"
|
||||
tell current location of network preferences
|
||||
repeat with vpn in (every service whose (kind is greater than 10 and kind is less than 17))
|
||||
set state to "Disconnected"
|
||||
if connected of current configuration of vpn is equal to true then
|
||||
set state to "Connected"
|
||||
end if
|
||||
set the end of vpn_connections to (name of vpn) & tab & state & tab & "macOS"
|
||||
end repeat
|
||||
end tell
|
||||
end tell
|
||||
|
||||
return my join_list(vpn_connections, linefeed)
|
||||
]])
|
||||
|
||||
if code == false or output == nil or output == "" then
|
||||
return connections
|
||||
end
|
||||
|
||||
for line in output:gmatch("[^\r\n]+") do
|
||||
parts = {}
|
||||
for part in line:gmatch("%S+") do
|
||||
table.insert(parts, part)
|
||||
end
|
||||
kind = parts[#parts]
|
||||
table.remove(parts, #parts)
|
||||
state = parts[#parts]
|
||||
table.remove(parts, #parts)
|
||||
name = table.concat(parts, " ")
|
||||
table.insert(connections, {name=name, state=state, kind=kind})
|
||||
end
|
||||
return connections
|
||||
end
|
||||
|
||||
function obj.disconnectVPN(name, kind)
|
||||
if kind == "Viscosity" then
|
||||
obj.disconnectViscosity(name)
|
||||
elseif kind == "macOS" then
|
||||
obj.disconnectMacOS(name)
|
||||
end
|
||||
end
|
||||
|
||||
function obj.disconnectViscosity(name)
|
||||
code, output, descriptor = hs.osascript.applescript(string.format([[
|
||||
-- Return true if VPN is active
|
||||
on vpn_is_active(vpn_name)
|
||||
tell application "Viscosity"
|
||||
repeat with the_connection in connections
|
||||
if (name of the_connection) is equal to vpn_name then
|
||||
if (state of the_connection) is equal to "Connected" then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end if
|
||||
end if
|
||||
end repeat
|
||||
end tell
|
||||
return false
|
||||
end vpn_is_active
|
||||
|
||||
on run argv
|
||||
set vpn_name to "%s"
|
||||
if my vpn_is_active(vpn_name) then
|
||||
tell application "Viscosity"
|
||||
disconnect vpn_name
|
||||
end tell
|
||||
end if
|
||||
end run
|
||||
]], name))
|
||||
end
|
||||
|
||||
function obj.disconnectMacOS(name)
|
||||
code, output, descriptor = hs.osascript.applescript(string.format([[
|
||||
-- Return true if VPN is active
|
||||
on vpn_is_active(vpn_name)
|
||||
tell application "System Events"
|
||||
tell current location of network preferences
|
||||
return connected of current configuration of service vpn_name
|
||||
end tell
|
||||
end tell
|
||||
end vpn_is_active
|
||||
|
||||
on connect_vpn(vpn_name)
|
||||
tell application "System Events"
|
||||
tell current location of network preferences
|
||||
connect service vpn_name
|
||||
end tell
|
||||
end tell
|
||||
end connect_vpn
|
||||
|
||||
on run argv
|
||||
set vpn_name to "%s"
|
||||
if my vpn_is_active(vpn_name) then
|
||||
tell application "System Events"
|
||||
tell current location of network preferences
|
||||
disconnect service vpn_name
|
||||
end tell
|
||||
end tell
|
||||
end if
|
||||
end run
|
||||
]], name))
|
||||
end
|
||||
|
||||
function obj.connectVPN(name, kind)
|
||||
if kind == "Viscosity" then
|
||||
obj.connectViscosity(name)
|
||||
elseif kind == "macOS" then
|
||||
obj.connectMacOS(name)
|
||||
end
|
||||
end
|
||||
|
||||
function obj.connectViscosity(name)
|
||||
code, output, descriptor = hs.osascript.applescript(string.format([[
|
||||
-- Return true if VPN is active
|
||||
on vpn_is_active(vpn_name)
|
||||
tell application "Viscosity"
|
||||
repeat with the_connection in connections
|
||||
if (name of the_connection) is equal to vpn_name then
|
||||
if (state of the_connection) is equal to "Connected" then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end if
|
||||
end if
|
||||
end repeat
|
||||
end tell
|
||||
return false
|
||||
end vpn_is_active
|
||||
|
||||
-- Connect to specified VPN
|
||||
on connect_vpn(vpn_name)
|
||||
tell application "Viscosity"
|
||||
connect vpn_name
|
||||
end tell
|
||||
end connect_vpn
|
||||
|
||||
on run argv
|
||||
set vpn_name to "%s"
|
||||
if my vpn_is_active(vpn_name) then
|
||||
log "VPN " & quote & vpn_name & quote & " is already active."
|
||||
return
|
||||
end if
|
||||
connect_vpn(vpn_name)
|
||||
end run
|
||||
]], name))
|
||||
end
|
||||
|
||||
function obj.connectMacOS(name)
|
||||
code, output, descriptor = hs.osascript.applescript(string.format([[
|
||||
-- Return true if VPN is active
|
||||
on vpn_is_active(vpn_name)
|
||||
tell application "System Events"
|
||||
tell current location of network preferences
|
||||
return connected of current configuration of service vpn_name
|
||||
end tell
|
||||
end tell
|
||||
end vpn_is_active
|
||||
|
||||
-- Connect to specified VPN
|
||||
on connect_vpn(vpn_name)
|
||||
tell application "System Events"
|
||||
tell current location of network preferences
|
||||
connect service vpn_name
|
||||
end tell
|
||||
end tell
|
||||
end connect_vpn
|
||||
|
||||
on run argv
|
||||
set vpn_name to "%s"
|
||||
if my vpn_is_active(vpn_name) then
|
||||
log "VPN " & quote & vpn_name & quote & " is already active."
|
||||
return
|
||||
end if
|
||||
connect_vpn(vpn_name)
|
||||
end run
|
||||
]], name))
|
||||
end
|
||||
|
||||
|
||||
function obj.choicesVPNCommand(query)
|
||||
local choices = {}
|
||||
local connections = obj.getVPNConnections()
|
||||
local img_connected = hs.image.imageFromPath(obj.seal.spoonPath.."/viscosity_locked.png")
|
||||
local img_disconnected = hs.image.imageFromPath(obj.seal.spoonPath.."/viscosity_unlocked.png")
|
||||
|
||||
for k,v in pairs(connections) do
|
||||
name = v["name"]
|
||||
if string.match(name:lower(), query:lower()) then
|
||||
state = v["state"]
|
||||
kind = v["kind"]
|
||||
local choice = {}
|
||||
choice["text"] = name
|
||||
choice["subText"] = state .. " (" .. kind .. ")"
|
||||
if state == "Connected" then
|
||||
choice["image"] = img_connected
|
||||
else
|
||||
choice["image"] = img_disconnected
|
||||
end
|
||||
choice["name"] = name
|
||||
choice["state"] = state
|
||||
choice["kind"] = kind
|
||||
choice["plugin"] = obj.__name
|
||||
choice["type"] = "toggle"
|
||||
table.insert(choices, choice)
|
||||
end
|
||||
end
|
||||
return choices
|
||||
end
|
||||
|
||||
function obj.completionCallback(rowInfo)
|
||||
if rowInfo["type"] == "toggle" then
|
||||
if rowInfo["state"] == "Connected" then
|
||||
obj.disconnectVPN(rowInfo["name"], rowInfo["kind"])
|
||||
else
|
||||
obj.connectVPN(rowInfo["name"], rowInfo["kind"])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return obj
|
||||
Reference in New Issue
Block a user