dsturnbull-carrierwave 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/Generators +4 -0
  2. data/History.txt +118 -0
  3. data/Manifest.txt +107 -0
  4. data/README.rdoc +502 -0
  5. data/Rakefile +38 -0
  6. data/cucumber.yml +2 -0
  7. data/features/caching.feature +28 -0
  8. data/features/download.feature +20 -0
  9. data/features/file_storage.feature +37 -0
  10. data/features/file_storage_overridden_filename.feature +38 -0
  11. data/features/file_storage_overridden_store_dir.feature +38 -0
  12. data/features/file_storage_reversing_processor.feature +43 -0
  13. data/features/fixtures/bork.txt +1 -0
  14. data/features/fixtures/monkey.txt +1 -0
  15. data/features/grid_fs_storage.feature +32 -0
  16. data/features/mount_activerecord.feature +46 -0
  17. data/features/mount_datamapper.feature +46 -0
  18. data/features/step_definitions/activerecord_steps.rb +22 -0
  19. data/features/step_definitions/caching_steps.rb +14 -0
  20. data/features/step_definitions/datamapper_steps.rb +29 -0
  21. data/features/step_definitions/download_steps.rb +4 -0
  22. data/features/step_definitions/file_steps.rb +53 -0
  23. data/features/step_definitions/general_steps.rb +85 -0
  24. data/features/step_definitions/mount_steps.rb +19 -0
  25. data/features/step_definitions/store_steps.rb +18 -0
  26. data/features/support/activerecord.rb +30 -0
  27. data/features/support/datamapper.rb +7 -0
  28. data/features/support/env.rb +22 -0
  29. data/features/versions_basics.feature +50 -0
  30. data/features/versions_nested_versions.feature +70 -0
  31. data/features/versions_overridden_filename.feature +51 -0
  32. data/features/versions_overriden_store_dir.feature +41 -0
  33. data/lib/carrierwave/compatibility/paperclip.rb +95 -0
  34. data/lib/carrierwave/core_ext/blank.rb +46 -0
  35. data/lib/carrierwave/core_ext/inheritable_attributes.rb +104 -0
  36. data/lib/carrierwave/core_ext/module_setup.rb +51 -0
  37. data/lib/carrierwave/mount.rb +359 -0
  38. data/lib/carrierwave/orm/activerecord.rb +73 -0
  39. data/lib/carrierwave/orm/datamapper.rb +27 -0
  40. data/lib/carrierwave/orm/mongoid.rb +23 -0
  41. data/lib/carrierwave/orm/mongomapper.rb +27 -0
  42. data/lib/carrierwave/orm/sequel.rb +45 -0
  43. data/lib/carrierwave/processing/image_science.rb +101 -0
  44. data/lib/carrierwave/processing/mini_magick.rb +269 -0
  45. data/lib/carrierwave/processing/rmagick.rb +282 -0
  46. data/lib/carrierwave/sanitized_file.rb +268 -0
  47. data/lib/carrierwave/storage/abstract.rb +30 -0
  48. data/lib/carrierwave/storage/file.rb +48 -0
  49. data/lib/carrierwave/storage/grid_fs.rb +96 -0
  50. data/lib/carrierwave/storage/right_s3.rb +170 -0
  51. data/lib/carrierwave/storage/s3.rb +199 -0
  52. data/lib/carrierwave/test/matchers.rb +128 -0
  53. data/lib/carrierwave/uploader/cache.rb +145 -0
  54. data/lib/carrierwave/uploader/callbacks.rb +42 -0
  55. data/lib/carrierwave/uploader/configuration.rb +122 -0
  56. data/lib/carrierwave/uploader/default_url.rb +19 -0
  57. data/lib/carrierwave/uploader/download.rb +59 -0
  58. data/lib/carrierwave/uploader/extension_whitelist.rb +37 -0
  59. data/lib/carrierwave/uploader/mountable.rb +39 -0
  60. data/lib/carrierwave/uploader/processing.rb +83 -0
  61. data/lib/carrierwave/uploader/proxy.rb +62 -0
  62. data/lib/carrierwave/uploader/remove.rb +22 -0
  63. data/lib/carrierwave/uploader/store.rb +89 -0
  64. data/lib/carrierwave/uploader/url.rb +24 -0
  65. data/lib/carrierwave/uploader/versions.rb +146 -0
  66. data/lib/carrierwave/uploader.rb +44 -0
  67. data/lib/carrierwave.rb +96 -0
  68. data/merb_generators/uploader_generator.rb +22 -0
  69. data/rails_generators/uploader/USAGE +2 -0
  70. data/rails_generators/uploader/templates/uploader.rb +47 -0
  71. data/rails_generators/uploader/uploader_generator.rb +21 -0
  72. data/script/console +10 -0
  73. data/script/destroy +14 -0
  74. data/script/generate +14 -0
  75. data/spec/compatibility/paperclip_spec.rb +52 -0
  76. data/spec/fixtures/bork.txt +1 -0
  77. data/spec/fixtures/landscape.jpg +0 -0
  78. data/spec/fixtures/portrait.jpg +0 -0
  79. data/spec/fixtures/test.jpeg +1 -0
  80. data/spec/fixtures/test.jpg +1 -0
  81. data/spec/mount_spec.rb +538 -0
  82. data/spec/orm/activerecord_spec.rb +271 -0
  83. data/spec/orm/datamapper_spec.rb +168 -0
  84. data/spec/orm/mongoid_spec.rb +206 -0
  85. data/spec/orm/mongomapper_spec.rb +202 -0
  86. data/spec/orm/sequel_spec.rb +183 -0
  87. data/spec/processing/image_science_spec.rb +56 -0
  88. data/spec/processing/mini_magick_spec.rb +76 -0
  89. data/spec/processing/rmagick_spec.rb +75 -0
  90. data/spec/sanitized_file_spec.rb +601 -0
  91. data/spec/spec_helper.rb +99 -0
  92. data/spec/storage/grid_fs_spec.rb +82 -0
  93. data/spec/storage/right_s3_spec.rb +75 -0
  94. data/spec/storage/s3_spec.rb +95 -0
  95. data/spec/uploader/cache_spec.rb +209 -0
  96. data/spec/uploader/configuration_spec.rb +105 -0
  97. data/spec/uploader/default_url_spec.rb +85 -0
  98. data/spec/uploader/download_spec.rb +75 -0
  99. data/spec/uploader/extension_whitelist_spec.rb +44 -0
  100. data/spec/uploader/mountable_spec.rb +33 -0
  101. data/spec/uploader/paths_spec.rb +22 -0
  102. data/spec/uploader/processing_spec.rb +73 -0
  103. data/spec/uploader/proxy_spec.rb +54 -0
  104. data/spec/uploader/remove_spec.rb +70 -0
  105. data/spec/uploader/store_spec.rb +248 -0
  106. data/spec/uploader/url_spec.rb +87 -0
  107. data/spec/uploader/versions_spec.rb +298 -0
  108. metadata +351 -0
@@ -0,0 +1,199 @@
1
+ # encoding: utf-8
2
+ require 'aws/s3'
3
+
4
+ module CarrierWave
5
+ module Storage
6
+
7
+ ##
8
+ # Uploads things to Amazon S3 webservices. It requies the aws/s3 gem. In order for
9
+ # CarrierWave to connect to Amazon S3, you'll need to specify an access key id, secret key
10
+ # and bucket:
11
+ #
12
+ # CarrierWave.configure do |config|
13
+ # config.s3_access_key_id = "xxxxxx"
14
+ # config.s3_secret_access_key = "xxxxxx"
15
+ # config.s3_bucket = "my_bucket_name"
16
+ # end
17
+ #
18
+ # You can also set the access policy for the uploaded files:
19
+ #
20
+ # CarrierWave.configure do |config|
21
+ # config.s3_access = :public
22
+ # end
23
+ #
24
+ # Possible values are the 'canned access control policies' provided in the aws/s3 gem,
25
+ # they are:
26
+ #
27
+ # [:private] No one else has any access rights.
28
+ # [:public_read] The anonymous principal is granted READ access.
29
+ # If this policy is used on an object, it can be read from a
30
+ # browser with no authentication.
31
+ # [:public_read_write] The anonymous principal is granted READ and WRITE access.
32
+ # [:authenticated_read] Any principal authenticated as a registered Amazon S3 user
33
+ # is granted READ access.
34
+ #
35
+ # The default is :public_read, it should work in most cases.
36
+ #
37
+ # You can assign HTTP headers to be used when S3 serves your files:
38
+ #
39
+ # CarrierWave.configure do |config|
40
+ # config.s3_headers = {"Content-Disposition" => "attachment; filename=foo.jpg;"}
41
+ # end
42
+ #
43
+ # You can also set the headers dynamically by overriding the s3_headers method:
44
+ #
45
+ # class MyUploader < CarrierWave::Uploader::Base
46
+ # def s3_headers
47
+ # { "Expires" => 1.year.from_how.httpdate }
48
+ # end
49
+ # end
50
+ #
51
+ # You can change the generated url to a cnamed domain by setting the cnamed config:
52
+ #
53
+ # CarrierWave.configure do |config|
54
+ # config.s3_cnamed = true
55
+ # config.s3_bucket = 'bucketname.domain.tld'
56
+ # end
57
+ #
58
+ # Now the resulting url will be
59
+ #
60
+ # http://bucketname.domain.tld/path/to/file
61
+ #
62
+ # instead of
63
+ #
64
+ # http://s3.amazonaws.com/bucketname.domain.tld/path/to/file
65
+ #
66
+ class S3 < Abstract
67
+
68
+ class File
69
+
70
+ def initialize(uploader, path)
71
+ @uploader = uploader
72
+ @path = path
73
+ end
74
+
75
+ ##
76
+ # Returns the current path of the file on S3
77
+ #
78
+ # === Returns
79
+ #
80
+ # [String] A path
81
+ #
82
+ def path
83
+ @path
84
+ end
85
+
86
+ ##
87
+ # Reads the contents of the file from S3
88
+ #
89
+ # === Returns
90
+ #
91
+ # [String] contents of the file
92
+ #
93
+ def read
94
+ AWS::S3::S3Object.value @path, @uploader.s3_bucket
95
+ end
96
+
97
+ ##
98
+ # Remove the file from Amazon S3
99
+ #
100
+ def delete
101
+ AWS::S3::S3Object.delete @path, @uploader.s3_bucket
102
+ end
103
+
104
+ ##
105
+ # Returns the url on Amazon's S3 service
106
+ #
107
+ # === Returns
108
+ #
109
+ # [String] file's url
110
+ #
111
+ def url
112
+ if @uploader.s3_cnamed
113
+ ["http://", @uploader.s3_bucket, "/", @path].compact.join
114
+ else
115
+ ["http://s3.amazonaws.com", @uploader.s3_bucket, @path].compact.join('/')
116
+ end
117
+ end
118
+
119
+ def about
120
+ s3_object.about
121
+ end
122
+
123
+ def metadata
124
+ s3_object.metadata
125
+ end
126
+
127
+ def content_type
128
+ s3_object.content_type
129
+ end
130
+
131
+ def content_type=(new_content_type)
132
+ s3_object.content_type = new_content_type
133
+ end
134
+
135
+ def content_disposition
136
+ s3_object.content_disposition
137
+ end
138
+
139
+ def content_disposition=(new_disposition)
140
+ s3_object.content_disposition = new_disposition
141
+ end
142
+
143
+ def store
144
+ s3_object.store
145
+ end
146
+
147
+ def s3_object
148
+ @s3_object ||= AWS::S3::S3Object.find(@path, @uploader.s3_bucket)
149
+ end
150
+
151
+ end
152
+
153
+ ##
154
+ # Store the file on S3
155
+ #
156
+ # === Parameters
157
+ #
158
+ # [file (CarrierWave::Storage::S3::File)] the file to store
159
+ #
160
+ # === Returns
161
+ #
162
+ # [CarrierWave::Storage::S3] the stored file
163
+ #
164
+ def store!(file)
165
+ connect!(uploader)
166
+ s3_options = {:access => uploader.s3_access, :content_type => file.content_type}
167
+ s3_options.merge!(uploader.s3_headers)
168
+ AWS::S3::S3Object.store(uploader.store_path, file.read, uploader.s3_bucket, s3_options)
169
+ CarrierWave::Storage::S3::File.new(uploader, uploader.store_path)
170
+ end
171
+
172
+ # Do something to retrieve the file
173
+ #
174
+ # @param [CarrierWave::Uploader] uploader an uploader object
175
+ # @param [String] identifier uniquely identifies the file
176
+ #
177
+ # [identifier (String)] uniquely identifies the file
178
+ #
179
+ # === Returns
180
+ #
181
+ # [CarrierWave::Storage::S3::File] the stored file
182
+ #
183
+ def retrieve!(identifier)
184
+ connect!(uploader)
185
+ CarrierWave::Storage::S3::File.new(uploader, uploader.store_path(identifier))
186
+ end
187
+
188
+ private
189
+
190
+ def connect!(uploader)
191
+ AWS::S3::Base.establish_connection!(
192
+ :access_key_id => uploader.s3_access_key_id,
193
+ :secret_access_key => uploader.s3_secret_access_key
194
+ )
195
+ end
196
+
197
+ end # S3
198
+ end # Storage
199
+ end # CarrierWave
@@ -0,0 +1,128 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+ module Test
5
+
6
+ ##
7
+ # These are some matchers that can be used in RSpec specs, to simplify the testing
8
+ # of uploaders.
9
+ #
10
+ module Matchers
11
+
12
+ class BeIdenticalTo # :nodoc:
13
+ def initialize(expected)
14
+ @expected = expected
15
+ end
16
+ def matches?(actual)
17
+ @actual = actual
18
+ FileUtils.identical?(@actual, @expected)
19
+ end
20
+ def failure_message
21
+ "expected #{@actual.inspect} to be identical to #{@expected.inspect}"
22
+ end
23
+ def negative_failure_message
24
+ "expected #{@actual.inspect} to not be identical to #{@expected.inspect}"
25
+ end
26
+ end
27
+
28
+ def be_identical_to(expected)
29
+ BeIdenticalTo.new(expected)
30
+ end
31
+
32
+ class HavePermissions # :nodoc:
33
+ def initialize(expected)
34
+ @expected = expected
35
+ end
36
+
37
+ def matches?(actual)
38
+ @actual = actual
39
+ # Satisfy expectation here. Return false or raise an error if it's not met.
40
+ (File.stat(@actual.path).mode & 0777) == @expected
41
+ end
42
+
43
+ def failure_message
44
+ "expected #{@actual.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
45
+ end
46
+
47
+ def negative_failure_message
48
+ "expected #{@actual.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
49
+ end
50
+ end
51
+
52
+ def have_permissions(expected)
53
+ HavePermissions.new(expected)
54
+ end
55
+
56
+ class BeNoLargerThan # :nodoc:
57
+ def initialize(width, height)
58
+ @width, @height = width, height
59
+ end
60
+
61
+ def matches?(actual)
62
+ @actual = actual
63
+ # Satisfy expectation here. Return false or raise an error if it's not met.
64
+ img = ::Magick::Image.read(@actual.current_path).first
65
+ @actual_width = img.columns
66
+ @actual_height = img.rows
67
+ @actual_width <= @width && @actual_height <= @height
68
+ end
69
+
70
+ def failure_message
71
+ "expected #{@actual.current_path.inspect} to be no larger than #{@width} by #{@height}, but it was #{@actual_width} by #{@actual_height}."
72
+ end
73
+
74
+ def negative_failure_message
75
+ "expected #{@actual.current_path.inspect} to be larger than #{@width} by #{@height}, but it wasn't."
76
+ end
77
+ end
78
+
79
+ def be_no_larger_than(width, height)
80
+ load_rmagick
81
+ BeNoLargerThan.new(width, height)
82
+ end
83
+
84
+ class HaveDimensions # :nodoc:
85
+ def initialize(width, height)
86
+ @width, @height = width, height
87
+ end
88
+
89
+ def matches?(actual)
90
+ @actual = actual
91
+ # Satisfy expectation here. Return false or raise an error if it's not met.
92
+ img = ::Magick::Image.read(@actual.current_path).first
93
+ @actual_width = img.columns
94
+ @actual_height = img.rows
95
+ @actual_width == @width && @actual_height == @height
96
+ end
97
+
98
+ def failure_message
99
+ "expected #{@actual.current_path.inspect} to have an exact size of #{@width} by #{@height}, but it was #{@actual_width} by #{@actual_height}."
100
+ end
101
+
102
+ def negative_failure_message
103
+ "expected #{@actual.current_path.inspect} not to have an exact size of #{@width} by #{@height}, but it did."
104
+ end
105
+ end
106
+
107
+ def have_dimensions(width, height)
108
+ load_rmagick
109
+ HaveDimensions.new(width, height)
110
+ end
111
+
112
+ private
113
+
114
+ def load_rmagick
115
+ unless defined? Magick
116
+ begin
117
+ require 'rmagick'
118
+ rescue LoadError
119
+ require 'RMagick'
120
+ rescue LoadError
121
+ puts "WARNING: Failed to require rmagick, image processing may fail!"
122
+ end
123
+ end
124
+ end
125
+
126
+ end # SpecHelper
127
+ end # Test
128
+ end # CarrierWave
@@ -0,0 +1,145 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+
5
+ class FormNotMultipart < UploadError
6
+ def message
7
+ "You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed.\n\n If this is a file upload, please check that your upload form is multipart encoded."
8
+ end
9
+ end
10
+
11
+ ##
12
+ # Generates a unique cache id for use in the caching system
13
+ #
14
+ # === Returns
15
+ #
16
+ # [String] a cache id in the format YYYYMMDD-HHMM-PID-RND
17
+ #
18
+ def self.generate_cache_id
19
+ Time.now.strftime('%Y%m%d-%H%M') + '-' + Process.pid.to_s + '-' + ("%04d" % rand(9999))
20
+ end
21
+
22
+ module Uploader
23
+ module Cache
24
+
25
+ depends_on CarrierWave::Uploader::Callbacks
26
+ depends_on CarrierWave::Uploader::Configuration
27
+
28
+ module ClassMethods
29
+
30
+ ##
31
+ # Removes cached files which are older than one day. You could call this method
32
+ # from a rake task to clean out old cached files.
33
+ #
34
+ # You can call this method directly on the module like this:
35
+ #
36
+ # CarrierWave.clean_cached_files!
37
+ #
38
+ # === Note
39
+ #
40
+ # This only works as long as you haven't done anything funky with your cache_dir.
41
+ # It's recommended that you keen cache files in one place only.
42
+ #
43
+ def clean_cached_files!
44
+ Dir.glob(File.expand_path(File.join(cache_dir, '*'), CarrierWave.root)).each do |dir|
45
+ time = dir.scan(/(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})/).first.map { |t| t.to_i }
46
+ time = Time.utc(*time)
47
+ if time < (Time.now - (60*60*24))
48
+ FileUtils.rm_rf(dir)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ ##
55
+ # Returns true if the uploader has been cached
56
+ #
57
+ # === Returns
58
+ #
59
+ # [Bool] whether the current file is cached
60
+ #
61
+ def cached?
62
+ @cache_id
63
+ end
64
+
65
+ ##
66
+ # Returns a String which uniquely identifies the currently cached file for later retrieval
67
+ #
68
+ # === Returns
69
+ #
70
+ # [String] a cache name, in the format YYYYMMDD-HHMM-PID-RND/filename.txt
71
+ #
72
+ def cache_name
73
+ File.join(cache_id, full_original_filename) if cache_id and original_filename
74
+ end
75
+
76
+ ##
77
+ # Caches the given file. Calls process! to trigger any process callbacks.
78
+ #
79
+ # === Parameters
80
+ #
81
+ # [new_file (File, IOString, Tempfile)] any kind of file object
82
+ #
83
+ # === Raises
84
+ #
85
+ # [CarrierWave::FormNotMultipart] if the assigned parameter is a string
86
+ #
87
+ def cache!(new_file)
88
+ new_file = CarrierWave::SanitizedFile.new(new_file)
89
+ raise CarrierWave::FormNotMultipart if new_file.is_path?
90
+
91
+ unless new_file.empty?
92
+ with_callbacks(:cache, new_file) do
93
+ self.cache_id = CarrierWave.generate_cache_id unless cache_id
94
+
95
+ @filename = new_file.filename
96
+ self.original_filename = new_file.filename
97
+
98
+ @file = new_file.copy_to(cache_path, permissions)
99
+ end
100
+ end
101
+ end
102
+
103
+ ##
104
+ # Retrieves the file with the given cache_name from the cache.
105
+ #
106
+ # === Parameters
107
+ #
108
+ # [cache_name (String)] uniquely identifies a cache file
109
+ #
110
+ # === Raises
111
+ #
112
+ # [CarrierWave::InvalidParameter] if the cache_name is incorrectly formatted.
113
+ #
114
+ def retrieve_from_cache!(cache_name)
115
+ with_callbacks(:retrieve_from_cache, cache_name) do
116
+ self.cache_id, self.original_filename = cache_name.to_s.split('/', 2)
117
+ @filename = original_filename
118
+ @file = CarrierWave::SanitizedFile.new(cache_path)
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ def cache_path
125
+ File.expand_path(File.join(cache_dir, cache_name), root)
126
+ end
127
+
128
+ attr_reader :cache_id, :original_filename
129
+
130
+ # We can override the full_original_filename method in other modules
131
+ alias_method :full_original_filename, :original_filename
132
+
133
+ def cache_id=(cache_id)
134
+ raise CarrierWave::InvalidParameter, "invalid cache id" unless cache_id =~ /\A[\d]{8}\-[\d]{4}\-[\d]+\-[\d]{4}\z/
135
+ @cache_id = cache_id
136
+ end
137
+
138
+ def original_filename=(filename)
139
+ raise CarrierWave::InvalidParameter, "invalid filename" unless filename =~ /\A[a-z0-9\.\-\+_]+\z/i
140
+ @original_filename = filename
141
+ end
142
+
143
+ end # Cache
144
+ end # Uploader
145
+ end # CarrierWave
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+ module Uploader
5
+ module Callbacks
6
+
7
+ setup do
8
+ extlib_inheritable_accessor :_before_callbacks, :_after_callbacks
9
+ end
10
+
11
+ def with_callbacks(kind, *args)
12
+ self.class._before_callbacks_for(kind).each { |callback| self.send(callback, *args) }
13
+ yield
14
+ self.class._after_callbacks_for(kind).each { |callback| self.send(callback, *args) }
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ def _before_callbacks_for(kind) #:nodoc:
20
+ self._before_callbacks ||= {}
21
+ self._before_callbacks[kind] ||= []
22
+ self._before_callbacks[kind]
23
+ end
24
+
25
+ def _after_callbacks_for(kind) #:nodoc:
26
+ self._after_callbacks ||= {}
27
+ self._after_callbacks[kind] ||= []
28
+ self._after_callbacks[kind]
29
+ end
30
+
31
+ def before(kind, callback)
32
+ _before_callbacks_for(kind) << callback
33
+ end
34
+
35
+ def after(kind, callback)
36
+ _after_callbacks_for(kind) << callback
37
+ end
38
+ end # ClassMethods
39
+
40
+ end # Callbacks
41
+ end # Uploader
42
+ end # CarrierWave
@@ -0,0 +1,122 @@
1
+ module CarrierWave
2
+
3
+ module Uploader
4
+ module Configuration
5
+ setup do
6
+ add_config :root
7
+ add_config :permissions
8
+ add_config :storage_engines
9
+ add_config :s3_access # for aws/s3
10
+ add_config :s3_access_policy # for right_aws
11
+ add_config :s3_bucket
12
+ add_config :s3_access_key_id
13
+ add_config :s3_secret_access_key
14
+ add_config :s3_cnamed
15
+ add_config :grid_fs_database
16
+ add_config :grid_fs_host
17
+ add_config :grid_fs_username
18
+ add_config :grid_fs_password
19
+ add_config :grid_fs_access_url
20
+ add_config :store_dir
21
+ add_config :cache_dir
22
+ add_config :enable_processing
23
+
24
+ # Mounting
25
+ add_config :ignore_integrity_errors
26
+ add_config :ignore_processing_errors
27
+ add_config :validate_integrity
28
+ add_config :validate_processing
29
+ add_config :mount_on
30
+
31
+ configure do |config|
32
+ config.permissions = 0644
33
+ config.storage_engines = {
34
+ :file => "CarrierWave::Storage::File",
35
+ :s3 => "CarrierWave::Storage::S3",
36
+ :grid_fs => "CarrierWave::Storage::GridFS",
37
+ :right_s3 => "CarrierWave::Storage::RightS3"
38
+ }
39
+ config.storage = :file
40
+ config.s3_access = :public_read
41
+ config.s3_access_policy = 'public-read'
42
+ config.grid_fs_database = 'carrierwave'
43
+ config.grid_fs_host = 'localhost'
44
+ config.store_dir = 'uploads'
45
+ config.cache_dir = 'uploads/tmp'
46
+ config.ignore_integrity_errors = true
47
+ config.ignore_processing_errors = true
48
+ config.validate_integrity = true
49
+ config.validate_processing = true
50
+ config.root = CarrierWave.root
51
+ config.enable_processing = true
52
+ end
53
+ end
54
+
55
+ module ClassMethods
56
+
57
+ ##
58
+ # Sets the storage engine to be used when storing files with this uploader.
59
+ # Can be any class that implements a #store!(CarrierWave::SanitizedFile) and a #retrieve!
60
+ # method. See lib/carrierwave/storage/file.rb for an example. Storage engines should
61
+ # be added to CarrierWave::Uploader::Base.storage_engines so they can be referred
62
+ # to by a symbol, which should be more convenient
63
+ #
64
+ # If no argument is given, it will simply return the currently used storage engine.
65
+ #
66
+ # === Parameters
67
+ #
68
+ # [storage (Symbol, Class)] The storage engine to use for this uploader
69
+ #
70
+ # === Returns
71
+ #
72
+ # [Class] the storage engine to be used with this uploader
73
+ #
74
+ # === Examples
75
+ #
76
+ # storage :file
77
+ # storage CarrierWave::Storage::File
78
+ # storage MyCustomStorageEngine
79
+ #
80
+ def storage(storage = nil)
81
+ if storage.is_a?(Symbol)
82
+ @storage = eval(storage_engines[storage])
83
+ elsif storage
84
+ @storage = storage
85
+ elsif @storage.nil?
86
+ # Get the storage from the superclass if there is one
87
+ @storage = superclass.storage rescue nil
88
+ end
89
+ return @storage
90
+ end
91
+ alias_method :storage=, :storage
92
+
93
+
94
+ def add_config(name)
95
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
96
+ def self.#{name}(value=nil)
97
+ @#{name} = value if value
98
+ return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
99
+ name = superclass.#{name}
100
+ return nil if name.nil? && !instance_variable_defined?("@#{name}")
101
+ @#{name} = name && !name.is_a?(Module) && !name.is_a?(Symbol) && !name.is_a?(Numeric) && !name.is_a?(TrueClass) && !name.is_a?(FalseClass) ? name.dup : name
102
+ end
103
+
104
+ def self.#{name}=(value)
105
+ @#{name} = value
106
+ end
107
+
108
+ def #{name}
109
+ self.class.#{name}
110
+ end
111
+ RUBY
112
+ end
113
+
114
+ def configure
115
+ yield self
116
+ end
117
+ end
118
+
119
+ end
120
+ end
121
+ end
122
+
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+ module Uploader
5
+ module DefaultUrl
6
+
7
+ def url(*args)
8
+ super || default_url
9
+ end
10
+
11
+ ##
12
+ # Override this method in your uploader to provide a default url
13
+ # in case no file has been cached/stored yet.
14
+ #
15
+ def default_url; end
16
+
17
+ end # DefaultPath
18
+ end # Uploader
19
+ end # CarrierWave