dor-services 4.22.5 → 4.22.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTI0OGVkMDM4YWVjYzE4MTgxOGJhYTI1MTExZDA4YWFlZTE0ZDRiNQ==
4
+ ZjA2MTBlOGEyMmQwNWQ2MWRmNzQ1NTE1OWQ5Zjc4NzA2NTQwYmUxNw==
5
5
  data.tar.gz: !binary |-
6
- ZjA2YmNkYjJkM2YxMTkzYTI1YjE4OTY3ZTEzYzMwMWUyNDliOTQwMA==
6
+ MzRmNDFlNWMyNmQzYzFkMTBlOGM0ZWFiMjU5NDMyNjc3ZjAxYzE2OA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDRmODA5Nzk5ZDJkZTNjN2M1MWQ5NDdkZTg4MjJhODRiYTczN2RmMWE5NWYw
10
- ZDI4YWEzYzE5OWI1YzM2Yjc1MzVkOWEzMzhmNDVhY2Q5NDVhYWY2YTA5MTY0
11
- M2VkOTFiODZhZjhjNWM0Yzc0YWMwOTdhNDU1ZDg0OWI0MDAwY2Y=
9
+ YTNkOTc0MmYzMGE2YmIxNDQ1MWQwODdkYWMwMzFjMWNmMWM4ZTZmY2IyZTYz
10
+ NGFhNWZjNGU0YWI0NmNjNTRiMWUxOWVkMGQzNWYwOWUzMmY5MDdmYTVkMWMw
11
+ OTRjYTQwMWQzODJkY2FkYjQ2NjJiZmI2OGIwMDJkYWMwYTBmMDY=
12
12
  data.tar.gz: !binary |-
13
- MTIyMmY0ZDY2NGQ1YzRiMTgxN2ZlZjFlM2JjY2M1NWJkNmY5MzhlZGZhMTY5
14
- NDc0NTk5ODJhNjllMzAzMjg4NmM0MWQ0OTgzMWQ0ODg3OWM2NzA2YjEzYjlm
15
- ZTUzMDI1MTFjOWYyNzYzMjNlNjk4OTcxYTQwNThhOTlhZmIzNmM=
13
+ ZGQ5ZDlmNDM4ZTljNGIwNjQ5ZDM3YzA2YjAzZWJkYjUxZjUxMGJlMzZiMzky
14
+ YmJmMzY0MGQzODNjNGI1ZTNmNmU4ZGIyMjk5NTM3NzQxMmE2NDE4NDZiYjkz
15
+ NjhiZmM5MTg3NTFjNDUxOWYxYTFkZTc0Mjk1ZDMzYjkyYjVmMjA=
@@ -65,13 +65,13 @@ Dor::Config.configure do
65
65
 
66
66
  end
67
67
 
68
- #WORKFLOW_URI = 'http://lyberservices-test.stanford.edu/workflow'
68
+ # WORKFLOW_URI = 'http://lyberservices-test.stanford.edu/workflow'
69
69
 
70
70
  # Constants for Dor::WorkflowService
71
- #module Dor
71
+ # module Dor
72
72
  # CREATE_WORKFLOW = DOR_CREATE_WORKFLOW = true
73
73
  # WF_URI = 'http://lyberservices-test.stanford.edu/workflow'
74
- #end
74
+ # end
75
75
 
76
76
  # External application locations
77
77
  JHOVE_HOME = File.join(ENV['HOME'], 'jhoveToolkit')
data/lib/dor-services.rb CHANGED
@@ -117,7 +117,6 @@ module Dor
117
117
  autoload :Editable, 'dor/models/editable'
118
118
  autoload :Discoverable, 'dor/models/discoverable'
119
119
  autoload :Geoable, 'dor/models/geoable'
120
- autoload :Presentable, 'dor/models/presentable'
121
120
  autoload :Releaseable, 'dor/models/releaseable'
122
121
  autoload :Rightsable, 'dor/models/rightsable'
123
122
 
@@ -67,10 +67,76 @@ module Dor
67
67
  save
68
68
  end
69
69
 
70
- def add_resource(files,resource_name, position,type = "file")
71
- xml = ng_xml
70
+ #
71
+ # Generates the XML tree for externalFile references. For example,
72
+ #
73
+ # <externalFile objectId="druid:mn123pq4567" resourceId="Image01" fileId="image_01.jp2000" mimetype="image/jp2" />
74
+ #
75
+ # @param [String] objectId the linked druid
76
+ # @param [String] resourceId the linked druid's resource identifier
77
+ # @param [String] fileId the linked druid's resource's file identifier
78
+ # @param [String] mimetype the file's MIME type
79
+ #
80
+ # @return [Nokogiri::XML::Element]
81
+ #
82
+ def generate_external_file_node(objectId, resourceId, fileId, mimetype)
83
+ externalFile = ng_xml.create_element 'externalFile'
84
+ externalFile[:objectId] = objectId
85
+ externalFile[:resourceId] = resourceId
86
+ externalFile[:fileId] = fileId
87
+ externalFile[:mimetype] = mimetype
88
+ externalFile
89
+ end
90
+
91
+ #
92
+ # Generates the XML tree for virtual resource relationship reference. For example,
93
+ #
94
+ # <relationship type="alsoAvailableAs" objectId="druid:mn123pq4567" />
95
+ #
96
+ # @param [String] objectId the linked druid
97
+ #
98
+ # @return [Nokogiri::XML::Element]
99
+ #
100
+ def generate_also_available_as_node(objectId)
101
+ relationship = ng_xml.create_element 'relationship'
102
+ relationship[:type] = 'alsoAvailableAs'
103
+ relationship[:objectId] = objectId
104
+ relationship
105
+ end
106
+
107
+ #
108
+ # Copies the child's resource into the parent (self) as a virtual resource.
109
+ # Assumes the resource isn't a duplicate of an existing virtual or real resource.
110
+ #
111
+ # @param [String] child_druid druid
112
+ # @param [Nokogiri::XML::Element] child_resource
113
+ #
114
+ # @return [Nokogiri::XML::Element] the new resource that was added to the contentMetadata
115
+ #
116
+ def add_virtual_resource(child_druid, child_resource)
117
+ # create a virtual resource element with attributes linked to the child and omit label
118
+ sequence_max = self.ng_xml.search('//resource').map{ |node| node[:sequence].to_i }.max
119
+ resource = Nokogiri::XML::Element.new('resource', self.ng_xml)
120
+ resource[:sequence] = sequence_max + 1
121
+ resource[:id] = "#{self.pid.gsub(/^druid:/, '')}_#{resource[:sequence]}"
122
+ resource[:type] = child_resource[:type]
123
+
124
+ # iterate over all the published files and link to them
125
+ child_resource.search('file[@publish=\'yes\']').each do |file|
126
+ resource << generate_external_file_node(child_druid, child_resource[:id], file[:id], file[:mimetype])
127
+ end
128
+ resource << generate_also_available_as_node(child_druid)
129
+
130
+ # save the virtual resource as a sibling and return
131
+ self.ng_xml.root << resource
132
+ resource
133
+ end
134
+
135
+ def add_resource(files,resource_name, position,type="file")
136
+ xml=ng_xml
72
137
  raise "resource #{resource_name} already exists" if xml.search('//resource[@id=\'' + resource_name + '\']').length > 0
73
- max = -1
138
+
139
+ max=-1
74
140
  xml.search('//resource').each do |node|
75
141
  max = node['sequence'].to_i if node['sequence'].to_i > max
76
142
  end
@@ -83,6 +149,7 @@ module Dor
83
149
  end
84
150
  max -= 1
85
151
  end
152
+
86
153
  node = Nokogiri::XML::Node.new('resource',xml)
87
154
  node['sequence'] = position.to_s
88
155
  node['id'] = resource_name
@@ -222,5 +222,13 @@ module Dor
222
222
  rightsMetadata.content = '<rightsMetadata/>'
223
223
  add_tag "Decommissioned : #{tag}"
224
224
  end
225
+
226
+ # Adds a RELS-EXT constituent relationship to the given druid
227
+ # @param [String] druid the parent druid of the constituent relationship
228
+ # e.g.,
229
+ # <fedora:isConstituentOf rdf:resource="info:fedora/druid:hj097bm8879" />
230
+ def add_constituent(druid)
231
+ add_relationship :is_constituent_of, ActiveFedora::Base.find(druid)
232
+ end
225
233
  end
226
234
  end
@@ -53,6 +53,7 @@ module Dor
53
53
  doc = descMetadata.ng_xml.dup(1)
54
54
  add_collection_reference(doc)
55
55
  add_access_conditions(doc)
56
+ add_constituent_relations(doc)
56
57
  doc.xpath('//comment()').remove
57
58
  new_doc = Nokogiri::XML(doc.to_xml) { |x| x.noblanks }
58
59
  new_doc.encoding = 'UTF-8'
@@ -139,6 +140,41 @@ module Dor
139
140
  related_item_node.add_child(type_node)
140
141
  end
141
142
  end
143
+
144
+ # expand constituent relations into relatedItem references -- see JUMBO-18
145
+ # @param [Nokogiri::XML] doc public MODS XML being built
146
+ def add_constituent_relations(doc)
147
+ self.public_relationships.search('//rdf:RDF/rdf:Description/fedora:isConstituentOf',
148
+ 'fedora' => 'info:fedora/fedora-system:def/relations-external#',
149
+ 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' ).each do |parent|
150
+ # fetch the parent object to get title
151
+ druid = parent['rdf:resource'].gsub(/^info:fedora\//, '')
152
+ parent_item = Dor::Item.find(druid)
153
+
154
+ # create the MODS relation
155
+ relatedItem = doc.create_element 'relatedItem'
156
+ relatedItem['type'] = 'host'
157
+ relatedItem['displayLabel'] = 'Appears in'
158
+
159
+ # load the title from the parent's DC.title
160
+ titleInfo = doc.create_element 'titleInfo'
161
+ title = doc.create_element 'title'
162
+ title.content = parent_item.datastreams['DC'].title.first
163
+ titleInfo << title
164
+ relatedItem << titleInfo
165
+
166
+ # point to the PURL for the parent
167
+ location = doc.create_element 'location'
168
+ url = doc.create_element 'url'
169
+ url.content = "http://#{Dor::Config.stacks.document_cache_host}/#{druid.split(':').last}"
170
+ location << url
171
+ relatedItem << location
172
+
173
+ # finish up by adding relation to public MODS
174
+ doc.root << relatedItem
175
+ end
176
+ end
177
+
142
178
  def metadata_namespace
143
179
  desc_md = datastreams['descMetadata'].ng_xml
144
180
  return nil if desc_md.nil? || desc_md.root.nil? || desc_md.root.namespace.nil?
@@ -7,7 +7,6 @@ module Dor
7
7
  include Governable
8
8
  include Describable
9
9
  include Itemizable
10
- include Presentable
11
10
 
12
11
  included do
13
12
  has_metadata name: 'rightsMetadata', type: ActiveFedora::OmDatastream, label: 'Rights Metadata'
@@ -21,7 +20,7 @@ module Dor
21
20
  end
22
21
 
23
22
  def public_relationships
24
- include_elements = ['fedora:isMemberOf', 'fedora:isMemberOfCollection']
23
+ include_elements = ['fedora:isMemberOf','fedora:isMemberOfCollection','fedora:isConstituentOf']
25
24
  rels_doc = Nokogiri::XML(datastreams['RELS-EXT'].content)
26
25
  rels_doc.xpath('/rdf:RDF/rdf:Description/*', 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#').each do |rel|
27
26
  unless include_elements.include?([rel.namespace.prefix, rel.name].join(':'))
@@ -72,7 +71,6 @@ module Dor
72
71
  DigitalStacksService.transfer_to_document_store(pid, datastreams['rightsMetadata'].to_xml, 'rightsMetadata')
73
72
  DigitalStacksService.transfer_to_document_store(pid, public_xml, 'public')
74
73
  DigitalStacksService.transfer_to_document_store(pid, generate_public_desc_md, 'mods') if metadata_format == 'mods'
75
- DigitalStacksService.transfer_to_document_store(pid, build_iiif_manifest(@public_xml_doc), 'manifest') if iiif_presentation_manifest_needed? @public_xml_doc
76
74
  else
77
75
  # Clear out the document cache for this item
78
76
  DigitalStacksService.prune_purl_dir pid
@@ -6,13 +6,9 @@ module Dor
6
6
  extend ActiveSupport::Concern
7
7
  include Itemizable
8
8
 
9
- #Add release tags to an item and initialize the item release workflow
10
- #
11
- #@params release_tags [Hash or Array] Either a hash of a single release tag. Each tag should be in the form of {:tag=>'Fitch : Batch2',:what=>'self',:to=>'Searchworks',:who=>'petucket', :release=>true/false}
12
- #
13
- #@raise [ArgumentError] Raised if the tags are improperly supplied
14
- #
15
- #
9
+ # Add release tags to an item and initialize the item release workflow
10
+ # @param release_tags [Hash or Array] Either a hash of a single release tag. Each tag should be in the form of {:tag=>'Fitch : Batch2',:what=>'self',:to=>'Searchworks',:who=>'petucket', :release=>true/false}
11
+ # @raise [ArgumentError] Raised if the tags are improperly supplied
16
12
  def add_release_nodes_and_start_releaseWF(release_tags)
17
13
  release_tags = [release_tags] unless release_tags.is_a?(Array)
18
14
 
@@ -26,9 +22,8 @@ module Dor
26
22
  initialize_workflow('releaseWF')
27
23
  end
28
24
 
29
- #Generate XML structure for inclusion to Purl
30
- #
31
- #@return [String] The XML release node as a string, with ReleaseDigest as the root document
25
+ # Generate XML structure for inclusion to Purl
26
+ # @return [String] The XML release node as a string, with ReleaseDigest as the root document
32
27
  def generate_release_xml
33
28
  builder = Nokogiri::XML::Builder.new do |xml|
34
29
  xml.releaseData {
@@ -40,10 +35,10 @@ module Dor
40
35
  builder.to_xml
41
36
  end
42
37
 
43
- #Determine which projects an item is released for
44
- #
45
- #@return [Hash] all namespaces in the form of {"Project" => Boolean}
46
- def released_for
38
+ # Determine which projects an item is released for
39
+ # @param [Boolean] skip_live_purl set true to skip requesting from purl backend
40
+ # @return [Hash{String => Boolean}] all namespaces, keys are Project name Strings, values are Boolean
41
+ def released_for(skip_live_purl = false)
47
42
  released_hash = {}
48
43
  # Get release tags on the item itself
49
44
  release_tags_on_this_item = release_nodes
@@ -68,13 +63,14 @@ module Dor
68
63
  # In a nil case, the lack of an explicit false tag we do nothing.
69
64
  (potential_applicable_release_tags.keys - released_hash.keys).each do |key| # don't bother checking if already added to the release hash, they were added due to a self tag so that has won
70
65
  latest_applicable_tag_for_key = latest_applicable_release_tag_in_array(potential_applicable_release_tags[key], administrative_tags)
71
- unless latest_applicable_tag_for_key.nil? # We have a valid tag, record it
72
- released_hash[key] = clean_release_tag_for_purl(latest_applicable_tag_for_key)
73
- end
66
+ next if latest_applicable_tag_for_key.nil? # We have a valid tag, record it
67
+ released_hash[key] = clean_release_tag_for_purl(latest_applicable_tag_for_key)
74
68
  end
75
69
 
76
70
  # See what the application is currently released for on Purl. If something is released in purl but not listed here, it needs to be added as a false
77
- add_tags_from_purl(released_hash)
71
+ add_tags_from_purl(released_hash) unless skip_live_purl
72
+
73
+ released_hash
78
74
  end
79
75
 
80
76
  #Take a hash of tags as obtained via Dor::Item.release_tags and returns all self tags
@@ -127,11 +123,9 @@ module Dor
127
123
  return_hash
128
124
  end
129
125
 
130
- #Take a hash of tags as obtained via Dor::Item.release_tags and returns the newest tag for each namespace
131
- #
132
- #@params tags [Hash] a hash of tags obtained via Dor::Item.release_tags or matching format
133
- #
134
- #@return [Hash] a hash of latest tags for each to value
126
+ # Take a hash of tags as obtained via Dor::Item.release_tags and returns the newest tag for each namespace
127
+ # @param tags [Hash] a hash of tags obtained via Dor::Item.release_tags or matching format
128
+ # @return [Hash] a hash of latest tags for each to value
135
129
  def get_newest_release_tag(tags)
136
130
  Hash[tags.map {|key, val| [key, newest_release_tag_in_an_array(val)]}]
137
131
  end
@@ -143,11 +137,9 @@ module Dor
143
137
  {'release' => tag['release']}
144
138
  end
145
139
 
146
- #Takes an array of release tags and returns the most recent one
147
- #
148
- #@params tags [Array] an array of hashes, with the hashes being release tags
149
- #
150
- #@return [Hash] the most recent tag
140
+ # Takes an array of release tags and returns the most recent one
141
+ # @param tags [Array] an array of hashes, with the hashes being release tags
142
+ # @return [Hash] the most recent tag
151
143
  def newest_release_tag_in_an_array(array_of_tags)
152
144
  latest_tag_in_array = array_of_tags[0] || {}
153
145
  array_of_tags.each do |tag|
@@ -202,11 +194,9 @@ module Dor
202
194
  return_hash
203
195
  end
204
196
 
205
- #method to convert one release element into an array
206
- #
207
- #@param rtag [Nokogiri::XML::Element] the release tag element
208
- #
209
- #return [Hash] in the form of {:to => String :attrs = Hash}
197
+ # Method to convert one release element into an array
198
+ # @param rtag [Nokogiri::XML::Element] the release tag element
199
+ # @return [Hash] in the form of {:to => String :attrs = Hash}
210
200
  def release_tag_node_to_hash(rtag)
211
201
  to = 'to'
212
202
  release = 'release'
@@ -226,18 +216,14 @@ module Dor
226
216
  return_hash
227
217
  end
228
218
 
229
- #Add a release node for the item
230
- #Will use the current time to add in the timestamp if you do not supply a timestamp, you can supply a timestap for correcting history, etc if desired
231
- #
232
- #@return [Nokogiri::XML::Element] the tag added if successful
233
- #
234
- #@raise [ArgumentError] Raised if attributes are improperly supplied
235
- #
236
- #@params tag [Boolean] True or false for the release node
237
- #@params attrs [hash] A hash of any attributes to be placed onto the tag
238
- #Timestamp will be calculated by the function, if no displayType is passed in, it will default to file
239
- #
240
- #@example
219
+ # Add a release node for the item
220
+ # Will use the current time to add in the timestamp if you do not supply a timestamp, you can supply a timestap for correcting history, etc if desired
221
+ # @param tag [Boolean] True or false for the release node
222
+ # @param attrs [hash] A hash of any attributes to be placed onto the tag
223
+ # Timestamp will be calculated by the function, if no displayType is passed in, it will default to file
224
+ # @return [Nokogiri::XML::Element] the tag added if successful
225
+ # @raise [ArgumentError] Raised if attributes are improperly supplied
226
+ # @example
241
227
  # item.add_tag(true,:release,{:tag=>'Fitch : Batch2',:what=>'self',:to=>'Searchworks',:who=>'petucket', :displayType='filmstrip'})
242
228
  def add_release_node(release, attrs = {})
243
229
  identity_metadata_ds = identityMetadata
@@ -251,13 +237,10 @@ module Dor
251
237
  identity_metadata_ds.add_value(:release, release.to_s, attrs)
252
238
  end
253
239
 
254
- #Determine if the supplied tag is a valid release node that meets all requirements
255
- #
256
- #@raises [ArgumentError] Raises an error of the first fault in the release tag
257
- #
258
- #@return [Boolean] Returns true if no errors found
259
- #
260
- #@params attrs [hash] A hash of attributes for the tag, must contain :when, a ISO 8601 timestamp and :who to identify who or what added the tag, :to,
240
+ # Determine if the supplied tag is a valid release node that meets all requirements
241
+ # @raises [ArgumentError] Raises an error of the first fault in the release tag
242
+ # @return [Boolean] Returns true if no errors found
243
+ # @param attrs [hash] A hash of attributes for the tag, must contain :when, a ISO 8601 timestamp and :who to identify who or what added the tag, :to,
261
244
  def valid_release_attributes(tag, attrs = {})
262
245
  raise ArgumentError, ":when is not iso8601" if attrs[:when].match('\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z').nil?
263
246
  [:who, :to, :what].each do |check_attr|
@@ -276,9 +259,8 @@ module Dor
276
259
  true
277
260
  end
278
261
 
279
- #helper method to get the release nodes as a nodeset
280
- #
281
- #@return [Nokogiri::XML::NodeSet] of all release tags and their attributes
262
+ # Helper method to get the release nodes as a nodeset
263
+ # @return [Nokogiri::XML::NodeSet] of all release tags and their attributes
282
264
  def release_nodes
283
265
  release_tags = identityMetadata.ng_xml.xpath('//release')
284
266
  return_hash = {}
@@ -293,15 +275,10 @@ module Dor
293
275
  return_hash
294
276
  end
295
277
 
296
- #Get a list of all release nodes found in a purl document
297
- #
298
- #@params druid [String]
299
- #
300
- #@raises [OpenURI::HTTPError]
301
- #
302
- #Fetches purl xml for a druid
303
- #
304
- #@return [Nokogiri::HTML::Document] the parsed xml for the druid or an empty document if no purl is found
278
+ # Get a list of all release nodes found in a purl document, fetches purl xml for a druid
279
+ # @param druid [String]
280
+ # @raises [OpenURI::HTTPError]
281
+ # @return [Nokogiri::HTML::Document] the parsed xml for the druid or an empty document if no purl is found
305
282
  def get_xml_from_purl
306
283
  url = form_purl_url
307
284
  handler = Proc.new do |exception, attempt_number, total_delay|
@@ -333,20 +310,17 @@ module Dor
333
310
  'https://' + Dor::Config.stacks.document_cache_host + "/#{remove_druid_prefix}.xml"
334
311
  end
335
312
 
336
- #Pull all release nodes from the public xml obtained via the purl query
337
- #
338
- #@params druid [Nokogiri::HTML::Document] The druid of the object you want
339
- #
340
- #@return [Array] An array containing all the release tags
313
+ # Pull all release nodes from the public xml obtained via the purl query
314
+ # @param druid [Nokogiri::HTML::Document] The druid of the object you want
315
+ # @return [Array] An array containing all the release tags
341
316
  def get_release_tags_from_purl_xml(doc)
342
317
  nodes = doc.xpath('//html/body/publicobject/releasedata').children
343
318
  # We only want the nodes with a name that isn't text
344
319
  nodes.reject {|n| n.name.nil? || n.name.downcase == 'text'}.map {|n| n.attr('to')}.uniq
345
320
  end
346
321
 
347
- #Pull all release nodes from the public xml obtained via the purl query
348
- #
349
- #@return [Array] An array containing all the release tags
322
+ # Pull all release nodes from the public xml obtained via the purl query
323
+ # @return [Array] An array containing all the release tags
350
324
  def get_release_tags_from_purl
351
325
  xml = get_xml_from_purl
352
326
  get_release_tags_from_purl_xml(xml)
@@ -370,7 +344,7 @@ module Dor
370
344
 
371
345
  # TODO: sort of worried about the performance impact in bulk reindex
372
346
  # situations, since released_for recurses all parent collections. jmartin 2015-07-14
373
- released_for().each { |key, val|
347
+ released_for(true).each { |key, val|
374
348
  add_solr_value(solr_doc, 'released_to', key, :symbol, []) if val
375
349
  }
376
350
 
data/lib/dor/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dor
2
- VERSION = '4.22.5'
2
+ VERSION = '4.22.6'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dor-services
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.22.5
4
+ version: 4.22.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Klein
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-11-04 00:00:00.000000000 Z
15
+ date: 2015-11-19 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: active-fedora
@@ -588,7 +588,6 @@ files:
588
588
  - lib/dor/models/item.rb
589
589
  - lib/dor/models/itemizable.rb
590
590
  - lib/dor/models/mods2dc.xslt
591
- - lib/dor/models/presentable.rb
592
591
  - lib/dor/models/preservable.rb
593
592
  - lib/dor/models/processable.rb
594
593
  - lib/dor/models/publishable.rb
@@ -1,147 +0,0 @@
1
- require 'iiif/presentation'
2
-
3
- module Dor
4
- module Presentable
5
-
6
- DC_NS = {"dc"=>"http://purl.org/dc/elements/1.1/", "oai_dc"=>"http://www.openarchives.org/OAI/2.0/oai_dc/"}
7
-
8
- def iiif_presentation_manifest_needed? pub_obj_doc
9
- if(pub_obj_doc.at_xpath('/publicObject/contentMetadata[contains(@type,"image") or contains(@type,"map")]/resource[@type="image"]'))
10
- return true
11
- elsif(pub_obj_doc.at_xpath('/publicObject/contentMetadata[@type="book"]/resource[@type="page"]'))
12
- return true
13
- else
14
- return false
15
- end
16
- end
17
-
18
- # Bypass this method if there are no image resources in contentMetadata
19
- def build_iiif_manifest pub_obj_doc
20
- id = pid.split(':').last
21
-
22
- lbl_node = pub_obj_doc.at_xpath '//oai_dc:dc/dc:title', DC_NS
23
- if lbl_node.nil?
24
- lbl_node = pub_obj_doc.at_xpath('/publicObject/identityMetadata/objectLabel')
25
- end
26
- raise "Unable to build IIIF Presentation manifest: No identityMetadata/objectLabel or dc:title" if lbl_node.nil?
27
- lbl = lbl_node.text
28
-
29
- purl_base_uri = "https://#{Dor::Config.stacks.document_cache_host}/#{id}"
30
-
31
- manifest_data = {
32
- '@id' => "#{purl_base_uri}/iiif/manifest.json",
33
- 'label' => lbl,
34
- 'attribution' => 'Provided by the Stanford University Libraries',
35
- 'logo' => {
36
- '@id' => "https://stacks.stanford.edu/image/iiif/wy534zh7137%2FSULAIR_rosette/full/400,/0/default.jpg",
37
- 'service' => {
38
- '@context' => "http://iiif.io/api/image/2/context.json",
39
- '@id' => "https://stacks.stanford.edu/image/iiif/wy534zh7137%2FSULAIR_rosette",
40
- 'profile' => "http://iiif.io/api/image/2/level1.json"
41
- }
42
- },
43
- 'seeAlso' => {
44
- '@id' => "#{purl_base_uri}.mods",
45
- 'format' => 'application/mods+xml'
46
- }
47
- }
48
- # Use the human copyright statement for attribution if present
49
- if(cr = pub_obj_doc.at_xpath('/publicObject/rightsMetadata/copyright/human[@type="copyright"]'))
50
- manifest_data['attribution'] = cr.text
51
- end
52
-
53
- manifest = IIIF::Presentation::Manifest.new manifest_data
54
-
55
- # Set viewingHint to paged if this is a book
56
- if(pub_obj_doc.at_xpath('/publicObject/contentMetadata[@type="book"]'))
57
- manifest.viewingHint = "paged"
58
- end
59
-
60
- metadata = []
61
- # make into method, pass in xpath and label
62
- add_metadata 'Creator', '//oai_dc:dc/dc:creator', metadata, pub_obj_doc
63
- add_metadata 'Contributor', '//oai_dc:dc/dc:contributor', metadata, pub_obj_doc
64
- add_metadata 'Publisher', '//oai_dc:dc/dc:publisher', metadata, pub_obj_doc
65
- add_metadata 'Date', '//oai_dc:dc/dc:date', metadata, pub_obj_doc
66
- add_metadata 'PublishVersion', '/publicObject/@publishVersion', metadata, pub_obj_doc
67
-
68
- # Save off the first dc:description without displayLabel
69
- if(desc = pub_obj_doc.at_xpath('//oai_dc:dc/dc:description[not(@displayLabel)]', DC_NS))
70
- manifest.description = desc.text
71
- end
72
-
73
- manifest.metadata = metadata unless metadata.empty?
74
-
75
- seq_data = {
76
- '@id' => "#{purl_base_uri}/sequence-1",
77
- 'label' => 'Current order'
78
- }
79
- sequence = IIIF::Presentation::Sequence.new seq_data
80
-
81
- # for each resource image, create a canvas
82
- count = 0
83
- pub_obj_doc.xpath('/publicObject/contentMetadata/resource[@type="image" or @type="page"]').each do |res_node|
84
- count += 1
85
- img_file_name = res_node.at_xpath('file[@mimetype="image/jp2"]/@id').text.split('.').first
86
- height = res_node.at_xpath('file[@mimetype="image/jp2"]/imageData/@height').text.to_i
87
- width = res_node.at_xpath('file[@mimetype="image/jp2"]/imageData/@width').text.to_i
88
- stacks_uri = "#{Dor::Config.stacks.url}/image/iiif/#{id}%2F#{img_file_name}"
89
-
90
- canv = IIIF::Presentation::Canvas.new
91
- canv['@id'] = "#{purl_base_uri}/canvas/canvas-#{count}"
92
- label_node = res_node.at_xpath('label')
93
- if label_node
94
- canv.label = label_node.text
95
- else
96
- canv.label = "image"
97
- end
98
- canv.height = height
99
- canv.width = width
100
-
101
- anno = IIIF::Presentation::Annotation.new
102
- anno['@id'] = "#{purl_base_uri}/imageanno/anno-#{count}"
103
- anno['on'] = canv['@id']
104
-
105
- img_res = IIIF::Presentation::ImageResource.new
106
- img_res['@id'] = "#{stacks_uri}/full/full/0/default.jpg"
107
- img_res.format = 'image/jpeg'
108
- img_res.height = height
109
- img_res.width = width
110
-
111
- svc = IIIF::Service.new ({
112
- '@context' => 'http://iiif.io/api/image/2/context.json',
113
- '@id' => stacks_uri,
114
- 'profile' => Dor::Config.stacks.iiif_profile
115
- })
116
-
117
- # Use the first image to create a thumbnail on the manifest
118
- if count == 1
119
- thumb = IIIF::Presentation::Resource.new
120
- thumb['@id'] = "#{stacks_uri}/full/400,/0/default.jpg"
121
- thumb.service = svc
122
- manifest.thumbnail = thumb
123
- end
124
-
125
- img_res.service = svc
126
- anno.resource = img_res
127
- canv.images << anno
128
- sequence.canvases << canv
129
- end
130
-
131
- manifest.sequences << sequence
132
- manifest.to_json(:pretty => true)
133
- end
134
-
135
- def add_metadata label, xpath, metadata, pub_obj_doc
136
- nodes = pub_obj_doc.xpath xpath, DC_NS
137
- nodes.each do |node|
138
- h = {
139
- 'label' => label,
140
- 'value' => node.text
141
- }
142
- metadata << h
143
- end
144
- end
145
-
146
- end
147
- end