Class: Condo::Strata::RackspaceCloudFiles

Inherits:
Object
  • Object
show all
Defined in:
lib/condo/strata/rackspace_cloud_files.rb

Overview

NOTE

Set Account Metadata Key for Public Access before this will work - X-Account-Meta-Temp-Url-Key: <your key>

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ RackspaceCloudFiles

Returns a new instance of RackspaceCloudFiles.

Raises:

  • (ArgumentError)


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 10

def initialize(options)
	@options = {
		:name => :RackspaceCloudFiles,
		:location => :dfw,			# dallas or chicago	- this is set at bucket creation time
		:fog => {
			:provider => 'Rackspace',
			:rackspace_username => options[:username],
			:rackspace_api_key => options[:secret_key],
			:rackspace_auth_url => options[:auth_url] || 'https://identity.api.rackspacecloud.com/v2.0' # is US and UK is 'lon.auth.api.rackspacecloud.com'
		}
	}.merge!(options)
	
	
	@options[:location] = case @options[:location]
		when :dfw, :dallas, :DFW then 'storage101.dfw1.clouddrive.com'
		when :ord, :chicago, :ORD then 'storage101.ord1.clouddrive.com'
	end
	
	
	#raise ArgumentError, 'Rackspace Username missing' if @options[:username].nil?
	#raise ArgumentError, 'Rackspace Secret Key missing' if @options[:secret_key].nil?
	
	raise ArgumentError, 'Rackspace Storage URL missing' if @options[:storage_url].nil?
	raise ArgumentError, 'Rackspace Temp URL Key missing' if @options[:temp_url_key].nil?
	
	
	@options[:location] = @options[:location].to_sym
end

Instance Method Details

#allow_cors(domains = 'http://localhost:3000', options_age = 10, headers = 'etag, x-object-manifest, content-type, accept, origin, x-requested-with') ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 62

def allow_cors(domains = 'http://localhost:3000', options_age = 10, headers = 'etag, x-object-manifest, content-type, accept, origin, x-requested-with')
	fog_connection.request(
		:expects  => [201, 202, 204],
		:method   => 'POST',
		:headers  => {
			'X-Container-Meta-Access-Control-Allow-Origin' => domains,
			'X-Container-Meta-Access-Control-Max-Age' => options_age,
			'X-Container-Meta-Access-Control-Allow-Headers' => headers
		}
	)
end

#destroy(upload) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 189

def destroy(upload)
	connection = fog_connection
	directory = connection.directories.get(upload.bucket_name)	# it is assumed this exists - if not then the upload wouldn't have taken place
	
	if upload.resumable
		directory.files.all({'prefix' => upload.object_key}).each do |file|
			return false unless file.destroy
		end
	end
	
	file = directory.files.get(upload.object_key)	# this is the manifest when resumable
	
	return true if file.nil?
	return file.destroy
end

#fog_connectionObject



183
184
185
186
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 183

def fog_connection
	@fog = @fog || Fog::Storage.new(@options[:fog])
	return @fog
end

#get_object(options) ⇒ Object

Create a signed URL for accessing a private file



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 78

def get_object(options)
	options = {}.merge!(options)	# Need to deep copy here
	options[:object_options] = {
		:expires => 5.minutes.from_now,
		:verb => :get,		# Post for multi-part uploads http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html
		:headers => {},
		:parameters => {}
	}.merge!(options[:object_options] || {})
	options.merge!(@options)
	
	#
	# provide the signed request
	#
	sign_request(options)[:url]
end

#get_parts(options) ⇒ Object

Returns the part we are up to



137
138
139
140
141
142
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 137

def get_parts(options)
	{
		:type => :parts,
		:current_part => options[:resumable_id]
	}
end

#locationObject



45
46
47
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 45

def location
	@options[:location]
end

#nameObject



40
41
42
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 40

def name
	@options[:name]
end

#new_upload(options) ⇒ Object

Creates a new upload request (either single shot or multi-part)

> Passed: bucket_name, object_key, object_options, file_size



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 99

def new_upload(options)
	options = {}.merge!(options)	# Need to deep copy here
	options[:object_options] = {
		:expires => 5.minutes.from_now,
		:verb => :put,
		:headers => {},
		:parameters => {}
	}.merge!(options[:object_options])
	options.merge!(@options)
	
	options[:object_options][:headers]['ETag'] = options[:file_id] if options[:file_id].present? && options[:object_options][:headers]['ETag'].nil?
	options[:object_options][:headers]['Content-Type'] = 'binary/octet-stream' if options[:object_options][:headers]['Content-Type'].nil?
	
	
	#
	# Decide what type of request is being sent
	#
	request = {}
	if options[:file_size] > 2097152	# 2 mb (minimum chunk size)
		
		options[:object_key] = options[:object_key] + '_p1'		# Append the part number
		request[:type] = :chunked_upload
	else
		
		request[:type] = :direct_upload
	end
	
	#
	# provide the signed request
	#
	request[:signature] = sign_request(options)
	request
end

#set_metadata_key(key) ⇒ Object

Here for convenience



53
54
55
56
57
58
59
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 53

def (key)
	fog_connection.request(
		:expects  => [201, 202, 204],
		:method   => 'POST',
		:headers  => {'X-Account-Meta-Temp-Url-Key' => key}
	)
end

#set_part(options) ⇒ Object

Returns the requests for uploading parts and completing a resumable upload



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/condo/strata/rackspace_cloud_files.rb', line 148

def set_part(options)
	options[:object_options] = {
		:expires => 5.minutes.from_now,
		:headers => {},
		:parameters => {},
		:verb => :put
	}.merge!(options[:object_options])
	options.merge!(@options)
	
	
	request = {}
	if options[:part] == 'finish'
		#
		# Send the commitment response
		#
		options[:object_options][:headers]['X-Object-Manifest'] = "#{options[:bucket_name]}/#{options[:object_key]}"
		request[:type] = :finish
	else
		#
		# Send the part upload request
		#
		options[:object_options][:headers]['ETag'] = options[:file_id] if options[:file_id].present? && options[:object_options][:headers]['ETag'].nil?
		options[:object_options][:headers]['Content-Type'] = 'binary/octet-stream' if options[:object_options][:headers]['Content-Type'].nil?
		options[:object_key] = options[:object_key] + '_p' + options[:part]
		request[:type] = :part_upload
	end
	
	#
	# provide the signed request
	#
	request[:signature] = sign_request(options)
	request
end