mss-sdk 1.0.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 +7 -0
- data/.yardopts +9 -0
- data/LICENSE.txt +0 -0
- data/README.md +192 -0
- data/bin/mss-rb +178 -0
- data/ca-bundle.crt +3554 -0
- data/lib/mss/core/async_handle.rb +89 -0
- data/lib/mss/core/cacheable.rb +76 -0
- data/lib/mss/core/client.rb +786 -0
- data/lib/mss/core/collection/simple.rb +81 -0
- data/lib/mss/core/collection/with_limit_and_next_token.rb +70 -0
- data/lib/mss/core/collection/with_next_token.rb +96 -0
- data/lib/mss/core/collection.rb +262 -0
- data/lib/mss/core/configuration.rb +527 -0
- data/lib/mss/core/credential_providers.rb +653 -0
- data/lib/mss/core/data.rb +251 -0
- data/lib/mss/core/deprecations.rb +83 -0
- data/lib/mss/core/endpoints.rb +36 -0
- data/lib/mss/core/http/connection_pool.rb +374 -0
- data/lib/mss/core/http/curb_handler.rb +150 -0
- data/lib/mss/core/http/handler.rb +88 -0
- data/lib/mss/core/http/net_http_handler.rb +144 -0
- data/lib/mss/core/http/patch.rb +98 -0
- data/lib/mss/core/http/request.rb +258 -0
- data/lib/mss/core/http/response.rb +80 -0
- data/lib/mss/core/indifferent_hash.rb +87 -0
- data/lib/mss/core/inflection.rb +55 -0
- data/lib/mss/core/ini_parser.rb +41 -0
- data/lib/mss/core/json_client.rb +46 -0
- data/lib/mss/core/json_parser.rb +75 -0
- data/lib/mss/core/json_request_builder.rb +34 -0
- data/lib/mss/core/json_response_parser.rb +78 -0
- data/lib/mss/core/lazy_error_classes.rb +107 -0
- data/lib/mss/core/log_formatter.rb +426 -0
- data/lib/mss/core/managed_file.rb +31 -0
- data/lib/mss/core/meta_utils.rb +44 -0
- data/lib/mss/core/model.rb +61 -0
- data/lib/mss/core/naming.rb +29 -0
- data/lib/mss/core/option_grammar.rb +737 -0
- data/lib/mss/core/options/json_serializer.rb +81 -0
- data/lib/mss/core/options/validator.rb +154 -0
- data/lib/mss/core/options/xml_serializer.rb +117 -0
- data/lib/mss/core/page_result.rb +74 -0
- data/lib/mss/core/policy.rb +938 -0
- data/lib/mss/core/query_client.rb +40 -0
- data/lib/mss/core/query_error_parser.rb +23 -0
- data/lib/mss/core/query_request_builder.rb +46 -0
- data/lib/mss/core/query_response_parser.rb +34 -0
- data/lib/mss/core/region.rb +84 -0
- data/lib/mss/core/region_collection.rb +79 -0
- data/lib/mss/core/resource.rb +412 -0
- data/lib/mss/core/resource_cache.rb +39 -0
- data/lib/mss/core/response.rb +214 -0
- data/lib/mss/core/response_cache.rb +49 -0
- data/lib/mss/core/rest_error_parser.rb +23 -0
- data/lib/mss/core/rest_json_client.rb +39 -0
- data/lib/mss/core/rest_request_builder.rb +153 -0
- data/lib/mss/core/rest_response_parser.rb +65 -0
- data/lib/mss/core/rest_xml_client.rb +46 -0
- data/lib/mss/core/service_interface.rb +82 -0
- data/lib/mss/core/signers/base.rb +45 -0
- data/lib/mss/core/signers/cloud_front.rb +55 -0
- data/lib/mss/core/signers/s3.rb +158 -0
- data/lib/mss/core/signers/version_2.rb +71 -0
- data/lib/mss/core/signers/version_3.rb +85 -0
- data/lib/mss/core/signers/version_3_https.rb +60 -0
- data/lib/mss/core/signers/version_4/chunk_signed_stream.rb +190 -0
- data/lib/mss/core/signers/version_4.rb +227 -0
- data/lib/mss/core/uri_escape.rb +43 -0
- data/lib/mss/core/xml/frame.rb +245 -0
- data/lib/mss/core/xml/frame_stack.rb +84 -0
- data/lib/mss/core/xml/grammar.rb +306 -0
- data/lib/mss/core/xml/parser.rb +69 -0
- data/lib/mss/core/xml/root_frame.rb +64 -0
- data/lib/mss/core/xml/sax_handlers/libxml.rb +46 -0
- data/lib/mss/core/xml/sax_handlers/nokogiri.rb +55 -0
- data/lib/mss/core/xml/sax_handlers/ox.rb +40 -0
- data/lib/mss/core/xml/sax_handlers/rexml.rb +46 -0
- data/lib/mss/core/xml/stub.rb +122 -0
- data/lib/mss/core.rb +602 -0
- data/lib/mss/errors.rb +161 -0
- data/lib/mss/rails.rb +194 -0
- data/lib/mss/s3/access_control_list.rb +262 -0
- data/lib/mss/s3/acl_object.rb +263 -0
- data/lib/mss/s3/acl_options.rb +200 -0
- data/lib/mss/s3/bucket.rb +757 -0
- data/lib/mss/s3/bucket_collection.rb +161 -0
- data/lib/mss/s3/bucket_lifecycle_configuration.rb +472 -0
- data/lib/mss/s3/bucket_region_cache.rb +51 -0
- data/lib/mss/s3/bucket_tag_collection.rb +110 -0
- data/lib/mss/s3/bucket_version_collection.rb +78 -0
- data/lib/mss/s3/cipher_io.rb +119 -0
- data/lib/mss/s3/client/xml.rb +265 -0
- data/lib/mss/s3/client.rb +2076 -0
- data/lib/mss/s3/config.rb +60 -0
- data/lib/mss/s3/cors_rule.rb +107 -0
- data/lib/mss/s3/cors_rule_collection.rb +193 -0
- data/lib/mss/s3/data_options.rb +190 -0
- data/lib/mss/s3/encryption_utils.rb +145 -0
- data/lib/mss/s3/errors.rb +93 -0
- data/lib/mss/s3/multipart_upload.rb +353 -0
- data/lib/mss/s3/multipart_upload_collection.rb +75 -0
- data/lib/mss/s3/object_collection.rb +355 -0
- data/lib/mss/s3/object_metadata.rb +102 -0
- data/lib/mss/s3/object_upload_collection.rb +76 -0
- data/lib/mss/s3/object_version.rb +153 -0
- data/lib/mss/s3/object_version_collection.rb +88 -0
- data/lib/mss/s3/paginated_collection.rb +74 -0
- data/lib/mss/s3/policy.rb +73 -0
- data/lib/mss/s3/prefix_and_delimiter_collection.rb +46 -0
- data/lib/mss/s3/prefixed_collection.rb +84 -0
- data/lib/mss/s3/presign_v4.rb +135 -0
- data/lib/mss/s3/presigned_post.rb +574 -0
- data/lib/mss/s3/region_detection.rb +75 -0
- data/lib/mss/s3/request.rb +61 -0
- data/lib/mss/s3/s3_object.rb +1795 -0
- data/lib/mss/s3/tree/branch_node.rb +67 -0
- data/lib/mss/s3/tree/child_collection.rb +103 -0
- data/lib/mss/s3/tree/leaf_node.rb +93 -0
- data/lib/mss/s3/tree/node.rb +21 -0
- data/lib/mss/s3/tree/parent.rb +86 -0
- data/lib/mss/s3/tree.rb +115 -0
- data/lib/mss/s3/uploaded_part.rb +81 -0
- data/lib/mss/s3/uploaded_part_collection.rb +83 -0
- data/lib/mss/s3/website_configuration.rb +101 -0
- data/lib/mss/s3.rb +161 -0
- data/lib/mss/version.rb +16 -0
- data/lib/mss-sdk.rb +2 -0
- data/lib/mss.rb +14 -0
- data/rails/init.rb +14 -0
- metadata +201 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
class Tree
|
16
|
+
|
17
|
+
# Represents a branch in an {S3::Tree}. From a branch node you
|
18
|
+
# can descend deeper into the tree using {Parent#children} or go
|
19
|
+
# back to the parent node using {#parent}.
|
20
|
+
#
|
21
|
+
# When enumerating nodes in an S3 tree keys grouped by a common
|
22
|
+
# prefix are represented as a branch node.
|
23
|
+
#
|
24
|
+
# Branch nodes are often treated like directories.
|
25
|
+
#
|
26
|
+
# @see Tree
|
27
|
+
# @note Generally you do not need to create branch nodes.
|
28
|
+
class BranchNode < Node
|
29
|
+
|
30
|
+
include Parent
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
def initialize parent, collection, options = {}
|
34
|
+
@parent = parent
|
35
|
+
super(collection,
|
36
|
+
options.merge(:prefix => collection.prefix))
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Tree, BranchNode] The parent node in the tree.
|
40
|
+
attr_reader :parent
|
41
|
+
|
42
|
+
# @return [true]
|
43
|
+
def branch?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [false]
|
48
|
+
def leaf?
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a new Tree object that starts at this branch node.
|
53
|
+
# The returned tree will have the same prefix, delimiter and
|
54
|
+
# append mode as the tree the branch belongs to.
|
55
|
+
#
|
56
|
+
# @return [Tree]
|
57
|
+
def as_tree
|
58
|
+
Tree.new(collection,
|
59
|
+
:prefix => prefix,
|
60
|
+
:delimiter => delimiter,
|
61
|
+
:append => append?)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
class Tree
|
16
|
+
|
17
|
+
class ChildCollection
|
18
|
+
|
19
|
+
include Core::Model
|
20
|
+
include Enumerable
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
def initialize parent, collection, options = {}
|
24
|
+
|
25
|
+
options = {
|
26
|
+
:prefix => nil,
|
27
|
+
:delimiter => '/',
|
28
|
+
:append => true,
|
29
|
+
}.merge(options)
|
30
|
+
|
31
|
+
@parent = parent
|
32
|
+
@collection = collection
|
33
|
+
@prefix = options[:prefix]
|
34
|
+
@delimiter = options[:delimiter]
|
35
|
+
@append = options[:append]
|
36
|
+
|
37
|
+
super
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Tree, BranchNode] The parent node in the tree.
|
42
|
+
attr_reader :parent
|
43
|
+
|
44
|
+
# @return [ObjectCollection, ObjectVersionCollection,
|
45
|
+
# MultipartUploadCollection] Returns the collection this
|
46
|
+
# tree is based on.
|
47
|
+
attr_reader :collection
|
48
|
+
|
49
|
+
# A tree may have a prefix of where in the bucket to be based from.
|
50
|
+
# @return [String,nil]
|
51
|
+
attr_reader :prefix
|
52
|
+
|
53
|
+
# When looking at S3 keys as a tree, the delimiter defines what
|
54
|
+
# string pattern seperates each level of the tree. The delimiter
|
55
|
+
# defaults to '/' (like in a file system).
|
56
|
+
# @return [String]
|
57
|
+
attr_reader :delimiter
|
58
|
+
|
59
|
+
# @return [Boolean] Returns true if the tree is set to auto-append
|
60
|
+
# the delimiter to the prefix when the prefix does not end with
|
61
|
+
# the delimiter.
|
62
|
+
def append?
|
63
|
+
@append
|
64
|
+
end
|
65
|
+
|
66
|
+
# Yields up branches and leaves.
|
67
|
+
#
|
68
|
+
# A branch node represents a common prefix (like a directory)
|
69
|
+
# and a leaf node represents a key (S3 object).
|
70
|
+
#
|
71
|
+
# @yield [tree_node] Yields up a mixture of branches and leafs.
|
72
|
+
# @yieldparam [BranchNode,LeafNode] tree_node A branch or a leaf.
|
73
|
+
# @return [nil]
|
74
|
+
def each &block
|
75
|
+
collection = self.collection
|
76
|
+
if prefix = prefix_with_delim
|
77
|
+
collection = collection.with_prefix(prefix)
|
78
|
+
end
|
79
|
+
collection.each(:delimiter => delimiter) do |member|
|
80
|
+
case
|
81
|
+
when member.respond_to?(:key)
|
82
|
+
yield LeafNode.new(parent, member)
|
83
|
+
when member.respond_to?(:prefix)
|
84
|
+
yield BranchNode.new(parent, member,
|
85
|
+
:delimiter => delimiter,
|
86
|
+
:append => append?)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
def prefix_with_delim
|
94
|
+
return prefix unless append?
|
95
|
+
return nil if prefix.nil?
|
96
|
+
prefix =~ /#{delimiter}$/ ? prefix : "#{prefix}#{delimiter}"
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
class Tree
|
16
|
+
|
17
|
+
# Represents a leaf in an {S3::Tree}.
|
18
|
+
#
|
19
|
+
# When enumerating nodes in an S3 tree, keys are yielded
|
20
|
+
# as leaf nodes (they have no children beneath them).
|
21
|
+
#
|
22
|
+
# @see Tree
|
23
|
+
# @note Generally you do not need to create leaf nodes
|
24
|
+
class LeafNode < Node
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
def initialize parent, member
|
28
|
+
@parent = parent
|
29
|
+
@member = member
|
30
|
+
super()
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Tree, BranchNode] The parent node in the tree.
|
34
|
+
attr_reader :parent
|
35
|
+
|
36
|
+
# @return [mixed] Returns the object this leaf node represents.
|
37
|
+
# @see #object
|
38
|
+
# @see #version
|
39
|
+
# @see #upload
|
40
|
+
attr_reader :member
|
41
|
+
|
42
|
+
# @return [String] the key this leaf node represents.
|
43
|
+
def key
|
44
|
+
@member.key
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [false]
|
48
|
+
def branch?
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [true]
|
53
|
+
def leaf?
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [S3Object] The object this leaf node represents.
|
58
|
+
def object
|
59
|
+
if @member.kind_of?(S3Object)
|
60
|
+
@member
|
61
|
+
else
|
62
|
+
@member.object
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [ObjectVersion] Returns the object version this leaf
|
67
|
+
# node represents.
|
68
|
+
def version
|
69
|
+
if @member.kind_of?(ObjectVersion)
|
70
|
+
@member
|
71
|
+
else
|
72
|
+
raise "This leaf does not represent a version"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [MultipartUpload] Returns the object version this leaf
|
77
|
+
# node represents.
|
78
|
+
def upload
|
79
|
+
if @member.kind_of?(MultipartUpload)
|
80
|
+
@member
|
81
|
+
else
|
82
|
+
raise "This leaf does not represent an upload"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def inspect
|
87
|
+
"<#{self.class}:#{@member.bucket.name}:#{key}>"
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
class Tree
|
16
|
+
# @api private
|
17
|
+
class Node
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
|
16
|
+
class Tree
|
17
|
+
|
18
|
+
# Common methods for tree nodes that are parents to other nodes
|
19
|
+
# ({Tree} and {BranchNode}).
|
20
|
+
module Parent
|
21
|
+
|
22
|
+
include Core::Model
|
23
|
+
|
24
|
+
# @api private
|
25
|
+
def initialize collection, options = {}
|
26
|
+
|
27
|
+
options = {
|
28
|
+
:prefix => nil,
|
29
|
+
:delimiter => '/',
|
30
|
+
:append => true,
|
31
|
+
}.merge(options)
|
32
|
+
|
33
|
+
@collection = collection
|
34
|
+
@prefix = options[:prefix]
|
35
|
+
@delimiter = options[:delimiter]
|
36
|
+
@append = options[:append]
|
37
|
+
|
38
|
+
super
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [ObjectCollection, BucketVersionCollection,
|
43
|
+
# MultipartUploadCollection] The collection whose members
|
44
|
+
# will be explored using the tree.
|
45
|
+
attr_reader :collection
|
46
|
+
|
47
|
+
# A tree may have a prefix of where in the bucket to be based
|
48
|
+
# from. A value of `nil` means that the tree will include all
|
49
|
+
# objects in the collection.
|
50
|
+
#
|
51
|
+
# @return [String,nil]
|
52
|
+
attr_reader :prefix
|
53
|
+
|
54
|
+
# When looking at S3 keys as a tree, the delimiter defines what
|
55
|
+
# string pattern seperates each level of the tree. The delimiter
|
56
|
+
# defaults to '/' (like in a file system).
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
attr_reader :delimiter
|
60
|
+
|
61
|
+
# @return [Boolean] Returns true if the tree is set to auto-append
|
62
|
+
# the delimiter to the prefix when the prefix does not end with
|
63
|
+
# the delimiter.
|
64
|
+
def append?
|
65
|
+
@append
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Tree::ChildCollection] A collection representing all
|
69
|
+
# the child nodes of this node. These may be either
|
70
|
+
# {Tree::BranchNode} objects or {Tree::LeafNode} objects.
|
71
|
+
def children
|
72
|
+
Tree::ChildCollection.new(self, collection,
|
73
|
+
:delimiter => delimiter,
|
74
|
+
:prefix => prefix,
|
75
|
+
:append => append?)
|
76
|
+
end
|
77
|
+
|
78
|
+
def inspect
|
79
|
+
"<#{self.class}:#{collection.bucket.name}:#{prefix}>"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/mss/s3/tree.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
|
16
|
+
# A utility class that supports exploring an S3 {Bucket} like a
|
17
|
+
# tree.
|
18
|
+
#
|
19
|
+
# Frequently objects stored in S3 have keys that look like a filesystem
|
20
|
+
# directory structure.
|
21
|
+
#
|
22
|
+
# Given you have a bucket with the following keys:
|
23
|
+
#
|
24
|
+
# README.txt
|
25
|
+
# videos/wedding.mpg
|
26
|
+
# videos/family_reunion.mpg
|
27
|
+
# photos/2010/house.jpg
|
28
|
+
# photos/2011/fall/leaves.jpg
|
29
|
+
# photos/2011/summer/vacation.jpg
|
30
|
+
# photos/2011/summer/family.jpg
|
31
|
+
#
|
32
|
+
# You might like to explore the contents of this bucket as a tree:
|
33
|
+
#
|
34
|
+
# tree = bucket.as_tree
|
35
|
+
#
|
36
|
+
# directories = tree.children.select(&:branch?).collect(&:prefix)
|
37
|
+
# #=> ['photos', 'videos']
|
38
|
+
#
|
39
|
+
# files = tree.children.select(&:leaf?).collect(&:key)
|
40
|
+
# #=> ['README.txt']
|
41
|
+
#
|
42
|
+
# If you want to start further down, pass a prefix to {Bucket#as_tree}:
|
43
|
+
#
|
44
|
+
# tree = bucket.as_tree(:prefix => 'photos/2011')
|
45
|
+
#
|
46
|
+
# directories = tree.children.select(&:branch?).collect(&:prefix)
|
47
|
+
# #=> ['photos/2011/fall', 'photos/2011/summer']
|
48
|
+
#
|
49
|
+
# files = tree.children.select(&:leaf?).collect(&:key)
|
50
|
+
# #=> []
|
51
|
+
#
|
52
|
+
# All non-leaf nodes ({Tree} and {Tree::BranchNode} instances)
|
53
|
+
# have a {Tree::Parent#children} method that provides access to
|
54
|
+
# the next level of the tree, and all nodes ({Tree},
|
55
|
+
# {Tree::BranchNode}, and {Tree::LeafNode}) have a {#parent}
|
56
|
+
# method that returns the parent node. In our examples above, the
|
57
|
+
# non-leaf nodes are common prefixes to multiple keys
|
58
|
+
# (directories) and leaf nodes are object keys.
|
59
|
+
#
|
60
|
+
# You can continue crawling the tree using the `children`
|
61
|
+
# collection on each branch node, which will contain the branch
|
62
|
+
# nodes and leaf nodes below it.
|
63
|
+
#
|
64
|
+
# You can construct a Tree object using the `as_tree` method of
|
65
|
+
# any of the following classes:
|
66
|
+
#
|
67
|
+
# * {Bucket} or {ObjectCollection} (for {S3Object} leaf nodes)
|
68
|
+
#
|
69
|
+
# * {BucketVersionCollection} (for {ObjectVersion} leaf nodes)
|
70
|
+
#
|
71
|
+
# * {MultipartUploadCollection} (for {MultipartUpload} leaf nodes)
|
72
|
+
#
|
73
|
+
# The methods to explore the tree are the same for each kind of
|
74
|
+
# leaf node, but {Tree::LeafNode#member} will return a different
|
75
|
+
# type of object depending on which kind of collection the tree is
|
76
|
+
# using.
|
77
|
+
class Tree
|
78
|
+
|
79
|
+
autoload :BranchNode, 'mss/s3/tree/branch_node'
|
80
|
+
autoload :ChildCollection, 'mss/s3/tree/child_collection'
|
81
|
+
autoload :LeafNode, 'mss/s3/tree/leaf_node'
|
82
|
+
autoload :Node, 'mss/s3/tree/node'
|
83
|
+
autoload :Parent, 'mss/s3/tree/parent'
|
84
|
+
|
85
|
+
include Parent
|
86
|
+
|
87
|
+
# @param [ObjectCollection, BucketVersionCollection,
|
88
|
+
# MultipartUploadCollection] collection The collection whose
|
89
|
+
# members will be explored using the tree.
|
90
|
+
#
|
91
|
+
# @param [Hash] options Additional options for constructing the
|
92
|
+
# tree.
|
93
|
+
#
|
94
|
+
# @option options [String] :prefix (nil) Set prefix to choose
|
95
|
+
# where the top of the tree will be. A value of `nil` means
|
96
|
+
# that the tree will include all objects in the collection.
|
97
|
+
#
|
98
|
+
# @option options [String] :delimiter ('/') The string that
|
99
|
+
# separates each level of the tree. This is usually a
|
100
|
+
# directory separator.
|
101
|
+
#
|
102
|
+
# @option options [Boolean] :append (true) If true, the delimiter is
|
103
|
+
# appended to the prefix when the prefix does not already end
|
104
|
+
# with the delimiter.
|
105
|
+
def initialize collection, options = {}
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return The parent node in the tree. In the case of a Tree,
|
110
|
+
# the parent is always nil.
|
111
|
+
def parent; nil; end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
|
16
|
+
# Represents a part of a multipart upload that has been uploaded
|
17
|
+
# to S3.
|
18
|
+
#
|
19
|
+
# @example Get the total size of the uploaded parts
|
20
|
+
# upload.parts.inject(0) { |sum, part| sum + part.size }
|
21
|
+
class UploadedPart
|
22
|
+
|
23
|
+
include Core::Model
|
24
|
+
|
25
|
+
# @return [MultipartUpload] The upload to which this belongs.
|
26
|
+
attr_reader :upload
|
27
|
+
|
28
|
+
# @return [Integer] The part number.
|
29
|
+
attr_reader :part_number
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def initialize(upload, part_number, opts = {})
|
33
|
+
@upload = upload
|
34
|
+
@part_number = part_number
|
35
|
+
@etag = opts[:etag]
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def ==(other)
|
40
|
+
other.kind_of?(UploadedPart) and
|
41
|
+
other.upload == upload and
|
42
|
+
other.part_number == part_number
|
43
|
+
end
|
44
|
+
alias_method :eql?, :==
|
45
|
+
|
46
|
+
# @return [Integer] The size of the part as it currently
|
47
|
+
# exists in S3.
|
48
|
+
def size
|
49
|
+
get_attribute(:size)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [DateTime] The time at which the part was last
|
53
|
+
# modified.
|
54
|
+
def last_modified
|
55
|
+
get_attribute(:last_modified)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String] The ETag of the part.
|
59
|
+
def etag
|
60
|
+
@etag ||= get_attribute(:etag)
|
61
|
+
@etag
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
private
|
66
|
+
def get_attribute(name)
|
67
|
+
(resp = client.list_parts(:bucket_name => upload.object.bucket.name,
|
68
|
+
:key => upload.object.key,
|
69
|
+
:upload_id => upload.id,
|
70
|
+
:part_number_marker => part_number-1,
|
71
|
+
:max_parts => 1) and
|
72
|
+
part = resp.parts.first and
|
73
|
+
part.part_number == part_number and
|
74
|
+
part.send(name)) or
|
75
|
+
raise "part #{part_number} of upload #{upload.id} does not exist"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
class S3
|
15
|
+
|
16
|
+
# Represents the collection of parts that have been uploaded for
|
17
|
+
# a given multipart upload. You can get an instance of this
|
18
|
+
# class by calling {MultipartUpload#parts}.
|
19
|
+
#
|
20
|
+
# @example Get the total size of the uploaded parts
|
21
|
+
# upload.parts.inject(0) { |sum, part| sum + part.size }
|
22
|
+
class UploadedPartCollection
|
23
|
+
|
24
|
+
include Enumerable
|
25
|
+
include Core::Model
|
26
|
+
include PaginatedCollection
|
27
|
+
|
28
|
+
# @return [MultipartUpload] The upload to which the parts belong.
|
29
|
+
attr_reader :upload
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def initialize(upload, opts = {})
|
33
|
+
@upload = upload
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [UploadedPart] An object representing the part with
|
38
|
+
# the given part number.
|
39
|
+
#
|
40
|
+
# @param [Integer] number The part number.
|
41
|
+
def [](number)
|
42
|
+
UploadedPart.new(upload, number)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @api private
|
46
|
+
protected
|
47
|
+
def each_member_in_page(page, &block)
|
48
|
+
page.parts.each do |part_info|
|
49
|
+
part = UploadedPart.new(upload, part_info.part_number, :etag => part_info.etag)
|
50
|
+
yield(part)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @api private
|
55
|
+
protected
|
56
|
+
def list_options(options)
|
57
|
+
opts = super
|
58
|
+
opts.merge!(:bucket_name => upload.object.bucket.name,
|
59
|
+
:key => upload.object.key,
|
60
|
+
:upload_id => upload.id)
|
61
|
+
opts
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
protected
|
66
|
+
def limit_param; :max_parts; end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
protected
|
70
|
+
def list_request(options)
|
71
|
+
client.list_parts(options)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @api private
|
75
|
+
protected
|
76
|
+
def pagination_markers
|
77
|
+
[:part_number_marker]
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|