moab-versioning 4.3.0 → 5.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/moab/bagger.rb +7 -2
- data/lib/moab/config.rb +40 -7
- data/lib/moab/exceptions.rb +6 -0
- data/lib/moab/file_group.rb +12 -9
- data/lib/moab/file_group_difference.rb +26 -23
- data/lib/moab/file_group_difference_subset.rb +5 -3
- data/lib/moab/file_instance.rb +4 -1
- data/lib/moab/file_instance_difference.rb +5 -3
- data/lib/moab/file_inventory.rb +13 -9
- data/lib/moab/file_inventory_difference.rb +8 -6
- data/lib/moab/file_manifestation.rb +5 -2
- data/lib/moab/file_signature.rb +12 -7
- data/lib/moab/signature_catalog.rb +13 -13
- data/lib/moab/signature_catalog_entry.rb +6 -4
- data/lib/moab/stanford.rb +2 -10
- data/lib/moab/storage_object.rb +11 -5
- data/lib/moab/storage_object_validator.rb +24 -10
- data/lib/moab/storage_object_version.rb +19 -12
- data/lib/moab/storage_repository.rb +49 -7
- data/lib/moab/storage_services.rb +12 -9
- data/lib/moab/utc_time.rb +2 -0
- data/lib/moab/verification_result.rb +4 -3
- data/lib/moab/version_metadata_entry.rb +6 -4
- data/lib/moab.rb +2 -9
- data/lib/serializer/manifest.rb +4 -2
- data/lib/serializer/serializable.rb +6 -1
- data/lib/serializer.rb +2 -0
- data/lib/stanford/content_inventory.rb +23 -19
- data/lib/stanford/storage_object_validator.rb +2 -0
- data/lib/stanford/storage_repository.rb +6 -2
- data/lib/stanford/storage_services.rb +2 -0
- metadata +22 -42
- data/lib/moab/deposit_bag_validator.rb +0 -323
- data/lib/moab/version_metadata.rb +0 -32
- data/lib/moab/version_metadata_event.rb +0 -40
- data/lib/stanford/active_fedora_object.rb +0 -28
- data/lib/stanford/dor_metadata.rb +0 -41
- data/lib/stanford/moab_storage_directory.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d109f89af3228b70fe8e8b8cf394830b9397f4815a8c2324bb7e09e849432d6
|
4
|
+
data.tar.gz: 9695c1dfb048663ff1b56084597b8ece2973966704a07d610dd7e537da8be61b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85be7b541e0056fd50296092448b01c4d83195529c00bd4aaa244cce6596336b0ae7b41ba855f54b618666bf265a9986844eaf6a0f7a78eb811b6ccdaf1329ae
|
7
|
+
data.tar.gz: 72dc3ada7f22d891e883ce08fe55c7c783689f73b8868e6c29bb5040c2bcc45197c044a3b5823a94f3e8ade7de6b16ccc291902ee142ab0e68036824623c6695
|
data/lib/moab/bagger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A class used to create a BagIt package from a version inventory and a set of source files.
|
3
5
|
# The {#fill_bag} method is called with a package_mode parameter that specifies
|
@@ -141,6 +143,7 @@ module Moab
|
|
141
143
|
def deposit_group(group_id, source_dir)
|
142
144
|
group = bag_inventory.group(group_id)
|
143
145
|
return nil? if group.nil? || group.files.empty?
|
146
|
+
|
144
147
|
target_dir = bag_pathname.join('data', group_id)
|
145
148
|
group.path_list.each do |relative_path|
|
146
149
|
source = source_dir.join(relative_path)
|
@@ -158,6 +161,7 @@ module Moab
|
|
158
161
|
def reconstuct_group(group_id, storage_object_dir)
|
159
162
|
group = bag_inventory.group(group_id)
|
160
163
|
return nil? if group.nil? || group.files.empty?
|
164
|
+
|
161
165
|
target_dir = bag_pathname.join('data', group_id)
|
162
166
|
group.files.each do |file|
|
163
167
|
catalog_entry = signature_catalog.signature_hash[file.signature]
|
@@ -165,7 +169,7 @@ module Moab
|
|
165
169
|
file.instances.each do |instance|
|
166
170
|
target = target_dir.join(instance.path)
|
167
171
|
target.parent.mkpath
|
168
|
-
FileUtils.symlink source, target
|
172
|
+
FileUtils.symlink source, target unless target.exist?
|
169
173
|
end
|
170
174
|
end
|
171
175
|
true
|
@@ -260,6 +264,7 @@ module Moab
|
|
260
264
|
shell_execute(tar_cmd.sub('--force-local', ''))
|
261
265
|
end
|
262
266
|
raise(MoabRuntimeError, "Unable to create tarfile #{tar_pathname}") unless tar_pathname.exist?
|
267
|
+
|
263
268
|
true
|
264
269
|
end
|
265
270
|
|
@@ -273,7 +278,7 @@ module Moab
|
|
273
278
|
stdout
|
274
279
|
else
|
275
280
|
msg = "Shell command failed: [#{command}] caused by <STDERR = #{stderr}>"
|
276
|
-
msg << " STDOUT = #{stdout}" if stdout
|
281
|
+
msg << " STDOUT = #{stdout}" if stdout&.length&.positive?
|
277
282
|
raise(MoabStandardError, msg)
|
278
283
|
end
|
279
284
|
rescue SystemCallError => e
|
data/lib/moab/config.rb
CHANGED
@@ -1,10 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
|
-
#
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
# A place to store configuration for the gem
|
5
|
+
class Configuration
|
6
|
+
def initialize
|
7
|
+
@path_method = :druid_tree
|
8
|
+
@checksum_algos = [:md5, :sha1, :sha256]
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure(&block)
|
12
|
+
instance_eval(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def storage_roots(new_value = nil)
|
16
|
+
@storage_roots = new_value if new_value
|
17
|
+
@storage_roots
|
18
|
+
end
|
19
|
+
|
20
|
+
def storage_trunk(new_value = nil)
|
21
|
+
@storage_trunk = new_value if new_value
|
22
|
+
@storage_trunk
|
23
|
+
end
|
24
|
+
|
25
|
+
def deposit_trunk(new_value = nil)
|
26
|
+
@deposit_trunk = new_value if new_value
|
27
|
+
@deposit_trunk
|
28
|
+
end
|
29
|
+
|
30
|
+
def path_method(new_value = nil)
|
31
|
+
@path_method = new_value if new_value
|
32
|
+
@path_method
|
33
|
+
end
|
34
|
+
|
35
|
+
def checksum_algos(new_value = nil)
|
36
|
+
@checksum_algos = new_value if new_value
|
37
|
+
@checksum_algos
|
38
|
+
end
|
9
39
|
end
|
40
|
+
|
41
|
+
# @return [Moab::Configuration] the configuration data
|
42
|
+
Config = Configuration.new
|
10
43
|
end
|
data/lib/moab/exceptions.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
class MoabRuntimeError < RuntimeError; end
|
5
|
+
|
3
6
|
class MoabStandardError < StandardError; end
|
4
7
|
|
5
8
|
class FileNotFoundException < MoabRuntimeError; end
|
9
|
+
|
6
10
|
class InvalidMetadataException < MoabRuntimeError; end
|
11
|
+
|
7
12
|
class InvalidSuriSyntaxError < MoabRuntimeError; end
|
13
|
+
|
8
14
|
class ObjectNotFoundException < MoabRuntimeError; end
|
9
15
|
end
|
data/lib/moab/file_group.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for a standard subset of a digital objects {FileManifestation} objects
|
3
5
|
# Used to segregate depositor content from repository metadata files
|
@@ -28,15 +30,15 @@ module Moab
|
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [String] The name of the file group
|
31
|
-
attribute :group_id, String, :
|
33
|
+
attribute :group_id, String, tag: 'groupId', key: true
|
32
34
|
|
33
35
|
# @attribute
|
34
36
|
# @return [String] The directory location or other source of this groups file data
|
35
|
-
attribute :data_source, String, :
|
37
|
+
attribute :data_source, String, tag: 'dataSource'
|
36
38
|
|
37
39
|
# @attribute
|
38
40
|
# @return [Integer] The total number of data files (dynamically calculated)
|
39
|
-
attribute :file_count, Integer, :
|
41
|
+
attribute :file_count, Integer, tag: 'fileCount', on_save: proc { |i| i.to_s }
|
40
42
|
|
41
43
|
def file_count
|
42
44
|
files.inject(0) { |sum, manifestation| sum + manifestation.file_count }
|
@@ -44,7 +46,7 @@ module Moab
|
|
44
46
|
|
45
47
|
# @attribute
|
46
48
|
# @return [Integer] The total size (in bytes) of all data files (dynamically calculated)
|
47
|
-
attribute :byte_count, Integer, :
|
49
|
+
attribute :byte_count, Integer, tag: 'byteCount', on_save: proc { |i| i.to_s }
|
48
50
|
|
49
51
|
def byte_count
|
50
52
|
files.inject(0) { |sum, manifestation| sum + manifestation.byte_count }
|
@@ -52,7 +54,7 @@ module Moab
|
|
52
54
|
|
53
55
|
# @attribute
|
54
56
|
# @return [Integer] The total disk usage (in 1 kB blocks) of all data files (estimating du -k result) (dynamically calculated)
|
55
|
-
attribute :block_count, Integer, :
|
57
|
+
attribute :block_count, Integer, tag: 'blockCount', on_save: proc { |i| i.to_s }
|
56
58
|
|
57
59
|
def block_count
|
58
60
|
files.inject(0) { |sum, manifestation| sum + manifestation.block_count }
|
@@ -65,7 +67,7 @@ module Moab
|
|
65
67
|
|
66
68
|
# @attribute
|
67
69
|
# @return [Array<FileManifestation>] The set of files comprising the group
|
68
|
-
has_many :files, FileManifestation, :
|
70
|
+
has_many :files, FileManifestation, tag: 'file'
|
69
71
|
|
70
72
|
def files
|
71
73
|
signature_hash.values
|
@@ -161,9 +163,11 @@ module Moab
|
|
161
163
|
# @return [Boolean] Test whether the given path is contained within the {#base_directory}
|
162
164
|
def is_descendent_of_base?(pathname)
|
163
165
|
raise(MoabRuntimeError, "base_directory has not been set") if @base_directory.nil?
|
166
|
+
|
164
167
|
is_descendent = false
|
165
168
|
pathname.expand_path.ascend { |ancestor| is_descendent ||= (ancestor == @base_directory) }
|
166
169
|
raise(MoabRuntimeError, "#{pathname} is not a descendent of #{@base_directory}") unless is_descendent
|
170
|
+
|
167
171
|
is_descendent
|
168
172
|
end
|
169
173
|
|
@@ -203,6 +207,7 @@ module Moab
|
|
203
207
|
validated ||= is_descendent_of_base?(pathname)
|
204
208
|
pathname.children.sort.each do |child|
|
205
209
|
next if child.basename.to_s == '.DS_Store'
|
210
|
+
|
206
211
|
if child.directory?
|
207
212
|
harvest_directory(child, recursive, validated) if recursive
|
208
213
|
else
|
@@ -222,9 +227,7 @@ module Moab
|
|
222
227
|
instance = FileInstance.new.instance_from_file(pathname, @base_directory)
|
223
228
|
if @signatures_from_bag && @signatures_from_bag[pathname]
|
224
229
|
signature = @signatures_from_bag[pathname]
|
225
|
-
unless signature.complete?
|
226
|
-
signature = signature.normalized_signature(pathname)
|
227
|
-
end
|
230
|
+
signature = signature.normalized_signature(pathname) unless signature.complete?
|
228
231
|
else
|
229
232
|
signature = FileSignature.new.signature_from_file(pathname)
|
230
233
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# Performs analysis and reports the differences between two matching {FileGroup} objects.
|
3
5
|
# The descending elements of the report hold a detailed breakdown of file-level differences, organized by change type.
|
@@ -51,18 +53,18 @@ module Moab
|
|
51
53
|
|
52
54
|
# (see Serializable#initialize)
|
53
55
|
def initialize(opts = {})
|
54
|
-
@subset_hash = Hash.new { |hash, key| hash[key] = FileGroupDifferenceSubset.new(:
|
56
|
+
@subset_hash = Hash.new { |hash, key| hash[key] = FileGroupDifferenceSubset.new(change: key.to_s) }
|
55
57
|
super(opts)
|
56
58
|
end
|
57
59
|
|
58
60
|
# @attribute
|
59
61
|
# @return [String] The name of the file group
|
60
|
-
attribute :group_id, String, :
|
62
|
+
attribute :group_id, String, tag: 'groupId', key: true
|
61
63
|
|
62
64
|
# @attribute
|
63
65
|
# @return [Integer] the total number of differences found between the two inventories that were
|
64
66
|
# compared (dynamically calculated)
|
65
|
-
attribute :difference_count, Integer, :
|
67
|
+
attribute :difference_count, Integer, tag: 'differenceCount', on_save: proc { |i| i.to_s }
|
66
68
|
|
67
69
|
def difference_count
|
68
70
|
count = 0
|
@@ -74,49 +76,49 @@ module Moab
|
|
74
76
|
|
75
77
|
# @attribute
|
76
78
|
# @return [Integer] How many files were unchanged
|
77
|
-
attribute :identical, Integer, :
|
79
|
+
attribute :identical, Integer, on_save: proc { |n| n.to_s }
|
78
80
|
def identical
|
79
81
|
subset_hash[:identical].count
|
80
82
|
end
|
81
83
|
|
82
84
|
# @attribute
|
83
85
|
# @return [Integer] How many duplicate copies of files were added
|
84
|
-
attribute :copyadded, Integer, :
|
86
|
+
attribute :copyadded, Integer, on_save: proc { |n| n.to_s }
|
85
87
|
def copyadded
|
86
88
|
subset_hash[:copyadded].count
|
87
89
|
end
|
88
90
|
|
89
91
|
# @attribute
|
90
92
|
# @return [Integer] How many duplicate copies of files were deleted
|
91
|
-
attribute :copydeleted, Integer, :
|
93
|
+
attribute :copydeleted, Integer, on_save: proc { |n| n.to_s }
|
92
94
|
def copydeleted
|
93
95
|
subset_hash[:copydeleted].count
|
94
96
|
end
|
95
97
|
|
96
98
|
# @attribute
|
97
99
|
# @return [Integer] How many files were renamed
|
98
|
-
attribute :renamed, Integer, :
|
100
|
+
attribute :renamed, Integer, on_save: proc { |n| n.to_s }
|
99
101
|
def renamed
|
100
102
|
subset_hash[:renamed].count
|
101
103
|
end
|
102
104
|
|
103
105
|
# @attribute
|
104
106
|
# @return [Integer] How many files were modified
|
105
|
-
attribute :modified, Integer, :
|
107
|
+
attribute :modified, Integer, on_save: proc { |n| n.to_s }
|
106
108
|
def modified
|
107
109
|
subset_hash[:modified].count
|
108
110
|
end
|
109
111
|
|
110
112
|
# @attribute
|
111
113
|
# @return [Integer] How many files were added
|
112
|
-
attribute :added, Integer, :
|
114
|
+
attribute :added, Integer, on_save: proc { |n| n.to_s }
|
113
115
|
def added
|
114
116
|
subset_hash[:added].count
|
115
117
|
end
|
116
118
|
|
117
119
|
# @attribute
|
118
120
|
# @return [Integer] How many files were deleted
|
119
|
-
attribute :deleted, Integer, :
|
121
|
+
attribute :deleted, Integer, on_save: proc { |n| n.to_s }
|
120
122
|
def deleted
|
121
123
|
subset_hash[:deleted].count
|
122
124
|
end
|
@@ -124,7 +126,7 @@ module Moab
|
|
124
126
|
# @attribute
|
125
127
|
# @return [Array<FileGroupDifferenceSubset>] A set of Arrays (one for each change type),
|
126
128
|
# each of which contains an collection of file-level differences having that change type.
|
127
|
-
has_many :subsets, FileGroupDifferenceSubset, :
|
129
|
+
has_many :subsets, FileGroupDifferenceSubset, tag: 'subset'
|
128
130
|
|
129
131
|
def subsets
|
130
132
|
subset_hash.values
|
@@ -132,6 +134,7 @@ module Moab
|
|
132
134
|
|
133
135
|
def subsets=(array)
|
134
136
|
return unless array
|
137
|
+
|
135
138
|
array.each { |subset| subset_hash[subset.change.to_sym] = subset }
|
136
139
|
end
|
137
140
|
|
@@ -144,14 +147,14 @@ module Moab
|
|
144
147
|
# @return [FileGroupDifference] Clone just this element for inclusion in a versionMetadata structure
|
145
148
|
def summary
|
146
149
|
FileGroupDifference.new(
|
147
|
-
:
|
148
|
-
:
|
149
|
-
:
|
150
|
-
:
|
151
|
-
:
|
152
|
-
:
|
153
|
-
:
|
154
|
-
:
|
150
|
+
group_id: group_id,
|
151
|
+
identical: identical,
|
152
|
+
copyadded: copyadded,
|
153
|
+
copydeleted: copydeleted,
|
154
|
+
renamed: renamed,
|
155
|
+
modified: modified,
|
156
|
+
added: added,
|
157
|
+
deleted: deleted
|
155
158
|
)
|
156
159
|
end
|
157
160
|
|
@@ -228,7 +231,7 @@ module Moab
|
|
228
231
|
other_paths = other_signature_hash[signature].paths
|
229
232
|
matching_paths = basis_paths & other_paths
|
230
233
|
matching_paths.each do |path|
|
231
|
-
fid = FileInstanceDifference.new(:
|
234
|
+
fid = FileInstanceDifference.new(change: 'identical')
|
232
235
|
fid.basis_path = path
|
233
236
|
fid.other_path = "same"
|
234
237
|
fid.signatures << signature
|
@@ -281,7 +284,7 @@ module Moab
|
|
281
284
|
# Container for reporting the set of file-level differences of type 'modified'
|
282
285
|
def tabulate_modified_files(basis_path_hash, other_path_hash)
|
283
286
|
matching_keys(basis_path_hash, other_path_hash).each do |path|
|
284
|
-
fid = FileInstanceDifference.new(:
|
287
|
+
fid = FileInstanceDifference.new(change: 'modified')
|
285
288
|
fid.basis_path = path
|
286
289
|
fid.other_path = "same"
|
287
290
|
fid.signatures << basis_path_hash[path]
|
@@ -300,7 +303,7 @@ module Moab
|
|
300
303
|
# Container for reporting the set of file-level differences of type 'added'
|
301
304
|
def tabulate_added_files(basis_path_hash, other_path_hash)
|
302
305
|
other_only_keys(basis_path_hash, other_path_hash).each do |path|
|
303
|
-
fid = FileInstanceDifference.new(:
|
306
|
+
fid = FileInstanceDifference.new(change: 'added')
|
304
307
|
fid.basis_path = ""
|
305
308
|
fid.other_path = path
|
306
309
|
fid.signatures << other_path_hash[path]
|
@@ -318,7 +321,7 @@ module Moab
|
|
318
321
|
# Container for reporting the set of file-level differences of type 'deleted'
|
319
322
|
def tabulate_deleted_files(basis_path_hash, other_path_hash)
|
320
323
|
basis_only_keys(basis_path_hash, other_path_hash).each do |path|
|
321
|
-
fid = FileInstanceDifference.new(:
|
324
|
+
fid = FileInstanceDifference.new(change: 'deleted')
|
322
325
|
fid.basis_path = path
|
323
326
|
fid.other_path = ""
|
324
327
|
fid.signatures << basis_path_hash[path]
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for reporting a set of file-level differences of the type specified by the change attribute
|
3
5
|
#
|
@@ -24,11 +26,11 @@ module Moab
|
|
24
26
|
|
25
27
|
# @attribute
|
26
28
|
# @return [String] The type of change (identical|renamed|modified|deleted|added)
|
27
|
-
attribute :change, String, :
|
29
|
+
attribute :change, String, key: true
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [Integer] How many files were changed
|
31
|
-
attribute :count, Integer, :
|
33
|
+
attribute :count, Integer, on_save: proc { |n| n.to_s }
|
32
34
|
|
33
35
|
def count
|
34
36
|
files.size
|
@@ -36,6 +38,6 @@ module Moab
|
|
36
38
|
|
37
39
|
# @attribute
|
38
40
|
# @return [Array<FileInstanceDifference>] The set of file instances having this type of change
|
39
|
-
has_many :files, FileInstanceDifference, :
|
41
|
+
has_many :files, FileInstanceDifference, tag: 'file'
|
40
42
|
end
|
41
43
|
end
|
data/lib/moab/file_instance.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# The file path and last modification date properties of a file
|
3
5
|
#
|
@@ -23,7 +25,7 @@ module Moab
|
|
23
25
|
|
24
26
|
# @attribute
|
25
27
|
# @return [String] The id is the filename path, relative to the file group's base directory
|
26
|
-
attribute :path, String, :
|
28
|
+
attribute :path, String, key: true
|
27
29
|
|
28
30
|
# @attribute
|
29
31
|
# @return [String] gsub(/\n/,' ')
|
@@ -52,6 +54,7 @@ module Moab
|
|
52
54
|
# @return [Boolean] Returns true if self and other have the same path.
|
53
55
|
def eql?(other)
|
54
56
|
return false unless other.respond_to?(:path) # Cannot equal an incomparable type!
|
57
|
+
|
55
58
|
path == other.path
|
56
59
|
end
|
57
60
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for recording difference information at the file level
|
3
5
|
# * If there was no change, the change type is set to <i>identical</i>
|
@@ -36,14 +38,14 @@ module Moab
|
|
36
38
|
|
37
39
|
# @attribute
|
38
40
|
# @return [String] The file's path in the basis inventory (usually for an old version)
|
39
|
-
attribute :basis_path, String, :
|
41
|
+
attribute :basis_path, String, tag: 'basisPath', on_save: proc { |s| s.to_s }
|
40
42
|
|
41
43
|
# @attribute
|
42
44
|
# @return [String] The file's path in the other inventory (usually for an new version) compared against the basis
|
43
|
-
attribute :other_path, String, :
|
45
|
+
attribute :other_path, String, tag: 'otherPath', on_save: proc { |s| s.to_s }
|
44
46
|
|
45
47
|
# @attribute
|
46
48
|
# @return [Array<FileSignature>] The fixity data of the file manifestation(s) (plural if change was a content modification)
|
47
|
-
has_many :signatures, FileSignature, :
|
49
|
+
has_many :signatures, FileSignature, tag: 'fileSignature'
|
48
50
|
end
|
49
51
|
end
|
data/lib/moab/file_inventory.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A structured container for recording information about a collection of related files.
|
3
5
|
#
|
@@ -44,20 +46,20 @@ module Moab
|
|
44
46
|
|
45
47
|
# @attribute
|
46
48
|
# @return [String] The digital object identifier (druid)
|
47
|
-
attribute :digital_object_id, String, :
|
49
|
+
attribute :digital_object_id, String, tag: 'objectId'
|
48
50
|
|
49
51
|
# @attribute
|
50
52
|
# @return [Integer] The ordinal version number
|
51
|
-
attribute :version_id, Integer, :
|
53
|
+
attribute :version_id, Integer, tag: 'versionId', key: true, on_save: proc { |n| n.to_s }
|
52
54
|
|
53
55
|
# @return [String] The unique identifier concatenating digital object id with version id
|
54
56
|
def composite_key
|
55
|
-
digital_object_id
|
57
|
+
"#{digital_object_id}-#{StorageObject.version_dirname(version_id)}"
|
56
58
|
end
|
57
59
|
|
58
60
|
# @attribute
|
59
61
|
# @return [String] The datetime at which the inventory was created
|
60
|
-
attribute :inventory_datetime, String, :
|
62
|
+
attribute :inventory_datetime, String, tag: 'inventoryDatetime'
|
61
63
|
|
62
64
|
def inventory_datetime=(datetime)
|
63
65
|
@inventory_datetime = Moab::UtcTime.input(datetime)
|
@@ -69,7 +71,7 @@ module Moab
|
|
69
71
|
|
70
72
|
# @attribute
|
71
73
|
# @return [Integer] The total number of data files in the inventory (dynamically calculated)
|
72
|
-
attribute :file_count, Integer, :
|
74
|
+
attribute :file_count, Integer, tag: 'fileCount', on_save: proc { |t| t.to_s }
|
73
75
|
|
74
76
|
def file_count
|
75
77
|
groups.inject(0) { |sum, group| sum + group.file_count }
|
@@ -77,7 +79,7 @@ module Moab
|
|
77
79
|
|
78
80
|
# @attribute
|
79
81
|
# @return [Integer] The total size (in bytes) in all files of all files in the inventory (dynamically calculated)
|
80
|
-
attribute :byte_count, Integer, :
|
82
|
+
attribute :byte_count, Integer, tag: 'byteCount', on_save: proc { |t| t.to_s }
|
81
83
|
|
82
84
|
def byte_count
|
83
85
|
groups.inject(0) { |sum, group| sum + group.byte_count }
|
@@ -85,7 +87,7 @@ module Moab
|
|
85
87
|
|
86
88
|
# @attribute
|
87
89
|
# @return [Integer] The total disk usage (in 1 kB blocks) of all data files (estimating du -k result) (dynamically calculated)
|
88
|
-
attribute :block_count, Integer, :
|
90
|
+
attribute :block_count, Integer, tag: 'blockCount', on_save: proc { |t| t.to_s }
|
89
91
|
|
90
92
|
def block_count
|
91
93
|
groups.inject(0) { |sum, group| sum + group.block_count }
|
@@ -93,7 +95,7 @@ module Moab
|
|
93
95
|
|
94
96
|
# @attribute
|
95
97
|
# @return [Array<FileGroup>] The set of data groups comprising the version
|
96
|
-
has_many :groups, FileGroup, :
|
98
|
+
has_many :groups, FileGroup, tag: 'fileGroup'
|
97
99
|
|
98
100
|
# @return [Array<FileGroup] The set of data groups that contain files
|
99
101
|
def non_empty_groups
|
@@ -132,9 +134,11 @@ module Moab
|
|
132
134
|
file_group = group(group_id)
|
133
135
|
errmsg = "group #{group_id} not found for #{digital_object_id} - #{version_id}"
|
134
136
|
raise FileNotFoundException, errmsg if file_group.nil?
|
137
|
+
|
135
138
|
file_signature = file_group.path_hash[file_id]
|
136
139
|
errmsg = "#{group_id} file #{file_id} not found for #{digital_object_id} - #{version_id}"
|
137
140
|
raise FileNotFoundException, errmsg if file_signature.nil?
|
141
|
+
|
138
142
|
file_signature
|
139
143
|
end
|
140
144
|
|
@@ -190,7 +194,7 @@ module Moab
|
|
190
194
|
signatures_from_bag = signatures_from_bagit_manifests(bag_pathname)
|
191
195
|
bag_data_subdirs = bag_pathname.join('data').children
|
192
196
|
bag_data_subdirs.each do |subdir|
|
193
|
-
groups << FileGroup.new(:
|
197
|
+
groups << FileGroup.new(group_id: subdir.basename.to_s).group_from_bagit_subdir(subdir, signatures_from_bag)
|
194
198
|
end
|
195
199
|
self
|
196
200
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# Compares two {FileInventory} instances based primarily on file signatures and secondarily on file pathnames.
|
3
5
|
# Although the usual use will be to compare the content of 2 different temporal versions of the same object,
|
@@ -28,11 +30,11 @@ module Moab
|
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [String] The digital object ID (druid)
|
31
|
-
attribute :digital_object_id, String, :
|
33
|
+
attribute :digital_object_id, String, tag: 'objectId'
|
32
34
|
|
33
35
|
# @attribute
|
34
36
|
# @return [Integer] the number of differences found between the two inventories that were compared (dynamically calculated)
|
35
|
-
attribute :difference_count, Integer, :
|
37
|
+
attribute :difference_count, Integer, tag: 'differenceCount', on_save: proc { |i| i.to_s }
|
36
38
|
|
37
39
|
def difference_count
|
38
40
|
@group_differences.inject(0) { |sum, group| sum + group.difference_count }
|
@@ -48,7 +50,7 @@ module Moab
|
|
48
50
|
|
49
51
|
# @attribute
|
50
52
|
# @return [String] The datetime at which the report was run
|
51
|
-
attribute :report_datetime, String, :
|
53
|
+
attribute :report_datetime, String, tag: 'reportDatetime'
|
52
54
|
|
53
55
|
def report_datetime=(datetime)
|
54
56
|
@report_datetime = Moab::UtcTime.input(datetime)
|
@@ -60,7 +62,7 @@ module Moab
|
|
60
62
|
|
61
63
|
# @attribute
|
62
64
|
# @return [Array<FileGroupDifference>] The set of data groups comprising the version
|
63
|
-
has_many :group_differences, FileGroupDifference, :
|
65
|
+
has_many :group_differences, FileGroupDifference, tag: 'fileGroupDifference'
|
64
66
|
|
65
67
|
# @return [Array<String>] The data fields to include in summary reports
|
66
68
|
def summary_fields
|
@@ -87,8 +89,8 @@ module Moab
|
|
87
89
|
group_ids = basis_inventory.group_ids | other_inventory.group_ids
|
88
90
|
group_ids.each do |group_id|
|
89
91
|
# get a pair of groups to compare, creating a empty group if not present in the inventory
|
90
|
-
basis_group = basis_inventory.group(group_id) || FileGroup.new(:
|
91
|
-
other_group = other_inventory.group(group_id) || FileGroup.new(:
|
92
|
+
basis_group = basis_inventory.group(group_id) || FileGroup.new(group_id: group_id)
|
93
|
+
other_group = other_inventory.group(group_id) || FileGroup.new(group_id: group_id)
|
92
94
|
@group_differences << FileGroupDifference.new.compare_file_groups(basis_group, other_group)
|
93
95
|
end
|
94
96
|
self
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Moab
|
2
4
|
# A container for a file signature and all the physical file instances that have that signature
|
3
5
|
# This element has one child {FileSignature} element, and one or more {FileInstance} elements
|
@@ -28,7 +30,7 @@ module Moab
|
|
28
30
|
|
29
31
|
# @attribute
|
30
32
|
# @return [FileSignature] The fixity data of the file instance
|
31
|
-
element :signature, FileSignature, :
|
33
|
+
element :signature, FileSignature, tag: 'fileSignature'
|
32
34
|
|
33
35
|
def signature
|
34
36
|
@signature.is_a?(Array) ? @signature[0] : @signature
|
@@ -40,7 +42,7 @@ module Moab
|
|
40
42
|
|
41
43
|
# @attribute
|
42
44
|
# @return [Array<FileInstance>] The location(s) of the file manifestation's file instances
|
43
|
-
has_many :instances, FileInstance, :
|
45
|
+
has_many :instances, FileInstance, tag: 'fileInstance'
|
44
46
|
|
45
47
|
# @api internal
|
46
48
|
# @return [Array<String>] Create an array from all the file paths of the child {FileInstance} objects
|
@@ -75,6 +77,7 @@ module Moab
|
|
75
77
|
# @return [Boolean] True if {FileManifestation} objects have same content
|
76
78
|
def ==(other)
|
77
79
|
return false unless other.respond_to?(:signature) && other.respond_to?(:instances) # Cannot equal an incomparable type!
|
80
|
+
|
78
81
|
(signature == other.signature) && (instances == other.instances)
|
79
82
|
end
|
80
83
|
end
|