Module: Dor::Publishable

Extended by:
ActiveSupport::Concern
Included in:
Item, Set
Defined in:
lib/dor/models/concerns/publishable.rb

Instance Method Summary collapse

Instance Method Details

#encoded_thumbString

Return a URI encoded version of the thumb image for use by indexers (leaving the extension of the filename)

Returns:

  • (String)

    URI encoded version of the thumb with the druid prefix, e.g. oo000oo0001%2Ffilenamewith%20space.jp2



53
54
55
56
57
58
59
# File 'lib/dor/models/concerns/publishable.rb', line 53

def encoded_thumb
  thumb_image = thumb # store the result locally, so we don't have to compute each time we use it below
  return unless thumb_image
  thumb_druid=thumb_image.split('/').first # the druid (before the first slash)
  thumb_filename=thumb_image.split(/#{pid_regex}[\/]/).last # everything after the druid
  "#{thumb_druid}%2F#{ERB::Util.url_encode(thumb_filename)}"
end

#public_relationshipsNokogiri::XML

strips away the relationships that should not be shown in public desc metadata

Returns:

  • (Nokogiri::XML)


71
72
73
74
75
76
77
78
79
80
81
# File 'lib/dor/models/concerns/publishable.rb', line 71

def public_relationships
  include_elements = ['fedora:isMemberOf', 'fedora:isMemberOfCollection', 'fedora:isConstituentOf']
  rels_doc = Nokogiri::XML(datastreams['RELS-EXT'].content)
  rels_doc.xpath('/rdf:RDF/rdf:Description/*', { 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' }).each do |rel|
    unless include_elements.include?([rel.namespace.prefix, rel.name].join(':'))
      rel.next_sibling.remove if rel.next_sibling.content.strip.empty?
      rel.remove
    end
  end
  rels_doc
end

#public_xmlxml

Generate the public .xml for a PURL page.

Returns:

  • (xml)

    The public xml for the item



85
86
87
# File 'lib/dor/models/concerns/publishable.rb', line 85

def public_xml
  PublicXmlService.new(self).to_xml
end

#publish_delete_on_successObject

When publishing a PURL, we notify purl-fetcher of changes.



143
144
145
146
147
148
149
# File 'lib/dor/models/concerns/publishable.rb', line 143

def publish_delete_on_success
  return unless Dor::Config.purl_services.url
  id = pid.gsub(/^druid:/, '')

  purl_services = Dor::Config.purl_services.rest_client
  purl_services["purls/#{id}"].delete
end

#publish_metadataObject

Copies this object’s public_xml to the Purl document cache if it is world discoverable

otherwise, it prunes the object's metadata from the document cache


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dor/models/concerns/publishable.rb', line 91

def 
  rights = datastreams['rightsMetadata'].ng_xml.clone.remove_namespaces!
  if rights.at_xpath("//rightsMetadata/access[@type='discover']/machine/world")
    dc_xml = generate_dublin_core.to_xml {|config| config.no_declaration}
    DigitalStacksService.transfer_to_document_store(pid, dc_xml, 'dc')
    %w(identityMetadata contentMetadata rightsMetadata).each do |stream|
      DigitalStacksService.transfer_to_document_store(pid, datastreams[stream].content.to_s, stream) if datastreams[stream]
    end
    DigitalStacksService.transfer_to_document_store(pid, public_xml, 'public')
    DigitalStacksService.transfer_to_document_store(pid, generate_public_desc_md, 'mods')
    publish_notify_on_success
  else
    # Clear out the document cache for this item
    DigitalStacksService.prune_purl_dir pid
    publish_delete_on_success
  end
end

#publish_metadata_remotelyObject

Call dor services app to have it publish the metadata



110
111
112
113
114
115
# File 'lib/dor/models/concerns/publishable.rb', line 110

def 
  dor_services = Dor::Config.dor_services.rest_client
  endpoint = dor_services["v1/objects/#{pid}/publish"]
  endpoint.post ''
  endpoint.url
end

#publish_notify_on_successObject

When publishing a PURL, we notify purl-fetcher of changes. If the purl service isn’t configured, instead we drop a ‘aa11bb2222` file into the `local_recent_changes` folder to notify other applications watching the filesystem (i.e., purl-fetcher). We also remove any .deletes entry that may have left over from a previous removal



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/dor/models/concerns/publishable.rb', line 122

def publish_notify_on_success
  id = pid.gsub(/^druid:/, '')

  if Dor::Config.purl_services.url
    purl_services = Dor::Config.purl_services.rest_client
    purl_services["purls/#{id}"].post ''
  else
    local_recent_changes = Config.stacks.local_recent_changes
    raise ArgumentError, "Missing local_recent_changes directory: #{local_recent_changes}" unless File.directory?(local_recent_changes)

    FileUtils.touch(File.join(local_recent_changes, id))
    begin
      DruidTools::Druid.new(id, Dor::Config.stacks.local_document_cache_root).deletes_delete_record
    rescue Errno::EACCES
      Dor.logger.warn "Access denied while trying to remove .deletes file for druid:#{id}"
    end
  end
end

#thumbString

Compute the thumbnail for this object following the rules at consul.stanford.edu/display/chimera/The+Rules+of+Thumb

Returns:

  • (String)

    the computed thumb filename, with the druid prefix and a slash in front of it, e.g. oo000oo0001/filenamewith space.jp2



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/dor/models/concerns/publishable.rb', line 10

def thumb
   return unless respond_to?(:contentMetadata) && !.nil?
   cm = .ng_xml
   mime_type_finder = "@mimetype='image/jp2' or @mimeType='image/jp2'" # allow the mimetype attribute to be lower or camelcase when searching to make it more robust
   thumb_image=nil

   # these are the finders we will use to search for a thumb resource in contentMetadata, they will be searched in the order provided, stopping when one is reached
   thumb_xpath_finders = [
       # first find a file of mimetype jp2 explicitly marked as a thumb in the resource type and with a thumb=yes attribute
       {image_type: 'local', finder: "/contentMetadata/resource[@type='thumb' and @thumb='yes']/file[#{mime_type_finder}]"},
       # same thing for external files
       {image_type: 'external', finder: "/contentMetadata/resource[@type='thumb' and @thumb='yes']/externalFile[#{mime_type_finder}]"},
       # next find any image or page resource types with the thumb=yes attribute of mimetype jp2
       {image_type: 'local', finder: "/contentMetadata/resource[(@type='page' or @type='image') and @thumb='yes']/file[#{mime_type_finder}]"},
       # same thing for external file
       {image_type: 'external', finder: "/contentMetadata/resource[(@type='page' or @type='image') and @thumb='yes']/externalFile[#{mime_type_finder}]"},
       # next find a file of mimetype jp2 and resource type=thumb but not marked with the thumb directive
       {image_type: 'local', finder: "/contentMetadata/resource[@type='thumb']/file[#{mime_type_finder}]"},
       # same thing for external file
       {image_type: 'external', finder: "/contentMetadata/resource[@type='thumb']/externalFile[#{mime_type_finder}]"},
       # finally find the first page or image resource of mimetype jp2
       {image_type: 'local', finder: "/contentMetadata/resource[@type='page' or @type='image']/file[#{mime_type_finder}]"},
       # same thing for external file
       {image_type: 'external', finder: "/contentMetadata/resource[@type='page' or @type='image']/externalFile[#{mime_type_finder}]"}
     ]

   thumb_xpath_finders.each do |search_path|
     thumb_files = cm.xpath(search_path[:finder]) # look for a thumb
     if thumb_files.size > 0   # if we find one, return the filename based on whether it is a local file or external file
       if search_path[:image_type] == 'local'
         thumb_image="#{remove_druid_prefix}/#{thumb_files[0]['id']}"
       else
         thumb_image="#{remove_druid_prefix(thumb_files[0]['objectId'])}/#{thumb_files[0]['fileId']}"
       end
       break  # break out of the loop so we stop searching
     end
   end

   thumb_image
end

#thumb_urlString

Return a full qualified thumbnail image URL if the thumb is computable

Returns:



63
64
65
66
67
# File 'lib/dor/models/concerns/publishable.rb', line 63

def thumb_url
  return unless encoded_thumb
  thumb_basename=File.basename(encoded_thumb, File.extname(encoded_thumb)) # strip the extension for URL generation
  "https://#{Dor::Config.stacks.host}/image/iiif/#{thumb_basename}/full/!400,400/0/default.jpg"
end