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 +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
|