cloud_tempfile 0.0.1
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.
- data/.gitignore +18 -0
- data/.rvmrc +2 -0
- data/.travis.yml +30 -0
- data/Appraisals +11 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +15 -0
- data/LICENSE +20 -0
- data/README.md +232 -0
- data/Rakefile +43 -0
- data/cloud_tempfile.gemspec +38 -0
- data/gemfiles/rails_3.1.gemfile +10 -0
- data/gemfiles/rails_3.2.gemfile +10 -0
- data/gemfiles/rails_4.0.gemfile +10 -0
- data/lib/cloud_tempfile/cloud_tempfile.rb +106 -0
- data/lib/cloud_tempfile/config.rb +206 -0
- data/lib/cloud_tempfile/engine.rb +53 -0
- data/lib/cloud_tempfile/multi_mime.rb +22 -0
- data/lib/cloud_tempfile/railtie.rb +11 -0
- data/lib/cloud_tempfile/storage.rb +151 -0
- data/lib/cloud_tempfile/version.rb +9 -0
- data/lib/cloud_tempfile.rb +11 -0
- data/lib/ext/fog/aws/models/storage/file.rb +19 -0
- data/lib/generators/cloud_tempfile/install_generator.rb +71 -0
- data/lib/generators/cloud_tempfile/templates/cloud_tempfile.rb +41 -0
- data/lib/generators/cloud_tempfile/templates/cloud_tempfile.yml +52 -0
- data/lib/tasks/cloud_tempfile_tasks.rake +7 -0
- data/spec/dummy_app/Rakefile +27 -0
- data/spec/fixtures/assets/TEST.doc +0 -0
- data/spec/fixtures/assets/TEST.docx +0 -0
- data/spec/fixtures/assets/TEST.pdf +0 -0
- data/spec/fixtures/assets/TEST.rtf +1 -0
- data/spec/fixtures/aws_with_yml/config/cloud_tempfile.yml +22 -0
- data/spec/fixtures/google_with_yml/config/.gitkeep +0 -0
- data/spec/fixtures/rackspace_with_yml/config/.gitkeep +0 -0
- data/spec/fixtures/with_invalid_yml/config/cloud_tempfile.yml +22 -0
- data/spec/fixtures/without_yml/public/.gitkeep +0 -0
- data/spec/integration/.gitkeep +0 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/unit/cloud_tempfile_spec.rb +208 -0
- data/spec/unit/multi_mime_spec.rb +48 -0
- data/spec/unit/railsless_spec.rb +50 -0
- data/spec/unit/storage_spec.rb +260 -0
- metadata +189 -0
@@ -0,0 +1,206 @@
|
|
1
|
+
# cloud_tempfile/config.rb
|
2
|
+
#
|
3
|
+
# Author:: Kevin Bolduc
|
4
|
+
# Date:: 14-02-24
|
5
|
+
# Time:: 3:23 PM
|
6
|
+
|
7
|
+
module CloudTempfile
|
8
|
+
class Config
|
9
|
+
include ActiveModel::Validations
|
10
|
+
|
11
|
+
# CloudTempfile
|
12
|
+
attr_accessor :enabled
|
13
|
+
|
14
|
+
attr_accessor :prefix
|
15
|
+
attr_accessor :public
|
16
|
+
attr_accessor :public_path
|
17
|
+
attr_accessor :expiry
|
18
|
+
attr_accessor :clean_up
|
19
|
+
attr_accessor :clean_up_older_than
|
20
|
+
|
21
|
+
# FOG configuration
|
22
|
+
attr_accessor :fog_host #
|
23
|
+
attr_accessor :fog_provider # Currently Supported ['AWS', 'Google', 'Rackspace', 'Local']
|
24
|
+
attr_accessor :fog_directory # e.g. 'the-bucket-name'
|
25
|
+
attr_accessor :fog_region # e.g. 'eu-west-1' or 'us-east-1' etc...
|
26
|
+
attr_accessor :fog_endpoint # e.g. '/'
|
27
|
+
|
28
|
+
# Amazon AWS
|
29
|
+
attr_accessor :aws_access_key_id, :aws_secret_access_key, :aws_reduced_redundancy, :aws_access_control_list
|
30
|
+
|
31
|
+
# Rackspace
|
32
|
+
attr_accessor :rackspace_username, :rackspace_api_key, :rackspace_auth_url
|
33
|
+
|
34
|
+
# Google Storage
|
35
|
+
attr_accessor :google_storage_secret_access_key, :google_storage_access_key_id
|
36
|
+
|
37
|
+
# Logging Options
|
38
|
+
attr_accessor :fail_silently
|
39
|
+
attr_accessor :log_silently
|
40
|
+
|
41
|
+
# Validation #######################################################################################################
|
42
|
+
validates :public, :presence => true
|
43
|
+
validates :fog_provider, :presence => true
|
44
|
+
validates :fog_directory, :presence => true
|
45
|
+
|
46
|
+
validates :aws_access_key_id, :presence => true, :if => :aws?
|
47
|
+
validates :aws_secret_access_key, :presence => true, :if => :aws?
|
48
|
+
validates :rackspace_username, :presence => true, :if => :rackspace?
|
49
|
+
validates :rackspace_api_key, :presence => true, :if => :rackspace?
|
50
|
+
validates :google_storage_secret_access_key, :presence => true, :if => :google?
|
51
|
+
validates :google_storage_access_key_id, :presence => true, :if => :google?
|
52
|
+
|
53
|
+
####################################################################################################################
|
54
|
+
def initialize
|
55
|
+
self.fog_region = nil
|
56
|
+
self.fog_endpoint = '/'
|
57
|
+
|
58
|
+
self.public = false
|
59
|
+
self.prefix = "tmp/"
|
60
|
+
|
61
|
+
self.fail_silently = false
|
62
|
+
self.log_silently = true
|
63
|
+
|
64
|
+
self.clean_up = false
|
65
|
+
self.clean_up_older_than = 600
|
66
|
+
|
67
|
+
load_yml! if defined?(Rails) && yml_exists?
|
68
|
+
end
|
69
|
+
|
70
|
+
def enabled?
|
71
|
+
enabled == true
|
72
|
+
end
|
73
|
+
|
74
|
+
def public?
|
75
|
+
public == true
|
76
|
+
end
|
77
|
+
|
78
|
+
def public_path
|
79
|
+
@public_path || Rails.public_path
|
80
|
+
end
|
81
|
+
|
82
|
+
def expiry?
|
83
|
+
!expiry.nil? && expiry.kind_of?(Fixnum)
|
84
|
+
end
|
85
|
+
|
86
|
+
def aws?
|
87
|
+
fog_provider == 'AWS'
|
88
|
+
end
|
89
|
+
|
90
|
+
def aws_rrs?
|
91
|
+
aws_reduced_redundancy == true
|
92
|
+
end
|
93
|
+
|
94
|
+
# Set file's access control list (ACL).
|
95
|
+
# Valid acls: private, public-read, public-read-write, authenticated-read, bucket-owner-read, bucket-owner-full-control
|
96
|
+
def aws_acl?
|
97
|
+
['private', 'public-read', 'public-read-write', 'authenticated-read', 'bucket-owner-read', 'bucket-owner-full-control'].include?(aws_access_control_list)
|
98
|
+
end
|
99
|
+
|
100
|
+
def rackspace?
|
101
|
+
fog_provider == 'Rackspace'
|
102
|
+
end
|
103
|
+
|
104
|
+
def google?
|
105
|
+
fog_provider == 'Google'
|
106
|
+
end
|
107
|
+
|
108
|
+
def local?
|
109
|
+
fog_provider == 'Local'
|
110
|
+
end
|
111
|
+
|
112
|
+
def clean_up?
|
113
|
+
clean_up == true
|
114
|
+
end
|
115
|
+
|
116
|
+
def fog_options
|
117
|
+
#If the CloudTempfile is disabled then revert to local file creation
|
118
|
+
@fog_provider = 'Local' if (!enabled? && !fog_provider.nil?)
|
119
|
+
|
120
|
+
options = { :provider => fog_provider }
|
121
|
+
if aws?
|
122
|
+
options.merge!({
|
123
|
+
:aws_access_key_id => aws_access_key_id,
|
124
|
+
:aws_secret_access_key => aws_secret_access_key
|
125
|
+
})
|
126
|
+
options.merge!({:host => fog_host}) if !fog_host.blank?
|
127
|
+
elsif rackspace?
|
128
|
+
options.merge!({
|
129
|
+
:rackspace_username => rackspace_username,
|
130
|
+
:rackspace_api_key => rackspace_api_key
|
131
|
+
})
|
132
|
+
options.merge!({
|
133
|
+
:rackspace_region => fog_region
|
134
|
+
}) if fog_region
|
135
|
+
options.merge!({ :rackspace_auth_url => rackspace_auth_url }) if rackspace_auth_url
|
136
|
+
elsif google?
|
137
|
+
options.merge!({
|
138
|
+
:google_storage_secret_access_key => google_storage_secret_access_key,
|
139
|
+
:google_storage_access_key_id => google_storage_access_key_id
|
140
|
+
})
|
141
|
+
elsif local?
|
142
|
+
options.merge!({
|
143
|
+
:local_root => public_path,
|
144
|
+
:endpoint => fog_endpoint
|
145
|
+
})
|
146
|
+
else
|
147
|
+
raise ArgumentError, "CloudTempfile Unknown provider: #{fog_provider} only AWS, Rackspace and Google are supported currently."
|
148
|
+
end
|
149
|
+
|
150
|
+
options.merge!({:region => fog_region}) if fog_region && !rackspace?
|
151
|
+
return options
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
def yml_exists?
|
156
|
+
defined?(Rails.root) ? File.exists?(self.yml_path) : false
|
157
|
+
end
|
158
|
+
|
159
|
+
def yml
|
160
|
+
begin
|
161
|
+
@yml ||= YAML.load(ERB.new(IO.read(yml_path)).result)[Rails.env] rescue nil || {}
|
162
|
+
rescue Psych::SyntaxError
|
163
|
+
@yml = {}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def yml_path
|
168
|
+
Rails.root.join("config", "cloud_tempfile.yml").to_s
|
169
|
+
end
|
170
|
+
|
171
|
+
def load_yml!
|
172
|
+
self.enabled = yml["enabled"] if yml.has_key?('enabled')
|
173
|
+
|
174
|
+
self.fog_provider = yml["fog_provider"]
|
175
|
+
self.fog_directory = yml["fog_directory"]
|
176
|
+
self.fog_region = yml["fog_region"]
|
177
|
+
self.fog_host = yml["fog_host"] if yml.has_key?("fog_host")
|
178
|
+
self.aws_access_key_id = yml["aws_access_key_id"]
|
179
|
+
self.aws_secret_access_key = yml["aws_secret_access_key"]
|
180
|
+
self.aws_reduced_redundancy = yml["aws_reduced_redundancy"]
|
181
|
+
self.rackspace_username = yml["rackspace_username"]
|
182
|
+
self.rackspace_auth_url = yml["rackspace_auth_url"] if yml.has_key?("rackspace_auth_url")
|
183
|
+
self.rackspace_api_key = yml["rackspace_api_key"]
|
184
|
+
self.google_storage_secret_access_key = yml["google_storage_secret_access_key"]
|
185
|
+
self.google_storage_access_key_id = yml["google_storage_access_key_id"]
|
186
|
+
|
187
|
+
self.clean_up = yml["clean_up"] if yml.has_key?("clean_up")
|
188
|
+
self.clean_up_older_than = yml["clean_up_older_than"] if yml.has_key?("clean_up_older_than")
|
189
|
+
self.fail_silently = yml["fail_silently"] if yml.has_key?("fail_silently")
|
190
|
+
self.prefix = yml["prefix"] if yml.has_key?("prefix")
|
191
|
+
self.public_path = yml["public_path"] if yml.has_key?("public_path")
|
192
|
+
self.expiry = yml["expiry"] if yml.has_key?("expiry")
|
193
|
+
end
|
194
|
+
|
195
|
+
def fail_silently?
|
196
|
+
fail_silently || !enabled?
|
197
|
+
end
|
198
|
+
|
199
|
+
def log_silently?
|
200
|
+
self.log_silently == false
|
201
|
+
end
|
202
|
+
|
203
|
+
class Invalid < StandardError; end
|
204
|
+
private
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# cloud_tempfile/engine.rb
|
2
|
+
#
|
3
|
+
# Author:: Kevin Bolduc
|
4
|
+
# Date:: 14-02-24
|
5
|
+
# Time:: 3:23 PM
|
6
|
+
|
7
|
+
module CloudTempfile
|
8
|
+
class Engine < Rails::Engine
|
9
|
+
|
10
|
+
engine_name "cloud_tempfile"
|
11
|
+
|
12
|
+
initializer "cloud_tempfile config", :group => :all do |app|
|
13
|
+
app_initializer = Rails.root.join('config', 'initializers', 'cloud_tempfile.rb').to_s
|
14
|
+
app_yaml = Rails.root.join('config', 'cloud_tempfile.yml').to_s
|
15
|
+
|
16
|
+
if File.exists?( app_initializer )
|
17
|
+
CloudTempfile.log "CloudTempfile: using #{app_initializer}"
|
18
|
+
load app_initializer
|
19
|
+
elsif !File.exists?( app_initializer ) && !File.exists?( app_yaml )
|
20
|
+
CloudTempfile.log "CloudTempfile: using default configuration from built-in initializer"
|
21
|
+
CloudTempfile.configure do |config|
|
22
|
+
config.fog_provider = ENV['FOG_PROVIDER'] if ENV.has_key?('FOG_PROVIDER')
|
23
|
+
config.fog_directory = ENV['FOG_DIRECTORY'] if ENV.has_key?('FOG_DIRECTORY')
|
24
|
+
config.fog_region = ENV['FOG_REGION'] if ENV.has_key?('FOG_REGION')
|
25
|
+
|
26
|
+
config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID'] if ENV.has_key?('AWS_ACCESS_KEY_ID')
|
27
|
+
config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] if ENV.has_key?('AWS_SECRET_ACCESS_KEY')
|
28
|
+
config.aws_reduced_redundancy = ENV['AWS_REDUCED_REDUNDANCY'] == true if ENV.has_key?('AWS_REDUCED_REDUNDANCY')
|
29
|
+
|
30
|
+
config.rackspace_username = ENV['RACKSPACE_USERNAME'] if ENV.has_key?('RACKSPACE_USERNAME')
|
31
|
+
config.rackspace_api_key = ENV['RACKSPACE_API_KEY'] if ENV.has_key?('RACKSPACE_API_KEY')
|
32
|
+
|
33
|
+
config.google_storage_access_key_id = ENV['GOOGLE_STORAGE_ACCESS_KEY_ID'] if ENV.has_key?('GOOGLE_STORAGE_ACCESS_KEY_ID')
|
34
|
+
config.google_storage_secret_access_key = ENV['GOOGLE_STORAGE_SECRET_ACCESS_KEY'] if ENV.has_key?('GOOGLE_STORAGE_SECRET_ACCESS_KEY')
|
35
|
+
|
36
|
+
config.enabled = (ENV['CLOUD_TEMPFILE_ENABLED'] == 'true') if ENV.has_key?('CLOUD_TEMPFILE_ENABLED')
|
37
|
+
config.public = (ENV['CLOUD_TEMPFILE_PUBLIC'] == 'true') if ENV.has_key?('CLOUD_TEMPFILE_PUBLIC')
|
38
|
+
config.public_path = ENV['CLOUD_TEMPFILE_PUBLIC_PATH'] if ENV.has_key?('CLOUD_TEMPFILE_PUBLIC_PATH')
|
39
|
+
config.expiry = ENV['CLOUD_TEMPFILE_EXPIRY'] if ENV.has_key?('CLOUD_TEMPFILE_EXPIRY')
|
40
|
+
|
41
|
+
config.clean_up = (ENV['CLOUD_TEMPFILE_CLEAN_UP'] == 'true') if ENV.has_key?('CLOUD_TEMPFILE_CLEAN_UP')
|
42
|
+
config.clean_up_older_than = ENV['CLOUD_TEMPFILE_CLEAN_UP_OLDER_THAN'] if ENV.has_key?('CLOUD_TEMPFILE_CLEAN_UP_OLDER_THAN')
|
43
|
+
end
|
44
|
+
|
45
|
+
config.prefix = ENV['CLOUD_TEMPFILE_PREFIX'] if ENV.has_key?('CLOUD_TEMPFILE_PREFIX')
|
46
|
+
end
|
47
|
+
|
48
|
+
if File.exists?( app_yaml )
|
49
|
+
CloudTempfile.log "CloudTempfile: YAML file found #{app_yaml} settings will be merged into the configuration"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# cloud_tempfile/multi_mime.rb
|
4
|
+
#
|
5
|
+
# Author:: Kevin Bolduc
|
6
|
+
# Date:: 14-02-24
|
7
|
+
# Time:: 3:23 PM
|
8
|
+
|
9
|
+
module CloudTempfile
|
10
|
+
class MultiMime
|
11
|
+
def self.lookup(ext)
|
12
|
+
if defined?(Mime::Type)
|
13
|
+
Mime::Type.lookup_by_extension(ext)
|
14
|
+
elsif defined?(Rack::Mime)
|
15
|
+
ext_with_dot = ".#{ext}"
|
16
|
+
Rack::Mime.mime_type(ext_with_dot)
|
17
|
+
else
|
18
|
+
MIME::Types.type_for(ext).first
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# cloud_tempfile/storage.rb
|
2
|
+
#
|
3
|
+
# Author:: Kevin Bolduc
|
4
|
+
# Date:: 14-02-24
|
5
|
+
# Time:: 3:23 PM
|
6
|
+
|
7
|
+
module CloudTempfile
|
8
|
+
class Storage
|
9
|
+
|
10
|
+
attr_accessor :config
|
11
|
+
|
12
|
+
def initialize(cfg)
|
13
|
+
@config = cfg
|
14
|
+
end
|
15
|
+
|
16
|
+
# This "connection" is the fog connection responsible for persisting the file
|
17
|
+
# @return [Fog::Storage]
|
18
|
+
def connection
|
19
|
+
@connection ||= ::Fog::Storage.new(self.config.fog_options)
|
20
|
+
end
|
21
|
+
|
22
|
+
# This "directory" action should only be used with the cloud provider and returns a <tt>Fog::Storage::Directory</tt> class
|
23
|
+
# @return [Fog::Storage::Directory]
|
24
|
+
def directory(options={})
|
25
|
+
prefix = options.has_key?(:prefix)? options[:prefix] : self.config.prefix
|
26
|
+
@directory ||= connection.directories.get(self.config.fog_directory, :prefix => prefix)
|
27
|
+
end
|
28
|
+
|
29
|
+
# This action will upload a AWS::File to the specified directory
|
30
|
+
# @return [Fog::Storage::File]
|
31
|
+
def upload_file(f, body, options={})
|
32
|
+
file = init_fog_file(f, body, options)
|
33
|
+
if self.config.enabled?
|
34
|
+
return directory(options).files.create( file )
|
35
|
+
else
|
36
|
+
return local_file(f, body, options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Used with the "Local" provider which will utilize the local file system with Fog.
|
41
|
+
# This is handy for development and test environments.
|
42
|
+
# @return [Fog::Storage::Local::File]
|
43
|
+
def local_file(f, body, options={})
|
44
|
+
#return !self.config.public?
|
45
|
+
file = init_fog_file(f, body, options)
|
46
|
+
# If the "file" is empty then return nil
|
47
|
+
return nil if file.nil? || file.blank? || local_root.nil?
|
48
|
+
file = local_root(options).files.create( file )
|
49
|
+
end
|
50
|
+
|
51
|
+
# This action will delete a AWS::File from the specified directory
|
52
|
+
# @param [Fog::Storage::File]
|
53
|
+
def delete_file(f)
|
54
|
+
#return false if !f.kind_of?(Fog::Storage::AWS::File) || !storage_provider.eql?(:aws)
|
55
|
+
log "Deleting: #{f.key}"
|
56
|
+
return f.destroy
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns a list of remote files for the specified directory
|
60
|
+
# @throws [BucketNotFound]
|
61
|
+
# @return [Array]
|
62
|
+
def get_remote_files
|
63
|
+
raise BucketNotFound.new("#{self.config.fog_provider} Bucket: #{self.config.fog_directory} not found.") unless directory
|
64
|
+
files = []
|
65
|
+
directory.files.each { |f| files << f.key if File.extname(f.key).present? }
|
66
|
+
return files
|
67
|
+
end
|
68
|
+
|
69
|
+
# Delete the expired file which are expired if the "config.clean_up" is true
|
70
|
+
# and "config.clean_up_older_than" is the amount of seconds it is older than.
|
71
|
+
#
|
72
|
+
# Note: This action should be used with the "bundle exec rake cloud_temp_file:clear" rake command (cronjob)
|
73
|
+
def delete_expired_tempfiles
|
74
|
+
return if !self.config.clean_up? || !self.config.enabled?
|
75
|
+
log "CloudTempfile.delete_expired_tempfiles is running..."
|
76
|
+
# Delete expired temp files
|
77
|
+
get_remote_files.each do |f|
|
78
|
+
f = directory.files.get(f)
|
79
|
+
if f.last_modified <= self.config.clean_up_older_than.ago
|
80
|
+
delete_file(f)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
log "CloudTempfile.delete_expired_tempfiles is complete!"
|
84
|
+
end
|
85
|
+
|
86
|
+
# Custom Errors (Exceptions)
|
87
|
+
class BucketNotFound < StandardError; end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# Initialize a Hash object to be use to by <tt>Fog::Storage</tt> to persist
|
92
|
+
# @param [String] filename
|
93
|
+
# @param [Object] body
|
94
|
+
# @return [Hash]
|
95
|
+
def init_fog_file(filename, body, options={})
|
96
|
+
# If the "filename" or the "body" are empty then return nil
|
97
|
+
return nil if filename.nil? || body.nil?
|
98
|
+
# Set file's access control list (ACL).
|
99
|
+
|
100
|
+
aws_acl = (self.config.aws_acl?)? self.config.aws_access_control_list.to_s : nil
|
101
|
+
# expiry is the number of seconds the file will available publicly
|
102
|
+
expiry = (self.config.expiry?)? self.config.expiry.to_i : nil
|
103
|
+
ext = File.extname(filename)[1..-1] # The file extension
|
104
|
+
mime = MultiMime.lookup(ext) # Look up the content type based off the file extension
|
105
|
+
prefix = options.has_key?(:prefix)? options[:prefix] : self.config.prefix
|
106
|
+
full_filename = (self.config.local? || !self.config.enabled?)? filename : "#{prefix}#{filename}"
|
107
|
+
|
108
|
+
# file Hash to be used to create a Fog for upload
|
109
|
+
file = {
|
110
|
+
:key => "#{full_filename}",
|
111
|
+
:body => body,
|
112
|
+
:content_type => mime
|
113
|
+
}
|
114
|
+
|
115
|
+
file.merge!({:public => true}) if self.config.public?
|
116
|
+
|
117
|
+
if self.config.aws?
|
118
|
+
if self.config.public? && self.config.expiry?
|
119
|
+
file.merge!({:cache_control => "public, max-age=#{expiry}"})
|
120
|
+
end
|
121
|
+
# valid acls: private, public-read, public-read-write, authenticated-read, bucket-owner-read, bucket-owner-full-control
|
122
|
+
file.merge!({:acl=>self.config.aws_access_control_list.to_s}) if self.config.aws_acl?
|
123
|
+
file.merge!({:expires => Time.now.utc.to_i + expiry}) if self.config.expiry?
|
124
|
+
file.merge!({:storage_class => 'REDUCED_REDUNDANCY'}) if self.config.aws_rrs?
|
125
|
+
end
|
126
|
+
|
127
|
+
return file
|
128
|
+
end
|
129
|
+
|
130
|
+
# This "local_root" action should only be used with the "Local" provider and returns a Fog::Storage::Local::Directory class
|
131
|
+
# @return [Fog::Storage::Local::Directory]
|
132
|
+
def local_root(options={})
|
133
|
+
prefix = options.has_key?(:prefix)? options[:prefix] : self.config.prefix
|
134
|
+
|
135
|
+
begin
|
136
|
+
if !connection.directories.get(prefix).nil?
|
137
|
+
@local_root ||= connection.directories.get(prefix)
|
138
|
+
else
|
139
|
+
@local_root ||= connection.directories.create(:key => prefix)
|
140
|
+
end
|
141
|
+
rescue
|
142
|
+
@local_root ||= connection.directories.create(:key => prefix)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def log(msg)
|
147
|
+
CloudTempfile.log(msg)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'fog'
|
2
|
+
require 'active_model'
|
3
|
+
require 'erb'
|
4
|
+
require "ext/fog/aws/models/storage/file"
|
5
|
+
require 'cloud_tempfile/cloud_tempfile'
|
6
|
+
require 'cloud_tempfile/config'
|
7
|
+
require 'cloud_tempfile/storage'
|
8
|
+
require 'cloud_tempfile/multi_mime'
|
9
|
+
|
10
|
+
require 'cloud_tempfile/railtie' if defined?(Rails)
|
11
|
+
require 'cloud_tempfile/engine' if defined?(Rails)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'fog/aws/models/storage/file'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Storage
|
5
|
+
class AWS
|
6
|
+
|
7
|
+
class File
|
8
|
+
fog_public_url = instance_method(:public_url)
|
9
|
+
|
10
|
+
define_method(:public_url) do
|
11
|
+
return_url = fog_public_url.bind(self).call()
|
12
|
+
return_url = url(expires) if return_url.nil? && !expires.nil?
|
13
|
+
return return_url
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module CloudTempfile
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
desc "Install a config/cloud_tempfile.yml "
|
5
|
+
|
6
|
+
# Commandline options can be defined here using Thor-like options:
|
7
|
+
class_option :use_yml, :type => :boolean, :default => false, :desc => "Use YML file instead of Rails Initializer"
|
8
|
+
class_option :provider, :type => :string, :default => "AWS", :desc => "Generate with support for 'AWS', 'Rackspace', or 'Google'"
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
12
|
+
end
|
13
|
+
|
14
|
+
def aws?
|
15
|
+
options[:provider] == 'AWS'
|
16
|
+
end
|
17
|
+
|
18
|
+
def google?
|
19
|
+
options[:provider] == 'Google'
|
20
|
+
end
|
21
|
+
|
22
|
+
def rackspace?
|
23
|
+
options[:provider] == 'Rackspace'
|
24
|
+
end
|
25
|
+
|
26
|
+
def fog_directory
|
27
|
+
"<%= ENV['FOG_DIRECTORY'] %>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def aws_access_key_id
|
31
|
+
"<%= ENV['AWS_ACCESS_KEY_ID'] %>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def aws_secret_access_key
|
35
|
+
"<%= ENV['AWS_SECRET_ACCESS_KEY'] %>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def google_storage_access_key_id
|
39
|
+
"<%= ENV['GOOGLE_STORAGE_ACCESS_KEY_ID'] %>"
|
40
|
+
end
|
41
|
+
|
42
|
+
def google_storage_secret_access_key
|
43
|
+
"<%= ENV['GOOGLE_STORAGE_SECRET_ACCESS_KEY'] %>"
|
44
|
+
end
|
45
|
+
|
46
|
+
def rackspace_username
|
47
|
+
"<%= ENV['RACKSPACE_USERNAME'] %>"
|
48
|
+
end
|
49
|
+
|
50
|
+
def rackspace_api_key
|
51
|
+
"<%= ENV['RACKSPACE_API_KEY'] %>"
|
52
|
+
end
|
53
|
+
|
54
|
+
def app_name
|
55
|
+
@app_name ||= Rails.application.is_a?(Rails::Application) && Rails.application.class.name.sub(/::Application$/, "").downcase
|
56
|
+
end
|
57
|
+
|
58
|
+
def generate_config
|
59
|
+
if options[:use_yml]
|
60
|
+
template "cloud_tempfile.yml", "config/cloud_tempfile.yml"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_initializer
|
65
|
+
unless options[:use_yml]
|
66
|
+
template "cloud_tempfile.rb", "config/initializers/cloud_tempfile.rb"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
CloudTempfile.configure do |config|
|
2
|
+
# Enable or disable the CloudTempfile functionality (Default: true)
|
3
|
+
# config.enabled = true
|
4
|
+
<%- if aws? -%>
|
5
|
+
config.fog_provider = 'AWS'
|
6
|
+
config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
7
|
+
config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
8
|
+
# The name of Amason S3 Bucket
|
9
|
+
config.fog_directory = ENV['FOG_DIRECTORY']
|
10
|
+
# You may need to specify what region your storage bucket is in. This may increase upload performance by configuring your region
|
11
|
+
# config.fog_region = 'eu-west-1'
|
12
|
+
# To use AWS reduced redundancy storage.
|
13
|
+
# (http://aws.amazon.com/about-aws/whats-new/2010/05/19/announcing-amazon-s3-reduced-redundancy-storage/)
|
14
|
+
# config.aws_reduced_redundancy = true
|
15
|
+
<%- elsif google? -%>
|
16
|
+
config.fog_provider = 'Google'
|
17
|
+
config.fog_directory = ENV['FOG_DIRECTORY']
|
18
|
+
config.google_storage_access_key_id = ENV['GOOGLE_STORAGE_ACCESS_KEY_ID']
|
19
|
+
config.google_storage_secret_access_key = ENV['GOOGLE_STORAGE_SECRET_ACCESS_KEY']
|
20
|
+
<%- elsif rackspace? -%>
|
21
|
+
config.fog_provider = 'Rackspace'
|
22
|
+
config.fog_directory = ENV['FOG_DIRECTORY']
|
23
|
+
config.rackspace_username = ENV['RACKSPACE_USERNAME']
|
24
|
+
config.rackspace_api_key = ENV['RACKSPACE_API_KEY']
|
25
|
+
# if you need to change rackspace_auth_url (e.g. if you need to use Rackspace London)
|
26
|
+
# config.rackspace_auth_url = "lon.auth.api.rackspacecloud.com"
|
27
|
+
<%- end -%>
|
28
|
+
#
|
29
|
+
# (String) This is a string file path which will be appended to the filename
|
30
|
+
# config.prefix = "<%= ENV['RAILS_ENV'] %>/tmp/"
|
31
|
+
# (Boolean) When true, the file publicly accessible. When false (default), a authenticated url will attempt to be generated
|
32
|
+
# config.public = true
|
33
|
+
# (Integer) The number of seconds the authenticated url will be valid (600 seconds = 10 minutes)
|
34
|
+
# config.expiry = 600
|
35
|
+
# (Boolean) When true, the clean up task (CloudTempfile.clear) will be able to run. Perfect for a cron clean up! ;)
|
36
|
+
# config.clean_up = true
|
37
|
+
# (Integer) The number of seconds the authenticated url will be valid (3600 seconds = 1 hour)
|
38
|
+
# config.clean_up_older_than = 3600
|
39
|
+
# (Boolean) Useful for environments such as Heroku
|
40
|
+
# config.fail_silently = true
|
41
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
# Enable or disable the CloudTempfile functionality (Default: true)
|
3
|
+
# enabled: true
|
4
|
+
<%- if aws? -%>
|
5
|
+
fog_provider: "AWS"
|
6
|
+
aws_access_key_id: "<%= aws_access_key_id %>"
|
7
|
+
aws_secret_access_key: "<%= aws_secret_access_key %>"
|
8
|
+
# The name of Amason S3 Bucket
|
9
|
+
fog_directory: "<%= fog_directory %>"
|
10
|
+
# You may need to specify what region your storage bucket is in. This may increase upload performance by configuring your region
|
11
|
+
# fog_region: "us-east-1"
|
12
|
+
# To use AWS reduced redundancy storage.
|
13
|
+
# (http://aws.amazon.com/about-aws/whats-new/2010/05/19/announcing-amazon-s3-reduced-redundancy-storage/)
|
14
|
+
# aws_reduced_redundancy: true
|
15
|
+
<%- elsif google? -%>
|
16
|
+
fog_provider: "Google"
|
17
|
+
fog_directory: "<%= fog_directory %>"
|
18
|
+
google_storage_access_key_id: "<%= google_storage_access_key_id %>"
|
19
|
+
google_storage_secret_access_key: "<%= google_storage_secret_access_key %>"
|
20
|
+
<%- elsif rackspace? -%>
|
21
|
+
fog_provider: "Rackspace"
|
22
|
+
fog_directory: "name_of_container"
|
23
|
+
rackspace_username: "<%= rackspace_username %>"
|
24
|
+
rackspace_api_key: "<%= rackspace_api_key %>"
|
25
|
+
# if you need to change rackspace_auth_url (e.g. if you need to use Rackspace London)
|
26
|
+
# rackspace_auth_url: "https://lon.identity.api.rackspacecloud.com/v2.0"
|
27
|
+
<%- end -%>
|
28
|
+
# (String) This is a string file path which will be appended to the filename
|
29
|
+
# prefix: "<%= ENV['RAILS_ENV'] %>/tmp/"
|
30
|
+
# (Boolean) When true, the file publicly accessible. When false (default), a authenticated url will attempt to be generated
|
31
|
+
# public: true
|
32
|
+
# (Integer) The number of seconds the authenticated url will be valid (600 seconds = 10 minutes)
|
33
|
+
# expiry: 600
|
34
|
+
# (Boolean) When true, the clean up task (CloudTempfile.clear) will be able to run. Perfect for a cron clean up! ;)
|
35
|
+
# clean_up: true
|
36
|
+
# (Integer) The number of seconds the authenticated url will be valid (3600 seconds = 1 hour)
|
37
|
+
# clean_up_older_than: 3600
|
38
|
+
# (Boolean) Useful for environments such as Heroku
|
39
|
+
# fail_silently: true
|
40
|
+
development:
|
41
|
+
<<: *defaults
|
42
|
+
enabled: false
|
43
|
+
|
44
|
+
test:
|
45
|
+
<<: *defaults
|
46
|
+
enabled: false
|
47
|
+
|
48
|
+
staging:
|
49
|
+
<<: *defaults
|
50
|
+
|
51
|
+
production:
|
52
|
+
<<: *defaults
|