class Listen::Record
@private api
@private api
Attributes
listener[RW]
TODO: deprecate
paths[RW]
TODO: deprecate
Public Class Methods
new(listener)
click to toggle source
# File lib/listen/record.rb, line 12 def initialize(listener) @listener = listener @paths = _auto_hash end
Public Instance Methods
add_dir(dir, rel_path)
click to toggle source
# File lib/listen/record.rb, line 17 def add_dir(dir, rel_path) return if [nil, '', '.'].include? rel_path @paths[dir.to_s][rel_path] ||= {} end
build()
click to toggle source
# File lib/listen/record.rb, line 61 def build start = Time.now.to_f @paths = _auto_hash # TODO: refactor this out (1 Record = 1 watched dir) listener.directories.each do |directory| _fast_build(directory.to_s) end Celluloid::Logger.info "Record.build(): #{Time.now.to_f - start} seconds" rescue Celluloid::Logger.warn "build crashed: #{$ERROR_INFO.inspect}" raise end
dir_entries(dir, rel_path)
click to toggle source
# File lib/listen/record.rb, line 45 def dir_entries(dir, rel_path) tree = if [nil, '', '.'].include? rel_path.to_s @paths[dir.to_s] else @paths[dir.to_s][rel_path.to_s] ||= _auto_hash @paths[dir.to_s][rel_path.to_s] end result = {} tree.each do |key, values| # only get data for file entries result[key] = values.key?(:mtime) ? values : {} end result end
file_data(dir, rel_path)
click to toggle source
# File lib/listen/record.rb, line 32 def file_data(dir, rel_path) root = @paths[dir.to_s] dirname, basename = Pathname(rel_path).split.map(&:to_s) if [nil, '', '.'].include? dirname root[basename] ||= {} root[basename].dup else root[dirname] ||= {} root[dirname][basename] ||= {} root[dirname][basename].dup end end
unset_path(dir, rel_path)
click to toggle source
# File lib/listen/record.rb, line 27 def unset_path(dir, rel_path) dirname, basename = Pathname(rel_path).split.map(&:to_s) _fast_unset_path(dir, dirname, basename) end
update_file(dir, rel_path, data)
click to toggle source
# File lib/listen/record.rb, line 22 def update_file(dir, rel_path, data) dirname, basename = Pathname(rel_path).split.map(&:to_s) _fast_update_file(dir, dirname, basename, data) end
Private Instance Methods
_auto_hash()
click to toggle source
# File lib/listen/record.rb, line 78 def _auto_hash Hash.new { |h, k| h[k] = Hash.new } end
_fast_build(root)
click to toggle source
TODO: test with a file name given TODO: test other permissions TODO: test with mixed encoding
# File lib/listen/record.rb, line 108 def _fast_build(root) symlink_detector = SymlinkDetector.new @paths[root] = _auto_hash remaining = Queue.new remaining << Entry.new(root, nil, nil) _fast_build_dir(remaining, symlink_detector) until remaining.empty? end
_fast_build_dir(remaining, symlink_detector)
click to toggle source
# File lib/listen/record.rb, line 116 def _fast_build_dir(remaining, symlink_detector) entry = remaining.pop children = entry.children # NOTE: children() implicitly tests if dir symlink_detector.verify_unwatched!(entry) children.each { |child| remaining << child } add_dir(entry.root, entry.record_dir_key) rescue Errno::ENOTDIR _fast_try_file(entry) rescue SystemCallError, SymlinkDetector::Error _fast_unset_path(entry.root, entry.relative, entry.name) end
_fast_try_file(entry)
click to toggle source
# File lib/listen/record.rb, line 128 def _fast_try_file(entry) _fast_update_file(entry.root, entry.relative, entry.name, entry.meta) rescue SystemCallError _fast_unset_path(entry.root, entry.relative, entry.name) end
_fast_unset_path(dir, dirname, basename)
click to toggle source
# File lib/listen/record.rb, line 92 def _fast_unset_path(dir, dirname, basename) root = @paths[dir.to_s] # this may need to be reworked to properly remove # entries from a tree, without adding non-existing dirs to the record if [nil, '', '.'].include? dirname return unless root.key?(basename) root.delete(basename) else return unless root.key?(dirname) root[dirname].delete(basename) end end
_fast_update_file(dir, dirname, basename, data)
click to toggle source
# File lib/listen/record.rb, line 82 def _fast_update_file(dir, dirname, basename, data) root = @paths[dir.to_s] if [nil, '', '.'].include? dirname root[basename] = (root[basename] || {}).merge(data) else root[dirname] ||= {} root[dirname][basename] = (root[dirname][basename] || {}).merge(data) end end