Module: Ddr::Utils

Defined in:
lib/ddr/utils.rb

Constant Summary collapse

DEFAULT_MIME_TYPE =
"application/octet-stream"

Class Method Summary collapse

Class Method Details

.digest(content, algorithm) ⇒ Object



7
8
9
10
11
12
13
# File 'lib/ddr/utils.rb', line 7

def self.digest content, algorithm
  raise TypeError, "Algorithm must be a string: #{algorithm.inspect}" unless algorithm.is_a?(String)
  digest_class = OpenSSL::Digest.const_get(algorithm.sub("-", "").to_sym)
  digest_class.new(content).to_s
rescue NameError => e
  raise ArgumentError, "Invalid algorithm: #{algorithm}"
end

.ds_as_of_date_time(ds) ⇒ Object



79
80
81
# File 'lib/ddr/utils.rb', line 79

def self.ds_as_of_date_time(ds)
  ds.create_date_string
end

.file_name_for(file) ⇒ Object



46
47
48
49
# File 'lib/ddr/utils.rb', line 46

def self.file_name_for file
  return file.original_filename if file.respond_to?(:original_filename) && file.original_filename.present?
  File.basename(file_path(file)) rescue nil
end

.file_or_path?(file) ⇒ Boolean

Returns:

  • (Boolean)


25
26
27
28
29
# File 'lib/ddr/utils.rb', line 25

def self.file_or_path? file
  file_path(file)
rescue ArgumentError
  false
end

.file_path(file) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/ddr/utils.rb', line 36

def self.file_path file
  if file.respond_to?(:path) 
    File.absolute_path(file.path)
  elsif file_path?(file)
    file
  else
    raise ArgumentError, "File argument is neither a File nor a path to an existing file."
  end
end

.file_path?(file) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
34
# File 'lib/ddr/utils.rb', line 31

def self.file_path? file
  # length is a sanity check
  file.is_a?(String) && (file.length < 1024) && File.exists?(file)
end

.file_uri?(uri) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
54
# File 'lib/ddr/utils.rb', line 51

def self.file_uri?(uri)
  return false unless uri
  URI.parse(uri).scheme == "file"
end

.mime_type_for(file, file_name = nil) ⇒ Object

Return a mime type for the file, using the file_name if necessary file can be a File object or file path (String) Return default mime type if unable to determine otherwise



18
19
20
21
22
23
# File 'lib/ddr/utils.rb', line 18

def self.mime_type_for(file, file_name=nil)
  return file.content_type if file.respond_to?(:content_type) # E.g., Rails uploaded file
  path = file_name || file_path(file) rescue nil
  mime_types = MIME::Types.of(path) rescue []                 # MIME::Types.of blows up on nil
  mime_types.empty? ? DEFAULT_MIME_TYPE : mime_types.first.content_type
end

.path_from_uri(uri) ⇒ Object

Return file path for URI string Should reverse .path_to_uri “file:/path/to/file” => “/path/to/file”



66
67
68
# File 'lib/ddr/utils.rb', line 66

def self.path_from_uri(uri)
  URI.unescape(URI.parse(uri).path)
end

.path_to_uri(path) ⇒ Object

Return URI string for file path Should reverse .path_from_uri “/path/to/file” => “file:/path/to/file”



73
74
75
76
77
# File 'lib/ddr/utils.rb', line 73

def self.path_to_uri(path)
  uri = URI.parse(URI.escape(path))
  uri.scheme = "file"
  uri.to_s
end

.pid_for_identifier(identifier, opts = {}) ⇒ Object

Find an object with a given identifier and return its PID. Returns the PID if a single object is found. Returns nil if no object is found. Raises Ddr::Models::Error if more than one object is found. Options can be provided to limit the scope of matching objects

model: Will only consider objects of that model
collection: Will only consider objects that either are that collection or which are
   direct children of that collection (i.e., effectively searches a collection and its
   items for an object with the given identifier)


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ddr/utils.rb', line 92

def self.pid_for_identifier(identifier, opts={})
  model = opts.fetch(:model, nil)
  collection = opts.fetch(:collection, nil)
  objs = []
  ActiveFedora::Base.find_each( { Ddr::IndexFields::IDENTIFIER => identifier }, { :cast => true } ) { |o| objs << o }
  pids = []
  objs.each { |obj| pids << obj.pid }
  if model.present?
    objs.each { |obj| pids.delete(obj.pid) unless obj.is_a?(model.constantize) }
  end
  if collection.present?
    objs.each do |obj|
      pids.delete(obj.pid) unless obj == collection || obj.parent == collection
    end
  end
  case pids.size
  when 0
    nil
  when 1
    pids.first
  else
    raise Ddr::Models::Error, I18n.t('ddr.errors.multiple_object_matches', :criteria => "identifier #{identifier}")
  end
end

.reflection_object_class(reflection) ⇒ Object

Returns the class associated with the :class_name attribute in the options of a reflection E.g., reflection_object_class(relationship_object_reflection(“Item”, “parent”)) returns the Collection class.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/ddr/utils.rb', line 142

def self.reflection_object_class(reflection)
  reflection_object_model = nil
  klass = nil
  if reflection[1].options[:class_name]
    reflection_object_model = reflection[1].options[:class_name]
  else
    reflection_object_model = ActiveSupport::Inflector.camelize(reflection[0])
  end
  if reflection_object_model
    begin
      klass = reflection_object_model.constantize
    rescue NameError
      # nothing to do here except that we can't return the reflection object class
    end
  end
  return klass
end

.relationship_object_reflection(model, relationship_name) ⇒ Object

Returns the reflection object for a given model name and relationship name E.g., relationship_object_reflection(“Item”, “parent”) returns the reflection object for an Item’s parent relationship. This reflection object can then be used to obtain the class of the relationship object using the reflection_object_class(reflection) method below.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ddr/utils.rb', line 121

def self.relationship_object_reflection(model, relationship_name)
  reflection = nil
  if model
    begin
      reflections = model.constantize.reflections
    rescue NameError
      # nothing to do here except that we can't return the appropriate reflection
    else
      reflections.each do |reflect|
        if reflect[0].eql?(relationship_name.to_sym)
          reflection = reflect
        end
      end
    end
  end
  return reflection
end

.sanitize_filename(file_name) ⇒ Object

Raises:

  • (ArgumentError)


56
57
58
59
60
61
# File 'lib/ddr/utils.rb', line 56

def self.sanitize_filename file_name
  return unless file_name
  raise ArgumentError, "file_name argument must be a string" unless file_name.is_a?(String)
  raise ArgumentError, "file_name argument must not include path" if file_name.include?(File::SEPARATOR)
  file_name.gsub(/[^\w\.\-]/,"_")
end