Module: Dor::Contentable

Extended by:
ActiveSupport::Concern
Included in:
BasicItem
Defined in:
lib/dor/models/contentable.rb

Instance Method Summary collapse

Instance Method Details

#add_file(file, resource, file_name, mime_type = nil, publish = 'no', shelve = 'no', preserve = 'no') ⇒ Object

add a file to a resource, not to be confused with add a resource to an object



6
7
8
9
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
# File 'lib/dor/models/contentable.rb', line 6

def add_file file, resource, file_name, mime_type=nil,publish='no', shelve='no', preserve='no'
  contentMD=self.datastreams['contentMetadata']
  xml=contentMD.ng_xml
  #make sure the resource exists
  if xml.search('//resource[@id=\''+resource+'\']').length == 0
    raise 'resource doesnt exist.'
  end
  sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
  druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
  location=druid_tools.path(file_name)
  oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
  md5=Digest::MD5.file(file.path).hexdigest
  sha1=Digest::SHA1.file(file.path).hexdigest
  size=File.size?(file.path)
  #update contentmd
  file_hash={:name=>file_name,:md5 => md5, :publish=>publish, :shelve=> shelve, :preserve => preserve, :size=>size.to_s, :sha1=>sha1, :mime_type => mime_type}
  begin
    request=sftp.stat!(location.gsub(file_name,''))
    begin
      request=sftp.stat!(location)
      raise 'The file '+file_name+' already exists!'
    rescue Net::SFTP::StatusException
      sftp.upload!(file.path,location)
      self..add_file file_hash,resource
    end
  rescue Net::SFTP::StatusException
    #the directory layout doesnt match the new style, so use the old style.
    begin
      request=sftp.stat!(oldlocation)
      raise 'The file '+file_name+' already exists!'
    rescue Net::SFTP::StatusException
      #the file doesnt already exist, which is good. Add it
      sftp.upload!(file.path,oldlocation)
      self..add_file file_hash,resource
    end
  end
  #can only arrive at this point if a non status exception occurred.
end

#copy_file_resources(source_obj_pids) ⇒ Object

Appends contentMetadata file resources from the source objects to this object

Parameters:

  • source_obj_pids (Array<String>)

    ids of the secondary objects that will get their contentMetadata merged into this one



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/dor/models/contentable.rb', line 154

def copy_file_resources source_obj_pids
  primary_cm = .ng_xml
  base_id = primary_cm.at_xpath('/contentMetadata/@objectId').value
  max_sequence = primary_cm.at_xpath('/contentMetadata/resource[last()]/@sequence').value.to_i

  source_obj_pids.each do |src_pid|
    source_obj = Dor::Item.find src_pid
    source_cm = source_obj..ng_xml

    # Copy the resources from each source object
    source_cm.xpath('/contentMetadata/resource').each do |old_resource|
      max_sequence += 1
      resource_copy = old_resource.clone
      resource_copy['sequence'] = "#{max_sequence}"

      # Append sequence number to each secondary filename, then
      # look for filename collisions with the primary object
      resource_copy.xpath('file').each do |secondary_file|
        secondary_file['id'] = new_secondary_file_name(secondary_file['id'], max_sequence)

        if primary_cm.at_xpath("//file[@id = '#{secondary_file["id"]}']")
          raise Dor::Exception.new "File '#{secondary_file['id']}' from secondary object #{src_pid} already exist in primary object: #{self.pid}"
        end
      end

      if old_resource['type']
        resource_copy['id'] = "#{old_resource['type']}_#{max_sequence}"
      else
        resource_copy['id'] = "#{base_id}_#{max_sequence}"
      end

      lbl = old_resource.at_xpath 'label'
      if lbl && lbl.text =~ /^(.*)\s+\d+$/
        resource_copy.at_xpath('label').content = "#{$1} #{max_sequence}"
      end

      primary_cm.at_xpath('/contentMetadata/resource[last()]').add_next_sibling resource_copy
      attr_node = primary_cm.create_element 'attr', src_pid, :name => 'mergedFromPid'
      resource_copy.first_element_child.add_previous_sibling attr_node
      attr_node = primary_cm.create_element 'attr', old_resource['id'], :name => 'mergedFromResource'
      resource_copy.first_element_child.add_previous_sibling attr_node
    end
  end
  self..content_will_change!
end

#decomission(tag) ⇒ Object

Clears RELS-EXT relationships, sets the isGovernedBy relationship to the SDR Graveyard APO

Parameters:

  • tag (String)

    optional String of text that is concatenated to the identityMetadata/tag “Decomissioned : ”



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/dor/models/contentable.rb', line 210

def decomission tag
  # remove isMemberOf and isMemberOfCollection relationships
  clear_relationship :is_member_of
  clear_relationship :is_member_of_collection
  # remove isGovernedBy relationship
  clear_relationship :is_governed_by
  # add isGovernedBy to graveyard APO druid:sw909tc7852
  # SEARCH BY dc title for 'SDR Graveyard'
  add_relationship :is_governed_by, ActiveFedora::Base.find(Dor::SearchService.sdr_graveyard_apo_druid)
  # eliminate contentMetadata. set it to <contentMetadata/> ?
  .content = '<contentMetadata/>'
  # eliminate rightsMetadata. set it to <rightsMetadata/> ?
  .content = '<rightsMetadata/>'
  add_tag "Decommissioned : #{tag}"
end

#get_file(file) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/dor/models/contentable.rb', line 80

def get_file file
  druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
  location=druid_tools.path(file)
  oldlocation=location.gsub('/'+file,'').gsub('/'+self.pid.gsub('druid:',''),'')+'/'+file
  sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
  begin
    data=sftp.download!(location)
  rescue
    data=sftp.download!(oldlocation)
  end
end

#get_preserved_file(file, version) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/dor/models/contentable.rb', line 68

def get_preserved_file file, version
  preservation_server=Config.content.sdr_server+'/sdr/objects/'+self.pid+"/content/"
  file=URI.encode(file)
  add=preservation_server+file+"?version="+version
  uri = URI(add)
  req = Net::HTTP::Get.new(uri.request_uri)
  req.basic_auth Config.content.sdr_user, Config.content.sdr_pass
  res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') {|http|
    http.request(req)
  }
end

#list_filesObject

list files in the workspace



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/dor/models/contentable.rb', line 129

def list_files
  filename='none'
  files=[]
  sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
  druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
  location=druid_tools.path(filename).gsub(filename,'')
  oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
  begin
    sftp.dir.entries(location, "*") do |file|
      files<<file.name
    end
  rescue
    begin
      sftp.dir.glob(oldlocation, "*") do |file|
        files<<file.name
      end
    rescue Net::SFTP::StatusException
      return files
    end
  end
  return files
end

#new_secondary_file_name(old_name, sequence_num) ⇒ Object



200
201
202
203
204
205
206
# File 'lib/dor/models/contentable.rb', line 200

def new_secondary_file_name old_name, sequence_num
  if old_name =~ /^(.*)\.(.*)$/
    return "#{$1}_#{sequence_num}.#{$2}"
  else
    return "#{old_name}_#{sequence_num}"
  end
end

#remove_file(filename) ⇒ Object



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

def remove_file filename
  druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
  location=druid_tools.path(filename)
  oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
  sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
  begin
    data=sftp.remove!(location)
  rescue
    #if the file doesnt exist, that is ok, not all files will be present in the workspace
    begin
      data=sftp.remove!(oldlocation)
    rescue Net::SFTP::StatusException
    end
  end
  self..remove_file filename
end

#remove_resource(resource_name) ⇒ Object



119
120
121
122
123
124
125
126
127
# File 'lib/dor/models/contentable.rb', line 119

def remove_resource resource_name
  #run delete for all of the files in the resource
  xml=self..ng_xml
  files=xml.search('//resource[@id=\''+resource_name+'\']/file').each do |file|
    self.remove_file(file['id'])
  end
  #remove the resource record from the metadata and renumber the resource sequence
  self..remove_resource resource_name
end

#rename_file(old_name, new_name) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/dor/models/contentable.rb', line 107

def rename_file old_name, new_name
  druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
  location=druid_tools.path(old_name)
  oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
  sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
  begin
    data=sftp.rename!(location,location.gsub(old_name,new_name))
  rescue
    data=sftp.rename!(oldlocation,oldlocation.gsub(old_name,new_name))
  end
  self..rename_file(old_name, new_name)
end

#replace_file(file, file_name) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/dor/models/contentable.rb', line 45

def replace_file file,file_name
  sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
  item=Dor::Item.find(self.pid)
  druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
  location=druid_tools.path(file_name)
  oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')

  md5=Digest::MD5.file(file.path).hexdigest
  sha1=Digest::SHA1.file(file.path).hexdigest
  size=File.size?(file.path)
  #update contentmd
  file_hash={:name=>file_name,:md5 => md5, :size=>size.to_s, :sha1=>sha1}
  begin
    request=sftp.stat!(location)
    sftp.upload!(file.path,location)
    #this doesnt allow renaming files
    item..update_file(file_hash, file_name)
  rescue
    sftp.upload!(file.path,oldlocation)
    item..update_file(file_hash, file_name)
  end
end