Class: Arrow::Path
Overview
The Arrow::Path class, which represents a collection of paths to search for various resources. Instances of this class are used to search for templates, applets, and other resources loaded by the server from a configured list of directories.
Synopsis
require 'arrow/path'
# Constructed from a String with PATH_SEPARATOR characters:
template_path = Arrow::Path.new( ".:/www/templates:/usr/local/www/templates" )
# ...or from an Array of Strings
template_path = Arrow::Path.new([ '.', '/www/templates', '/usr/local/www/templates' ])
# Return only those paths that exist, are directories, are readable
# by the current user, and are not world-writable. This will use a
# cached value if it has been built within
# Arrow::Path::DEFAULT_CACHE_LIFESPAN seconds of the last fetch.
paths = template_path.valid_dirs
# Fetch without caching
template_path.find_valid_dirs
# ...or turn caching off and fetch
template_path.cache_lifespan = 0
paths = template_path.valid_dirs
Authors
-
Michael Granger <[email protected]>
Please see the file LICENSE in the top-level directory for licensing details.
Constant Summary collapse
- SEPARATOR =
The character to split path Strings on, and join on when converting back to a String.
File::PATH_SEPARATOR
- DEFAULT_CACHE_LIFESPAN =
How many seconds to cache directory stat information, in seconds.
1.5
Constants included from Constants
Constants::HTML_MIMETYPE, Constants::RUBY_MARSHALLED_MIMETYPE, Constants::RUBY_OBJECT_MIMETYPE, Constants::XHTML_MIMETYPE, Constants::YAML_DOMAIN
Instance Attribute Summary collapse
-
#cache_lifespan ⇒ Object
How long (in seconds) to cache the list of good directories.
-
#dirs ⇒ Object
The raw list of directories contained in the path, including invalid (non-existent or unreadable) ones.
Class Method Summary collapse
-
.to_yaml_type ⇒ Object
Return the YAML type for this class.
Instance Method Summary collapse
-
#each(&block) ⇒ Object
Enumerable interface method.
-
#find_valid_dirs ⇒ Object
Fetch the list of paths in the search path, vetted to only contain those that are not tainted, exist, are directories, are readable by the current user, and are not world-writable.
-
#initialize(path = [], cache_lifespan = DEFAULT_CACHE_LIFESPAN) ⇒ Path
constructor
Create a new Arrow::Path object for the specified
path
, which can be either a String containing directory names separated by File::PATH_SEPARATOR, an Array of directory names, or an object which returns such an Array when #to_a is called on it. -
#to_s ⇒ Object
Return the path as a
SEPARATOR
-separated String. -
#to_yaml(opts = {}) ⇒ Object
Return the path as YAML text.
-
#valid_dirs ⇒ Object
Fetch the list of valid directories, using a cached value if the path has caching enabled (which is the default).
Constructor Details
#initialize(path = [], cache_lifespan = DEFAULT_CACHE_LIFESPAN) ⇒ Path
Create a new Arrow::Path object for the specified path
, which can be either a String containing directory names separated by File::PATH_SEPARATOR, an Array of directory names, or an object which returns such an Array when #to_a is called on it. If cache_lifespan
is non-zero, the Array of valid directories will be cached for cache_lifespan
seconds to save calls to stat().
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/arrow/path.rb', line 83 def initialize( path=[], cache_lifespan=DEFAULT_CACHE_LIFESPAN ) @dirs = case path when Array path.flatten when String path.split(SEPARATOR) else path.to_a.flatten end @dirs.collect! {|dir| dir.untaint.to_s } @valid_dirs = [] @cache_lifespan = cache_lifespan @last_stat = Time.at(0) end |
Instance Attribute Details
#cache_lifespan ⇒ Object
How long (in seconds) to cache the list of good directories. Setting this to 0 turns off caching.
111 112 113 |
# File 'lib/arrow/path.rb', line 111 def cache_lifespan @cache_lifespan end |
#dirs ⇒ Object
The raw list of directories contained in the path, including invalid (non-existent or unreadable) ones.
107 108 109 |
# File 'lib/arrow/path.rb', line 107 def dirs @dirs end |
Class Method Details
.to_yaml_type ⇒ Object
Return the YAML type for this class
68 69 70 |
# File 'lib/arrow/path.rb', line 68 def self::to_yaml_type "!%s/arrowPath" % [ Arrow::Constants::YAML_DOMAIN ] end |
Instance Method Details
#each(&block) ⇒ Object
Enumerable interface method. Iterate over the list of valid dirs in this path, calling the specified block for each.
173 174 175 |
# File 'lib/arrow/path.rb', line 173 def each( &block ) self.valid_dirs.each( &block ) end |
#find_valid_dirs ⇒ Object
Fetch the list of paths in the search path, vetted to only contain those that are not tainted, exist, are directories, are readable by the current user, and are not world-writable.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/arrow/path.rb', line 136 def find_valid_dirs return @dirs.find_all do |dir| if dir.tainted? self.log.info "Discarding tainted directory entry %p" % [ dir ] next end path = Pathname.new( dir ) if ! path.exist? self.log.debug "Discarding non-existant path: %s" % [ path ] next false elsif ! path.directory? self.log.debug "Discarding non-directory: %s" % [ path ] next false elsif ! path.readable? self.log.debug "Discarding unreadable directory: %s" % [ path ] next false elsif( (path.stat.mode & 0002).nonzero? ) self.log.debug "Discarding world-writable directory: %s" % [ path ] next false end true end.map {|pn| pn.to_s } end |
#to_s ⇒ Object
Return the path as a SEPARATOR
-separated String.
179 180 181 |
# File 'lib/arrow/path.rb', line 179 def to_s return self.valid_dirs.join( SEPARATOR ) end |
#to_yaml(opts = {}) ⇒ Object
Return the path as YAML text
185 186 187 188 189 190 191 192 |
# File 'lib/arrow/path.rb', line 185 def to_yaml( opts={} ) require 'yaml' YAML.quick_emit( self.object_id, opts ) {|out| out.seq( self.class.to_yaml_type ){|seq| seq.add( self.dirs ) } } end |
#valid_dirs ⇒ Object
Fetch the list of valid directories, using a cached value if the path has caching enabled (which is the default). Otherwise, it fetches the valid list via #find_valid_dirs and caches the result for #cache_lifespan seconds. If caching is disabled, this is equivalent to just calling #find_valid_dirs.
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/arrow/path.rb', line 119 def valid_dirs if ( @cache_lifespan.nonzero? && ((Time.now - @last_stat) < @cache_lifespan) ) self.log.debug "Returning cached dirs." return @valid_dirs end @valid_dirs = self.find_valid_dirs @last_stat = Time.now return @valid_dirs end |