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
188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 188 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
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 145 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 119 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 / -> /
178 179 180 181 182 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 178 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
148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 148 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)
162 163 164 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 162 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
230 231 232 233 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 230 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
223 224 225 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 223 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
207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 207 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 |