Class: DruidTools::Druid

Inherits:
Object
  • Object
show all
Defined in:
lib/druid_tools/druid.rb

Direct Known Subclasses

AccessDruid

Constant Summary collapse

@@deletes_directory_name =
'.deletes'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(druid, base = '.') ⇒ Druid

Returns a new instance of Druid.

Parameters:

  • druid (String)

    A valid druid

  • base (String) (defaults to: '.')

    The directory used by #path



45
46
47
48
49
50
51
52
53
# File 'lib/druid_tools/druid.rb', line 45

def initialize(druid, base='.')
  druid = druid.to_s unless druid.is_a? String
  unless self.class.valid?(druid)
    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

.prefixObject

Returns the value of attribute prefix.



10
11
12
# File 'lib/druid_tools/druid.rb', line 10

def prefix
  @prefix
end

Instance Attribute Details

#baseObject

Returns the value of attribute base.



7
8
9
# File 'lib/druid_tools/druid.rb', line 7

def base
  @base
end

#druidObject

Returns the value of attribute druid.



7
8
9
# File 'lib/druid_tools/druid.rb', line 7

def druid
  @druid
end

Class Method Details

.globString

Returns suitable for use in [Dir#glob].

Returns:

  • (String)

    suitable for use in [Dir#glob]



18
19
20
# File 'lib/druid_tools/druid.rb', line 18

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

.patternRegexp

Returns matches druid:aa111aa1111 or aa111aa1111.

Returns:

  • (Regexp)

    matches druid:aa111aa1111 or aa111aa1111



13
14
15
# File 'lib/druid_tools/druid.rb', line 13

def pattern
  /\A(?:#{self.prefix}:)?([a-z]{2})(\d{3})([a-z]{2})(\d{4})\z/
end

.valid?(druid) ⇒ Boolean

Returns true if druid matches pattern; otherwise false.

Parameters:

  • druid (String)

    id

Returns:

  • (Boolean)

    true if druid matches pattern; otherwise false



24
25
26
# File 'lib/druid_tools/druid.rb', line 24

def valid?(druid)
  return druid =~ pattern ? true : false
end

Instance Method Details

#base_pathnameObject



132
133
134
# File 'lib/druid_tools/druid.rb', line 132

def base_pathname
  Pathname self.base
end

#create_deletes_dirvoid

This method returns an undefined value.

Creates the deletes dir using the path supplied by deletes_dir_pathname



187
188
189
# File 'lib/druid_tools/druid.rb', line 187

def create_deletes_dir
  FileUtils::mkdir_p deletes_dir_pathname
end

#creates_delete_recordvoid

This method returns an undefined value.

Creates an empty (pointer) file using the object’s id in the .deletes dir



205
206
207
208
# File 'lib/druid_tools/druid.rb', line 205

def creates_delete_record
  prep_deletes_dir
  FileUtils.touch(deletes_record_pathname)
end

#deletes_delete_recordObject

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]



196
197
198
# File 'lib/druid_tools/druid.rb', line 196

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

Returns:

  • (Boolean)

    true if if exists, false if it does not



174
175
176
# File 'lib/druid_tools/druid.rb', line 174

def deletes_dir_exists?
  return File.directory?(deletes_dir_pathname) 
end

#deletes_dir_pathnamePathname

Provide the location for the .deletes directory in the tree

Returns:

  • (Pathname)

    the path to the directory, ex: “stacks/.deletes”



163
164
165
# File 'lib/druid_tools/druid.rb', line 163

def deletes_dir_pathname
  return Pathname(self.base.to_s + (File::SEPARATOR+@@deletes_directory_name))
end

#deletes_record_exists?Boolean

Returns:

  • (Boolean)


178
179
180
# File 'lib/druid_tools/druid.rb', line 178

def deletes_record_exists?
  return File.exists?(deletes_dir_pathname.to_s + File::SEPARATOR + self.id)
end

#deletes_record_pathnameObject



167
168
169
# File 'lib/druid_tools/druid.rb', line 167

def deletes_record_pathname
  return Pathname(deletes_dir_pathname.to_s + File::SEPARATOR + self.id)
end

#find(type, path) ⇒ Object



80
81
82
83
84
# File 'lib/druid_tools/druid.rb', line 80

def find(type, path)
  possibles = [self.path(type.to_s),self.path,File.expand_path('..',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.

Parameters:

  • type (String)

    The type of directory being sought (‘content’, ‘metadata’, or ‘temp’)

  • filelist (Array<String>, String)

    The files that are expected to be present in the directory

Returns:

  • (Pathname)

    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.



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/druid_tools/druid.rb', line 90

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

#idObject



55
56
57
# File 'lib/druid_tools/druid.rb', line 55

def id
  @druid.scan(self.class.pattern).flatten.join('')
end

#mkdir(extra = nil) ⇒ Object



69
70
71
72
73
74
75
76
77
78
# File 'lib/druid_tools/druid.rb', line 69

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


103
104
105
106
107
108
109
110
111
# File 'lib/druid_tools/druid.rb', line 103

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.expand_path('..',new_path)
  FileUtils.mkdir_p(real_path)
  FileUtils.ln_s(source, new_path, :force=>true)
end

#path(extra = nil, create = false) ⇒ Object



63
64
65
66
67
# File 'lib/druid_tools/druid.rb', line 63

def path(extra=nil, create=false)
  result = File.join(*([base,tree,extra].compact))
  mkdir(extra) if create and not File.exists?(result)
  result
end

#pathnameObject



128
129
130
# File 'lib/druid_tools/druid.rb', line 128

def pathname
  Pathname self.path
end

#prep_deletes_dirvoid

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.



151
152
153
154
155
156
157
158
# File 'lib/druid_tools/druid.rb', line 151

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



136
137
138
139
140
141
142
# File 'lib/druid_tools/druid.rb', line 136

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.

Parameters:

  • outermost_branch (Pathname)

    The branch at which pruning begins



212
213
214
215
216
217
218
219
# File 'lib/druid_tools/druid.rb', line 212

def prune_ancestors(outermost_branch)
  while outermost_branch.children.size == 0
    outermost_branch.rmdir
    outermost_branch = outermost_branch.parent
    break if  outermost_branch == base_pathname
  end
rescue
end

#rmdir(extra = nil) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/druid_tools/druid.rb', line 113

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

#treeObject



59
60
61
# File 'lib/druid_tools/druid.rb', line 59

def tree
  @druid.scan(self.class.pattern).flatten + [id]
end