dor-services 4.22.5 → 4.22.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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