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
242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 242 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
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 173 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 / -> /
232 233 234 235 236 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 232 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
202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 202 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)
216 217 218 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 216 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
284 285 286 287 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 284 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
277 278 279 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 277 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
261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 261 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 |