s33r 0.4.2 → 0.5

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.
Files changed (114) hide show
  1. data/examples/cli/instant_download_server.rb +88 -0
  2. data/examples/cli/s3cli.rb +31 -52
  3. data/examples/cli/simple.rb +16 -6
  4. data/examples/fores33r/app/controllers/browser_controller.rb +12 -10
  5. data/examples/fores33r/app/helpers/application_helper.rb +2 -1
  6. data/examples/fores33r/app/views/browser/_upload.rhtml +1 -1
  7. data/examples/fores33r/app/views/browser/index.rhtml +4 -4
  8. data/examples/fores33r/config/environment.rb +5 -3
  9. data/examples/fores33r/log/development.log +2259 -0
  10. data/examples/fores33r/log/mongrel.log +59 -0
  11. data/examples/s3.yaml +2 -6
  12. data/lib/s33r/bucket.rb +103 -0
  13. data/lib/s33r/bucket_listing.rb +33 -76
  14. data/lib/s33r/client.rb +305 -446
  15. data/lib/s33r/networking.rb +197 -0
  16. data/lib/s33r/s33r_exception.rb +29 -18
  17. data/lib/s33r/s33r_http.rb +36 -18
  18. data/lib/s33r/s3_acl.rb +32 -52
  19. data/lib/s33r/s3_logging.rb +117 -0
  20. data/lib/s33r/s3_obj.rb +124 -69
  21. data/lib/s33r/utility.rb +447 -0
  22. data/test/cases/spec_acl.rb +10 -40
  23. data/test/cases/spec_bucket_listing.rb +12 -32
  24. data/test/cases/spec_logging.rb +47 -0
  25. data/test/cases/spec_networking.rb +11 -0
  26. data/test/cases/spec_s3_object.rb +44 -5
  27. data/test/cases/spec_utility.rb +264 -0
  28. data/test/files/acl.xml +0 -6
  29. data/test/files/config.yaml +5 -0
  30. data/test/files/logging_status_disabled.xml +3 -0
  31. data/test/files/logging_status_enabled.xml +7 -0
  32. data/test/test_setup.rb +7 -2
  33. metadata +16 -94
  34. data/examples/cli/acl_x.rb +0 -41
  35. data/examples/cli/logging_x.rb +0 -20
  36. data/examples/fores33r/README +0 -183
  37. data/html/classes/MIME.html +0 -120
  38. data/html/classes/MIME/InvalidContentType.html +0 -119
  39. data/html/classes/MIME/Type.html +0 -1173
  40. data/html/classes/MIME/Types.html +0 -566
  41. data/html/classes/Net.html +0 -108
  42. data/html/classes/Net/HTTPGenericRequest.html +0 -233
  43. data/html/classes/Net/HTTPResponse.html +0 -271
  44. data/html/classes/S33r.html +0 -986
  45. data/html/classes/S33r/BucketListing.html +0 -434
  46. data/html/classes/S33r/Client.html +0 -1575
  47. data/html/classes/S33r/LoggingResource.html +0 -222
  48. data/html/classes/S33r/NamedBucket.html +0 -693
  49. data/html/classes/S33r/OrderlyXmlMarkup.html +0 -165
  50. data/html/classes/S33r/S33rException.html +0 -124
  51. data/html/classes/S33r/S33rException/BucketListingMaxKeysError.html +0 -111
  52. data/html/classes/S33r/S33rException/BucketNotLogTargetable.html +0 -119
  53. data/html/classes/S33r/S33rException/InvalidBucketListing.html +0 -111
  54. data/html/classes/S33r/S33rException/InvalidPermission.html +0 -111
  55. data/html/classes/S33r/S33rException/InvalidS3GroupType.html +0 -111
  56. data/html/classes/S33r/S33rException/MalformedBucketName.html +0 -111
  57. data/html/classes/S33r/S33rException/MethodNotAvailable.html +0 -111
  58. data/html/classes/S33r/S33rException/MissingBucketName.html +0 -111
  59. data/html/classes/S33r/S33rException/MissingRequiredHeaders.html +0 -111
  60. data/html/classes/S33r/S33rException/MissingResource.html +0 -111
  61. data/html/classes/S33r/S33rException/S3FallenOver.html +0 -111
  62. data/html/classes/S33r/S33rException/TryingToPutEmptyResource.html +0 -117
  63. data/html/classes/S33r/S33rException/UnsupportedCannedACL.html +0 -111
  64. data/html/classes/S33r/S33rException/UnsupportedHTTPMethod.html +0 -111
  65. data/html/classes/S33r/S3ACL.html +0 -125
  66. data/html/classes/S33r/S3ACL/ACLDoc.html +0 -521
  67. data/html/classes/S33r/S3ACL/AmazonCustomer.html +0 -168
  68. data/html/classes/S33r/S3ACL/CanonicalUser.html +0 -212
  69. data/html/classes/S33r/S3ACL/Grant.html +0 -403
  70. data/html/classes/S33r/S3ACL/Grantee.html +0 -239
  71. data/html/classes/S33r/S3ACL/Group.html +0 -178
  72. data/html/classes/S33r/S3Object.html +0 -618
  73. data/html/classes/S33r/Sync.html +0 -152
  74. data/html/classes/XML.html +0 -202
  75. data/html/classes/XML/Document.html +0 -125
  76. data/html/classes/XML/Node.html +0 -124
  77. data/html/created.rid +0 -1
  78. data/html/files/CHANGELOG.html +0 -107
  79. data/html/files/MIT-LICENSE.html +0 -129
  80. data/html/files/README_txt.html +0 -259
  81. data/html/files/lib/s33r/bucket_listing_rb.html +0 -101
  82. data/html/files/lib/s33r/builder_rb.html +0 -108
  83. data/html/files/lib/s33r/client_rb.html +0 -111
  84. data/html/files/lib/s33r/core_rb.html +0 -113
  85. data/html/files/lib/s33r/libxml_extensions_rb.html +0 -101
  86. data/html/files/lib/s33r/libxml_loader_rb.html +0 -109
  87. data/html/files/lib/s33r/logging_rb.html +0 -108
  88. data/html/files/lib/s33r/mimetypes_rb.html +0 -120
  89. data/html/files/lib/s33r/named_bucket_rb.html +0 -101
  90. data/html/files/lib/s33r/s33r_exception_rb.html +0 -101
  91. data/html/files/lib/s33r/s33r_http_rb.html +0 -108
  92. data/html/files/lib/s33r/s3_acl_rb.html +0 -108
  93. data/html/files/lib/s33r/s3_obj_rb.html +0 -108
  94. data/html/files/lib/s33r/sync_rb.html +0 -101
  95. data/html/files/lib/s33r_rb.html +0 -101
  96. data/html/fr_class_index.html +0 -66
  97. data/html/fr_file_index.html +0 -44
  98. data/html/fr_method_index.html +0 -183
  99. data/html/index.html +0 -24
  100. data/html/rdoc-style.css +0 -208
  101. data/lib/s33r/core.rb +0 -296
  102. data/lib/s33r/logging.rb +0 -43
  103. data/lib/s33r/named_bucket.rb +0 -148
  104. data/lib/s33r/sync.rb +0 -13
  105. data/test/cases/spec_all_buckets.rb +0 -28
  106. data/test/cases/spec_client.rb +0 -101
  107. data/test/cases/spec_core.rb +0 -128
  108. data/test/cases/spec_namedbucket.rb +0 -46
  109. data/test/cases/spec_sync.rb +0 -34
  110. data/test/files/all_buckets.xml +0 -21
  111. data/test/files/client_config.yml +0 -5
  112. data/test/files/namedbucket_config.yml +0 -8
  113. data/test/files/namedbucket_config2.yml +0 -8
  114. data/test/test_bucket_setup.rb +0 -41
data/lib/s33r/core.rb DELETED
@@ -1,296 +0,0 @@
1
- require 'base64'
2
- require 'time'
3
- require 'net/http'
4
- require 'net/https'
5
- require 'openssl'
6
- require 'parsedate'
7
- require File.join(File.dirname(__FILE__), 'libxml_loader')
8
-
9
- # Module to handle S3 operations which don't require an internet connection,
10
- # i.e. data validation and request-building operations;
11
- # also holds all the constants relating to S3.
12
- #
13
- # Parts of this code are heavily based on Amazon's code. Here's their license:
14
- #
15
- # This software code is made available "AS IS" without warranties of any
16
- # kind. You may copy, display, modify and redistribute the software
17
- # code either by itself or as incorporated into your code; provided that
18
- # you do not remove any proprietary notices. Your use of this software
19
- # code is at your own risk and you waive any claim against Amazon
20
- # Digital Services, Inc. or its affiliates with respect to your use of
21
- # this software code. (c) 2006 Amazon Digital Services, Inc. or its
22
- # affiliates.
23
- module S33r
24
- HOST = 's3.amazonaws.com'
25
- PORT = 443
26
- NON_SSL_PORT = 80
27
- METADATA_PREFIX = 'x-amz-meta-'
28
- # Size of each chunk (in bytes) to be sent per request when putting files (1Mb).
29
- DEFAULT_CHUNK_SIZE = 1048576
30
- AWS_HEADER_PREFIX = 'x-amz-'
31
- AWS_AUTH_HEADER_VALUE = "AWS %s:%s"
32
- INTERESTING_HEADERS = ['content-md5', 'content-type', 'date']
33
- # Headers which must be included with every request to S3.
34
- REQUIRED_HEADERS = ['Content-Type', 'Date']
35
- # Canned ACLs made available by S3.
36
- CANNED_ACLS = ['private', 'public-read', 'public-read-write', 'authenticated-read']
37
- # HTTP methods which S3 will respond to.
38
- METHOD_VERBS = ['GET', 'PUT', 'HEAD', 'POST', 'DELETE']
39
- # Maximum number which can be passed in max-keys parameter when GETting bucket list.
40
- BUCKET_LIST_MAX_MAX_KEYS = 1000
41
- # Default number of seconds an authenticated URL will last for (15 minutes).
42
- DEFAULT_EXPIRY_SECS = 60 * 15
43
- # The namespace used for response body XML documents.
44
- RESPONSE_NAMESPACE_URI = "http://s3.amazonaws.com/doc/2006-03-01/"
45
-
46
- # Permissions which can be set within a <Grant>
47
- # (see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingPermissions.html).
48
- #
49
- # NB I've missed out the WRITE_ACP permission as this is functionally
50
- # equivalent to FULL_CONTROL.
51
- PERMISSIONS = {
52
- :read => 'READ', # permission to read
53
- :write => 'WRITE', # permission to write
54
- :read_acl => 'READ_ACP', # permission to read ACL settings
55
- :all => 'FULL_CONTROL' # do anything
56
- }
57
-
58
- # Used for generating ACL XML documents.
59
- NAMESPACE = 'xsi'
60
- NAMESPACE_URI = 'http://www.w3.org/2001/XMLSchema-instance'
61
- GRANTEE_TYPES = {
62
- :amazon_customer => 'AmazonCustomerByEmail',
63
- :canonical_user => 'CanonicalUser',
64
- :group => 'Group'
65
- }
66
- S3_GROUP_TYPES = {
67
- :all_users => 'global/AllUsers',
68
- :authenticated_users => 'global/AuthenticatedUsers',
69
- :log_delivery => 's3/LogDelivery'
70
- }
71
- GROUP_ACL_URI_BASE = 'http://acs.amazonaws.com/groups/'
72
-
73
- # Build canonical string for signing;
74
- # modified (slightly) from the Amazon sample code.
75
- def generate_canonical_string(method, path, headers={}, expires=nil)
76
- interesting_headers = {}
77
- headers.each do |key, value|
78
- lk = key.downcase
79
- if (INTERESTING_HEADERS.include?(lk) or lk =~ /^#{AWS_HEADER_PREFIX}/o)
80
- interesting_headers[lk] = value
81
- end
82
- end
83
-
84
- # These fields get empty strings if they don't exist.
85
- interesting_headers['content-type'] ||= ''
86
- interesting_headers['content-md5'] ||= ''
87
-
88
- # If you're using expires for query string auth, then it trumps date.
89
- if not expires.nil?
90
- interesting_headers['date'] = expires
91
- end
92
-
93
- buf = "#{method}\n"
94
- interesting_headers.sort { |a, b| a[0] <=> b[0] }.each do |key, value|
95
- if key =~ /^#{AWS_HEADER_PREFIX}/o
96
- buf << "#{key}:#{value}\n"
97
- else
98
- buf << "#{value}\n"
99
- end
100
- end
101
-
102
- # Ignore everything after the question mark...
103
- buf << path.gsub(/\?.*$/, '')
104
-
105
- # ...unless there is an acl, logging or torrent parameter
106
- if path =~ /[&?]acl($|&|=)/
107
- buf << '?acl'
108
- elsif path =~ /[&?]torrent($|&|=)/
109
- buf << '?torrent'
110
- elsif path =~ /[&?]logging($|&|=)/
111
- buf << '?logging'
112
- end
113
-
114
- buf
115
- end
116
-
117
- # Get the value for the AWS authentication header.
118
- def generate_auth_header_value(method, path, headers, aws_access_key, aws_secret_access_key)
119
- raise S33rException::MethodNotAvailable, "Method %s not available" % method if !METHOD_VERBS.include?(method)
120
-
121
- # check the headers needed for authentication have been set
122
- missing_headers = REQUIRED_HEADERS - headers.keys
123
- if !(missing_headers.empty?)
124
- raise S33rException::MissingRequiredHeaders,
125
- "Headers required for AWS auth value are missing: " + missing_headers.join(', ')
126
- end
127
-
128
- # get the AWS header
129
- canonical_string = generate_canonical_string(method, path, headers)
130
- signature = generate_signature(aws_secret_access_key, canonical_string)
131
- AWS_AUTH_HEADER_VALUE % [aws_access_key, signature]
132
- end
133
-
134
- # Encode the given string with the aws_secret_access_key, by taking the
135
- # hmac sha1 sum, and then base64 encoding it.
136
- def generate_signature(aws_secret_access_key, str)
137
- digest = OpenSSL::HMAC::digest(OpenSSL::Digest::Digest.new("SHA1"), aws_secret_access_key, str)
138
- Base64.encode64(digest).strip
139
- end
140
-
141
- # Build the headers required with every S3 request (Date and Content-Type);
142
- # options hash can contain extra header settings;
143
- # +:date+ and +:content_type+ are required headers, and set to defaults if not supplied
144
- def add_default_headers(headers, options={})
145
- # set the default headers required by AWS
146
- missing_headers = REQUIRED_HEADERS - headers.keys
147
-
148
- if missing_headers.include?('Content-Type')
149
- headers['Content-Type'] = options[:content_type] || ''
150
- end
151
-
152
- if missing_headers.include?('Date')
153
- date = options[:date] || Time.now
154
- headers['Date'] = date.httpdate
155
- end
156
-
157
- headers
158
- end
159
-
160
- # Add metadata headers, correctly prefixing them first,
161
- # e.g. you might do metadata_headers({}, {'myname' => 'elliot', 'myage' => 36})
162
- # to add two headers to the request:
163
- #
164
- # x-amz-meta-myname: elliot
165
- # x-amz-meta-myage: 36
166
- #
167
- # Returns headers with the metadata headers appended.
168
- def metadata_headers(headers, metadata={})
169
- unless metadata.empty?
170
- metadata.each { |key, value| headers[METADATA_PREFIX + key] = value.to_s }
171
- end
172
- headers
173
- end
174
-
175
- # Add a canned ACL setter header.
176
- def canned_acl_header(canned_acl, headers={})
177
- unless canned_acl.nil?
178
- unless CANNED_ACLS.include?(canned_acl)
179
- raise S33rException::UnsupportedCannedACL, "The canned ACL #{canned_acl} is not supported"
180
- end
181
- headers[AWS_HEADER_PREFIX + 'acl'] = canned_acl
182
- end
183
- headers
184
- end
185
-
186
- # Guess a file's mime type.
187
- # If the mime_type for a file cannot be guessed, "text/plain" is used.
188
- def guess_mime_type(file_name)
189
- mime_type = MIME::Types.type_for(file_name)[0]
190
- mime_type ||= MIME::Types['text/plain'][0]
191
- mime_type
192
- end
193
-
194
- # Ensure that a bucket_name is well-formed (no leading or trailing slash).
195
- def bucket_name_valid?(bucket_name)
196
- if ('/' == bucket_name[0,1] || '/' == bucket_name[-1,1])
197
- raise S33rException::MalformedBucketName, "Bucket name cannot have a leading or trailing slash"
198
- end
199
- end
200
-
201
- # Convert a hash of name/value pairs to querystring variables.
202
- # Name for a variable can be a string or symbol.
203
- def generate_querystring(pairs={})
204
- str = ''
205
- if pairs.size > 0
206
- str += "?" + pairs.map { |key, value| "#{key}=#{CGI::escape(value.to_s)}" }.join('&')
207
- end
208
- str
209
- end
210
-
211
- # Return the location of the ACL for a resource.
212
- def s3_acl_path(bucket_name, resource_key)
213
- s3_path(bucket_name, resource_key) + "?acl"
214
- end
215
-
216
- # Return the location of the logging definition for a resource.
217
- def s3_logging_path(bucket_name, resource_key)
218
- s3_path(bucket_name, resource_key) + "?logging"
219
- end
220
-
221
- # Prepend scheme and HOST to path.
222
- def s3_url(path)
223
- "http://" + HOST + path
224
- end
225
-
226
- # Public readable URL for a bucket and resource.
227
- def s3_public_url(bucket_name, resource_key='')
228
- path = s3_path(bucket_name, resource_key)
229
- s3_url(path)
230
- end
231
-
232
- # Returns the path for this bucket and key.
233
- def s3_path(bucket_name, resource_key)
234
- path = '/' + bucket_name
235
- path += '/' + resource_key unless '' == resource_key or resource_key.nil?
236
- path
237
- end
238
-
239
- # Generate a get-able URL for an S3 resource key which passes authentication in querystring.
240
- #
241
- # int +expires+: when the URL expires (seconds since the epoch); NB you can use S33r.parse_expiry
242
- # to generate a suitable value from a string.
243
- def s3_authenticated_url(aws_access_key, aws_secret_access_key, bucket_name, resource_key,
244
- expires=nil)
245
- path = s3_path(bucket_name, resource_key)
246
- expires = S33r.parse_expiry(expires)
247
-
248
- canonical_string = generate_canonical_string('GET', path, {}, expires)
249
- signature = generate_signature(aws_secret_access_key, canonical_string)
250
-
251
- querystring = generate_querystring({ 'Signature' => signature, 'Expires' => expires,
252
- 'AWSAccessKeyId' => aws_access_key })
253
-
254
- return s3_url(path) + querystring
255
- end
256
-
257
- # Turn keys in a hash +hsh+ into symbols.
258
- #
259
- # Returns a hash with 'symbolised' keys.
260
- def S33r.keys_to_symbols(hsh)
261
- symbolised = hsh.inject({}) do |symbolised, key_value|
262
- symbolised.merge({key_value[0].to_sym => key_value[1]})
263
- end
264
- symbolised
265
- end
266
-
267
- # Parse an expiry date to seconds since the epoch.
268
- #
269
- # +expires+ can be set to 'forever' to get a time 20 years in the future;
270
- # 'default' to use the current time + DEFAULT_EXPIRY_SECS;
271
- # or to a specific date (parseable by ParseDate); or to an integer
272
- # representing seconds since the epoch.
273
- #
274
- # TODO: testing for this
275
- def S33r.parse_expiry(expires)
276
- base_expires = Time.now.to_i
277
- if 'forever' == expires
278
- # 20 years (same as forever in computer terms)
279
- expires = base_expires + (60 * 60 * 24 * 365.25 * 20).to_i
280
- elsif 'default' == expires
281
- # default to DEFAULT_EXPIRY_SECS seconds from now if expires not set
282
- expires = base_expires + DEFAULT_EXPIRY_SECS
283
- elsif expires.is_a?(String)
284
- datetime_parts = ParseDate.parsedate(expires)
285
- expires = Time.gm(*datetime_parts).to_i
286
- end
287
- expires
288
- end
289
-
290
- # Remove the namespace declaration from S3 XML response bodies (libxml
291
- # isn't fond of it).
292
- def S33r.remove_namespace(xml_in)
293
- namespace = S33r::RESPONSE_NAMESPACE_URI.gsub('/', '\/')
294
- xml_in.gsub(/ xmlns="#{namespace}"/, '')
295
- end
296
- end
data/lib/s33r/logging.rb DELETED
@@ -1,43 +0,0 @@
1
- require 'rubygems'
2
- require_gem 'builder'
3
- require File.join(File.dirname(__FILE__), 'libxml_loader')
4
-
5
- module S33r
6
- # For manipulating logging directives on resources
7
- # (see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/LoggingHowTo.html).
8
- #
9
- # Creating a LoggingResource instance using new and no arguments will generate a "blank" instance;
10
- # this can be put to the ?logging URL for a resource to remove logging from it.
11
- class LoggingResource
12
- attr_reader :log_target, :log_prefix
13
-
14
- def initialize(log_target=nil, log_prefix=nil)
15
- @log_target = log_target
16
- @log_prefix = log_prefix
17
- end
18
-
19
- # Generate a BucketLoggingStatus XML document for putting to the ?logging
20
- # URL for a resource.
21
- #
22
- #-- TODO: test generates correct XML
23
- def to_xml
24
- xml_str = ""
25
- xml = Builder::XmlMarkup.new(:target => xml_str, :indent => 0)
26
-
27
- xml.instruct!
28
-
29
- # BucketLoggingStatus XML.
30
- xml.BucketLoggingStatus({"xmlns" => RESPONSE_NAMESPACE_URI}) {
31
- unless @log_target.nil? and @log_prefix.nil?
32
- xml.LoggingEnabled {
33
- xml.TargetBucket @log_target
34
- xml.TargetPrefix @log_prefix
35
- }
36
- end
37
- }
38
-
39
- xml_str
40
- end
41
-
42
- end
43
- end
@@ -1,148 +0,0 @@
1
- #-- TODO: manipulation of bucket_listing through options hash, e.g. fetch particular page,
2
- #-- specify a prefix and/or delimiter
3
-
4
- require File.join(File.dirname(__FILE__), 'client')
5
- require File.join(File.dirname(__FILE__), 's3_obj')
6
- require File.join(File.dirname(__FILE__), 's33r_exception')
7
-
8
- module S33r
9
- # Wraps the S33r::Client class to make it more convenient for use with a single bucket.
10
- class NamedBucket < Client
11
- attr_accessor :name, :strict, :public_contents, :dump_requests
12
-
13
- # Initialize an instance from a config_file. The config. file can include a separate
14
- # +options+ section specifying options specific to NamedBucket instances (see the initialize method
15
- # for more details).
16
- # Other options are as for S33r::Client.init.
17
- def NamedBucket.init(config_file)
18
- aws_access_key, aws_secret_access_key, options = super.class.load_config(config_file)
19
- NamedBucket.new(aws_access_key, aws_secret_access_key, options)
20
- end
21
-
22
- # Initialize a NamedBucket instance.
23
- #
24
- # +options+ is a hash of options for this instance:
25
- # * <tt>:default_bucket => 'xxxx'</tt>: name of the bucket this client is attached to.
26
- # * <tt>:public_contents => true</tt>: all items put into bucket are made public (can be overridden per request).
27
- # * <tt>:strict => true</tt>: check whether the bucket exists before attempting to initialize; initialization \
28
- # fails if the bucket does not exist
29
- def initialize(aws_access_key, aws_secret_access_key, options={}, &block)
30
- super(aws_access_key, aws_secret_access_key, options)
31
-
32
- @name = options[:default_bucket]
33
- if @name.nil?
34
- raise S33rException::MissingBucketName, "NamedBucket cannot be initialised without specifying\
35
- a :default_bucket option"
36
- end
37
-
38
- # all content inside the bucket should be created as public-read
39
- @public_contents = (true == options[:public_contents])
40
- @client_headers.merge!(canned_acl_header('public-read')) if @public_contents
41
-
42
- @strict = (true == options[:strict])
43
- if @strict && !bucket_exists?(@name)
44
- raise S33rException::MissingResource, "Non-existent bucket #{@bucket_name} specified"
45
- end
46
-
47
- yield self if block_given?
48
- end
49
-
50
- # Are all objects added to this bucket made public by default?
51
- def public_contents?
52
- @public_contents
53
- end
54
-
55
- # Is this a strict bucket (i.e. the target bucket must exist on S3)?
56
- def strict?
57
- @strict
58
- end
59
-
60
- # Get a single object from a bucket as an S3Object.
61
- #
62
- # To get a bare object (with no content):
63
- #
64
- # bucket['key']
65
- #
66
- # To get the object and load its content:
67
- #
68
- # bucket['key', :load]
69
- def [](key, eager=false)
70
- obj = listing.contents[key]
71
- obj.named_bucket = self
72
- obj.load if :load == eager
73
- obj
74
- end
75
-
76
- # Get a raw response for a key inside the bucket.
77
- def get_raw(key, headers={})
78
- get_resource(@name, key, headers)
79
- end
80
-
81
- # Get a BucketListing instance for the content of this bucket.
82
- # Uses the Client.list_bucket method to get the listing.
83
- def listing
84
- list_bucket(@name)[1]
85
- end
86
-
87
- # Does this bucket exist?
88
- # Returns true if the bucket this NamedBucket is mapped to exists.
89
- def exists?
90
- bucket_exists?(@name)
91
- end
92
-
93
- # Delete the bucket.
94
- def destroy(headers={}, options={})
95
- delete_bucket(@name, headers, options)
96
- end
97
-
98
- # Get a pretty list of the keys in the bucket.
99
- def keys
100
- listing.pretty
101
- end
102
-
103
- # List content of the bucket, and attach each item to this NamedBucket
104
- # instance as it is yielded (to enable easier manipulation directly from the S3Object).
105
- # Note that the objects are incomplete, as the data associated with them has not been
106
- # "got" from S3 yet.
107
- def each_object
108
- listing.contents.each_value { |obj| obj.named_bucket = self; yield obj }
109
- end
110
-
111
- # Does the given key exist in the bucket?
112
- # Returns boolean
113
- def key_exists?(key)
114
- resource_exists?(@name, key)
115
- end
116
-
117
- # Put a string into a key inside the bucket.
118
- def put_text(string, resource_key, headers={})
119
- super(string, @name, resource_key, headers)
120
- end
121
-
122
- # Put a file into the bucket.
123
- def put_file(filename, resource_key=nil, headers={}, options={})
124
- super(filename, @name, resource_key, headers, options)
125
- end
126
-
127
- # Put a generic stream (e.g. from a file handle) into the bucket.
128
- def put_stream(data, resource_key, headers={})
129
- put_resource(@name, resource_key, data, headers)
130
- end
131
-
132
- # Delete an object from the bucket.
133
- # NB S3 doesn't discriminate between successfully deleting a key
134
- # and trying to delete a non-existent key (both return a 204).
135
- # If you want to test for existence first, use key_exists?.
136
- def delete(key, headers={})
137
- delete_resource(@name, key, headers)
138
- end
139
-
140
- # Generate an authenticated URL (see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/)
141
- # for an object inside this bucket.
142
- #
143
- # +expires+: time in secs since the epoch when the link should become invalid.
144
- def s3_authenticated_url(resource_key, expires=(Time.now.to_i + DEFAULT_EXPIRY_SECS))
145
- super(@aws_access_key, @aws_secret_access_key, @name, resource_key, expires)
146
- end
147
- end
148
- end