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 +8 -8
- data/config/dev_console_env.rb +3 -3
- data/lib/dor-services.rb +0 -1
- data/lib/dor/datastreams/content_metadata_ds.rb +70 -3
- data/lib/dor/models/contentable.rb +8 -0
- data/lib/dor/models/describable.rb +36 -0
- data/lib/dor/models/publishable.rb +1 -3
- data/lib/dor/models/releaseable.rb +47 -73
- data/lib/dor/version.rb +1 -1
- metadata +2 -3
- data/lib/dor/models/presentable.rb +0 -147
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZjA2MTBlOGEyMmQwNWQ2MWRmNzQ1NTE1OWQ5Zjc4NzA2NTQwYmUxNw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzRmNDFlNWMyNmQzYzFkMTBlOGM0ZWFiMjU5NDMyNjc3ZjAxYzE2OA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTNkOTc0MmYzMGE2YmIxNDQ1MWQwODdkYWMwMzFjMWNmMWM4ZTZmY2IyZTYz
|
10
|
+
NGFhNWZjNGU0YWI0NmNjNTRiMWUxOWVkMGQzNWYwOWUzMmY5MDdmYTVkMWMw
|
11
|
+
OTRjYTQwMWQzODJkY2FkYjQ2NjJiZmI2OGIwMDJkYWMwYTBmMDY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZGQ5ZDlmNDM4ZTljNGIwNjQ5ZDM3YzA2YjAzZWJkYjUxZjUxMGJlMzZiMzky
|
14
|
+
YmJmMzY0MGQzODNjNGI1ZTNmNmU4ZGIyMjk5NTM3NzQxMmE2NDE4NDZiYjkz
|
15
|
+
NjhiZmM5MTg3NTFjNDUxOWYxYTFkZTc0Mjk1ZDMzYjkyYjVmMjA=
|
data/config/dev_console_env.rb
CHANGED
@@ -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
|
-
|
71
|
-
|
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
|
-
|
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',
|
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
|
-
|
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
|
-
|
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
|
-
|
72
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
206
|
-
#
|
207
|
-
|
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
|
-
|
233
|
-
#
|
234
|
-
|
235
|
-
#
|
236
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
|
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
|
-
|
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
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.
|
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-
|
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
|