Class: DruidTools::Druid

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

Direct Known Subclasses

AccessDruid

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]'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Druid.

Parameters:

  • druid (String)

    A valid druid

  • true (boolean)

    if validation should be more restrictive about allowed letters (no aeioul)

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

    The directory used by #path

Raises:

  • (ArgumentError)


59
60
61
62
63
64
65
66
# File 'lib/druid_tools/druid.rb', line 59

def initialize(druid, base = '.', strict = false)
  druid = druid.to_s unless druid.is_a? String
  raise ArgumentError, "Invalid DRUID: '#{druid}'" unless self.class.valid?(druid, strict)

  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.



15
16
17
# File 'lib/druid_tools/druid.rb', line 15

def prefix
  @prefix
end

Instance Attribute Details

#baseObject

Returns the value of attribute base.



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

def base
  @base
end

#druidObject

Returns the value of attribute druid.



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

def druid
  @druid
end

Class Method Details

.globString

Returns suitable for use in [Dir#glob].

Returns:

  • (String)

    suitable for use in [Dir#glob]



26
27
28
# File 'lib/druid_tools/druid.rb', line 26

def glob
  "{#{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.

Parameters:

  • true (boolean)

    if validation should be more restrictive about allowed letters (no aeioul)

Returns:

  • (Regexp)

    matches druid:aa111aa1111 or aa111aa1111



19
20
21
22
23
# File 'lib/druid_tools/druid.rb', line 19

def pattern(strict = false)
  return /\A(?:#{prefix}:)?(#{STRICT_LET}{2})(\d{3})(#{STRICT_LET}{2})(\d{4})\z/ if strict

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

.strict_globString

Returns suitable for use in [Dir#glob].

Returns:

  • (String)

    suitable for use in [Dir#glob]



31
32
33
# File 'lib/druid_tools/druid.rb', line 31

def strict_glob
  "{#{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.

Parameters:

  • druid (String)

    id

  • true (boolean)

    if validation should be more restrictive about allowed letters (no aeioul)

Returns:

  • (Boolean)

    true if druid matches pattern; otherwise false



38
39
40
# File 'lib/druid_tools/druid.rb', line 38

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

Instance Method Details

#base_pathnameObject



145
146
147
# File 'lib/druid_tools/druid.rb', line 145

def base_pathname
  Pathname base
end

#find(type, path) ⇒ Object



90
91
92
93
94
# File 'lib/druid_tools/druid.rb', line 90

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



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

def find_filelist_parent(type, filelist)
  raise 'File list not specified' if filelist.nil? || filelist.empty?

  filelist = [filelist] unless filelist.is_a?(Array)
  search_dir = Pathname(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 '#{found_dir}'" unless found_dir.join(filename).exist?
  end
  found_dir
end

#idObject



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
# File 'lib/druid_tools/druid.rb', line 82

def mkdir(extra = nil)
  new_path = path(extra)
  raise DruidTools::DifferentContentExistsError, "Unable to create directory, link already exists: #{new_path}" if File.symlink? new_path
  raise DruidTools::SameContentExistsError, "The directory already exists: #{new_path}" if File.directory? new_path

  FileUtils.mkdir_p(new_path)
end


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

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



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 && !File.exist?(result)
  result
end

#pathnameObject



141
142
143
# File 'lib/druid_tools/druid.rb', line 141

def pathname
  Pathname path
end

#prune!Object



149
150
151
152
153
154
# 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
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



158
159
160
161
162
163
164
# File 'lib/druid_tools/druid.rb', line 158

def prune_ancestors(outermost_branch)
  while outermost_branch.exist? && outermost_branch.children.empty?
    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?
  until parts.empty?
    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



72
73
74
# File 'lib/druid_tools/druid.rb', line 72

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