Module: Ddr::Utils

Extended by:
Deprecation
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



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

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



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

def self.ds_as_of_date_time(ds)
  ds.create_date_string
end

.file_name_for(file) ⇒ Object



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

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)


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

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

.file_path(file) ⇒ Object



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

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)


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

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)


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

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



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

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”



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

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”



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

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)


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

def self.pid_for_identifier(identifier, opts={})
  Deprecation.warn(self, "`Ddr::Utils.pid_for_identifier` is deprecated. Use .having_local_id model class method and get id from result object(s). (#{caller.first})")
  model = opts.fetch(:model, nil)
  collection = opts.fetch(:collection, nil)
  objs = []
  ActiveFedora::Base.find_each( { Ddr::Index::Fields::IDENTIFIER_ALL => identifier }, { :cast => true } ) { |o| objs << o }
  pids = []
  objs.each { |obj| pids << obj.id }
  if model.present?
    objs.each { |obj| pids.delete(obj.id) unless obj.is_a?(model.constantize) }
  end
  if collection.present?
    objs.each do |obj|
      pids.delete(obj.id) 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.



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

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.



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

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)


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

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

.solr_date(dt) ⇒ String

Returns a string suitable to index as a Solr date

Parameters:

  • dt (Date, DateTime, Time)

    the date/time

Returns:

  • (String)


165
166
167
168
# File 'lib/ddr/utils.rb', line 165

def self.solr_date(dt)
  return if dt.nil?
  dt.to_time.utc.iso8601
end

.solr_dates(dts) ⇒ Object



170
171
172
# File 'lib/ddr/utils.rb', line 170

def self.solr_dates(dts)
  dts.map { |dt| solr_date(dt) }
end