duracloud-client 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +105 -24
- data/duracloud.gemspec +1 -0
- data/lib/duracloud/audit_log.rb +35 -0
- data/lib/duracloud/bit_integrity_report.rb +40 -26
- data/lib/duracloud/configuration.rb +7 -3
- data/lib/duracloud/content.rb +65 -65
- data/lib/duracloud/csv_reader.rb +18 -0
- data/lib/duracloud/durastore_request.rb +1 -1
- data/lib/duracloud/error.rb +2 -2
- data/lib/duracloud/error_handler.rb +8 -0
- data/lib/duracloud/has_properties.rb +7 -0
- data/lib/duracloud/manifest.rb +37 -14
- data/lib/duracloud/persistence.rb +1 -1
- data/lib/duracloud/properties.rb +43 -6
- data/lib/duracloud/request.rb +24 -12
- data/lib/duracloud/rest_methods.rb +49 -37
- data/lib/duracloud/space.rb +201 -35
- data/lib/duracloud/space_acls.rb +6 -2
- data/lib/duracloud/space_properties.rb +0 -12
- data/lib/duracloud/store.rb +12 -0
- data/lib/duracloud/version.rb +1 -1
- data/lib/duracloud.rb +2 -0
- data/spec/spec_helper.rb +13 -20
- data/spec/unit/audit_log_spec.rb +5 -0
- data/spec/unit/bit_integrity_report_spec.rb +5 -0
- data/spec/unit/client_spec.rb +276 -5
- data/spec/unit/content_spec.rb +107 -14
- data/spec/{fixtures/responses/GetManifest.tsv → unit/manifest_spec.rb} +9 -0
- data/spec/unit/space_spec.rb +136 -1
- data/spec/unit/store_spec.rb +36 -1
- metadata +24 -8
- data/spec/fixtures/responses/GetSpaces.xml +0 -5
- data/spec/fixtures/responses/GetStores.xml +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16480155d0d2f9036d3f8c199f5a46d2b85f7a25
|
4
|
+
data.tar.gz: 573389d2175aa32650c97f06933688dee8526bf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06f61f2484247a0f729d96bdefda8836fbe5220b8e2986c5ddf6bbc56e8f9add646161d70d7b5664307f6fdc32e2cfbf5690371c15ae67f29655dd11c41bd2a1
|
7
|
+
data.tar.gz: 8c3b83a4b8fc005e24cccac9346a1b95318ec90adc881b2d6d24a9ac311775b7463f6442cbb142f10fcf9f2ebee0a616030d94e072997425811bbd4d1427809a
|
data/README.md
CHANGED
@@ -40,7 +40,7 @@ end
|
|
40
40
|
|
41
41
|
```
|
42
42
|
> c = Duracloud::Client.new
|
43
|
-
=> #<Duracloud::Client:0x007fe953a1c630 @config=#<Duracloud::Configuration host="foo.duracloud.org", port=nil, user="bob@example.com"
|
43
|
+
=> #<Duracloud::Client:0x007fe953a1c630 @config=#<Duracloud::Configuration host="foo.duracloud.org", port=nil, user="bob@example.com">>
|
44
44
|
```
|
45
45
|
|
46
46
|
#### Logging
|
@@ -53,29 +53,80 @@ Duracloud::Client.configure do |config|
|
|
53
53
|
end
|
54
54
|
```
|
55
55
|
|
56
|
+
You can also silence logging:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
Duracloud::Client.configure do |config|
|
60
|
+
config.silence_logging! # sets logger device to null device
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
56
64
|
### List Storage Providers
|
57
65
|
|
58
66
|
```
|
59
|
-
|
67
|
+
>> stores = Duracloud::Store.all
|
60
68
|
=> [#<Duracloud::Store:0x007faa592e9068 @owner_id="0", @primary="0", @id="1", @provider_type="AMAZON_GLACIER">, #<Duracloud::Store:0x007faa592dbd78 @owner_id="0", @primary="1", @id="2", @provider_type="AMAZON_S3">]
|
61
69
|
|
62
|
-
|
63
|
-
=> false
|
70
|
+
>> stores.first.primary?
|
71
|
+
=> false
|
72
|
+
|
73
|
+
>> Duracloud::Store.primary
|
74
|
+
=> #<Duracloud::Store:0x007faa592dbd78 @owner_id="0", @primary="1", @id="2", @provider_type="AMAZON_S3">
|
64
75
|
```
|
65
76
|
|
66
|
-
###
|
77
|
+
### Spaces
|
67
78
|
|
68
|
-
|
79
|
+
#### Create a new space
|
69
80
|
|
70
|
-
|
81
|
+
```
|
82
|
+
>> space = Duracloud::Space.create("rest-api-testing2")
|
83
|
+
D, [2016-04-29T12:12:32.641574 #28275] DEBUG -- : Duracloud::Client PUT https://foo.duracloud.org/durastore/rest-api-testing2 201 Created
|
84
|
+
=> #<Duracloud::Space space_id="rest-api-testing2", store_id="(default)">
|
85
|
+
```
|
71
86
|
|
72
|
-
|
87
|
+
A `Duracloud::BadRequestError` is raise if the space ID is invalid (illegal characters, too long, etc.).
|
73
88
|
|
74
|
-
|
89
|
+
#### Retrieve a space and view its properties
|
75
90
|
|
76
91
|
```
|
77
|
-
>>
|
78
|
-
|
92
|
+
>> space = Duracloud::Space.find("rest-api-testing")
|
93
|
+
D, [2016-04-29T12:15:12.593075 #28275] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing 200 OK
|
94
|
+
=> #<Duracloud::Space space_id="rest-api-testing", store_id="(default)">
|
95
|
+
|
96
|
+
>> space.count
|
97
|
+
=> 8
|
98
|
+
|
99
|
+
>> space.created
|
100
|
+
=> #<DateTime: 2016-04-05T17:59:11+00:00 ((2457484j,64751s,0n),+0s,2299161j)>
|
101
|
+
```
|
102
|
+
|
103
|
+
A `Duracloud::NotFoundError` exception is raise if the space does not exist.
|
104
|
+
|
105
|
+
#### Enumerate the content IDs of the space
|
106
|
+
|
107
|
+
```
|
108
|
+
> space.content_ids.each { |id| puts id }
|
109
|
+
ark:/99999/fk4zzzz
|
110
|
+
foo
|
111
|
+
foo2
|
112
|
+
foo22
|
113
|
+
foo3
|
114
|
+
foo5
|
115
|
+
foo7
|
116
|
+
foo8
|
117
|
+
=> nil
|
118
|
+
|
119
|
+
> space.content_ids.to_a
|
120
|
+
=> ["ark:/99999/fk4zzzz", "foo", "foo2", "foo22", "foo3", "foo5", "foo7", "foo8"]
|
121
|
+
```
|
122
|
+
|
123
|
+
### Content
|
124
|
+
|
125
|
+
#### Create a new content item and store it in DuraCloud
|
126
|
+
|
127
|
+
```
|
128
|
+
>> new_content = Duracloud::Content.new("rest-api-testing", "ark:/99999/fk4zzzz")
|
129
|
+
=> #<Duracloud::Content space_id="rest-api-testing", content_id="ark:/99999/fk4zzzz", store_id=(default)>
|
79
130
|
|
80
131
|
>> new_content.body = "test"
|
81
132
|
=> "test"
|
@@ -84,32 +135,62 @@ TODO
|
|
84
135
|
=> "text/plain"
|
85
136
|
|
86
137
|
>> new_content.save
|
87
|
-
=> #<Duracloud::Content space_id="rest-api-testing",
|
138
|
+
=> #<Duracloud::Content space_id="rest-api-testing", content_id="ark:/99999/fk4zzzz", store_id=(default)>
|
88
139
|
```
|
89
140
|
|
90
|
-
|
141
|
+
When storing content a `Duracloud::NotFoundError` is raised if the space does not exist. A `Duracloud::BadRequestError` is raised if the content ID is invalid.
|
142
|
+
|
143
|
+
#### Retrieve an existing content item from DuraCloud
|
91
144
|
|
92
145
|
```
|
93
|
-
>> Duracloud::Content.
|
94
|
-
|
95
|
-
c.content_type = "text/plain"
|
96
|
-
end
|
97
|
-
=> #<Duracloud::Content space_id="rest-api-testing", id="ark:/99999/fk4zzzz">
|
146
|
+
>> Duracloud::Content.find("spaceID", "contentID")
|
147
|
+
=> #<Duracloud::Content space_id="spaceID", content_id="contentID", store_id=(default)>
|
98
148
|
```
|
99
149
|
|
100
|
-
|
150
|
+
If the space or content ID does not exist, a `Duracloud::NotFoundError` is raised.
|
151
|
+
|
152
|
+
#### Update the properties for a content item
|
101
153
|
|
102
|
-
```ruby
|
103
|
-
Duracloud::Content.find(id: "contentID", space_id: "spaceID")
|
104
154
|
```
|
155
|
+
>> space = Duracloud::Space.find("rest-api-testing")
|
156
|
+
=> #<Duracloud::Space space_id="rest-api-testing", store_id="(default)">
|
157
|
+
|
158
|
+
>> content = space.find_content("foo3")
|
159
|
+
D, [2016-04-29T18:31:16.975749 #32379] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
|
160
|
+
=> #<Duracloud::Content space_id="rest-api-testing", content_id="foo3", store_id=(default)>
|
105
161
|
|
106
|
-
|
162
|
+
>> content.properties
|
163
|
+
=> #<Duracloud::ContentProperties x-dura-meta-owner="ellen@example.com">
|
107
164
|
|
108
|
-
|
165
|
+
>> content.properties.creator = "bob@example.com"
|
166
|
+
>> content.save
|
167
|
+
D, [2016-04-29T18:31:52.770195 #32379] DEBUG -- : Duracloud::Client POST https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
|
168
|
+
I, [2016-04-29T18:31:52.770293 #32379] INFO -- : Content foo3 updated successfully
|
169
|
+
=> true
|
170
|
+
|
171
|
+
>> content.properties.creator
|
172
|
+
D, [2016-04-29T18:32:06.465928 #32379] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
|
173
|
+
=> "bob@example.com"
|
174
|
+
```
|
109
175
|
|
110
176
|
#### Delete a content item
|
111
177
|
|
112
|
-
|
178
|
+
```
|
179
|
+
>> space = Duracloud::Space.find("rest-api-testing")
|
180
|
+
=> #<Duracloud::Space space_id="rest-api-testing", store_id="(default)">
|
181
|
+
|
182
|
+
>> content = space.find_content("foo2")
|
183
|
+
=> #<Duracloud::Content space_id="rest-api-testing", content_id="foo2", store_id=(default)>
|
184
|
+
|
185
|
+
>> content.delete
|
186
|
+
D, [2016-04-29T18:28:31.459962 #32379] DEBUG -- : Duracloud::Client DELETE https://foo.duracloud.org/durastore/rest-api-testing/foo2 200 OK
|
187
|
+
I, [2016-04-29T18:28:31.460069 #32379] INFO -- : Content foo2 deleted successfully
|
188
|
+
=> #<Duracloud::Content space_id="rest-api-testing", content_id="foo2", store_id=(default)>
|
189
|
+
|
190
|
+
>> Duracloud::Content.exist?("rest-api-testing", "foo2")
|
191
|
+
D, [2016-04-29T18:29:03.935451 #32379] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo2 404 Not Found
|
192
|
+
=> false
|
193
|
+
```
|
113
194
|
|
114
195
|
## Versioning
|
115
196
|
|
data/duracloud.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency "activemodel", "~> 4.2"
|
26
26
|
spec.add_dependency "nokogiri", "~> 1.6"
|
27
27
|
|
28
|
+
spec.add_development_dependency "webmock", "~> 2.0"
|
28
29
|
spec.add_development_dependency "rspec", "~> 3.4"
|
29
30
|
spec.add_development_dependency "rspec-its", "~> 1.2"
|
30
31
|
spec.add_development_dependency "bundler", "~> 1.7"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Duracloud
|
2
|
+
class AuditLog
|
3
|
+
|
4
|
+
attr_reader :space_id, :store_id
|
5
|
+
|
6
|
+
def initialize(space_id, store_id = nil)
|
7
|
+
@space_id = space_id
|
8
|
+
@store_id = store_id
|
9
|
+
@response = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def csv(opts = {})
|
13
|
+
CSVReader.call(tsv, opts)
|
14
|
+
end
|
15
|
+
|
16
|
+
def tsv
|
17
|
+
response.body
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
tsv
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def response
|
27
|
+
@response ||= Client.get_manifest(space_id, **query)
|
28
|
+
end
|
29
|
+
|
30
|
+
def query
|
31
|
+
{ storeID: store_id }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require "date"
|
2
|
-
require "csv"
|
3
2
|
|
4
3
|
module Duracloud
|
5
4
|
class BitIntegrityReport
|
@@ -7,56 +6,71 @@ module Duracloud
|
|
7
6
|
SUCCESS = "SUCCESS".freeze
|
8
7
|
FAILURE = "FAILURE".freeze
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
headers: :first_row,
|
13
|
-
write_headers: true,
|
14
|
-
return_headers: true,
|
15
|
-
}
|
9
|
+
COMPLETION_DATE_HEADER = "Bit-Integrity-Report-Completion-Date".freeze
|
10
|
+
RESULT_HEADER = "Bit-Integrity-Report-Result".freeze
|
16
11
|
|
17
|
-
|
18
|
-
new(space_id).success?
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_reader :space_id
|
12
|
+
attr_reader :space_id, :store_id
|
22
13
|
|
23
|
-
def initialize(space_id)
|
14
|
+
def initialize(space_id, store_id = nil)
|
24
15
|
@space_id = space_id
|
16
|
+
@store_id = store_id
|
17
|
+
@report, @properties = nil, nil
|
25
18
|
end
|
26
19
|
|
27
|
-
def
|
20
|
+
def tsv
|
28
21
|
report.body
|
29
22
|
end
|
30
23
|
|
31
24
|
def completion_date
|
32
|
-
DateTime.parse(properties[
|
25
|
+
DateTime.parse(properties[COMPLETION_DATE_HEADER].first)
|
33
26
|
end
|
34
27
|
|
35
28
|
def result
|
36
|
-
properties[
|
29
|
+
properties[RESULT_HEADER].first
|
37
30
|
end
|
38
31
|
|
39
32
|
def csv(opts = {})
|
40
|
-
|
33
|
+
CSVReader.new(tsv, opts)
|
41
34
|
end
|
42
35
|
|
43
36
|
def success?
|
44
37
|
result == SUCCESS
|
45
38
|
end
|
46
39
|
|
47
|
-
private
|
48
|
-
|
49
40
|
def report
|
50
|
-
@report ||=
|
41
|
+
@report ||= fetch_report
|
42
|
+
end
|
43
|
+
|
44
|
+
def report_loaded?
|
45
|
+
!@report.nil?
|
51
46
|
end
|
52
47
|
|
53
48
|
def properties
|
54
|
-
@properties ||=
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
49
|
+
@properties ||= fetch_properties
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def fetch_report
|
55
|
+
reset_properties
|
56
|
+
Client.get_bit_integrity_report(space_id, **query)
|
57
|
+
end
|
58
|
+
|
59
|
+
def reset_properties
|
60
|
+
@properties = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def fetch_properties
|
64
|
+
if report_loaded?
|
65
|
+
report.headers
|
66
|
+
else
|
67
|
+
response = Client.get_bit_integrity_report_properties(space_id, **query)
|
68
|
+
response.headers
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def query
|
73
|
+
{ storeID: store_id }
|
60
74
|
end
|
61
75
|
|
62
76
|
end
|
@@ -6,6 +6,10 @@ module Duracloud
|
|
6
6
|
|
7
7
|
class << self
|
8
8
|
attr_accessor :host, :port, :user, :password, :logger
|
9
|
+
|
10
|
+
def silence_logging!
|
11
|
+
self.logger = Logger.new(File::NULL)
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
attr_reader :host, :port, :user, :password, :logger
|
@@ -15,7 +19,7 @@ module Duracloud
|
|
15
19
|
@port = port || default(:port)
|
16
20
|
@user = user || default(:user)
|
17
21
|
@password = password || default(:password)
|
18
|
-
@logger = logger || Logger.new(STDERR)
|
22
|
+
@logger = logger || self.class.logger || Logger.new(STDERR)
|
19
23
|
freeze
|
20
24
|
end
|
21
25
|
|
@@ -24,8 +28,8 @@ module Duracloud
|
|
24
28
|
end
|
25
29
|
|
26
30
|
def inspect
|
27
|
-
"#<#{self.class} host=#{host.inspect}, port=#{port.inspect},
|
28
|
-
"
|
31
|
+
"#<#{self.class} host=#{host.inspect}, port=#{port.inspect}," \
|
32
|
+
" user=#{user.inspect}>"
|
29
33
|
end
|
30
34
|
|
31
35
|
private
|
data/lib/duracloud/content.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require "uri"
|
2
1
|
require "stringio"
|
3
2
|
require "active_model"
|
4
3
|
|
@@ -13,67 +12,59 @@ module Duracloud
|
|
13
12
|
|
14
13
|
after_save :changes_applied
|
15
14
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# @
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
new(id: id, space_id: space_id) do |content|
|
24
|
-
content.load_properties
|
25
|
-
end
|
15
|
+
# Does the content exist in DuraCloud?
|
16
|
+
# @see .new for arguments
|
17
|
+
# @return [Boolean] whether the content exists
|
18
|
+
def self.exist?(*args)
|
19
|
+
find(*args) && true
|
20
|
+
rescue NotFoundError
|
21
|
+
false
|
26
22
|
end
|
27
23
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# @
|
31
|
-
# @
|
32
|
-
|
33
|
-
|
34
|
-
# @raise [Duracloud::NotFoundError] if the space ID does not exist
|
35
|
-
# @raise [Duracloud::Error] if the body is empty.
|
36
|
-
def self.create(id:, space_id:, body:)
|
37
|
-
new(id: id, space_id: space_id) do |content|
|
38
|
-
content.body = body
|
39
|
-
yield content if block_given?
|
40
|
-
content.save
|
41
|
-
end
|
24
|
+
# Find content in DuraCloud.
|
25
|
+
# @see .new for arguments
|
26
|
+
# @return [Duraclound::Content] the content
|
27
|
+
# @raise [Duracloud::NotFoundError] the space, content, or store does not exist.
|
28
|
+
def self.find(*args)
|
29
|
+
new(*args) { |content| content.load_properties }
|
42
30
|
end
|
43
31
|
|
44
|
-
attr_reader :
|
32
|
+
attr_reader :space_id, :content_id, :store_id
|
33
|
+
alias_method :id, :content_id
|
45
34
|
|
46
|
-
define_attribute_methods :content_type, :body
|
35
|
+
define_attribute_methods :content_type, :body
|
47
36
|
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# @param
|
51
|
-
# @param space_id [String] The space ID
|
52
|
-
#
|
37
|
+
# @param space_id [String] The space ID (required)
|
38
|
+
# @param content_id [String] The content ID (required)
|
39
|
+
# @param store_id [String] the store ID (optional)
|
53
40
|
# @example
|
54
|
-
# new(
|
55
|
-
def initialize(
|
56
|
-
@
|
57
|
-
@space_id = space_id
|
58
|
-
@
|
59
|
-
@content_type = nil
|
60
|
-
@md5 = nil
|
41
|
+
# new("myspace", "mycontent.txt")
|
42
|
+
def initialize(space_id, content_id, store_id = nil)
|
43
|
+
@content_id = content_id
|
44
|
+
@space_id = space_id
|
45
|
+
@store_id = store_id
|
46
|
+
@body, @content_type = nil, nil
|
61
47
|
yield self if block_given?
|
62
48
|
end
|
63
49
|
|
50
|
+
# Return the space associated with this content.
|
51
|
+
# @return [Duracloud::Space] the space.
|
52
|
+
# @raise [Duracloud::NotFoundError] the space or store does not exist.
|
64
53
|
def space
|
65
|
-
Space.find(space_id)
|
54
|
+
Space.find(space_id, store_id)
|
66
55
|
end
|
67
56
|
|
68
57
|
def inspect
|
69
|
-
"#<#{self.class}
|
58
|
+
"#<#{self.class} space_id=#{space_id.inspect}," \
|
59
|
+
" content_id=#{content_id.inspect}," \
|
60
|
+
" store_id=#{store_id || '(default)'}>"
|
70
61
|
end
|
71
62
|
|
72
63
|
# @api private
|
73
64
|
# @raise [Duracloud::NotFoundError] the content does not exist in DuraCloud.
|
74
65
|
def load_body
|
75
|
-
response = Client.get_content(
|
76
|
-
|
66
|
+
response = Client.get_content(*args, **query)
|
67
|
+
set_body(response) # don't use setter b/c marks as dirty
|
77
68
|
persisted!
|
78
69
|
end
|
79
70
|
|
@@ -85,18 +76,19 @@ module Duracloud
|
|
85
76
|
end
|
86
77
|
|
87
78
|
def body=(str_or_io)
|
88
|
-
|
89
|
-
|
90
|
-
self.md5 = Digest::MD5.hexdigest(val)
|
91
|
-
body_will_change! if md5_changed?
|
92
|
-
@body = StringIO.new(val, "r")
|
79
|
+
set_body(str_or_io)
|
80
|
+
body_will_change!
|
93
81
|
end
|
94
82
|
|
83
|
+
# Return the content body, loading from DuraCloud if necessary.
|
84
|
+
# @return [String, StringIO] the content body
|
95
85
|
def body
|
96
86
|
load_body if persisted? && empty?
|
97
87
|
@body
|
98
88
|
end
|
99
89
|
|
90
|
+
# Is the content empty?
|
91
|
+
# @return [Boolean] whether the content is empty (nil or empty string)
|
100
92
|
def empty?
|
101
93
|
@body.nil? || @body.size == 0
|
102
94
|
end
|
@@ -110,34 +102,34 @@ module Duracloud
|
|
110
102
|
@content_type
|
111
103
|
end
|
112
104
|
|
113
|
-
def md5
|
114
|
-
@md5
|
115
|
-
end
|
116
|
-
|
117
105
|
private
|
118
106
|
|
119
|
-
def
|
120
|
-
|
121
|
-
@md5 = val
|
107
|
+
def set_body(str_or_io)
|
108
|
+
@body = StringIO.new(read_string_or_io(str_or_io), "r")
|
122
109
|
end
|
123
110
|
|
124
111
|
def set_properties
|
125
112
|
headers = properties.to_h
|
126
113
|
headers["Content-Type"] = content_type if content_type_changed?
|
127
|
-
|
128
|
-
|
114
|
+
options = { headers: headers, query: query }
|
115
|
+
Client.set_content_properties(*args, **options)
|
129
116
|
end
|
130
117
|
|
131
118
|
def store
|
132
|
-
headers = {
|
133
|
-
|
119
|
+
headers = {
|
120
|
+
"Content-MD5" => md5,
|
121
|
+
"Content-Type" => content_type || "application/octet-stream"
|
122
|
+
}
|
134
123
|
headers.merge!(properties)
|
135
|
-
|
136
|
-
|
124
|
+
options = { body: body, headers: headers, query: query }
|
125
|
+
Client.store_content(*args, **options)
|
137
126
|
end
|
138
127
|
|
139
|
-
def
|
140
|
-
|
128
|
+
def md5
|
129
|
+
body.rewind
|
130
|
+
Digest::MD5.hexdigest(body.read)
|
131
|
+
ensure
|
132
|
+
body.rewind
|
141
133
|
end
|
142
134
|
|
143
135
|
def properties_class
|
@@ -145,11 +137,11 @@ module Duracloud
|
|
145
137
|
end
|
146
138
|
|
147
139
|
def get_properties_response
|
148
|
-
Client.get_content_properties(
|
140
|
+
Client.get_content_properties(*args, **query)
|
149
141
|
end
|
150
142
|
|
151
143
|
def do_delete
|
152
|
-
Client.delete_content(
|
144
|
+
Client.delete_content(*args, **query)
|
153
145
|
end
|
154
146
|
|
155
147
|
def do_save
|
@@ -181,5 +173,13 @@ module Duracloud
|
|
181
173
|
end
|
182
174
|
end
|
183
175
|
|
176
|
+
def args
|
177
|
+
[ space_id, content_id ]
|
178
|
+
end
|
179
|
+
|
180
|
+
def query
|
181
|
+
{ storeID: store_id }
|
182
|
+
end
|
183
|
+
|
184
184
|
end
|
185
185
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "csv"
|
2
|
+
|
3
|
+
module Duracloud
|
4
|
+
class CSVReader
|
5
|
+
|
6
|
+
CSV_OPTS = {
|
7
|
+
col_sep: '\t',
|
8
|
+
headers: :first_row,
|
9
|
+
write_headers: true,
|
10
|
+
return_headers: true,
|
11
|
+
}
|
12
|
+
|
13
|
+
def self.call(data, opts = {})
|
14
|
+
CSV.new(data, CSV_OPTS.merge(opts))
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/duracloud/error.rb
CHANGED
@@ -2,6 +2,6 @@ module Duracloud
|
|
2
2
|
class Error < ::StandardError; end
|
3
3
|
class ServerError < Error; end
|
4
4
|
class NotFoundError < Error; end
|
5
|
-
class
|
6
|
-
class
|
5
|
+
class BadRequestError < Error; end
|
6
|
+
class ConflictError < Error; end
|
7
7
|
end
|
@@ -37,10 +37,18 @@ module Duracloud
|
|
37
37
|
Error
|
38
38
|
end
|
39
39
|
|
40
|
+
def handle_400
|
41
|
+
BadRequestError
|
42
|
+
end
|
43
|
+
|
40
44
|
def handle_404
|
41
45
|
NotFoundError
|
42
46
|
end
|
43
47
|
|
48
|
+
def handle_409
|
49
|
+
ConflictError
|
50
|
+
end
|
51
|
+
|
44
52
|
def response_has_error_message?
|
45
53
|
response.plain_text? && response.has_body?
|
46
54
|
end
|
@@ -10,11 +10,18 @@ module Duracloud
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
# Return the properties associated with this resource,
|
14
|
+
# loading from Duracloud if necessary.
|
15
|
+
# @return [Duracloud::Properties] the properties
|
16
|
+
# @raise [Duracloud::NotFoundError] if the resource is marked persisted
|
17
|
+
# but does not exist in Duracloud
|
13
18
|
def properties
|
14
19
|
load_properties if persisted? && @properties.nil?
|
15
20
|
@properties ||= properties_class.new
|
16
21
|
end
|
17
22
|
|
23
|
+
# @api private
|
24
|
+
# @raise [Duracloud::NotFoundError] the resource does not exist in DuraCloud.
|
18
25
|
def load_properties
|
19
26
|
response = get_properties_response
|
20
27
|
self.properties = response.headers
|