Class: DruidTools::Druid
- Inherits:
-
Object
- Object
- DruidTools::Druid
- Defined in:
- lib/druid_tools/druid.rb
Direct Known Subclasses
Constant Summary collapse
- STRICT_LET =
See consul.stanford.edu/pages/viewpage.action?title=SURI+2.0+Specification&spaceKey=chimera character class matching allowed letters in a druid suitable for use in regex (no aeioul)
'[b-df-hjkmnp-tv-z]'.freeze
- @@deletes_directory_name =
'.deletes'
Class Attribute Summary collapse
-
.prefix ⇒ Object
Returns the value of attribute prefix.
Instance Attribute Summary collapse
-
#base ⇒ Object
Returns the value of attribute base.
-
#druid ⇒ Object
Returns the value of attribute druid.
Class Method Summary collapse
-
.glob ⇒ String
Suitable for use in [Dir#glob].
-
.pattern(strict = false) ⇒ Regexp
Matches druid:aa111aa1111 or aa111aa1111.
-
.strict_glob ⇒ String
Suitable for use in [Dir#glob].
-
.valid?(druid, strict = false) ⇒ Boolean
True if druid matches pattern; otherwise false.
Instance Method Summary collapse
- #base_pathname ⇒ Object
-
#create_deletes_dir ⇒ void
Creates the deletes dir using the path supplied by deletes_dir_pathname.
-
#creates_delete_record ⇒ void
Creates an empty (pointer) file using the object’s id in the .deletes dir.
-
#deletes_delete_record ⇒ Object
Deletes the delete record if it currently exists.
-
#deletes_dir_exists? ⇒ Boolean
Using the deletes directory path supplied by deletes_dir_pathname, this function determines if this directory exists.
-
#deletes_dir_pathname ⇒ Pathname
Provide the location for the .deletes directory in the tree.
- #deletes_record_exists? ⇒ Boolean
- #deletes_record_pathname ⇒ Object
- #find(type, path) ⇒ Object
-
#find_filelist_parent(type, filelist) ⇒ Pathname
Search for and return the pathname of the directory that contains the list of files.
- #id ⇒ Object
-
#initialize(druid, base = '.', strict = false) ⇒ Druid
constructor
A new instance of Druid.
- #mkdir(extra = nil) ⇒ Object
- #mkdir_with_final_link(source, extra = nil) ⇒ Object
- #path(extra = nil, create = false) ⇒ Object
- #pathname ⇒ Object
-
#prep_deletes_dir ⇒ void
This function checks for existance of a .deletes dir one level into the path (ex: stacks/.deletes or purl/.deletes).
- #prune! ⇒ Object
-
#prune_ancestors(outermost_branch) ⇒ void
Ascend the druid tree and prune empty branches.
- #rmdir(extra = nil) ⇒ Object
- #tree ⇒ Object
Constructor Details
#initialize(druid, base = '.', strict = false) ⇒ Druid
Returns a new instance of Druid.
58 59 60 61 62 63 64 65 66 |
# File 'lib/druid_tools/druid.rb', line 58 def initialize(druid, base='.', strict=false) druid = druid.to_s unless druid.is_a? String unless self.class.valid?(druid, strict) raise ArgumentError, "Invalid DRUID: '#{druid}'" end druid = [self.class.prefix, druid].join(':') unless druid =~ /^#{self.class.prefix}:/ @base = base @druid = druid end |
Class Attribute Details
.prefix ⇒ Object
Returns the value of attribute prefix.
14 15 16 |
# File 'lib/druid_tools/druid.rb', line 14 def prefix @prefix end |
Instance Attribute Details
#base ⇒ Object
Returns the value of attribute base.
7 8 9 |
# File 'lib/druid_tools/druid.rb', line 7 def base @base end |
#druid ⇒ Object
Returns the value of attribute druid.
7 8 9 |
# File 'lib/druid_tools/druid.rb', line 7 def druid @druid end |
Class Method Details
.glob ⇒ String
Returns suitable for use in [Dir#glob].
24 25 26 |
# File 'lib/druid_tools/druid.rb', line 24 def glob "{#{self.prefix}:,}[a-z][a-z][0-9][0-9][0-9][a-z][a-z][0-9][0-9][0-9][0-9]" end |
.pattern(strict = false) ⇒ Regexp
Returns matches druid:aa111aa1111 or aa111aa1111.
18 19 20 21 |
# File 'lib/druid_tools/druid.rb', line 18 def pattern(strict=false) return /\A(?:#{self.prefix}:)?(#{STRICT_LET}{2})(\d{3})(#{STRICT_LET}{2})(\d{4})\z/ if strict /\A(?:#{self.prefix}:)?([a-z]{2})(\d{3})([a-z]{2})(\d{4})\z/ end |
.strict_glob ⇒ String
Returns suitable for use in [Dir#glob].
29 30 31 |
# File 'lib/druid_tools/druid.rb', line 29 def strict_glob "{#{self.prefix}:,}#{STRICT_LET}#{STRICT_LET}[0-9][0-9][0-9]#{STRICT_LET}#{STRICT_LET}[0-9][0-9][0-9][0-9]" end |
.valid?(druid, strict = false) ⇒ Boolean
Returns true if druid matches pattern; otherwise false.
36 37 38 |
# File 'lib/druid_tools/druid.rb', line 36 def valid?(druid, strict=false) druid =~ pattern(strict) ? true : false end |
Instance Method Details
#base_pathname ⇒ Object
145 146 147 |
# File 'lib/druid_tools/druid.rb', line 145 def base_pathname Pathname self.base end |
#create_deletes_dir ⇒ void
This method returns an undefined value.
Creates the deletes dir using the path supplied by deletes_dir_pathname
200 201 202 |
# File 'lib/druid_tools/druid.rb', line 200 def create_deletes_dir FileUtils::mkdir_p deletes_dir_pathname end |
#creates_delete_record ⇒ void
This method returns an undefined value.
Creates an empty (pointer) file using the object’s id in the .deletes dir
218 219 220 221 |
# File 'lib/druid_tools/druid.rb', line 218 def creates_delete_record prep_deletes_dir FileUtils.touch(deletes_record_pathname) end |
#deletes_delete_record ⇒ Object
Deletes the delete record if it currently exists. This is done to change the filed created, not just last modified time, on the system
return [void]
209 210 211 |
# File 'lib/druid_tools/druid.rb', line 209 def deletes_delete_record FileUtils.rm(deletes_record_pathname) if deletes_record_exists? #thrown in to prevent an Errno::ENOENT if you call this on something without a delete record end |
#deletes_dir_exists? ⇒ Boolean
Using the deletes directory path supplied by deletes_dir_pathname, this function determines if this directory exists
187 188 189 |
# File 'lib/druid_tools/druid.rb', line 187 def deletes_dir_exists? return File.directory?(deletes_dir_pathname) end |
#deletes_dir_pathname ⇒ Pathname
Provide the location for the .deletes directory in the tree
176 177 178 |
# File 'lib/druid_tools/druid.rb', line 176 def deletes_dir_pathname return Pathname(self.base.to_s + (File::SEPARATOR+@@deletes_directory_name)) end |
#deletes_record_exists? ⇒ Boolean
191 192 193 |
# File 'lib/druid_tools/druid.rb', line 191 def deletes_record_exists? return File.exists?(deletes_dir_pathname.to_s + File::SEPARATOR + self.id) end |
#deletes_record_pathname ⇒ Object
180 181 182 |
# File 'lib/druid_tools/druid.rb', line 180 def deletes_record_pathname return Pathname(deletes_dir_pathname.to_s + File::SEPARATOR + self.id) end |
#find(type, path) ⇒ Object
93 94 95 96 97 |
# File 'lib/druid_tools/druid.rb', line 93 def find(type, path) possibles = [self.path(type.to_s),self.path,File.('..',self.path)] loc = possibles.find { |p| File.exists?(File.join(p,path)) } loc.nil? ? nil : File.join(loc,path) end |
#find_filelist_parent(type, filelist) ⇒ Pathname
Returns Search for and return the pathname of the directory that contains the list of files. Raises an exception unless a directory is found that contains all the files in the list.
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/druid_tools/druid.rb', line 103 def find_filelist_parent(type, filelist) raise "File list not specified" if filelist.nil? or filelist.empty? filelist = [filelist] unless filelist.is_a?(Array) search_dir = Pathname(self.path(type)) directories = [search_dir, search_dir.parent, search_dir.parent.parent] found_dir = directories.find { |pathname| pathname.join(filelist[0]).exist? } raise "#{type} dir not found for '#{filelist[0]}' when searching '#{search_dir}'" if found_dir.nil? filelist.each do |filename| raise "File '#{filename}' not found in #{type} dir s'#{found_dir}'" unless found_dir.join(filename).exist? end found_dir end |
#id ⇒ Object
68 69 70 |
# File 'lib/druid_tools/druid.rb', line 68 def id @druid.scan(self.class.pattern).flatten.join('') end |
#mkdir(extra = nil) ⇒ Object
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/druid_tools/druid.rb', line 82 def mkdir(extra=nil) new_path = path(extra) if(File.symlink? new_path) raise DruidTools::DifferentContentExistsError, "Unable to create directory, link already exists: #{new_path}" end if(File.directory? new_path) raise DruidTools::SameContentExistsError, "The directory already exists: #{new_path}" end FileUtils.mkdir_p(new_path) end |
#mkdir_with_final_link(source, extra = nil) ⇒ Object
116 117 118 119 120 121 122 123 124 |
# File 'lib/druid_tools/druid.rb', line 116 def mkdir_with_final_link(source, extra=nil) new_path = path(extra) if(File.directory?(new_path) && !File.symlink?(new_path)) raise DruidTools::DifferentContentExistsError, "Unable to create link, directory already exists: #{new_path}" end real_path = File.('..',new_path) FileUtils.mkdir_p(real_path) FileUtils.ln_s(source, new_path, :force=>true) end |
#path(extra = nil, create = false) ⇒ Object
76 77 78 79 80 |
# File 'lib/druid_tools/druid.rb', line 76 def path(extra=nil, create=false) result = File.join(*([base,tree,extra].compact)) mkdir(extra) if create and not File.exists?(result) result end |
#pathname ⇒ Object
141 142 143 |
# File 'lib/druid_tools/druid.rb', line 141 def pathname Pathname self.path end |
#prep_deletes_dir ⇒ void
This method returns an undefined value.
This function checks for existance of a .deletes dir one level into the path (ex: stacks/.deletes or purl/.deletes). If the directory does not exist, it is created. If the directory exists, check to see if the current druid has an entry there, if it does delete it. This is done because a file might be deleted, then republishing, then deleted we again, and we want to log the most recent delete.
164 165 166 167 168 169 170 171 |
# File 'lib/druid_tools/druid.rb', line 164 def prep_deletes_dir #Check for existences of deletes dir create_deletes_dir if !deletes_dir_exists? #In theory we could return true after this step (if it fires), since if there was no deletes dir then the file can't be present in the dir #Check to see if this druid has been deleted before, meaning file currently exists deletes_delete_record if deletes_record_exists? end |
#prune! ⇒ Object
149 150 151 152 153 154 155 |
# File 'lib/druid_tools/druid.rb', line 149 def prune! this_path = pathname parent = this_path.parent parent.rmtree if parent.exist? && parent != base_pathname prune_ancestors parent.parent creates_delete_record end |
#prune_ancestors(outermost_branch) ⇒ void
This method returns an undefined value.
Returns Ascend the druid tree and prune empty branches.
225 226 227 228 229 230 231 |
# File 'lib/druid_tools/druid.rb', line 225 def prune_ancestors(outermost_branch) while outermost_branch.exist? && outermost_branch.children.size == 0 outermost_branch.rmdir outermost_branch = outermost_branch.parent break if outermost_branch == base_pathname end end |
#rmdir(extra = nil) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/druid_tools/druid.rb', line 126 def rmdir(extra=nil) parts = tree parts << extra unless extra.nil? while parts.length > 0 dir = File.join(base, *parts) begin FileUtils.rm(File.join(dir,'.DS_Store'), :force => true) FileUtils.rmdir(dir) rescue Errno::ENOTEMPTY break end parts.pop end end |
#tree ⇒ Object
72 73 74 |
# File 'lib/druid_tools/druid.rb', line 72 def tree @druid.scan(self.class.pattern).flatten + [id] end |