Class: OpenHAB::DSL::Rules::Triggers::WatchHandler::WatchTriggerHandler
- Inherits:
-
Object
- Object
- OpenHAB::DSL::Rules::Triggers::WatchHandler::WatchTriggerHandler
- Defined in:
- lib/openhab/dsl/rules/triggers/watch/watch_handler.rb
Overview
Implements the openHAB TriggerHandler interface to process Watch Triggers
Class Method Summary collapse
-
.dir_subdir_glob(path, glob) ⇒ Array<String,Boolean,String>?
Returns the directory to watch, subdir flag, and glob pattern to use.
-
.find_parent(pathname) ⇒ Pathname?
Find the part of the path that exists on disk.
-
.glob?(string) ⇒ Boolean
Returns true if string contains glob characters.
-
.recursive_glob?(string) ⇒ Boolean
Returns true if string contains a recursive glob pattern (** or x/y).
Instance Method Summary collapse
-
#dispose ⇒ Object
Dispose of handler which deactivates watcher.
-
#initialize(trigger) ⇒ WatchTriggerHandler
constructor
Creates a new WatchTriggerHandler.
-
#setCallback(callback) ⇒ Object
Called by openHAB to set the rule engine to invoke when triggered.
-
#watch_event_handler(glob) ⇒ Proc
Create a lambda to use to invoke rule engine when file watch notification happens.
Constructor Details
#initialize(trigger) ⇒ WatchTriggerHandler
Creates a new WatchTriggerHandler
187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 187 def initialize(trigger) @trigger = trigger config = trigger.configuration.properties.to_hash.transform_keys(&:to_sym) @path, subdirs, glob = self.class.dir_subdir_glob(config[:path], config[:glob]) logger.trace { "WatchTriggerHandler#initialize path: #{@path}, subdirs: #{subdirs}, glob: #{glob}" } unless @path logger.warn("Watch error: the given path doesn't exist: '#{@path}'") return end @watcher = Watcher.new(@path, subdirs, config[:types], &watch_event_handler(glob)) @watcher.activate logger.trace { "Created watcher for #{@path} subdirs: #{subdirs}" } end |
Class Method Details
.dir_subdir_glob(path, glob) ⇒ Array<String,Boolean,String>?
Returns the directory to watch, subdir flag, and glob pattern to use
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 118 def dir_subdir_glob(path, glob) pathname = Pathname.new(path) return [pathname.dirname.to_s, false, path] if pathname.file? dir = find_parent(pathname) return unless dir # we were given the exact existing directory to watch if dir == pathname glob_pathname = Pathname.new(glob) subdirs = recursive_glob?(glob) unless glob_pathname.absolute? || glob.start_with?("**") glob = subdirs ? "**/#{glob}" : "#{path}/#{glob}" end return [path, subdirs, glob] end if glob != "*" # if it isn't the default glob logger.warn("The provided glob '#{glob}' is ignored because " \ "the given path (#{path}) isn't an existing directory, " \ "so it is used as the glob pattern") end relative_glob = pathname.relative_path_from(dir).to_s subdir_flag = dir != pathname.dirname || recursive_glob?(relative_glob) [dir.to_s, subdir_flag, path] end |
.find_parent(pathname) ⇒ Pathname?
Find the part of the path that exists on disk.
/a/b/c//d/.e -> /a/b/c if it exists /a/b/c/d/e/f -> /a/b/c if /a/b/c directory exists, but /a/b/c/d doesn’t exist /a/b/c -> nil if /a doesn’t exist / -> /
177 178 179 180 181 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 177 def find_parent(pathname) return pathname if pathname.root? pathname.ascend { |part| return part if part.directory? && !part.root? } end |
.glob?(string) ⇒ Boolean
Returns true if string contains glob characters
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 147 def glob?(string) unless @regexp # (?<!X) is a negative lookbehind pattern: only match the pattern if it wasn't # preceded with X. In this case we want to match only non escaped glob chars glob_pattern = %w[** * ? [ ] { }].map { |char| Regexp.escape(char) } .join("|") .then { |pattern| "(?<!\\\\)(#{pattern})" } @regexp = Regexp.new(glob_pattern) end @regexp.match?(string) end |
.recursive_glob?(string) ⇒ Boolean
Returns true if string contains a recursive glob pattern (** or x/y)
161 162 163 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 161 def recursive_glob?(string) /(?<!\\\\)\*\*/.match?(string) || Pathname.new(string).each_filename.to_a.size > 1 end |
Instance Method Details
#dispose ⇒ Object
Dispose of handler which deactivates watcher
229 230 231 232 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 229 def dispose logger.trace { "Deactivating watcher for #{@path}" } @watcher.deactivate end |
#setCallback(callback) ⇒ Object
Called by openHAB to set the rule engine to invoke when triggered
222 223 224 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 222 def setCallback(callback) # rubocop:disable Naming/MethodName @rule_engine_callback = callback end |
#watch_event_handler(glob) ⇒ Proc
Create a lambda to use to invoke rule engine when file watch notification happens
206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 206 def watch_event_handler(glob) default_fs = java.nio.file.FileSystems.default path_matcher = default_fs.get_path_matcher("glob:#{glob}") lambda do |watch_event| if path_matcher.matches(default_fs.get_path(watch_event.path.to_s)) logger.trace do "Received event(#{watch_event}) glob: #{glob}, rule_engine_callback = #{@rule_engine_callback}" end @rule_engine_callback&.triggered(@trigger, { "event" => watch_event }) else logger.trace { "Event #{watch_event} did not match glob(#{glob})" } end end end |