From 80dd613667aff7e70b9958d6bd15d87b00c5159c Mon Sep 17 00:00:00 2001 From: Nicholas Riley Date: Sun, 19 Jan 2020 17:33:13 -0500 Subject: [PATCH] Optionally act on transitions from nil networks. To use, set WiFiTransitions.actOnNilTransitions`. Fixes #158. --- Source/WiFiTransitions.spoon/docs.json | 326 +++++++++++++++++++------ Source/WiFiTransitions.spoon/init.lua | 13 +- 2 files changed, 254 insertions(+), 85 deletions(-) diff --git a/Source/WiFiTransitions.spoon/docs.json b/Source/WiFiTransitions.spoon/docs.json index f3712d85..2b87e24c 100644 --- a/Source/WiFiTransitions.spoon/docs.json +++ b/Source/WiFiTransitions.spoon/docs.json @@ -1,110 +1,274 @@ [ { - "Command": [], - "Constant": [], - "Constructor": [], - "Deprecated": [], - "Field": [], - "Function": [], - "Method": [ + "Constant" : [ + + ], + "submodules" : [ + + ], + "Function" : [ + + ], + "Variable" : [ { - "def": "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", - "desc": "Process the rules and execute any actions corresponding to the specified transition.", - "doc": "Process the rules and execute any actions corresponding to the specified transition.\n\nThis method is called internally by the `hs.wifi.watcher` object\nwhen WiFi transitions happen. It does not get any system\ninformation nor does it set any Spoon state information, so it can\nalso be used to \"trigger\" transitions manually, either for testing\nor if the automated processing fails for any reason.\n\nParameters:\n * new_ssid - new SSID name\n * prev_ssid - previous SSID name. Defaults to `nil`\n * interface - interface where the transition occurred. Defaults to `nil`", - "name": "processTransition", - "parameters": [ - " * new_ssid - new SSID name", - " * prev_ssid - previous SSID name. Defaults to `nil`", - " * interface - interface where the transition occurred. Defaults to `nil`" + "doc" : "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", + "def" : "WiFiTransitions.logger", + "stripped_doc" : [ + "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon." ], - "signature": "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", - "stripped_doc": "This method is called internally by the `hs.wifi.watcher` object\nwhen WiFi transitions happen. It does not get any system\ninformation nor does it set any Spoon state information, so it can\nalso be used to \"trigger\" transitions manually, either for testing\nor if the automated processing fails for any reason.", - "type": "Method" + "name" : "logger", + "notes" : [ + + ], + "signature" : "WiFiTransitions.logger", + "type" : "Variable", + "returns" : [ + + ], + "desc" : "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", + "parameters" : [ + + ] }, { - "def": "WiFiTransitions:start()", - "desc": "Start the WiFi watcher", - "doc": "Start the WiFi watcher\n\nReturns:\n * The WiFiTransitions spoon object", - "name": "start", - "returns": [ - " * The WiFiTransitions spoon object" + "doc" : "Table containing a list of actions to execute for SSID transitions. Transitions to a \"no network\" state (`nil` SSID) are ignored unless you set `WiFiTransitions.actOnNilTransitions`. Each action is itself a table with the following keys:\n * to - if given, pattern to match against the new SSID. Defaults to match any network.\n * from - if given, pattern to match against the previous SSID. Defaults to match any network.\n * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:\n * event - always \"SSIDChange\"\n * interface - name of the interface on which the SSID changed\n * old_ssid - previous SSID name\n * new_ssid - new SSID name\n * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored.", + "def" : "WiFiTransitions.actions", + "stripped_doc" : [ + "Table containing a list of actions to execute for SSID transitions. Transitions to a \"no network\" state (`nil` SSID) are ignored unless you set `WiFiTransitions.actOnNilTransitions`. Each action is itself a table with the following keys:", + " * to - if given, pattern to match against the new SSID. Defaults to match any network.", + " * from - if given, pattern to match against the previous SSID. Defaults to match any network.", + " * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:", + " * event - always \"SSIDChange\"", + " * interface - name of the interface on which the SSID changed", + " * old_ssid - previous SSID name", + " * new_ssid - new SSID name", + " * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored." + ], + "name" : "actions", + "notes" : [ + + ], + "signature" : "WiFiTransitions.actions", + "type" : "Variable", + "returns" : [ + + ], + "desc" : "Table containing a list of actions to execute for SSID transitions. Transitions to a \"no network\" state (`nil` SSID) are ignored unless you set `WiFiTransitions.actOnNilTransitions`. Each action is itself a table with the following keys:", + "parameters" : [ + + ] + }, + { + "doc" : "Whether to evaluate `WiFiTransitions.actions` if the \"to\" network is no network (`nil`). Defaults to `false` to maintain backward compatibility; if unset, note that `from` transitions may not execute as expected.", + "def" : "WiFiTransitions.actOnNilTransitions", + "stripped_doc" : [ + "Whether to evaluate `WiFiTransitions.actions` if the \"to\" network is no network (`nil`). Defaults to `false` to maintain backward compatibility; if unset, note that `from` transitions may not execute as expected." + ], + "name" : "actOnNilTransitions", + "notes" : [ + ], - "signature": "WiFiTransitions:start()", - "stripped_doc": "", - "type": "Method" + "signature" : "WiFiTransitions.actOnNilTransitions", + "type" : "Variable", + "returns" : [ + + ], + "desc" : "Whether to evaluate `WiFiTransitions.actions` if the \"to\" network is no network (`nil`). Defaults to `false` to maintain backward compatibility; if unset, note that `from` transitions may not execute as expected.", + "parameters" : [ + + ] } ], - "Variable": [ + "stripped_doc" : [ + + ], + "desc" : "Allow arbitrary actions when transitioning between SSIDs", + "Deprecated" : [ + + ], + "type" : "Module", + "Constructor" : [ + + ], + "doc" : "Allow arbitrary actions when transitioning between SSIDs\n\nDownload: [https:\/\/github.com\/Hammerspoon\/Spoons\/raw\/master\/Spoons\/WiFiTransitions.spoon.zip](https:\/\/github.com\/Hammerspoon\/Spoons\/raw\/master\/Spoons\/WiFiTransitions.spoon.zip)", + "Method" : [ { - "def": "WiFiTransitions.actions", - "desc": "Table containing a list of actions to execute for SSID transitions. Each action is itself a table with the following keys:", - "doc": "Table containing a list of actions to execute for SSID transitions. Each action is itself a table with the following keys:\n * to - if given, pattern to match against the new SSID. Defaults to match any network. Transitions through the disabled state are ignored (i.e. normally a `nil` SSID is reported when switching SSIDs)\n * from - if given, pattern to match against the previous SSID. Defaults to match any network.\n * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:\n * event - always \"SSIDChange\"\n * interface - name of the interface on which the SSID changed\n * old_ssid - previous SSID name\n * new_ssid - new SSID name\n * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored.", - "name": "actions", - "signature": "WiFiTransitions.actions", - "stripped_doc": " * to - if given, pattern to match against the new SSID. Defaults to match any network. Transitions through the disabled state are ignored (i.e. normally a `nil` SSID is reported when switching SSIDs)\n * from - if given, pattern to match against the previous SSID. Defaults to match any network.\n * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:\n * event - always \"SSIDChange\"\n * interface - name of the interface on which the SSID changed\n * old_ssid - previous SSID name\n * new_ssid - new SSID name\n * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored.", - "type": "Variable" + "doc" : "Process the rules and execute any actions corresponding to the specified transition.\n\nThis method is called internally by the `hs.wifi.watcher` object\nwhen WiFi transitions happen. It does not get any system\ninformation nor does it set any Spoon state information, so it can\nalso be used to \"trigger\" transitions manually, either for testing\nor if the automated processing fails for any reason.\n\nParameters:\n * new_ssid - new SSID name\n * prev_ssid - previous SSID name. Defaults to `nil`\n * interface - interface where the transition occurred. Defaults to `nil`", + "def" : "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", + "stripped_doc" : [ + "Process the rules and execute any actions corresponding to the specified transition.", + "", + "This method is called internally by the `hs.wifi.watcher` object", + "when WiFi transitions happen. It does not get any system", + "information nor does it set any Spoon state information, so it can", + "also be used to \"trigger\" transitions manually, either for testing", + "or if the automated processing fails for any reason.", + "" + ], + "name" : "processTransition", + "notes" : [ + + ], + "signature" : "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", + "type" : "Method", + "returns" : [ + + ], + "desc" : "Process the rules and execute any actions corresponding to the specified transition.", + "parameters" : [ + " * new_ssid - new SSID name", + " * prev_ssid - previous SSID name. Defaults to `nil`", + " * interface - interface where the transition occurred. Defaults to `nil`" + ] }, { - "def": "WiFiTransitions.logger", - "desc": "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", - "doc": "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", - "name": "logger", - "signature": "WiFiTransitions.logger", - "stripped_doc": "", - "type": "Variable" + "doc" : "Start the WiFi watcher\n\nReturns:\n * The WiFiTransitions spoon object", + "def" : "WiFiTransitions:start()", + "stripped_doc" : [ + "Start the WiFi watcher", + "" + ], + "name" : "start", + "notes" : [ + + ], + "signature" : "WiFiTransitions:start()", + "type" : "Method", + "returns" : [ + " * The WiFiTransitions spoon object" + ], + "desc" : "Start the WiFi watcher", + "parameters" : [ + + ] } ], - "desc": "Allow arbitrary actions when transitioning between SSIDs", - "doc": "Allow arbitrary actions when transitioning between SSIDs\n\nDownload: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/WiFiTransitions.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/WiFiTransitions.spoon.zip)", - "items": [ + "Command" : [ + + ], + "Field" : [ + + ], + "items" : [ + { + "doc" : "Whether to evaluate `WiFiTransitions.actions` if the \"to\" network is no network (`nil`). Defaults to `false` to maintain backward compatibility; if unset, note that `from` transitions may not execute as expected.", + "def" : "WiFiTransitions.actOnNilTransitions", + "stripped_doc" : [ + "Whether to evaluate `WiFiTransitions.actions` if the \"to\" network is no network (`nil`). Defaults to `false` to maintain backward compatibility; if unset, note that `from` transitions may not execute as expected." + ], + "name" : "actOnNilTransitions", + "notes" : [ + + ], + "signature" : "WiFiTransitions.actOnNilTransitions", + "type" : "Variable", + "returns" : [ + + ], + "desc" : "Whether to evaluate `WiFiTransitions.actions` if the \"to\" network is no network (`nil`). Defaults to `false` to maintain backward compatibility; if unset, note that `from` transitions may not execute as expected.", + "parameters" : [ + + ] + }, { - "def": "WiFiTransitions.actions", - "desc": "Table containing a list of actions to execute for SSID transitions. Each action is itself a table with the following keys:", - "doc": "Table containing a list of actions to execute for SSID transitions. Each action is itself a table with the following keys:\n * to - if given, pattern to match against the new SSID. Defaults to match any network. Transitions through the disabled state are ignored (i.e. normally a `nil` SSID is reported when switching SSIDs)\n * from - if given, pattern to match against the previous SSID. Defaults to match any network.\n * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:\n * event - always \"SSIDChange\"\n * interface - name of the interface on which the SSID changed\n * old_ssid - previous SSID name\n * new_ssid - new SSID name\n * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored.", - "name": "actions", - "signature": "WiFiTransitions.actions", - "stripped_doc": " * to - if given, pattern to match against the new SSID. Defaults to match any network. Transitions through the disabled state are ignored (i.e. normally a `nil` SSID is reported when switching SSIDs)\n * from - if given, pattern to match against the previous SSID. Defaults to match any network.\n * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:\n * event - always \"SSIDChange\"\n * interface - name of the interface on which the SSID changed\n * old_ssid - previous SSID name\n * new_ssid - new SSID name\n * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored.", - "type": "Variable" + "doc" : "Table containing a list of actions to execute for SSID transitions. Transitions to a \"no network\" state (`nil` SSID) are ignored unless you set `WiFiTransitions.actOnNilTransitions`. Each action is itself a table with the following keys:\n * to - if given, pattern to match against the new SSID. Defaults to match any network.\n * from - if given, pattern to match against the previous SSID. Defaults to match any network.\n * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:\n * event - always \"SSIDChange\"\n * interface - name of the interface on which the SSID changed\n * old_ssid - previous SSID name\n * new_ssid - new SSID name\n * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored.", + "def" : "WiFiTransitions.actions", + "stripped_doc" : [ + "Table containing a list of actions to execute for SSID transitions. Transitions to a \"no network\" state (`nil` SSID) are ignored unless you set `WiFiTransitions.actOnNilTransitions`. Each action is itself a table with the following keys:", + " * to - if given, pattern to match against the new SSID. Defaults to match any network.", + " * from - if given, pattern to match against the previous SSID. Defaults to match any network.", + " * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments:", + " * event - always \"SSIDChange\"", + " * interface - name of the interface on which the SSID changed", + " * old_ssid - previous SSID name", + " * new_ssid - new SSID name", + " * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored." + ], + "name" : "actions", + "notes" : [ + + ], + "signature" : "WiFiTransitions.actions", + "type" : "Variable", + "returns" : [ + + ], + "desc" : "Table containing a list of actions to execute for SSID transitions. Transitions to a \"no network\" state (`nil` SSID) are ignored unless you set `WiFiTransitions.actOnNilTransitions`. Each action is itself a table with the following keys:", + "parameters" : [ + + ] }, { - "def": "WiFiTransitions.logger", - "desc": "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", - "doc": "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", - "name": "logger", - "signature": "WiFiTransitions.logger", - "stripped_doc": "", - "type": "Variable" + "doc" : "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", + "def" : "WiFiTransitions.logger", + "stripped_doc" : [ + "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon." + ], + "name" : "logger", + "notes" : [ + + ], + "signature" : "WiFiTransitions.logger", + "type" : "Variable", + "returns" : [ + + ], + "desc" : "Logger object used within the Spoon. Can be accessed to set the default log level for the messages coming from the Spoon.", + "parameters" : [ + + ] }, { - "def": "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", - "desc": "Process the rules and execute any actions corresponding to the specified transition.", - "doc": "Process the rules and execute any actions corresponding to the specified transition.\n\nThis method is called internally by the `hs.wifi.watcher` object\nwhen WiFi transitions happen. It does not get any system\ninformation nor does it set any Spoon state information, so it can\nalso be used to \"trigger\" transitions manually, either for testing\nor if the automated processing fails for any reason.\n\nParameters:\n * new_ssid - new SSID name\n * prev_ssid - previous SSID name. Defaults to `nil`\n * interface - interface where the transition occurred. Defaults to `nil`", - "name": "processTransition", - "parameters": [ + "doc" : "Process the rules and execute any actions corresponding to the specified transition.\n\nThis method is called internally by the `hs.wifi.watcher` object\nwhen WiFi transitions happen. It does not get any system\ninformation nor does it set any Spoon state information, so it can\nalso be used to \"trigger\" transitions manually, either for testing\nor if the automated processing fails for any reason.\n\nParameters:\n * new_ssid - new SSID name\n * prev_ssid - previous SSID name. Defaults to `nil`\n * interface - interface where the transition occurred. Defaults to `nil`", + "def" : "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", + "stripped_doc" : [ + "Process the rules and execute any actions corresponding to the specified transition.", + "", + "This method is called internally by the `hs.wifi.watcher` object", + "when WiFi transitions happen. It does not get any system", + "information nor does it set any Spoon state information, so it can", + "also be used to \"trigger\" transitions manually, either for testing", + "or if the automated processing fails for any reason.", + "" + ], + "name" : "processTransition", + "notes" : [ + + ], + "signature" : "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", + "type" : "Method", + "returns" : [ + + ], + "desc" : "Process the rules and execute any actions corresponding to the specified transition.", + "parameters" : [ " * new_ssid - new SSID name", " * prev_ssid - previous SSID name. Defaults to `nil`", " * interface - interface where the transition occurred. Defaults to `nil`" - ], - "signature": "WiFiTransitions:processTransition(new_ssid, prev_ssid, interface)", - "stripped_doc": "This method is called internally by the `hs.wifi.watcher` object\nwhen WiFi transitions happen. It does not get any system\ninformation nor does it set any Spoon state information, so it can\nalso be used to \"trigger\" transitions manually, either for testing\nor if the automated processing fails for any reason.", - "type": "Method" + ] }, { - "def": "WiFiTransitions:start()", - "desc": "Start the WiFi watcher", - "doc": "Start the WiFi watcher\n\nReturns:\n * The WiFiTransitions spoon object", - "name": "start", - "returns": [ + "doc" : "Start the WiFi watcher\n\nReturns:\n * The WiFiTransitions spoon object", + "def" : "WiFiTransitions:start()", + "stripped_doc" : [ + "Start the WiFi watcher", + "" + ], + "name" : "start", + "notes" : [ + + ], + "signature" : "WiFiTransitions:start()", + "type" : "Method", + "returns" : [ " * The WiFiTransitions spoon object" ], - "signature": "WiFiTransitions:start()", - "stripped_doc": "", - "type": "Method" + "desc" : "Start the WiFi watcher", + "parameters" : [ + + ] } ], - "name": "WiFiTransitions", - "stripped_doc": "\nDownload: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/WiFiTransitions.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/WiFiTransitions.spoon.zip)", - "submodules": [], - "type": "Module" + "name" : "WiFiTransitions" } -] \ No newline at end of file +] diff --git a/Source/WiFiTransitions.spoon/init.lua b/Source/WiFiTransitions.spoon/init.lua index 483436d4..d720d3f1 100644 --- a/Source/WiFiTransitions.spoon/init.lua +++ b/Source/WiFiTransitions.spoon/init.lua @@ -9,7 +9,7 @@ obj.__index = obj -- Metadata obj.name = "WiFiTransitions" -obj.version = "0.1" +obj.version = "0.2" obj.author = "Diego Zamboni " obj.homepage = "https://github.com/Hammerspoon/Spoons" obj.license = "MIT - https://opensource.org/licenses/MIT" @@ -21,8 +21,8 @@ obj.logger = hs.logger.new('WiFiTransitions') --- WiFiTransitions.actions --- Variable ---- Table containing a list of actions to execute for SSID transitions. Each action is itself a table with the following keys: ---- * to - if given, pattern to match against the new SSID. Defaults to match any network. Transitions through the disabled state are ignored (i.e. normally a `nil` SSID is reported when switching SSIDs) +--- Table containing a list of actions to execute for SSID transitions. Transitions to a "no network" state (`nil` SSID) are ignored unless you set `WiFiTransitions.actOnNilTransitions`. Each action is itself a table with the following keys: +--- * to - if given, pattern to match against the new SSID. Defaults to match any network. --- * from - if given, pattern to match against the previous SSID. Defaults to match any network. --- * fn - function to execute if there is a match. Can also be a list of functions, which will be executed in sequence. Each function will receive the following arguments: --- * event - always "SSIDChange" @@ -32,6 +32,11 @@ obj.logger = hs.logger.new('WiFiTransitions') --- * cmd - shell command to execute if there is a match. Can also be a list of commands, which will be executed in sequence using `hs.execute`. If `fn` is given, `cmd` is ignored. obj.actions = {} +--- WiFiTransitions.actOnNilTransitions +--- Variable +--- Whether to evaluate `WiFiTransitions.actions` if the "to" network is no network (`nil`). Defaults to `false` to maintain backward compatibility; if unset, note that `from` transitions may not execute as expected. +obj.actOnNilTransitions = false + -- Internal variable - previous SSID obj.previous_ssid = nil -- Internal variable - hs.wifi.watcher object @@ -62,7 +67,7 @@ end --- * interface - interface where the transition occurred. Defaults to `nil` function obj:processTransition(new_ssid, prev_ssid, interface) self.logger.df("Processing transition new_ssid=%s, prev_ssid=%s, interface=%s", new_ssid, prev_ssid, interface) - if new_ssid ~= nil then + if self.actOnNilTransitions or new_ssid ~= nil then for _,a in ipairs(self.actions) do self.logger.df(" Evaluating spec %s", hs.inspect(a)) if self.ssid_match(prev_ssid, a.from) and self.ssid_match(new_ssid, a.to) and (new_ssid ~= prev_ssid) then