dor-services 4.6.6.3 → 4.6.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -27,6 +27,7 @@ Dor::Config.configure do
27
27
  end
28
28
 
29
29
  stacks do
30
+ document_cache_storage_root '/home/lyberadmin/document_cache'
30
31
  document_cache_host 'purl-dev.stanford.edu'
31
32
  document_cache_user 'lyberadmin'
32
33
  local_workspace_root '/dor/workspace'
@@ -88,7 +88,7 @@ module Dor
88
88
  config[:stomp][:host] ||= URI.parse(config.fedora.url).host rescue nil
89
89
 
90
90
  [:cert_file, :key_file, :key_pass].each do |key|
91
- stack = caller.dup
91
+ stack = Kernel.caller.dup
92
92
  stack.shift while stack[0] =~ %r{(active_support/callbacks|dor/config|dor-services)\.rb}
93
93
  if config.fedora[key].present?
94
94
  ActiveSupport::Deprecation.warn "Dor::Config -- fedora.#{key.to_s} is deprecated. Please use ssl.#{key.to_s} instead.", stack
@@ -6,7 +6,6 @@ module Dor
6
6
  set_terminology do |t|
7
7
  t.root :path => 'contentMetadata', :index_as => [:not_searchable]
8
8
  t.contentType :path => '/contentMetadata/@type', :index_as => [:not_searchable]
9
- t.stacks :path=> '/contentMetadata/@stacks', :index_as => [:not_searchable]
10
9
  t.resource(:index_as => [:not_searchable]) do
11
10
  t.id_ :path => { :attribute => 'id' }
12
11
  t.sequence :path => { :attribute => 'sequence' }#, :data_type => :integer
@@ -3,7 +3,7 @@
3
3
  geo2mods.xsl - Transformation from ISO 19139 XML into MODS v3
4
4
 
5
5
 
6
- Copyright 2013, The Board of Trustees of the Leland Stanford Junior University
6
+ Copyright 2013-2014, The Board of Trustees of the Leland Stanford Junior University
7
7
 
8
8
  Licensed under the Apache License, Version 2.0 (the "License");
9
9
  you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@
26
26
  http://www.schemacentral.com/sc/niem21/t-gml32_GeometryPropertyType.html
27
27
  * purl - e.g., http://purl.stanford.edu/aa111bb2222
28
28
  * zipName - e.g., data.zip
29
- * format - e.g., MIME type application/x-esri-shapefile
30
29
 
31
30
  TODO:
32
31
  * Series statements may need work?
@@ -41,7 +40,6 @@
41
40
  version="1.0" exclude-result-prefixes="gml gmd gco gmi xsl">
42
41
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
43
42
  <xsl:strip-space elements="*"/>
44
- <xsl:param name="format" select="'application/x-esri-shapefile'"/>
45
43
  <xsl:param name="geometryType"/>
46
44
  <xsl:param name="purl"/>
47
45
  <xsl:param name="zipName" select="'data.zip'"/>
@@ -51,15 +49,27 @@
51
49
  -->
52
50
  <xsl:param name="geoformat" select="'MARC255'"/>
53
51
  <xsl:param name="fileIdentifier" select="''"/>
52
+ <xsl:variable name="format">
53
+ <xsl:choose>
54
+ <xsl:when test="contains(gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:distributionFormat/gmd:MD_Format/gmd:name, 'Raster Dataset')">
55
+ <xsl:text>image/tiff</xsl:text>
56
+ </xsl:when>
57
+ <xsl:when test="contains(gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:distributionFormat/gmd:MD_Format/gmd:name, 'GeoTIFF')">
58
+ <xsl:text>image/tiff</xsl:text>
59
+ </xsl:when>
60
+ <xsl:when test="contains(gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:distributionFormat/gmd:MD_Format/gmd:name, 'Shapefile')">
61
+ <xsl:text>application/x-esri-shapefile</xsl:text>
62
+ </xsl:when>
63
+ </xsl:choose>
64
+ </xsl:variable>
54
65
  <xsl:template match="/">
55
66
  <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink" version="3.4" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
56
67
  <xsl:for-each select="/gmi:MI_Metadata|/gmd:MD_Metadata|//gmd:MD_Metadata">
57
68
  <xsl:if test="gmd:fileIdentifier/gco:CharacterString/text()">
58
69
  <xsl:variable name="fileIdentifier" select="."/>
59
70
  </xsl:if>
60
- <xsl:if test="gmd:dataSetURI/gco:CharacterString/text()">
61
- <xsl:variable name="purl" select="."/>
62
- </xsl:if>
71
+ <xsl:variable name="purl" select="gmd:dataSetURI"/>
72
+
63
73
  <titleInfo>
64
74
  <title>
65
75
  <xsl:apply-templates select="gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:title"/>
@@ -153,21 +163,8 @@
153
163
  </xsl:choose>
154
164
  </dateIssued>
155
165
 
156
-
157
- <!-- kd: construct dateValid from Temporal_EX field?
158
- <xsl:if test="gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod">
159
- <dateValid>
160
- <xsl:attribute name="point">start</xsl:attribute>
161
-
162
- <xsl:value-of select="substring-before(gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:beginPosition, 'T')"/>
163
- </dateValid>
164
- <dateValid>
165
- <xsl:attribute name="point">end</xsl:attribute>
166
- <xsl:value-of select="substring-before(gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:endPosition, 'T')"/>
167
- </dateValid>
168
- </xsl:if> -->
169
-
170
- <xsl:for-each select="gmd:identificationInfo/gmd:MD_DataIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords">
166
+
167
+ <xsl:for-each select="gmd:identificationInfo/gmd:MD_DataIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords">
171
168
  <xsl:if test="gmd:type/gmd:MD_KeywordTypeCode[@codeListValue='temporal']">
172
169
  <xsl:for-each select="gmd:keyword">
173
170
 
@@ -226,15 +223,10 @@
226
223
  <xsl:for-each select="gmd:distributionInfo/gmd:MD_Distribution/gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:transferSize">
227
224
  <extent>
228
225
  <xsl:value-of select="gco:Real"/>
229
- <xsl:choose>
230
- <xsl:when test="ancestor-or-self::*/gmd:MD_DigitalTransferOptions/gmd:unitsOfDistribution">
226
+ <xsl:if test="ancestor-or-self::*/gmd:MD_DigitalTransferOptions/gmd:unitsOfDistribution">
231
227
  <xsl:text> </xsl:text>
232
228
  <xsl:value-of select="ancestor-or-self::*/gmd:MD_DigitalTransferOptions/gmd:unitsOfDistribution"/>
233
- </xsl:when>
234
- <xsl:otherwise>
235
- <xsl:text> MB</xsl:text>
236
- </xsl:otherwise>
237
- </xsl:choose>
229
+ </xsl:if>
238
230
  </extent>
239
231
 
240
232
  <!-- The digitalOrigin is coded here:
@@ -506,6 +498,13 @@
506
498
  </title>
507
499
  </titleInfo>
508
500
  <typeOfResource collection="yes"/>
501
+ <xsl:if test="gmd:aggregateDataSetName/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code">
502
+ <location>
503
+ <url>
504
+ <xsl:value-of select="gmd:aggregateDataSetName/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code"/>
505
+ </url>
506
+ </location>
507
+ </xsl:if>
509
508
  <xsl:for-each select="gmd:aggregateDataSetName/gmd:CI_Citation/gmd:citedResponsibleParty/gmd:CI_ResponsibleParty/gmd:organisationName">
510
509
  <xsl:if test="ancestor-or-self::gmd:CI_ResponsibleParty/gmd:role/gmd:CI_RoleCode[@codeListValue='originator']">
511
510
  <name type="corporate">
@@ -547,7 +546,9 @@
547
546
  </edition>
548
547
  </xsl:for-each>
549
548
  </originInfo>
550
- <xsl:for-each select="gmd:aggregateDataSetName/gmd:CI_Citation/gmd:series/gmd:CI_Series">
549
+
550
+ <!-- series titles / not in use -->
551
+ <!-- <xsl:for-each select="gmd:aggregateDataSetName/gmd:CI_Citation/gmd:series/gmd:CI_Series">
551
552
  <relatedItem>
552
553
  <xsl:attribute name="type">host</xsl:attribute>
553
554
  <titleInfo>
@@ -562,7 +563,7 @@
562
563
  <issuance>continuing</issuance>
563
564
  </originInfo>
564
565
  </relatedItem>
565
- </xsl:for-each>
566
+ </xsl:for-each> -->
566
567
  </relatedItem>
567
568
  </xsl:if>
568
569
  </xsl:for-each>
@@ -749,9 +750,9 @@
749
750
  <xsl:attribute name="valueURI"><xsl:value-of select="."/></xsl:attribute>
750
751
  <xsl:text>Planning and Cadastral</xsl:text>
751
752
  </xsl:when>
752
- <xsl:when test="contains(.,'structural')">
753
+ <xsl:when test="contains(.,'structure')">
753
754
  <xsl:attribute name="valueURI"><xsl:value-of select="."/></xsl:attribute>
754
- <xsl:text>Structures</xsl:text>
755
+ <xsl:text>Structure</xsl:text>
755
756
  </xsl:when>
756
757
  <xsl:when test="contains(.,'transportation')">
757
758
  <xsl:attribute name="valueURI"><xsl:value-of select="."/></xsl:attribute>
@@ -769,13 +770,37 @@
769
770
  </topic>
770
771
  </subject>
771
772
  </xsl:for-each>
772
- <!-- TODO: Need a metadata practice for GIS Dataset's Online Resource. -->
773
+
774
+
775
+ <location>
776
+ <url>
777
+ <xsl:value-of select="$purl"/>
778
+ </url>
779
+ </location>
780
+
773
781
  <!-- access rights to be mapped from restrictionCode/otherRestrictions/APO -->
774
782
  <xsl:for-each select="gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:otherConstraints">
775
783
  <accessCondition type="useAndReproduction">
776
784
  <xsl:value-of select=". "/>
777
785
  </accessCondition>
778
786
  </xsl:for-each>
787
+
788
+ <!-- recordInfo -->
789
+
790
+
791
+ <recordInfo>
792
+ <recordContentSource>
793
+ <xsl:text>Stanford</xsl:text>
794
+ </recordContentSource>
795
+ <recordIdentifier>
796
+ <xsl:value-of select="gmd:fileIdentifier"/>
797
+ </recordIdentifier>
798
+ <recordOrigin>This record was translated from ISO 19139 to MODS v.3 using an xsl transformation.</recordOrigin>
799
+ <languageOfCataloging>
800
+ <languageTerm authority="iso639-2b" type="code">eng</languageTerm>
801
+ </languageOfCataloging>
802
+ </recordInfo>
803
+
779
804
 
780
805
  <!-- Output geo extension to MODS -->
781
806
  <xsl:if test="gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:geographicElement/gmd:EX_GeographicBoundingBox">
@@ -823,7 +848,7 @@
823
848
  <xsl:value-of select="../../@xlink:href"/>
824
849
  </xsl:attribute>
825
850
  <xsl:attribute name="dc:language">
826
- <xsl:value-of select="../../../../../gmd:language/gmd:LanguageCode"/>
851
+ <xsl:value-of select="../../../../../gmd:language/gmd:LanguageCode"/>
827
852
  </xsl:attribute>
828
853
  <xsl:attribute name="dc:title">
829
854
  <xsl:value-of select="."/>
@@ -56,9 +56,7 @@ module Dor
56
56
  doc = self.descMetadata.ng_xml.dup(1)
57
57
  add_collection_reference(doc)
58
58
  add_access_conditions(doc)
59
- new_doc = Nokogiri::XML(doc.to_xml) { |x| x.noblanks }
60
- new_doc.encoding = 'UTF-8'
61
- new_doc.to_xml
59
+ Nokogiri::XML(doc.to_xml) { |x| x.noblanks }.to_xml { |config| config.no_declaration }
62
60
  end
63
61
 
64
62
  # Create MODS accessCondition statements from rightsMetadata
@@ -11,6 +11,33 @@ module Dor
11
11
  after_initialize :set_workflows_datastream_location
12
12
  end
13
13
 
14
+ #verbiage we want to use to describe an item when it has completed a particular step
15
+ STATUS_CODE_DISP_TXT = {
16
+ 0 => 'Unknown Status', #if there are no milestones for the current version, someone likely messed up the versioning process.
17
+ 1 => 'Registered',
18
+ 2 => 'In accessioning',
19
+ 3 => 'In accessioning (described)',
20
+ 4 => 'In accessioning (described, published)',
21
+ 5 => 'In accessioning (described, published, deposited)',
22
+ 6 => 'Accessioned',
23
+ 7 => 'Accessioned (indexed)',
24
+ 8 => 'Accessioned (indexed, ingested)',
25
+ 9 => 'Opened'
26
+ }
27
+
28
+ #milestones from accessioning and the order they happen in
29
+ STEPS = {
30
+ 'registered' => 1,
31
+ 'submitted' => 2,
32
+ 'described' => 3,
33
+ 'published' => 4,
34
+ 'deposited' => 5,
35
+ 'accessioned' => 6,
36
+ 'indexed' => 7,
37
+ 'shelved' => 8,
38
+ 'opened' => 1
39
+ }
40
+
14
41
  def set_workflows_datastream_location
15
42
  # This is a work-around for some strange logic in ActiveFedora that
16
43
  # don't allow self.workflows.new? to work if we load the object using
@@ -78,69 +105,49 @@ module Dor
78
105
  def milestones
79
106
  Dor::WorkflowService.get_milestones('dor',self.pid)
80
107
  end
81
- def status(include_time=false)
82
- current_version='1'
108
+
109
+ def status_info()
110
+ current_version = '1'
83
111
  begin
84
112
  current_version = self.versionMetadata.current_version_id
85
113
  rescue
86
114
  end
87
- status = 0
88
- version = ''
89
- #verbage we want to use to describe an item when it has completed a particular step
90
- status_hash={
91
- 0 => 'Unknown Status', #if there are no milestones for the current version, someone likely messed up the versioning process.
92
- 1 => 'Registered',
93
- 2 => 'In accessioning',
94
- 3 => 'In accessioning (described)',
95
- 4 => 'In accessioning (described, published)',
96
- 5 => 'In accessioning (described, published, deposited)',
97
- 6 => 'Accessioned',
98
- 7 => 'Accessioned (indexed)',
99
- 8 => 'Accessioned (indexed, ingested)',
100
- 9 => 'Opened'
101
- }
102
- #milestones from accesioning and the order they happen in
103
- steps={
104
- 'registered' => 1,
105
- 'submitted' => 2,
106
- 'described' => 3,
107
- 'published' => 4,
108
- 'deposited' => 5,
109
- 'accessioned' => 6,
110
- 'indexed' => 7,
111
- 'shelved' => 8,
112
- 'opened' => 1
113
- }
114
- status_time=nil
115
-
116
- current=false
117
- versions=[]
118
- result=""
115
+
119
116
  current_milestones = []
120
- #only get steps that are part of accessioning and part of the current version. That can mean they were archived with the current version number, or they might be active (no version number)
117
+ #only get steps that are part of accessioning and part of the current version. That can mean they were archived with the current version
118
+ #number, or they might be active (no version number).
121
119
  milestones.each do |m|
122
- if steps.keys.include?(m[:milestone]) and (m[:version].nil? or m[:version] == current_version)
120
+ if STEPS.keys.include?(m[:milestone]) and (m[:version].nil? or m[:version] == current_version)
123
121
  current_milestones << m unless m[:milestone] == 'registered' and current_version.to_i > 1
124
122
  end
125
123
  end
126
- status = 0
124
+
125
+ status_code = 0
127
126
  status_time = ''
128
127
  #for each milestone in the current version, see if it comes after the current 'last' step, if so, make it the last and record the date/time
129
128
  current_milestones.each do |m|
130
- name=m[:milestone]
131
- time=m[:at].utc.xmlschema
132
- if steps.keys.include? name
133
- if steps[name] > status
134
- status = steps[name]
135
- status_time=time
129
+ name = m[:milestone]
130
+ time = m[:at].utc.xmlschema
131
+ if STEPS.keys.include? name
132
+ if STEPS[name] > status_code
133
+ status_code = STEPS[name]
134
+ status_time = time
136
135
  end
137
136
  end
138
137
  end
138
+
139
+ return {:current_version => current_version, :status_code => status_code, :status_time => status_time}
140
+ end
141
+
142
+ def status(include_time=false)
143
+ status_info_hash = status_info
144
+ current_version, status_code, status_time = status_info_hash[:current_version], status_info_hash[:status_code], status_info_hash[:status_time]
145
+
139
146
  #use the translation table to get the appropriate verbage for the latest step
140
- result='v'+current_version.to_s+' '+status_hash[status].to_s
141
- result +=" #{format_date(status_time)}" if include_time
142
- result
143
- end
147
+ result = "v#{current_version} #{STATUS_CODE_DISP_TXT[status_code]}"
148
+ result += " #{format_date(status_time)}" if include_time
149
+ return result
150
+ end
144
151
 
145
152
  def to_solr(solr_doc=Hash.new, *args)
146
153
  super(solr_doc, *args)
@@ -210,6 +217,8 @@ module Dor
210
217
  opts[:priority] = priority if(priority > 0)
211
218
  Dor::WorkflowService.create_workflow(repo, self.pid, name, Dor::WorkflowObject.initial_workflow(name), opts)
212
219
  end
220
+
221
+
213
222
  private
214
223
  #handles formating utc date/time to human readable
215
224
  def format_date datetime
@@ -41,9 +41,7 @@ module Dor
41
41
  rels = public_relationships.root
42
42
  pub.add_child(rels.clone) unless rels.nil? # TODO: Should never be nil in practice; working around an ActiveFedora quirk for testing
43
43
  pub.add_child(self.generate_dublin_core.root.clone)
44
- new_pub = Nokogiri::XML(pub.to_xml) { |x| x.noblanks }
45
- new_pub.encoding = 'UTF-8'
46
- new_pub.to_xml
44
+ Nokogiri::XML(pub.to_xml) { |x| x.noblanks }.to_xml { |config| config.no_declaration }
47
45
  end
48
46
 
49
47
  # Copies this object's public_xml to the Purl document cache if it is world discoverable
@@ -7,58 +7,21 @@ module Dor
7
7
 
8
8
  # Push file changes for shelve-able files into the stacks
9
9
  def shelve
10
- # retrieve the differences between the current contentMetadata and the previously ingested version
11
- shelve_diff = get_shelve_diff
12
- stacks_object_pathname = get_stacks_location
13
- # determine the location of the object's files in the stacks area
14
- stacks_druid = DruidTools::StacksDruid.new id, stacks_object_pathname
15
- stacks_object_pathname = Pathname(stacks_druid.path)
16
- # determine the location of the object's content files in the workspace area
17
- workspace_druid = DruidTools::Druid.new(id,Config.stacks.local_workspace_root)
18
- workspace_content_pathname = workspace_content_dir(shelve_diff, workspace_druid)
19
- # delete, rename, or copy files to the stacks area
20
- DigitalStacksService.remove_from_stacks(stacks_object_pathname, shelve_diff)
21
- DigitalStacksService.rename_in_stacks(stacks_object_pathname, shelve_diff)
22
- DigitalStacksService.shelve_to_stacks(workspace_content_pathname, stacks_object_pathname, shelve_diff)
23
- end
24
-
25
- # retrieve the differences between the current contentMetadata and the previously ingested version
26
- # (filtering to select only the files that should be shelved to stacks)
27
- def get_shelve_diff
28
10
  inventory_diff_xml = self.get_content_diff(:shelve)
29
11
  inventory_diff = Moab::FileInventoryDifference.parse(inventory_diff_xml)
30
- shelve_diff = inventory_diff.group_difference("content")
31
- shelve_diff
32
- end
12
+ content_group_diff = inventory_diff.group_difference("content")
13
+ deltas = content_group_diff.file_deltas
33
14
 
34
- # Find the location of the object's content files in the workspace area
35
- # @param [Moab::FileGroupDifference] content_diff The differences between the current contentMetadata and the previously ingested version
36
- # @param [DruidTools::Druid] workspace_druid the location of the object's files in the workspace area
37
- # @return [Pathname] The location of the object's content files in the workspace area
38
- def workspace_content_dir (content_diff, workspace_druid)
39
- deltas = content_diff.file_deltas
40
- filelist = deltas[:modified] + deltas[:added] + deltas[:copyadded].collect{|old,new| new}
41
- return nil if filelist.empty?
42
- content_pathname = Pathname(workspace_druid.find_filelist_parent('content', filelist))
43
- content_pathname
44
- end
45
-
46
-
47
- # get the stack location based on the contentMetadata stacks attribute
48
- # or using the default value from the config file if it doesn't exist
49
- def get_stacks_location
50
-
51
- contentMetadataDS = self.datastreams['contentMetadata']
52
- unless contentMetadataDS.nil? or contentMetadataDS.stacks.length == 0
53
- stacks_location = contentMetadataDS.stacks[0]
54
- if stacks_location.start_with?"/" #Absolute stacks path
55
- return stacks_location
56
- else
57
- raise "stacks attribute for item: "+self.id+ " contentMetadata should start with /. The current value is "+stacks_location
58
- end
59
- end
60
- return Config.stacks.local_stacks_root #Default stacks
61
-
15
+ if content_group_diff.rename_require_temp_files(deltas[:renamed])
16
+ triplets = content_group_diff.rename_tempfile_triplets(deltas[:renamed])
17
+ DigitalStacksService.rename_in_stacks self.pid, triplets.collect{|old,new,temp| [old,temp]}
18
+ DigitalStacksService.rename_in_stacks self.pid, triplets.collect{|old,new,temp| [temp,new]}
19
+ else
20
+ DigitalStacksService.rename_in_stacks self.pid, deltas[:renamed]
21
+ end
22
+ DigitalStacksService.shelve_to_stacks self.pid, deltas[:modified] + deltas[:added] + deltas[:copyadded].collect{|old,new| new}
23
+ DigitalStacksService.remove_from_stacks self.pid, deltas[:deleted] + deltas[:copydeleted]
62
24
  end
25
+
63
26
  end
64
27
  end
@@ -2,128 +2,42 @@ require 'net/ssh'
2
2
  require 'net/sftp'
3
3
 
4
4
  module Dor
5
-
6
5
  class DigitalStacksService
7
6
 
8
- # Delete files from stacks that have change type 'deleted', 'copydeleted', or 'modified'
9
- # @param [Pathname] stacks_object_pathname the stacks location of the digital object
10
- # @param [Moab::FileGroupDifference] content_diff the content file version differences report
11
- def self.remove_from_stacks(stacks_object_pathname, content_diff)
12
- [:deleted, :copydeleted, :modified].each do |change_type|
13
- subset = content_diff.subset(change_type) # {Moab::FileGroupDifferenceSubset}
14
- subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
15
- moab_signature = moab_file.signatures.first # {Moab::FileSignature}
16
- file_pathname = stacks_object_pathname.join(moab_file.basis_path)
17
- self.delete_file(file_pathname, moab_signature)
18
- end
19
- end
20
- end
21
-
22
- # Delete a file, but only if it exists and matches the expected signature
23
- # @param [Pathname] file_pathname The location of the file to be deleted
24
- # @param [Moab::FileSignature] moab_signature The fixity values of the file
25
- # @return [Boolean] true if file deleted, false otherwise
26
- def self.delete_file(file_pathname, moab_signature)
27
- if file_pathname.exist? and (file_pathname.size == moab_signature.size)
28
- file_signature = Moab::FileSignature.new.signature_from_file(file_pathname)
29
- if (file_signature == moab_signature)
30
- file_pathname.delete
31
- return true
32
- end
33
- end
34
- return false
35
- end
36
-
37
- # Rename files from stacks that have change type 'renamed' using an intermediate temp filename.
38
- # The 2-step renaming allows chained or cyclic renames to occur without file collisions.
39
- # @param [Pathname] stacks_object_pathname the stacks location of the digital object
40
- # @param [Moab::FileGroupDifference] content_diff the content file version differences report
41
- def self.rename_in_stacks(stacks_object_pathname, content_diff)
42
- subset = content_diff.subset(:renamed) # {Moab::FileGroupDifferenceSubset
43
-
44
- # 1st Pass - rename files from original name to checksum-based name
45
- subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
46
- moab_signature = moab_file.signatures.first # {Moab::FileSignature}
47
- original_pathname = stacks_object_pathname.join(moab_file.basis_path)
48
- temp_pathname = stacks_object_pathname.join(moab_signature.checksums.values.last)
49
- self.rename_file(original_pathname, temp_pathname, moab_signature)
50
- end
51
-
52
- # 2nd Pass - rename files from checksum-based name to new name
53
- subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
54
- moab_signature = moab_file.signatures.first # {Moab::FileSignature}
55
- temp_pathname = stacks_object_pathname.join(moab_signature.checksums.values.last)
56
- new_pathname = stacks_object_pathname.join(moab_file.other_path)
57
- self.rename_file(temp_pathname, new_pathname, moab_signature)
58
- end
59
-
7
+ def self.transfer_to_document_store(id, content, filename)
8
+ druid = DruidTools::PurlDruid.new id, Config.stacks.local_document_cache_root
9
+ druid.content_dir # create the druid tree if it doesn't exist yet
10
+ File.open(File.join(druid.content_dir, filename), 'w') {|f| f.write content }
60
11
  end
61
12
 
62
- # Rename a file, but only if it exists and has the expected signature
63
- # @param [Pathname] old_pathname The original location/name of the file being renamed
64
- # @param [Pathname] new_pathname The new location/name of the file
65
- # @param [Moab::FileSignature] moab_signature The fixity values of the file
66
- # @return [Boolean] true if file renamed, false otherwise
67
- def self.rename_file(old_pathname, new_pathname, moab_signature)
68
- if old_pathname.exist? and (old_pathname.size == moab_signature.size)
69
- file_signature = Moab::FileSignature.new.signature_from_file(old_pathname)
70
- if (file_signature == moab_signature)
71
- new_pathname.parent.mkpath
72
- old_pathname.rename(new_pathname)
73
- return true
74
- end
13
+ def self.remove_from_stacks(id, files)
14
+ files.each do |file|
15
+ dr = DruidTools::StacksDruid.new id, Config.stacks.local_stacks_root
16
+ content = dr.find_content file
17
+ FileUtils.rm content if content
75
18
  end
76
- return false
77
19
  end
78
20
 
79
- # Add files to stacks that have change type 'added', 'copyadded' or 'modified'.
80
- # @param [Pathname] workspace_content_pathname The dor workspace location of the digital object's content fies
81
- # @param [Pathname] stacks_object_pathname the stacks location of the digital object's shelved files
82
- # @param [Moab::FileGroupDifference] content_diff the content file version differences report
83
- def self.shelve_to_stacks(workspace_content_pathname, stacks_object_pathname, content_diff)
84
- return false if workspace_content_pathname.nil?
85
- [:added, :copyadded, :modified,].each do |change_type|
86
- subset = content_diff.subset(change_type) # {Moab::FileGroupDifferenceSubset
87
- subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
88
- moab_signature = moab_file.signatures.last # {Moab::FileSignature}
89
- filename = (change_type == :modified) ? moab_file.basis_path : moab_file.other_path
90
- workspace_pathname = workspace_content_pathname.join(filename)
91
- stacks_pathname = stacks_object_pathname.join(filename)
92
- self.copy_file(workspace_pathname, stacks_pathname, moab_signature)
93
- end
21
+ # @param [String] id object pid
22
+ # @param [Array<Array<String>>] file_map an array of two string arrays. Each inner array represents old-file/new-file mappings. First string is the old file name, second string is the new file name. e.g:
23
+ # [ ['src1.file', 'dest1.file'], ['src2.file', 'dest2.file'] ]
24
+ def self.rename_in_stacks(id, file_map)
25
+ return if file_map.nil? or file_map.empty?
26
+ dr = DruidTools::StacksDruid.new id, Config.stacks.local_stacks_root
27
+ content_dir = dr.find_filelist_parent('content', file_map.first.first)
28
+ file_map.each do |src, dest|
29
+ File.rename(File.join(content_dir, src), File.join(content_dir, dest))
94
30
  end
95
- true
96
31
  end
97
32
 
98
- # Copy a file to stacks, but only if it does not yet exist with the expected signature
99
- # @param [Pathname] workspace_pathname The location of the file in the DOR workspace
100
- # @param [Pathname] stacks_pathname The location of the file in the stacks
101
- # @param [Moab::FileSignature] moab_signature The fixity values of the file
102
- # @return [Boolean] true if file copied, false otherwise
103
- def self.copy_file(workspace_pathname, stacks_pathname, moab_signature)
104
- if stacks_pathname.exist?
105
- file_signature = Moab::FileSignature.new.signature_from_file(stacks_pathname)
106
- stacks_pathname.delete if (file_signature != moab_signature)
107
- end
108
- unless stacks_pathname.exist?
109
- stacks_pathname.parent.mkpath
110
- FileUtils.cp workspace_pathname.to_s, stacks_pathname.to_s
111
- return true
33
+ def self.shelve_to_stacks(id, files)
34
+ workspace_druid = DruidTools::Druid.new(id,Config.stacks.local_workspace_root)
35
+ stacks_druid = DruidTools::StacksDruid.new(id,Config.stacks.local_stacks_root)
36
+ files.each do |file|
37
+ stacks_druid.content_dir
38
+ workspace_file = workspace_druid.find_content(file)
39
+ FileUtils.cp workspace_file, stacks_druid.content_dir
112
40
  end
113
- return false
114
- end
115
-
116
- ### depricated ???
117
-
118
- # Create a file inside the content directory under the stacks.local_document_cache_root
119
- # @param [String] id The druid identifier for the object
120
- # @param [String] content The contents of the file to be created
121
- # @param [String] filename The name of the file to be created
122
- # @return [void]
123
- def self.transfer_to_document_store(id, content, filename)
124
- druid = DruidTools::PurlDruid.new id, Config.stacks.local_document_cache_root
125
- druid.content_dir # create the druid tree if it doesn't exist yet
126
- File.open(File.join(druid.content_dir, filename), 'w') { |f| f.write content }
127
41
  end
128
42
 
129
43
  # Assumes the digital stacks storage root is mounted to the local file system
@@ -1,3 +1,3 @@
1
1
  module Dor
2
- VERSION = '4.6.6.3'
2
+ VERSION = '4.6.7'
3
3
  end
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.6.6.3
4
+ version: 4.6.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2014-08-20 00:00:00.000000000 Z
16
+ date: 2014-06-02 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: active-fedora
@@ -36,7 +36,7 @@ dependencies:
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  none: false
38
38
  requirements:
39
- - - ~>
39
+ - - ! '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: 3.2.16
42
42
  type: :runtime
@@ -44,7 +44,7 @@ dependencies:
44
44
  version_requirements: !ruby/object:Gem::Requirement
45
45
  none: false
46
46
  requirements:
47
- - - ~>
47
+ - - ! '>='
48
48
  - !ruby/object:Gem::Version
49
49
  version: 3.2.16
50
50
  - !ruby/object:Gem::Dependency
@@ -134,7 +134,7 @@ dependencies:
134
134
  requirements:
135
135
  - - ~>
136
136
  - !ruby/object:Gem::Version
137
- version: '1.6'
137
+ version: 1.6.0
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
@@ -142,7 +142,7 @@ dependencies:
142
142
  requirements:
143
143
  - - ~>
144
144
  - !ruby/object:Gem::Version
145
- version: '1.6'
145
+ version: 1.6.0
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: om
148
148
  requirement: !ruby/object:Gem::Requirement
@@ -342,10 +342,7 @@ dependencies:
342
342
  requirements:
343
343
  - - ~>
344
344
  - !ruby/object:Gem::Version
345
- version: 1.5.0
346
- - - ! '>='
347
- - !ruby/object:Gem::Version
348
- version: 1.5.1
345
+ version: '1.5'
349
346
  type: :runtime
350
347
  prerelease: false
351
348
  version_requirements: !ruby/object:Gem::Requirement
@@ -353,10 +350,7 @@ dependencies:
353
350
  requirements:
354
351
  - - ~>
355
352
  - !ruby/object:Gem::Version
356
- version: 1.5.0
357
- - - ! '>='
358
- - !ruby/object:Gem::Version
359
- version: 1.5.1
353
+ version: '1.5'
360
354
  - !ruby/object:Gem::Dependency
361
355
  name: druid-tools
362
356
  requirement: !ruby/object:Gem::Requirement