Module: Dor::Releaseable
- Extended by:
- ActiveSupport::Concern
- Includes:
- Itemizable
- Included in:
- BasicItem
- Defined in:
- lib/dor/models/releaseable.rb
Constant Summary
Constants included from Itemizable
Itemizable::DIFF_FILENAME, Itemizable::DIFF_QUERY
Instance Method Summary collapse
-
#add_release_node(release, attrs = {}) ⇒ Nokogiri::XML::Element
Add a release node for the item 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.
-
#add_release_nodes_and_start_releaseWF(release_tags) ⇒ Object
Add release tags to an item and initialize the item release workflow.
-
#add_tags_from_purl(new_tags) ⇒ Object
This function calls purl and gets a list of all release tags currently in purl.
-
#clean_release_tag_for_purl(tag) ⇒ Hash
Take a tag and return only the attributes we want to put into purl.
-
#combine_two_release_tag_hashes(hash_one, hash_two) ⇒ Hash
Take two hashes of tags and combine them, will not overwrite but will enforce uniqueness of the tags.
-
#does_release_tag_apply(release_tag, admin_tags = false) ⇒ Boolean
Takes a tag and returns true or false if it applies to the specific item.
-
#form_purl_url ⇒ Object
Take the and create the entire purl url that will usable for the open method in open-uri, returns http.
-
#generate_release_xml ⇒ String
Generate XML structure for inclusion to Purl.
-
#get_newest_release_tag(tags) ⇒ Hash
Take a hash of tags as obtained via Dor::Item.release_tags and returns the newest tag for each namespace.
-
#get_release_tags_for_item_and_all_governing_sets ⇒ Hash
Take an item and get all of its release tags and all tags on collections it is a member of it.
-
#get_release_tags_from_purl ⇒ Array
Pull all release nodes from the public xml obtained via the purl query.
-
#get_release_tags_from_purl_xml(doc) ⇒ Array
Pull all release nodes from the public xml obtained via the purl query.
-
#get_self_release_tags(tags) ⇒ Hash
Take a hash of tags as obtained via Dor::Item.release_tags and returns all self tags.
-
#get_tags_for_what_value(tags, what_target) ⇒ Hash
Take a hash of tags and return all tags with the matching what target.
-
#get_xml_from_purl ⇒ Nokogiri::HTML::Document
Get a list of all release nodes found in a purl document.
-
#latest_applicable_release_tag_in_array(release_tags, admin_tags) ⇒ Hash
Takes an array of release tags and returns the most recent one that applies to this item.
-
#newest_release_tag_in_an_array(array_of_tags) ⇒ Hash
Takes an array of release tags and returns the most recent one.
-
#release_nodes ⇒ Nokogiri::XML::NodeSet
helper method to get the release nodes as a nodeset.
-
#release_tag_node_to_hash(rtag) ⇒ Object
method to convert one release element into an array.
-
#release_tags ⇒ Nokogiri::XML::NodeSet
helper method to get the release tags as a nodeset.
-
#released_for ⇒ Hash
Determine which projects an item is released for.
-
#remove_druid_prefix ⇒ String
Since purl does not use the druid: prefix but much of dor does, use this function to strip the druid: if needed.
-
#valid_release_attributes(tag, attrs = {}) ⇒ Boolean
Determine if the supplied tag is a valid release node that meets all requirements.
-
#valid_release_attributes_and_tag(tag, attrs = {}) ⇒ Boolean
Determine if the supplied tag is a valid release tag that meets all requirements.
Methods included from Itemizable
#clear_diff_cache, #get_content_diff
Instance Method Details
#add_release_node(release, attrs = {}) ⇒ Nokogiri::XML::Element
Add a release node for the item 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
Timestamp will be calculated by the function, if no displayType is passed in, it will default to file
289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/dor/models/releaseable.rb', line 289 def add_release_node(release, attrs={}) = self.identityMetadata attrs[:when] = Time.now.utc.iso8601 if attrs[:when].nil? #add the timestamp attrs[:displayType] = 'file' if attrs[:displayType].nil? #default to file is no display type is passed valid_release_attributes(release, attrs) #Remove the old displayType and then add the one for this tag remove_displayTypes .add_value(:displayType, attrs[:displayType], {}) return .add_value(:release, release.to_s, attrs) end |
#add_release_nodes_and_start_releaseWF(release_tags) ⇒ Object
Add release tags to an item and initialize the item release workflow
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/dor/models/releaseable.rb', line 16 def add_release_nodes_and_start_releaseWF() = [] if .class != Array #Add in each tag .each do |r_tag| self.add_release_node(r_tag[:release],r_tag) end #Save the item to dor so the robots work with the latest data self.save #Intialize the release workflow self.initialize_workflow('releaseWF') end |
#add_tags_from_purl(new_tags) ⇒ Object
This function calls purl and gets a list of all release tags currently in purl. It then compares to the list you have generated. Any tag that is on purl, but not in the newly generated list is added to the new list with a value of false.
params new_tags [Hash] a hash of all new tags in the form of => Boolean, where Project is a string
return [Hash], a hash in the same form as new_tags, with all missing tags not in new_tags, but in current_tag_names, added in with a Boolean value of false
415 416 417 418 419 420 421 422 |
# File 'lib/dor/models/releaseable.rb', line 415 def () = self. = .map(&:downcase) - .keys.map(&:downcase) .each do |missing_tag| [missing_tag.capitalize] = {"release"=>false} end return end |
#clean_release_tag_for_purl(tag) ⇒ Hash
Take a tag and return only the attributes we want to put into purl
156 157 158 159 160 161 162 163 |
# File 'lib/dor/models/releaseable.rb', line 156 def clean_release_tag_for_purl(tag) for_purl = ['release'] return_hash = {} for_purl.each do |attr| return_hash[attr] = tag[attr] end return return_hash end |
#combine_two_release_tag_hashes(hash_one, hash_two) ⇒ Hash
Take two hashes of tags and combine them, will not overwrite but will enforce uniqueness of the tags
114 115 116 117 118 119 120 |
# File 'lib/dor/models/releaseable.rb', line 114 def combine_two_release_tag_hashes(hash_one, hash_two) hash_two.keys.each do |key| hash_one[key] = hash_two[key] if hash_one[key] == nil hash_one[key] = (hash_one[key] + hash_two[key]).uniq if hash_one[key] != nil end return hash_one end |
#does_release_tag_apply(release_tag, admin_tags = false) ⇒ Boolean
Takes a tag and returns true or false if it applies to the specific item
184 185 186 187 188 189 190 |
# File 'lib/dor/models/releaseable.rb', line 184 def does_release_tag_apply(release_tag, =false) #Is the tag global or restricted return true if release_tag['tag'] == nil #there is no specific tag specificied, so that means this tag is global to all members of the collection, it applies, return true = self. if ! #We use false instead of [], since an item can have no admin_tags that which point we'd be passing down this variable as [] and would not an attempt to retrieve it return .include?(release_tag['tag']) end |
#form_purl_url ⇒ Object
Take the and create the entire purl url that will usable for the open method in open-uri, returns http
params druid [String], the druid without or without the driud prefix
return [String], the full url
381 382 383 384 |
# File 'lib/dor/models/releaseable.rb', line 381 def form_purl_url prefix = "http://" return prefix + Dor::Config.stacks.document_cache_host + "/#{self.remove_druid_prefix}.xml" end |
#generate_release_xml ⇒ String
Generate XML structure for inclusion to Purl
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/dor/models/releaseable.rb', line 34 def generate_release_xml builder = Nokogiri::XML::Builder.new do |xml| xml.releaseData { self.released_for.each do |project,released_value| xml.release(released_value["release"],:to=>project) end } end return builder.to_xml end |
#get_newest_release_tag(tags) ⇒ Hash
Take a hash of tags as obtained via Dor::Item.release_tags and returns the newest tag for each namespace
142 143 144 145 146 147 148 149 |
# File 'lib/dor/models/releaseable.rb', line 142 def get_newest_release_tag() return_hash = {} .keys.each do |key| latest_for_key = newest_release_tag_in_an_array([key]) return_hash[key] = latest_for_key end return return_hash end |
#get_release_tags_for_item_and_all_governing_sets ⇒ Hash
Take an item and get all of its release tags and all tags on collections it is a member of it
100 101 102 103 104 105 106 |
# File 'lib/dor/models/releaseable.rb', line 100 def = self.release_nodes || {} self.collections.each do |collection| = combine_two_release_tag_hashes(, Dor::Item.find(collection.id).) #this will function recurvisely so parents of parents are found end return end |
#get_release_tags_from_purl ⇒ Array
Pull all release nodes from the public xml obtained via the purl query
404 405 406 407 |
# File 'lib/dor/models/releaseable.rb', line 404 def xml = self.get_xml_from_purl return self.(xml) end |
#get_release_tags_from_purl_xml(doc) ⇒ Array
Pull all release nodes from the public xml obtained via the purl query
391 392 393 394 395 396 397 398 399 |
# File 'lib/dor/models/releaseable.rb', line 391 def (doc) nodes = doc.xpath("//html/body/publicobject/releasedata").children #We only want the nodes with a name that isn't text return_array = [] nodes.each do |n| return_array << n.attr('to') if n.name != nil and n.name.downcase != "text" end return return_array.uniq end |
#get_self_release_tags(tags) ⇒ Hash
Take a hash of tags as obtained via Dor::Item.release_tags and returns all self tags
92 93 94 |
# File 'lib/dor/models/releaseable.rb', line 92 def () return (, 'self') end |
#get_tags_for_what_value(tags, what_target) ⇒ Hash
Take a hash of tags and return all tags with the matching what target
128 129 130 131 132 133 134 135 |
# File 'lib/dor/models/releaseable.rb', line 128 def (, what_target) return_hash = {} .keys.each do |key| = [key].select{|tag| tag['what'] == what_target.downcase} return_hash[key] = if .size > 0 end return return_hash end |
#get_xml_from_purl ⇒ Nokogiri::HTML::Document
Get a list of all release nodes found in a purl document
Fetches purl xml for a druid
353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/dor/models/releaseable.rb', line 353 def get_xml_from_purl handler = Proc.new do |exception, attempt_number, total_delay| #We assume a 404 means the document has never been published before and thus has no purl #The strip is needed before the actual message is "404 " return Nokogiri::HTML::Document.new if exception..strip == "404" end with_retries(:max_retries => 5, :base_sleep_seconds => 3, :max_sleep_seconds=> 5, :rescue => OpenURI::HTTPError, :handler => handler) { #If you change the method used for opening the webpage, you can change the :rescue param to handle the new method's errors return Nokogiri::HTML(open(self.form_purl_url)) } end |
#latest_applicable_release_tag_in_array(release_tags, admin_tags) ⇒ Hash
Takes an array of release tags and returns the most recent one that applies to this item
param admin_tags [Array] the administrative tags on an on item
198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/dor/models/releaseable.rb', line 198 def latest_applicable_release_tag_in_array(, ) newest_tag = newest_release_tag_in_an_array() return newest_tag if does_release_tag_apply(newest_tag, ) #Return true if we have it #The latest tag wasn't applicable, slice it off and try again #This could be optimized by reordering on the timestamp and just running down it instead of constantly resorting, at least if we end up getting numerous release tags on an item .slice!(.index(newest_tag)) return latest_applicable_release_tag_in_array(, ) if .size > 0 #Try again after dropping the one that wasn't applicable return nil #We're out of tags, no applicable ones end |
#newest_release_tag_in_an_array(array_of_tags) ⇒ Hash
Takes an array of release tags and returns the most recent one
170 171 172 173 174 175 176 |
# File 'lib/dor/models/releaseable.rb', line 170 def newest_release_tag_in_an_array() latest_tag_in_array = [0] || {} .each do |tag| latest_tag_in_array = tag if tag['when'] > latest_tag_in_array['when'] end return latest_tag_in_array end |
#release_nodes ⇒ Nokogiri::XML::NodeSet
helper method to get the release nodes as a nodeset
330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'lib/dor/models/releaseable.rb', line 330 def release_nodes = self.identityMetadata.ng_xml.xpath('//release') return_hash = {} .each do |release_tag| hashed_node = self.release_tag_node_to_hash(release_tag) if return_hash[hashed_node[:to]] != nil return_hash[hashed_node[:to]] << hashed_node[:attrs] else return_hash[hashed_node[:to]] = [hashed_node[:attrs]] end end return return_hash end |
#release_tag_node_to_hash(rtag) ⇒ Object
method to convert one release element into an array
return [Hash] in the form of => String :attrs = Hash
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/dor/models/releaseable.rb', line 233 def release_tag_node_to_hash(rtag) to = 'to' release = 'release' when_word = 'when' #TODO: Make to and when_word load from some config file instead of hardcoded here attrs = rtag.attributes return_hash = { :to => attrs[to].value } attrs.tap { |a| a.delete(to)} attrs[release] = rtag.text.downcase == "true" #save release as a boolean return_hash[:attrs] = attrs #convert all the attrs beside :to to strings, they are currently Nokogiri::XML::Attr (return_hash[:attrs].keys-[to]).each do |a| return_hash[:attrs][a] = return_hash[:attrs][a].to_s if a != release end return_hash[:attrs][when_word] = Time.parse(return_hash[:attrs][when_word]) #convert when to a datetime return return_hash end |
#release_tags ⇒ Nokogiri::XML::NodeSet
helper method to get the release tags as a nodeset
214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/dor/models/releaseable.rb', line 214 def = self.identityMetadata.ng_xml.xpath('//release') return_hash = {} .each do |release_tag| hashed_node = self.release_tag_node_to_hash(release_tag) if return_hash[hashed_node[:to]] != nil return_hash[hashed_node[:to]] << hashed_node[:attrs] else return_hash[hashed_node[:to]] = [hashed_node[:attrs]] end end return return_hash end |
#released_for ⇒ Hash
Determine which projects an item is released for
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/dor/models/releaseable.rb', line 48 def released_for released_hash = {} #Get release tags on the item itself = self.release_nodes #Get any self tags on this item = self.() #Get the most recent self tag for all targets and save their result since most recent self always trumps any other non self tags = self.get_newest_release_tag() .keys.each do |target| released_hash[target] = self.clean_release_tag_for_purl([target]) end #With Self Tags Resolved We Now need to deal with tags on all sets this object is part of = {} #This will be where we store all tags that apply, regardless of their timestamp #Get all release tags on the item and strip out the what = self ones, we've already processed all the self tags on this item = (self., 'collection') = self. #Get them once here and pass them down #We now have the keys for all potential releases, we need to check the tags and the most recent time stamp with an explicit true or false wins, in a nil case, the lack of an explicit false tag we do nothing (.keys-released_hash.keys).each do |key| #don't bother checking the ones already added to the release hash, they were added due to a self tag and that has won latest_applicable_tag_for_key = latest_applicable_release_tag_in_array([key], ) if latest_applicable_tag_for_key != nil #We have a valid tag, record it released_hash[key] = self.clean_release_tag_for_purl(latest_applicable_tag_for_key) end end #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 released_hash = self.(released_hash) return released_hash end |
#remove_druid_prefix ⇒ String
Since purl does not use the druid: prefix but much of dor does, use this function to strip the druid: if needed
370 371 372 373 374 |
# File 'lib/dor/models/releaseable.rb', line 370 def remove_druid_prefix druid_prefix = "druid:" return self.id.split(druid_prefix)[1] if self.id.split(druid_prefix).size > 1 return druid end |
#valid_release_attributes(tag, attrs = {}) ⇒ Boolean
Determine if the supplied tag is a valid release node that meets all requirements
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/dor/models/releaseable.rb', line 309 def valid_release_attributes(tag, attrs={}) 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 [:who, :to, :what].each do |check_attr| raise ArgumentError, "#{check_attr} not supplied as a String" if attrs[check_attr].class != String end what_correct = false ['self', 'collection'].each do |allowed_what_value| what_correct = true if attrs[:what] == allowed_what_value end raise ArgumentError, ":what must be self or collection" if ! what_correct raise ArgumentError, "the value set for this tag is not a boolean" if !!tag != tag raise ArgumentError, ":displayType must be passed in as a String" unless attrs[:displayType].class == String validate_tag_format(attrs[:tag]) if attrs[:tag] != nil #Will Raise exception if invalid tag return true end |
#valid_release_attributes_and_tag(tag, attrs = {}) ⇒ Boolean
Determine if the supplied tag is a valid release tag that meets all requirements
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/dor/models/releaseable.rb', line 260 def valid_release_attributes_and_tag(tag, attrs={}) 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 [:who, :to, :what].each do |check_attr| raise ArgumentError, "#{check_attr} not supplied as a String" if attrs[check_attr].class != String end what_correct = false ['self', 'collection'].each do |allowed_what_value| what_correct = true if attrs[:what] == allowed_what_value end raise ArgumentError, ":what must be self or collection" if ! what_correct raise ArgumentError, "the value set for this tag is not a boolean" if !!tag != tag validate_tag_format(attrs[:tag]) if attrs[:tag] != nil #Will Raise exception if invalid tag return true end |