duracloud-client 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/duracloud/audit_log.rb +1 -5
- data/lib/duracloud/bit_integrity_report.rb +1 -1
- data/lib/duracloud/content.rb +18 -0
- data/lib/duracloud/manifest.rb +1 -1
- data/lib/duracloud/properties.rb +1 -1
- data/lib/duracloud/rest_methods.rb +3 -4
- data/lib/duracloud/tsv.rb +39 -17
- data/lib/duracloud/version.rb +1 -1
- data/spec/unit/audit_log_spec.rb +22 -9
- data/spec/unit/bit_integrity_report_spec.rb +22 -9
- data/spec/unit/client_spec.rb +7 -5
- data/spec/unit/content_spec.rb +37 -8
- data/spec/unit/manifest_spec.rb +22 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 328f7556852dc8ca4dbdf2fed3314aa6ca2c160b
|
4
|
+
data.tar.gz: d10ae8810f1e964d495b8b88142246d42fc2c410
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efa0688d30ec628915d6497422377c9edf95c06233af784947103ab110a4ea8925b7ff99854ccf829e024414eba6b370edd409dc525ff81b14c8707c1f6ccd93
|
7
|
+
data.tar.gz: 08bfcbd0b87934908c9b229b09400648699f90dd32e903b77d362033b8dcdbb1c737e3727e095b4a1343b32930dac68066895e5b5edc84f3d4e04c6e6a2db8e5
|
data/lib/duracloud/audit_log.rb
CHANGED
data/lib/duracloud/content.rb
CHANGED
@@ -107,6 +107,24 @@ module Duracloud
|
|
107
107
|
@md5
|
108
108
|
end
|
109
109
|
|
110
|
+
# @return [Duracloud::Content] the copied content
|
111
|
+
# The current instance still represents the original content.
|
112
|
+
def copy(target_space_id:, target_content_id:, target_store_id: nil)
|
113
|
+
copy_headers = {'x-dura-meta-copy-source'=>[space_id, content_id].join('/')}
|
114
|
+
copy_headers['x-dura-meta-copy-source-store'] = store_id if store_id
|
115
|
+
options = { storeID: target_store_id, headers: copy_headers }
|
116
|
+
Client.copy_content(target_space_id, target_content_id, **options)
|
117
|
+
Content.find(space_id: target_space_id, content_id: target_content_id, store_id: target_store_id, md5: md5)
|
118
|
+
end
|
119
|
+
|
120
|
+
# @return [Duracloud::Content] the moved content
|
121
|
+
# The current instance still represents the deleted content.
|
122
|
+
def move(**args)
|
123
|
+
copied = copy(**args)
|
124
|
+
delete
|
125
|
+
copied
|
126
|
+
end
|
127
|
+
|
110
128
|
private
|
111
129
|
|
112
130
|
def set_md5!(response)
|
data/lib/duracloud/manifest.rb
CHANGED
data/lib/duracloud/properties.rb
CHANGED
@@ -19,7 +19,7 @@ module Duracloud
|
|
19
19
|
SPACE_ACLS = /\A#{PREFIX}acl-/
|
20
20
|
|
21
21
|
# Copy Content headers
|
22
|
-
COPY_CONTENT = /\A#{PREFIX}copy-source(-store)
|
22
|
+
COPY_CONTENT = /\A#{PREFIX}copy-source(-store)?\z/
|
23
23
|
|
24
24
|
# DuraCloud internal content properties
|
25
25
|
INTERNAL = /\A#{PREFIX}content-(mimetype|size|checksum|modified)\z/
|
@@ -49,9 +49,8 @@ module Duracloud
|
|
49
49
|
durastore_content(:put, space_id, content_id, **options)
|
50
50
|
end
|
51
51
|
|
52
|
-
def copy_content(
|
53
|
-
|
54
|
-
"The API method 'Copy Content' has not yet been implemented."
|
52
|
+
def copy_content(target_space_id, target_content_id, **options)
|
53
|
+
durastore_content(:put, target_space_id, target_content_id, **options)
|
55
54
|
end
|
56
55
|
|
57
56
|
def delete_content(space_id, content_id, **options)
|
@@ -91,7 +90,7 @@ module Duracloud
|
|
91
90
|
end
|
92
91
|
|
93
92
|
def durastore_content(http_method, space_id, content_id, **options)
|
94
|
-
escaped_content_id = content_id.gsub(/%/, "%25")
|
93
|
+
escaped_content_id = content_id.gsub(/%/, "%25").gsub(/ /, "%20")
|
95
94
|
url = [ space_id, escaped_content_id ].join("/")
|
96
95
|
durastore(http_method, url, **options)
|
97
96
|
end
|
data/lib/duracloud/tsv.rb
CHANGED
@@ -2,31 +2,53 @@ require "csv"
|
|
2
2
|
|
3
3
|
module Duracloud
|
4
4
|
module TSV
|
5
|
-
|
5
|
+
|
6
6
|
def csv
|
7
|
-
@csv ||= CSV
|
8
|
-
header_line, rows = tsv.split(/\r?\n/, 2)
|
9
|
-
headers = header_line.split("\t").map { |h| h.downcase.gsub(/-/, "_") }
|
10
|
-
header_row = CSV::Row.new(headers, headers, true)
|
11
|
-
csv << header_row
|
12
|
-
rows.split(/\r?\n/).each do |row|
|
13
|
-
csv << row.split("\t")
|
14
|
-
end
|
15
|
-
end
|
7
|
+
@csv ||= CSV.new(tsv, csv_options)
|
16
8
|
end
|
17
9
|
|
18
|
-
# @return [Enumerator] rows as hashes
|
19
10
|
def rows
|
20
|
-
Enumerator.new do |e|
|
21
|
-
|
22
|
-
next if row.header_row?
|
23
|
-
e << row.to_hash
|
24
|
-
end
|
11
|
+
@rows ||= Enumerator.new do |e|
|
12
|
+
table.each { |row| e << row.to_hash }
|
25
13
|
end
|
26
14
|
end
|
27
15
|
|
16
|
+
def table
|
17
|
+
csv.rewind
|
18
|
+
csv.read
|
19
|
+
ensure
|
20
|
+
csv.rewind
|
21
|
+
end
|
22
|
+
|
28
23
|
def tsv
|
29
|
-
|
24
|
+
@tsv
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_tsv(io_or_str)
|
28
|
+
@tsv = io_or_str
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_tsv_file(path)
|
32
|
+
load_tsv(File.new(path, "rb"))
|
30
33
|
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
tsv.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def csv_options
|
42
|
+
{ col_sep: "\t",
|
43
|
+
quote_char: "`",
|
44
|
+
headers: true,
|
45
|
+
header_converters: header_converters,
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def header_converters
|
50
|
+
lambda { |h| h.downcase.gsub(/-/, "_") }
|
51
|
+
end
|
52
|
+
|
31
53
|
end
|
32
54
|
end
|
data/lib/duracloud/version.rb
CHANGED
data/spec/unit/audit_log_spec.rb
CHANGED
@@ -1,22 +1,35 @@
|
|
1
1
|
module Duracloud
|
2
2
|
RSpec.describe AuditLog do
|
3
3
|
|
4
|
-
let(:
|
5
|
-
|
6
|
-
before {
|
7
|
-
allow(subject).to receive(:tsv) { tsv }
|
8
|
-
}
|
4
|
+
let(:path) { File.expand_path('../../fixtures/audit_log.tsv', __FILE__) }
|
9
5
|
|
10
6
|
subject { described_class.new("myspace") }
|
11
7
|
|
12
|
-
describe "
|
8
|
+
describe "#csv" do
|
9
|
+
before {
|
10
|
+
allow(subject).to receive(:tsv) { File.read(path) }
|
11
|
+
subject.csv.read
|
12
|
+
}
|
13
13
|
specify {
|
14
14
|
expect(subject.csv.headers).to eq(%w(account store_id space_id content_id content_md5 content_size content_mimetype content_properties space_acls source_space_id source_content_id timestamp action username))
|
15
|
-
expect(subject.
|
16
|
-
expect(subject.
|
17
|
-
expect(subject.rows.next).to eq({"account"=>"example", "store_id"=>"1065", "space_id"=>"myspace", "content_id"=>"", "content_md5"=>"", "content_size"=>"", "content_mimetype"=>"", "content_properties"=>"", "space_acls"=>"", "source_space_id"=>"", "source_content_id"=>"", "timestamp"=>"2016-04-27T18:34:18.018", "action"=>"CREATE_SPACE", "username"=>"bob@example.com"})
|
15
|
+
expect(subject.rows.to_a.size).to eq(6)
|
16
|
+
expect(subject.rows.first).to eq({"account"=>"example", "store_id"=>"1065", "space_id"=>"myspace", "content_id"=>nil, "content_md5"=>nil, "content_size"=>nil, "content_mimetype"=>nil, "content_properties"=>nil, "space_acls"=>nil, "source_space_id"=>nil, "source_content_id"=>nil, "timestamp"=>"2016-04-27T18:34:18.018", "action"=>"CREATE_SPACE", "username"=>"bob@example.com"})
|
18
17
|
}
|
19
18
|
end
|
20
19
|
|
20
|
+
describe "#load_tsv" do
|
21
|
+
it "loads a string" do
|
22
|
+
tsv = File.read(path)
|
23
|
+
subject.load_tsv(tsv)
|
24
|
+
expect(subject.tsv).to eq(tsv)
|
25
|
+
end
|
26
|
+
it "loads an IO" do
|
27
|
+
tsv = File.read(path)
|
28
|
+
tsv_io = File.new(path, "rb")
|
29
|
+
subject.load_tsv(tsv)
|
30
|
+
expect(subject.tsv.to_s).to eq(tsv)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
21
34
|
end
|
22
35
|
end
|
@@ -1,22 +1,35 @@
|
|
1
1
|
module Duracloud
|
2
2
|
RSpec.describe BitIntegrityReport do
|
3
3
|
|
4
|
-
let(:
|
5
|
-
|
6
|
-
before {
|
7
|
-
allow(subject).to receive(:tsv) { tsv }
|
8
|
-
}
|
4
|
+
let(:path) { File.expand_path('../../fixtures/bit_integrity_report.tsv', __FILE__) }
|
9
5
|
|
10
6
|
subject { described_class.new("myspace") }
|
11
7
|
|
12
|
-
describe "
|
8
|
+
describe "#csv" do
|
9
|
+
before do
|
10
|
+
allow(subject).to receive(:tsv) { File.read(path) }
|
11
|
+
subject.csv.read
|
12
|
+
end
|
13
13
|
specify {
|
14
14
|
expect(subject.csv.headers).to eq(%w(date_checked account store_id store_type space_id content_id result content_checksum provider_checksum manifest_checksum details))
|
15
|
-
expect(subject.
|
16
|
-
expect(subject.
|
17
|
-
expect(subject.rows.next).to eq({"date_checked"=>"2016-05-15T04:11:14", "account"=>"example", "store_id"=>"1065", "store_type"=>"AMAZON_S3", "space_id"=>"myspace", "content_id"=>"BINARIES/00/00/e8/0000e819ac3e67d039d288adaab5b5e44c3c21d9", "result"=>"SUCCESS", "content_checksum"=>"27333f3c06a6d259863384799be68d30", "provider_checksum"=>"27333f3c06a6d259863384799be68d30", "manifest_checksum"=>"27333f3c06a6d259863384799be68d30", "details"=>"--"})
|
15
|
+
expect(subject.rows.to_a.size).to eq(3)
|
16
|
+
expect(subject.rows.first).to eq({"date_checked"=>"2016-05-15T04:11:14", "account"=>"example", "store_id"=>"1065", "store_type"=>"AMAZON_S3", "space_id"=>"myspace", "content_id"=>"BINARIES/00/00/e8/0000e819ac3e67d039d288adaab5b5e44c3c21d9", "result"=>"SUCCESS", "content_checksum"=>"27333f3c06a6d259863384799be68d30", "provider_checksum"=>"27333f3c06a6d259863384799be68d30", "manifest_checksum"=>"27333f3c06a6d259863384799be68d30", "details"=>"--"})
|
18
17
|
}
|
19
18
|
end
|
20
19
|
|
20
|
+
describe "#load_tsv" do
|
21
|
+
it "loads a string" do
|
22
|
+
tsv = File.read(path)
|
23
|
+
subject.load_tsv(tsv)
|
24
|
+
expect(subject.tsv).to eq(tsv)
|
25
|
+
end
|
26
|
+
it "loads an IO" do
|
27
|
+
tsv = File.read(path)
|
28
|
+
tsv_io = File.new(path, "rb")
|
29
|
+
subject.load_tsv(tsv)
|
30
|
+
expect(subject.tsv.to_s).to eq(tsv)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
21
34
|
end
|
22
35
|
end
|
data/spec/unit/client_spec.rb
CHANGED
@@ -130,9 +130,9 @@ module Duracloud
|
|
130
130
|
subject.get_content_properties("foo", "bar")
|
131
131
|
expect(stub).to have_been_requested
|
132
132
|
}
|
133
|
-
it "escapes percent signs in the content id" do
|
134
|
-
stub = stub_request(:head, "https://example.com/durastore/foo/z/z/bar%252Fbaz")
|
135
|
-
subject.get_content_properties("foo", "z/z/bar%2Fbaz")
|
133
|
+
it "escapes percent signs and spaces in the content id" do
|
134
|
+
stub = stub_request(:head, "https://example.com/durastore/foo/z/z/bar%252Fbaz%20spam%20eggs")
|
135
|
+
subject.get_content_properties("foo", "z/z/bar%2Fbaz spam eggs")
|
136
136
|
expect(stub).to have_been_requested
|
137
137
|
end
|
138
138
|
specify {
|
@@ -240,8 +240,10 @@ module Duracloud
|
|
240
240
|
|
241
241
|
describe "copy_content" do
|
242
242
|
specify {
|
243
|
-
|
244
|
-
|
243
|
+
stub = stub_request(:put, "https://example.com/durastore/spam/eggs")
|
244
|
+
.with(headers: {'x-dura-meta-copy-source'=>'foo/bar'})
|
245
|
+
subject.copy_content("spam", "eggs", headers: {'x-dura-meta-copy-source'=>'foo/bar'})
|
246
|
+
expect(stub).to have_been_requested
|
245
247
|
}
|
246
248
|
end
|
247
249
|
|
data/spec/unit/content_spec.rb
CHANGED
@@ -159,19 +159,48 @@ module Duracloud
|
|
159
159
|
end
|
160
160
|
|
161
161
|
describe "#properties" do
|
162
|
-
before
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
}
|
169
|
-
}
|
162
|
+
before do
|
163
|
+
stub_request(:head, url)
|
164
|
+
.to_return(headers: {'x-dura-meta-creator'=>'testuser',
|
165
|
+
'Content-Type'=>'text/plain',
|
166
|
+
'Content-MD5'=>'08a008a01d498c404b0c30852b39d3b8'})
|
167
|
+
end
|
170
168
|
specify {
|
169
|
+
pending "Research Webmock problem with return headers"
|
171
170
|
content = Content.find(space_id: "foo", content_id: "bar")
|
172
171
|
expect(content.properties.x_dura_meta_creator).to eq('testuser')
|
173
172
|
}
|
174
173
|
end
|
175
174
|
|
175
|
+
describe "#copy" do
|
176
|
+
let(:target) { "https://example.com/durastore/spam/eggs" }
|
177
|
+
subject { Content.new(space_id: "foo", content_id: "bar") }
|
178
|
+
specify {
|
179
|
+
stub1 = stub_request(:put, target)
|
180
|
+
.with(headers: {'x-dura-meta-copy-source'=>'foo/bar'})
|
181
|
+
stub2 = stub_request(:head, target)
|
182
|
+
copied = subject.copy(target_space_id: "spam", target_content_id: "eggs")
|
183
|
+
expect(copied).to be_a(Content)
|
184
|
+
expect(stub1).to have_been_requested
|
185
|
+
expect(stub2).to have_been_requested
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "#move" do
|
190
|
+
let(:target) { "https://example.com/durastore/spam/eggs" }
|
191
|
+
subject { Content.new(space_id: "foo", content_id: "bar") }
|
192
|
+
specify {
|
193
|
+
stub1 = stub_request(:put, target)
|
194
|
+
.with(headers: {'x-dura-meta-copy-source'=>'foo/bar'})
|
195
|
+
stub2 = stub_request(:head, target)
|
196
|
+
stub3 = stub_request(:delete, "https://example.com/durastore/foo/bar")
|
197
|
+
moved = subject.move(target_space_id: "spam", target_content_id: "eggs")
|
198
|
+
expect(moved).to be_a(Content)
|
199
|
+
expect(stub1).to have_been_requested
|
200
|
+
expect(stub2).to have_been_requested
|
201
|
+
expect(stub3).to have_been_requested
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
176
205
|
end
|
177
206
|
end
|
data/spec/unit/manifest_spec.rb
CHANGED
@@ -1,22 +1,34 @@
|
|
1
1
|
module Duracloud
|
2
2
|
RSpec.describe Manifest do
|
3
3
|
|
4
|
-
let(:tsv) { File.read(File.expand_path('../../fixtures/manifest.tsv', __FILE__)) }
|
5
|
-
|
6
|
-
before {
|
7
|
-
allow(subject).to receive(:tsv) { tsv }
|
8
|
-
}
|
9
|
-
|
10
4
|
subject { described_class.new("myspace") }
|
5
|
+
let(:path) { File.expand_path('../../fixtures/manifest.tsv', __FILE__) }
|
11
6
|
|
12
|
-
describe "
|
7
|
+
describe "#csv" do
|
8
|
+
before do
|
9
|
+
allow(subject).to receive(:tsv) { File.read(path) }
|
10
|
+
subject.csv.read
|
11
|
+
end
|
13
12
|
specify {
|
14
13
|
expect(subject.csv.headers).to eq(%w(space_id content_id md5))
|
15
|
-
expect(subject.
|
16
|
-
expect(subject.
|
17
|
-
expect(subject.rows.next).to eq({"space_id"=>"myspace", "content_id"=>"METADATA/d6/42/0c/9c/d6420c9c-82f8-4f6a-baf7-37b9be7f4c5f/20160502_172925/manifest-md5.txt", "md5"=>"21fef474787860ccfb67bdd99ddee93a"})
|
14
|
+
expect(subject.rows.to_a.size).to eq(3)
|
15
|
+
expect(subject.rows.first).to eq({"space_id"=>"myspace", "content_id"=>"METADATA/d6/42/0c/9c/d6420c9c-82f8-4f6a-baf7-37b9be7f4c5f/20160502_172925/manifest-md5.txt", "md5"=>"21fef474787860ccfb67bdd99ddee93a"})
|
18
16
|
}
|
19
17
|
end
|
20
18
|
|
19
|
+
describe "#load_tsv" do
|
20
|
+
it "loads a string" do
|
21
|
+
tsv = File.read(path)
|
22
|
+
subject.load_tsv(tsv)
|
23
|
+
expect(subject.tsv).to eq(tsv)
|
24
|
+
end
|
25
|
+
it "loads an IO" do
|
26
|
+
tsv = File.read(path)
|
27
|
+
tsv_io = File.new(path, "rb")
|
28
|
+
subject.load_tsv(tsv)
|
29
|
+
expect(subject.tsv.to_s).to eq(tsv)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
21
33
|
end
|
22
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duracloud-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chandek-Stark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|