fog-internet-archive 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +53 -0
  3. data/.travis.yml +16 -0
  4. data/Gemfile +3 -0
  5. data/README.md +6 -0
  6. data/Rakefile +19 -0
  7. data/fog-internet-archive.gemspec +32 -0
  8. data/lib/fog/bin/internet_archive.rb +32 -0
  9. data/lib/fog/internet_archive.rb +1 -0
  10. data/lib/fog/internet_archive/core.rb +291 -0
  11. data/lib/fog/internet_archive/models/storage/directories.rb +39 -0
  12. data/lib/fog/internet_archive/models/storage/directory.rb +105 -0
  13. data/lib/fog/internet_archive/models/storage/file.rb +254 -0
  14. data/lib/fog/internet_archive/models/storage/files.rb +119 -0
  15. data/lib/fog/internet_archive/models/storage/ia_attributes.rb +36 -0
  16. data/lib/fog/internet_archive/parsers/storage/access_control_list.rb +42 -0
  17. data/lib/fog/internet_archive/parsers/storage/complete_multipart_upload.rb +20 -0
  18. data/lib/fog/internet_archive/parsers/storage/copy_object.rb +18 -0
  19. data/lib/fog/internet_archive/parsers/storage/cors_configuration.rb +38 -0
  20. data/lib/fog/internet_archive/parsers/storage/delete_multiple_objects.rb +45 -0
  21. data/lib/fog/internet_archive/parsers/storage/get_bucket.rb +58 -0
  22. data/lib/fog/internet_archive/parsers/storage/get_bucket_lifecycle.rb +64 -0
  23. data/lib/fog/internet_archive/parsers/storage/get_bucket_location.rb +16 -0
  24. data/lib/fog/internet_archive/parsers/storage/get_bucket_logging.rb +36 -0
  25. data/lib/fog/internet_archive/parsers/storage/get_bucket_website.rb +22 -0
  26. data/lib/fog/internet_archive/parsers/storage/get_request_payment.rb +16 -0
  27. data/lib/fog/internet_archive/parsers/storage/get_service.rb +28 -0
  28. data/lib/fog/internet_archive/parsers/storage/initiate_multipart_upload.rb +20 -0
  29. data/lib/fog/internet_archive/parsers/storage/list_multipart_uploads.rb +52 -0
  30. data/lib/fog/internet_archive/parsers/storage/list_parts.rb +36 -0
  31. data/lib/fog/internet_archive/requests/storage/abort_multipart_upload.rb +27 -0
  32. data/lib/fog/internet_archive/requests/storage/acl_utils.rb +60 -0
  33. data/lib/fog/internet_archive/requests/storage/complete_multipart_upload.rb +46 -0
  34. data/lib/fog/internet_archive/requests/storage/copy_object.rb +77 -0
  35. data/lib/fog/internet_archive/requests/storage/cors_utils.rb +39 -0
  36. data/lib/fog/internet_archive/requests/storage/delete_bucket.rb +42 -0
  37. data/lib/fog/internet_archive/requests/storage/delete_bucket_cors.rb +26 -0
  38. data/lib/fog/internet_archive/requests/storage/delete_bucket_lifecycle.rb +26 -0
  39. data/lib/fog/internet_archive/requests/storage/delete_bucket_policy.rb +26 -0
  40. data/lib/fog/internet_archive/requests/storage/delete_bucket_website.rb +26 -0
  41. data/lib/fog/internet_archive/requests/storage/delete_multiple_objects.rb +88 -0
  42. data/lib/fog/internet_archive/requests/storage/delete_object.rb +46 -0
  43. data/lib/fog/internet_archive/requests/storage/get_bucket.rb +108 -0
  44. data/lib/fog/internet_archive/requests/storage/get_bucket_acl.rb +65 -0
  45. data/lib/fog/internet_archive/requests/storage/get_bucket_cors.rb +61 -0
  46. data/lib/fog/internet_archive/requests/storage/get_bucket_lifecycle.rb +35 -0
  47. data/lib/fog/internet_archive/requests/storage/get_bucket_location.rb +54 -0
  48. data/lib/fog/internet_archive/requests/storage/get_bucket_logging.rb +45 -0
  49. data/lib/fog/internet_archive/requests/storage/get_bucket_policy.rb +31 -0
  50. data/lib/fog/internet_archive/requests/storage/get_bucket_website.rb +38 -0
  51. data/lib/fog/internet_archive/requests/storage/get_object.rb +163 -0
  52. data/lib/fog/internet_archive/requests/storage/get_object_acl.rb +72 -0
  53. data/lib/fog/internet_archive/requests/storage/get_object_http_url.rb +48 -0
  54. data/lib/fog/internet_archive/requests/storage/get_object_https_url.rb +30 -0
  55. data/lib/fog/internet_archive/requests/storage/get_object_torrent.rb +45 -0
  56. data/lib/fog/internet_archive/requests/storage/get_object_url.rb +49 -0
  57. data/lib/fog/internet_archive/requests/storage/get_request_payment.rb +45 -0
  58. data/lib/fog/internet_archive/requests/storage/get_service.rb +50 -0
  59. data/lib/fog/internet_archive/requests/storage/head_object.rb +57 -0
  60. data/lib/fog/internet_archive/requests/storage/initiate_multipart_upload.rb +42 -0
  61. data/lib/fog/internet_archive/requests/storage/list_multipart_uploads.rb +52 -0
  62. data/lib/fog/internet_archive/requests/storage/list_parts.rb +53 -0
  63. data/lib/fog/internet_archive/requests/storage/post_object_hidden_fields.rb +36 -0
  64. data/lib/fog/internet_archive/requests/storage/put_bucket.rb +70 -0
  65. data/lib/fog/internet_archive/requests/storage/put_bucket_acl.rb +69 -0
  66. data/lib/fog/internet_archive/requests/storage/put_bucket_cors.rb +47 -0
  67. data/lib/fog/internet_archive/requests/storage/put_bucket_lifecycle.rb +76 -0
  68. data/lib/fog/internet_archive/requests/storage/put_bucket_logging.rb +79 -0
  69. data/lib/fog/internet_archive/requests/storage/put_bucket_policy.rb +25 -0
  70. data/lib/fog/internet_archive/requests/storage/put_bucket_website.rb +59 -0
  71. data/lib/fog/internet_archive/requests/storage/put_object.rb +94 -0
  72. data/lib/fog/internet_archive/requests/storage/put_object_acl.rb +73 -0
  73. data/lib/fog/internet_archive/requests/storage/put_object_url.rb +43 -0
  74. data/lib/fog/internet_archive/requests/storage/put_request_payment.rb +45 -0
  75. data/lib/fog/internet_archive/requests/storage/sync_clock.rb +24 -0
  76. data/lib/fog/internet_archive/requests/storage/upload_part.rb +39 -0
  77. data/lib/fog/internet_archive/signaturev4.rb +71 -0
  78. data/lib/fog/internet_archive/storage.rb +381 -0
  79. data/lib/fog/internet_archive/version.rb +5 -0
  80. data/tasks/bundler.rake +3 -0
  81. data/tasks/console.rake +17 -0
  82. data/tasks/lint.rake +3 -0
  83. data/tasks/test.rake +7 -0
  84. data/tests/helper.rb +36 -0
  85. data/tests/helpers/collection_helper.rb +88 -0
  86. data/tests/helpers/formats_helper.rb +98 -0
  87. data/tests/helpers/formats_helper_tests.rb +106 -0
  88. data/tests/helpers/mock_helper.rb +13 -0
  89. data/tests/helpers/model_helper.rb +29 -0
  90. data/tests/helpers/responds_to_helper.rb +11 -0
  91. data/tests/helpers/schema_validator_tests.rb +101 -0
  92. data/tests/helpers/succeeds_helper.rb +9 -0
  93. data/tests/internet_archive/models/storage/directory_tests.rb +42 -0
  94. data/tests/internet_archive/models/storage/file_tests.rb +61 -0
  95. data/tests/internet_archive/models/storage/files_tests.rb +60 -0
  96. data/tests/internet_archive/models/storage/url_tests.rb +28 -0
  97. data/tests/internet_archive/requests/storage/acl_utils_tests.rb +209 -0
  98. data/tests/internet_archive/requests/storage/bucket_tests.rb +324 -0
  99. data/tests/internet_archive/requests/storage/cors_utils_tests.rb +108 -0
  100. data/tests/internet_archive/requests/storage/multipart_upload_tests.rb +132 -0
  101. data/tests/internet_archive/requests/storage/object_tests.rb +166 -0
  102. data/tests/internet_archive/signaturev4_tests.rb +41 -0
  103. data/tests/internet_archive/signed_params_tests.rb +5 -0
  104. data/tests/lorem.txt +1 -0
  105. metadata +322 -0
@@ -0,0 +1,39 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/internet_archive/models/storage/directory'
3
+
4
+ module Fog
5
+ module Storage
6
+ class InternetArchive
7
+ class Directories < Fog::Collection
8
+ model Fog::Storage::InternetArchive::Directory
9
+
10
+ def all
11
+ data = service.get_service.body['Buckets']
12
+ load(data)
13
+ end
14
+
15
+ def get(key, options = {})
16
+ remap_attributes(options, {
17
+ :delimiter => 'delimiter',
18
+ :marker => 'marker',
19
+ :max_keys => 'max-keys',
20
+ :prefix => 'prefix'
21
+ })
22
+ data = service.get_bucket(key, options).body
23
+ directory = new(:key => data['Name'])
24
+ options = {}
25
+ for k, v in data
26
+ if ['CommonPrefixes', 'Delimiter', 'IsTruncated', 'Marker', 'MaxKeys', 'Prefix'].include?(k)
27
+ options[k] = v
28
+ end
29
+ end
30
+ directory.files.merge_attributes(options)
31
+ directory.files.load(data['Contents'])
32
+ directory
33
+ rescue Excon::Errors::NotFound
34
+ nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,105 @@
1
+ require 'fog/core/model'
2
+ require 'fog/internet_archive/models/storage/files'
3
+ require 'fog/internet_archive/models/storage/ia_attributes.rb'
4
+
5
+ module Fog
6
+ module Storage
7
+ class InternetArchive
8
+ class Directory < Fog::Model
9
+ extend Fog::Storage::IAAttributes::ClassMethods
10
+ include Fog::Storage::IAAttributes::InstanceMethods
11
+
12
+ identity :key, :aliases => ['Name', 'name']
13
+
14
+ attribute :creation_date, :aliases => 'CreationDate'
15
+
16
+ # treat these differently
17
+ attribute :collections
18
+ attribute :subjects
19
+
20
+ ia_metadata_attribute :ignore_preexisting_bucket
21
+ ia_metadata_attribute :interactive_priority
22
+
23
+ # acl for internet archive is always public-read
24
+ def acl
25
+ 'public-read'
26
+ end
27
+
28
+ def acl=(new_acl)
29
+ 'public-read'
30
+ end
31
+
32
+ # See http://archive.org/help/abouts3.txt
33
+ def destroy
34
+ Fog::Logger.warning("fog: Internet Archive does not support deleting a Bucket (i.e. Item). For details see: See http://archive.org/help/abouts3.txt")
35
+ false
36
+ end
37
+
38
+ def location
39
+ requires :key
40
+ attributes[:location] || bucket_location || self.service.region
41
+ end
42
+
43
+ def location=(new_location)
44
+ if INVALID_LOCATIONS.include?(new_location)
45
+ raise ArgumentError, "location must not include any of #{INVALID_LOCATIONS.join(', ')}. See http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html"
46
+ else
47
+ merge_attributes(:location => new_location)
48
+ end
49
+ end
50
+
51
+ def files
52
+ @files ||= Fog::Storage::InternetArchive::Files.new(:directory => self, :service => service)
53
+ end
54
+
55
+ def payer
56
+ requires :key
57
+ data = service.get_request_payment(key)
58
+ data.body['Payer']
59
+ end
60
+
61
+ def payer=(new_payer)
62
+ requires :key
63
+ service.put_request_payment(key, new_payer)
64
+ @payer = new_payer
65
+ end
66
+
67
+ def public=(new_public)
68
+ 'public-read'
69
+ end
70
+
71
+ def public_url
72
+ requires :key
73
+ "http://#{Fog::InternetArchive::DOMAIN_NAME}/details/#{key}"
74
+ end
75
+
76
+ def save
77
+ requires :key
78
+
79
+ options = {}
80
+
81
+ options['x-archive-ignore-preexisting-bucket'] = ignore_preexisting_bucket if ignore_preexisting_bucket
82
+ options['x-archive-interactive-priority'] = interactive_priority if interactive_priority
83
+
84
+ set_metadata_array_headers(:collections, options)
85
+ set_metadata_array_headers(:subjects, options)
86
+
87
+ if location = attributes[:location] || (self.service.region != 'us-east-1' && self.service.region)
88
+ options['LocationConstraint'] = location
89
+ end
90
+
91
+ service.put_bucket(key, options)
92
+
93
+ true
94
+ end
95
+
96
+ private
97
+
98
+ def bucket_location
99
+ data = service.get_bucket_location(key)
100
+ data.body['LocationConstraint']
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,254 @@
1
+ require 'fog/core/model'
2
+ require 'fog/internet_archive/models/storage/ia_attributes.rb'
3
+
4
+ module Fog
5
+ module Storage
6
+ class InternetArchive
7
+ class File < Fog::Model
8
+ extend Fog::Storage::IAAttributes::ClassMethods
9
+ include Fog::Storage::IAAttributes::InstanceMethods
10
+
11
+ # @see AWS Object docs http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectOps.html
12
+
13
+ # @note Chunk size to use for multipart uploads.
14
+ # Use small chunk sizes to minimize memory. E.g. 5242880 = 5mb
15
+ attr_accessor :multipart_chunk_size
16
+
17
+ attr_writer :body
18
+
19
+ identity :key, :aliases => 'Key'
20
+
21
+ attribute :cache_control, :aliases => 'Cache-Control'
22
+ attribute :content_disposition, :aliases => 'Content-Disposition'
23
+ attribute :content_encoding, :aliases => 'Content-Encoding'
24
+ attribute :content_length, :aliases => ['Content-Length', 'Size'], :type => :integer
25
+ attribute :content_md5, :aliases => 'Content-MD5'
26
+ attribute :content_type, :aliases => 'Content-Type'
27
+ attribute :etag, :aliases => ['Etag', 'ETag']
28
+ attribute :expires, :aliases => 'Expires'
29
+ attribute :last_modified, :aliases => ['Last-Modified', 'LastModified']
30
+ attribute :metadata
31
+ attribute :owner, :aliases => 'Owner'
32
+
33
+ # treat these differently
34
+ attribute :collections
35
+ attribute :subjects
36
+
37
+ ia_metadata_attribute :auto_make_bucket
38
+ ia_metadata_attribute :cascade_delete
39
+ ia_metadata_attribute :ignore_preexisting_bucket
40
+ ia_metadata_attribute :interactive_priority
41
+ ia_metadata_attribute :keep_old_version
42
+ ia_metadata_attribute :queue_derive
43
+ ia_metadata_attribute :size_hint
44
+
45
+ # acl for internet archive is always public-read
46
+ def acl
47
+ 'public-read'
48
+ end
49
+
50
+ def acl=(new_acl)
51
+ 'public-read'
52
+ end
53
+
54
+ # Get file's body if exists, else ' '.
55
+ #
56
+ # @return [File]
57
+ #
58
+ def body
59
+ attributes[:body] ||= if last_modified && (file = collection.get(identity))
60
+ file.body
61
+ else
62
+ ''
63
+ end
64
+ end
65
+
66
+ # Set body attribute.
67
+ #
68
+ # @param [File] new_body
69
+ # @return [File] attributes[:body]
70
+ #
71
+ def body=(new_body)
72
+ attributes[:body] = new_body
73
+ end
74
+
75
+ # Get the file instance's directory.
76
+ #
77
+ # @return [Fog::InternetArchive::Storage::Directory]
78
+ #
79
+ def directory
80
+ @directory
81
+ end
82
+
83
+ # Copy object from one bucket to other bucket.
84
+ #
85
+ # required attributes: directory, key
86
+ #
87
+ # @param target_directory_key [String]
88
+ # @param target_file_key [String]
89
+ # @param options [Hash] options for copy_object method
90
+ # @return [String] Fog::InternetArchive::Files#head status of directory contents
91
+ #
92
+ def copy(target_directory_key, target_file_key, options = {})
93
+ requires :directory, :key
94
+ service.copy_object(directory.key, key, target_directory_key, target_file_key, options)
95
+ target_directory = service.directories.new(:key => target_directory_key)
96
+ target_directory.files.head(target_file_key)
97
+ end
98
+
99
+ # Destroy file via http DELETE.
100
+ #
101
+ # required attributes: directory, key
102
+ #
103
+ # @param options [Hash]
104
+ # @return [Boolean] true if successful
105
+ #
106
+ def destroy(options = {})
107
+ requires :directory, :key
108
+ options['x-archive-cascade-delete'] = cascade_delete if cascade_delete
109
+ service.delete_object(directory.key, key, options)
110
+ true
111
+ end
112
+
113
+ remove_method :metadata
114
+ def metadata
115
+ attributes.reject {|key, value| !(key.to_s =~ /^x-(amz||archive)-meta/)}
116
+ end
117
+
118
+ remove_method :metadata=
119
+ def metadata=(new_metadata)
120
+ merge_attributes(new_metadata)
121
+ end
122
+
123
+ remove_method :owner=
124
+ def owner=(new_owner)
125
+ if new_owner
126
+ attributes[:owner] = {
127
+ :display_name => new_owner['DisplayName'],
128
+ :id => new_owner['ID']
129
+ }
130
+ end
131
+ end
132
+
133
+ # Set Access-Control-List permissions.
134
+ #
135
+ # valid new_publics: public_read, private
136
+ #
137
+ # @param [String] new_public
138
+ # @return [String] new_public
139
+ #
140
+ def public=(new_public)
141
+ 'public-read'
142
+ end
143
+
144
+ # Get publicly acessible url via http GET.
145
+ #
146
+ # required attributes: directory, key
147
+ #
148
+ # @return [String] public url
149
+ #
150
+ def public_url
151
+ requires :directory, :key
152
+ "http://#{Fog::InternetArchive::DOMAIN_NAME}/download/#{directory.key}/#{Fog::InternetArchive.escape(key)}".gsub('%2F','/')
153
+ end
154
+
155
+ # Save file with body as contents to directory.key with name key via http PUT
156
+ #
157
+ # required attributes: body, directory, key
158
+ #
159
+ # @param [Hash] options
160
+ # @option options [String] cache_control sets Cache-Control header. For example, 'No-cache'
161
+ # @option options [String] content_disposition sets Content-Disposition HTTP header. For exampple, 'attachment; filename=testing.txt'
162
+ # @option options [String] content_encoding sets Content-Encoding HTTP header. For example, 'x-gzip'
163
+ # @option options [String] content_md5 sets Content-MD5. For example, '79054025255fb1a26e4bc422aef54eb4'
164
+ # @option options [String] content_type Content-Type. For example, 'text/plain'
165
+ # @option options [String] expires sets number of seconds before AWS Object expires.
166
+ # @option options [String] storage_class sets x-amz-storage-class HTTP header. Defaults to 'STANDARD'. Or, 'REDUCED_REDUNDANCY'
167
+ # @option options [String] encryption sets HTTP encryption header. Set to 'AES256' to encrypt files at rest on S3
168
+ # @return [Boolean] true if no errors
169
+ #
170
+ def save(options = {})
171
+ requires :body, :directory, :key
172
+ if options != {}
173
+ Fog::Logger.deprecation("options param is deprecated [light_black](#{caller.first})[/]")
174
+ end
175
+ options['Cache-Control'] = cache_control if cache_control
176
+ options['Content-Disposition'] = content_disposition if content_disposition
177
+ options['Content-Encoding'] = content_encoding if content_encoding
178
+ options['Content-MD5'] = content_md5 if content_md5
179
+ options['Content-Type'] = content_type if content_type
180
+ options['Expires'] = expires if expires
181
+ options.merge!(metadata)
182
+
183
+ options['x-archive-auto-make-bucket'] = auto_make_bucket if auto_make_bucket
184
+ options['x-archive-interactive-priority'] = interactive_priority if interactive_priority
185
+ options['x-archive-keep-old-version'] = keep_old_version if keep_old_version
186
+ options['x-archive-queue-derive'] = queue_derive if queue_derive
187
+ options['x-archive-size-hint'] = size_hint.to_i.to_s if size_hint
188
+
189
+ set_metadata_array_headers(:collections, options)
190
+ set_metadata_array_headers(:subjects, options)
191
+
192
+ if multipart_chunk_size && body.respond_to?(:read)
193
+ data = multipart_save(options)
194
+ merge_attributes(data.body)
195
+ else
196
+ data = service.put_object(directory.key, key, body, options)
197
+ merge_attributes(data.headers.reject {|key, value| ['Content-Length', 'Content-Type'].include?(key)})
198
+ end
199
+ self.etag.gsub!('"','') if self.etag
200
+ self.content_length = Fog::Storage.get_body_size(body)
201
+ self.content_type ||= Fog::Storage.get_content_type(body)
202
+ true
203
+ end
204
+
205
+ # Get a url for file.
206
+ #
207
+ # required attributes: key
208
+ #
209
+ # @param expires [String] number of seconds before url expires
210
+ # @param options [Hash]
211
+ # @return [String] url
212
+ #
213
+ def url(expires, options = {})
214
+ requires :key
215
+ collection.get_url(key, expires, options)
216
+ end
217
+
218
+ private
219
+
220
+ def directory=(new_directory)
221
+ @directory = new_directory
222
+ end
223
+
224
+ def multipart_save(options)
225
+ # Initiate the upload
226
+ res = service.initiate_multipart_upload(directory.key, key, options)
227
+ upload_id = res.body["UploadId"]
228
+
229
+ # Store ETags of upload parts
230
+ part_tags = []
231
+
232
+ # Upload each part
233
+ # TODO: optionally upload chunks in parallel using threads
234
+ # (may cause network performance problems with many small chunks)
235
+ # TODO: Support large chunk sizes without reading the chunk into memory
236
+ body.rewind if body.respond_to?(:rewind)
237
+ while (chunk = body.read(multipart_chunk_size)) do
238
+ md5 = Base64.encode64(Digest::MD5.digest(chunk)).strip
239
+ part_upload = service.upload_part(directory.key, key, upload_id, part_tags.size + 1, chunk, 'Content-MD5' => md5 )
240
+ part_tags << part_upload.headers["ETag"]
241
+ end
242
+
243
+ rescue
244
+ # Abort the upload & reraise
245
+ service.abort_multipart_upload(directory.key, key, upload_id) if upload_id
246
+ raise
247
+ else
248
+ # Complete the upload
249
+ service.complete_multipart_upload(directory.key, key, upload_id, part_tags)
250
+ end
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,119 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/internet_archive/models/storage/file'
3
+
4
+ module Fog
5
+ module Storage
6
+ class InternetArchive
7
+ class Files < Fog::Collection
8
+ extend Fog::Deprecation
9
+ deprecate :get_url, :get_https_url
10
+
11
+ attribute :common_prefixes, :aliases => 'CommonPrefixes'
12
+ attribute :delimiter, :aliases => 'Delimiter'
13
+ attribute :directory
14
+ attribute :is_truncated, :aliases => 'IsTruncated'
15
+ attribute :marker, :aliases => 'Marker'
16
+ attribute :max_keys, :aliases => ['MaxKeys', 'max-keys']
17
+ attribute :prefix, :aliases => 'Prefix'
18
+
19
+ model Fog::Storage::InternetArchive::File
20
+
21
+ def all(options = {})
22
+ requires :directory
23
+ options = {
24
+ 'delimiter' => delimiter,
25
+ 'marker' => marker,
26
+ 'max-keys' => max_keys,
27
+ 'prefix' => prefix
28
+ }.merge!(options)
29
+ options = options.reject {|key,value| value.nil? || value.to_s.empty?}
30
+ merge_attributes(options)
31
+ parent = directory.collection.get(
32
+ directory.key,
33
+ options
34
+ )
35
+ if parent
36
+ merge_attributes(parent.files.attributes)
37
+ load(parent.files.map {|file| file.attributes})
38
+ else
39
+ nil
40
+ end
41
+ end
42
+
43
+ alias_method :each_file_this_page, :each
44
+ def each
45
+ if !block_given?
46
+ self
47
+ else
48
+ subset = dup.all
49
+
50
+ subset.each_file_this_page {|f| yield f}
51
+ while subset.is_truncated
52
+ subset = subset.all(:marker => subset.last.key)
53
+ subset.each_file_this_page {|f| yield f}
54
+ end
55
+
56
+ self
57
+ end
58
+ end
59
+
60
+ def get(key, options = {}, &block)
61
+ requires :directory
62
+ data = service.get_object(directory.key, key, options, &block)
63
+ normalize_headers(data)
64
+ file_data = data.headers.merge({
65
+ :body => data.body,
66
+ :key => key
67
+ })
68
+ new(file_data)
69
+ rescue Excon::Errors::NotFound => error
70
+ case error.response.body
71
+ when /<Code>NoSuchKey<\/Code>/
72
+ nil
73
+ when /<Code>NoSuchBucket<\/Code>/
74
+ raise(Fog::Storage::InternetArchive::NotFound.new("Directory #{directory.identity} does not exist."))
75
+ else
76
+ raise(error)
77
+ end
78
+ end
79
+
80
+ def get_url(key, expires, options = {})
81
+ requires :directory
82
+ service.get_object_url(directory.key, key, expires, options)
83
+ end
84
+
85
+ def get_http_url(key, expires, options = {})
86
+ requires :directory
87
+ service.get_object_http_url(directory.key, key, expires, options)
88
+ end
89
+
90
+ def get_https_url(key, expires, options = {})
91
+ requires :directory
92
+ service.get_object_https_url(directory.key, key, expires, options)
93
+ end
94
+
95
+ def head(key, options = {})
96
+ requires :directory
97
+ data = service.head_object(directory.key, key, options)
98
+ normalize_headers(data)
99
+ file_data = data.headers.merge({
100
+ :key => key
101
+ })
102
+ new(file_data)
103
+ rescue Excon::Errors::NotFound
104
+ nil
105
+ end
106
+
107
+ def new(attributes = {})
108
+ requires :directory
109
+ super({ :directory => directory }.merge!(attributes))
110
+ end
111
+
112
+ def normalize_headers(data)
113
+ data.headers['Last-Modified'] = Time.parse(data.get_header('Last-Modified'))
114
+ data.headers['ETag'] = data.get_header('ETag').gsub('"','')
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end