carrierwave-pressplane 0.5.8.3

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 (36) hide show
  1. data/README.md +748 -0
  2. data/lib/carrierwave.rb +116 -0
  3. data/lib/carrierwave/compatibility/paperclip.rb +95 -0
  4. data/lib/carrierwave/locale/en.yml +9 -0
  5. data/lib/carrierwave/mount.rb +382 -0
  6. data/lib/carrierwave/orm/activerecord.rb +46 -0
  7. data/lib/carrierwave/processing/mime_types.rb +58 -0
  8. data/lib/carrierwave/processing/mini_magick.rb +252 -0
  9. data/lib/carrierwave/processing/rmagick.rb +279 -0
  10. data/lib/carrierwave/sanitized_file.rb +315 -0
  11. data/lib/carrierwave/storage/abstract.rb +30 -0
  12. data/lib/carrierwave/storage/cloud_files.rb +188 -0
  13. data/lib/carrierwave/storage/file.rb +56 -0
  14. data/lib/carrierwave/storage/fog.rb +333 -0
  15. data/lib/carrierwave/storage/right_s3.rb +1 -0
  16. data/lib/carrierwave/storage/s3.rb +240 -0
  17. data/lib/carrierwave/test/matchers.rb +241 -0
  18. data/lib/carrierwave/uploader.rb +44 -0
  19. data/lib/carrierwave/uploader/cache.rb +178 -0
  20. data/lib/carrierwave/uploader/callbacks.rb +35 -0
  21. data/lib/carrierwave/uploader/configuration.rb +168 -0
  22. data/lib/carrierwave/uploader/default_url.rb +19 -0
  23. data/lib/carrierwave/uploader/download.rb +75 -0
  24. data/lib/carrierwave/uploader/extension_whitelist.rb +49 -0
  25. data/lib/carrierwave/uploader/mountable.rb +39 -0
  26. data/lib/carrierwave/uploader/processing.rb +90 -0
  27. data/lib/carrierwave/uploader/proxy.rb +77 -0
  28. data/lib/carrierwave/uploader/remove.rb +23 -0
  29. data/lib/carrierwave/uploader/store.rb +113 -0
  30. data/lib/carrierwave/uploader/url.rb +47 -0
  31. data/lib/carrierwave/uploader/versions.rb +237 -0
  32. data/lib/carrierwave/validations/active_model.rb +64 -0
  33. data/lib/carrierwave/version.rb +3 -0
  34. data/lib/generators/templates/uploader.rb +48 -0
  35. data/lib/generators/uploader_generator.rb +7 -0
  36. metadata +215 -0
@@ -0,0 +1,241 @@
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
+
17
+ def matches?(actual)
18
+ @actual = actual
19
+ FileUtils.identical?(@actual, @expected)
20
+ end
21
+
22
+ def failure_message
23
+ "expected #{@actual.inspect} to be identical to #{@expected.inspect}"
24
+ end
25
+
26
+ def negative_failure_message
27
+ "expected #{@actual.inspect} to not be identical to #{@expected.inspect}"
28
+ end
29
+
30
+ def description
31
+ "be identical to #{@expected.inspect}"
32
+ end
33
+ end
34
+
35
+ def be_identical_to(expected)
36
+ BeIdenticalTo.new(expected)
37
+ end
38
+
39
+ class HavePermissions # :nodoc:
40
+ def initialize(expected)
41
+ @expected = expected
42
+ end
43
+
44
+ def matches?(actual)
45
+ @actual = actual
46
+ # Satisfy expectation here. Return false or raise an error if it's not met.
47
+ (File.stat(@actual.path).mode & 0777) == @expected
48
+ end
49
+
50
+ def failure_message
51
+ "expected #{@actual.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
52
+ end
53
+
54
+ def negative_failure_message
55
+ "expected #{@actual.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
56
+ end
57
+
58
+ def description
59
+ "have permissions #{@expected.to_s(8)}"
60
+ end
61
+ end
62
+
63
+ def have_permissions(expected)
64
+ HavePermissions.new(expected)
65
+ end
66
+
67
+ class BeNoLargerThan # :nodoc:
68
+ def initialize(width, height)
69
+ @width, @height = width, height
70
+ end
71
+
72
+ def matches?(actual)
73
+ @actual = actual
74
+ # Satisfy expectation here. Return false or raise an error if it's not met.
75
+ image = ImageLoader.load_image(@actual.current_path)
76
+ @actual_width = image.width
77
+ @actual_height = image.height
78
+ @actual_width <= @width && @actual_height <= @height
79
+ end
80
+
81
+ def failure_message
82
+ "expected #{@actual.current_path.inspect} to be no larger than #{@width} by #{@height}, but it was #{@actual_width} by #{@actual_height}."
83
+ end
84
+
85
+ def negative_failure_message
86
+ "expected #{@actual.current_path.inspect} to be larger than #{@width} by #{@height}, but it wasn't."
87
+ end
88
+
89
+ def description
90
+ "be no larger than #{@width} by #{@height}"
91
+ end
92
+ end
93
+
94
+ def be_no_larger_than(width, height)
95
+ BeNoLargerThan.new(width, height)
96
+ end
97
+
98
+ class HaveDimensions # :nodoc:
99
+ def initialize(width, height)
100
+ @width, @height = width, height
101
+ end
102
+
103
+ def matches?(actual)
104
+ @actual = actual
105
+ # Satisfy expectation here. Return false or raise an error if it's not met.
106
+ image = ImageLoader.load_image(@actual.current_path)
107
+ @actual_width = image.width
108
+ @actual_height = image.height
109
+ @actual_width == @width && @actual_height == @height
110
+ end
111
+
112
+ def failure_message
113
+ "expected #{@actual.current_path.inspect} to have an exact size of #{@width} by #{@height}, but it was #{@actual_width} by #{@actual_height}."
114
+ end
115
+
116
+ def negative_failure_message
117
+ "expected #{@actual.current_path.inspect} not to have an exact size of #{@width} by #{@height}, but it did."
118
+ end
119
+
120
+ def description
121
+ "have an exact size of #{@width} by #{@height}"
122
+ end
123
+ end
124
+
125
+ def have_dimensions(width, height)
126
+ HaveDimensions.new(width, height)
127
+ end
128
+
129
+ class BeNoWiderThan # :nodoc:
130
+ def initialize(width)
131
+ @width = width
132
+ end
133
+
134
+ def matches?(actual)
135
+ @actual = actual
136
+ # Satisfy expectation here. Return false or raise an error if it's not met.
137
+ image = ImageLoader.load_image(@actual.current_path)
138
+ @actual_width = image.width
139
+ @actual_width <= @width
140
+ end
141
+
142
+ def failure_message
143
+ "expected #{@actual.current_path.inspect} to be no wider than #{@width}, but it was #{@actual_width}."
144
+ end
145
+
146
+ def negative_failure_message
147
+ "expected #{@actual.current_path.inspect} not to be wider than #{@width}, but it is."
148
+ end
149
+
150
+ def description
151
+ "have a width less than or equal to #{@width}"
152
+ end
153
+ end
154
+
155
+ def be_no_wider_than(width)
156
+ BeNoWiderThan.new(width)
157
+ end
158
+
159
+ class BeNoTallerThan # :nodoc:
160
+ def initialize(height)
161
+ @height = height
162
+ end
163
+
164
+ def matches?(actual)
165
+ @actual = actual
166
+ # Satisfy expectation here. Return false or raise an error if it's not met.
167
+ image = ImageLoader.load_image(@actual.current_path)
168
+ @actual_height = image.height
169
+ @actual_height <= @height
170
+ end
171
+
172
+ def failure_message
173
+ "expected #{@actual.current_path.inspect} to be no taller than #{@height}, but it was #{@actual_height}."
174
+ end
175
+
176
+ def negative_failure_message
177
+ "expected #{@actual.current_path.inspect} not to be taller than #{@height}, but it is."
178
+ end
179
+
180
+ def description
181
+ "have a height less than or equal to #{@height}"
182
+ end
183
+ end
184
+
185
+ def be_no_height_than(height)
186
+ BeNoTallerThan.new(height)
187
+ end
188
+
189
+ class ImageLoader # :nodoc:
190
+ def self.load_image(filename)
191
+ if defined? ::MiniMagick
192
+ MiniMagickWrapper.new(filename)
193
+ else
194
+ unless defined? ::Magick
195
+ begin
196
+ require 'rmagick'
197
+ rescue LoadError
198
+ require 'RMagick'
199
+ rescue LoadError
200
+ puts "WARNING: Failed to require rmagick, image processing may fail!"
201
+ end
202
+ end
203
+ MagickWrapper.new(filename)
204
+ end
205
+ end
206
+ end
207
+
208
+ class MagickWrapper # :nodoc:
209
+ attr_reader :image
210
+ def width
211
+ image.columns
212
+ end
213
+
214
+ def height
215
+ image.rows
216
+ end
217
+
218
+ def initialize(filename)
219
+ @image = ::Magick::Image.read(filename).first
220
+ end
221
+ end
222
+
223
+ class MiniMagickWrapper # :nodoc:
224
+ attr_reader :image
225
+ def width
226
+ image[:width]
227
+ end
228
+
229
+ def height
230
+ image[:height]
231
+ end
232
+
233
+ def initialize(filename)
234
+ @image = ::MiniMagick::Image.open(filename)
235
+ end
236
+ end
237
+
238
+ end # Matchers
239
+ end # Test
240
+ end # CarrierWave
241
+
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+
5
+ ##
6
+ # See CarrierWave::Uploader::Base
7
+ #
8
+ module Uploader
9
+
10
+ ##
11
+ # An uploader is a class that allows you to easily handle the caching and storage of
12
+ # uploaded files. Please refer to the README for configuration options.
13
+ #
14
+ # Once you have an uploader you can use it in isolation:
15
+ #
16
+ # my_uploader = MyUploader.new
17
+ # my_uploader.cache!(File.open(path_to_file))
18
+ # my_uploader.retrieve_from_store!('monkey.png')
19
+ #
20
+ # Alternatively, you can mount it on an ORM or other persistence layer, with
21
+ # +CarrierWave::Mount#mount_uploader+. There are extensions for activerecord and datamapper
22
+ # these are *very* simple (they are only a dozen lines of code), so adding your own should
23
+ # be trivial.
24
+ #
25
+ class Base
26
+ attr_reader :file
27
+
28
+ include CarrierWave::Uploader::Callbacks
29
+ include CarrierWave::Uploader::Proxy
30
+ include CarrierWave::Uploader::Url
31
+ include CarrierWave::Uploader::Mountable
32
+ include CarrierWave::Uploader::Cache
33
+ include CarrierWave::Uploader::Store
34
+ include CarrierWave::Uploader::Download
35
+ include CarrierWave::Uploader::Remove
36
+ include CarrierWave::Uploader::ExtensionWhitelist
37
+ include CarrierWave::Uploader::Processing
38
+ include CarrierWave::Uploader::Versions
39
+ include CarrierWave::Uploader::DefaultUrl
40
+ include CarrierWave::Uploader::Configuration
41
+ end # Base
42
+
43
+ end # Uploader
44
+ end # CarrierWave
@@ -0,0 +1,178 @@
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
+ extend ActiveSupport::Concern
25
+
26
+ include CarrierWave::Uploader::Callbacks
27
+ include CarrierWave::Uploader::Configuration
28
+
29
+ module ClassMethods
30
+
31
+ ##
32
+ # Removes cached files which are older than one day. You could call this method
33
+ # from a rake task to clean out old cached files.
34
+ #
35
+ # You can call this method directly on the module like this:
36
+ #
37
+ # CarrierWave.clean_cached_files!
38
+ #
39
+ # === Note
40
+ #
41
+ # This only works as long as you haven't done anything funky with your cache_dir.
42
+ # It's recommended that you keep cache files in one place only.
43
+ #
44
+ def clean_cached_files!(seconds=60*60*24)
45
+ Dir.glob(File.expand_path(File.join(cache_dir, '*'), CarrierWave.root)).each do |dir|
46
+ time = dir.scan(/(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})/).first.map { |t| t.to_i }
47
+ time = Time.utc(*time)
48
+ if time < (Time.now.utc - seconds)
49
+ FileUtils.rm_rf(dir)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ ##
56
+ # Returns true if the uploader has been cached
57
+ #
58
+ # === Returns
59
+ #
60
+ # [Bool] whether the current file is cached
61
+ #
62
+ def cached?
63
+ @cache_id
64
+ end
65
+
66
+ ##
67
+ # Caches the remotely stored file
68
+ #
69
+ # This is useful when about to process images. Most processing solutions
70
+ # require the file to be stored on the local filesystem.
71
+ #
72
+ def cache_stored_file!
73
+ return if file.nil?
74
+
75
+ _content = file.read
76
+ if _content.is_a?(File) # could be if storage is Fog
77
+ sanitized = CarrierWave::Storage::Fog.new(self).retrieve!(File.basename(_content.path))
78
+ sanitized.read rescue ''
79
+
80
+ else
81
+ sanitized = SanitizedFile.new :tempfile => StringIO.new(file.read),
82
+ :filename => File.basename(path), :content_type => file.content_type
83
+ end
84
+
85
+ cache! sanitized
86
+ end
87
+
88
+ ##
89
+ # Returns a String which uniquely identifies the currently cached file for later retrieval
90
+ #
91
+ # === Returns
92
+ #
93
+ # [String] a cache name, in the format YYYYMMDD-HHMM-PID-RND/filename.txt
94
+ #
95
+ def cache_name
96
+ File.join(cache_id, full_original_filename) if cache_id and original_filename
97
+ end
98
+
99
+ ##
100
+ # Caches the given file. Calls process! to trigger any process callbacks.
101
+ #
102
+ # By default, cache!() uses copy_to(), which operates by copying the file
103
+ # to the cache, then deleting the original file. If move_to_cache() is
104
+ # overriden to return true, then cache!() uses move_to(), which simply
105
+ # moves the file to the cache. Useful for large files.
106
+ #
107
+ # === Parameters
108
+ #
109
+ # [new_file (File, IOString, Tempfile)] any kind of file object
110
+ #
111
+ # === Raises
112
+ #
113
+ # [CarrierWave::FormNotMultipart] if the assigned parameter is a string
114
+ #
115
+ def cache!(new_file)
116
+ new_file = CarrierWave::SanitizedFile.new(new_file)
117
+
118
+ unless new_file.empty?
119
+ raise CarrierWave::FormNotMultipart if new_file.is_path? && ensure_multipart_form
120
+
121
+ with_callbacks(:cache, new_file) do
122
+ self.cache_id = CarrierWave.generate_cache_id unless cache_id
123
+
124
+ @filename = new_file.filename
125
+ self.original_filename = new_file.filename
126
+
127
+ if move_to_cache
128
+ @file = new_file.move_to(cache_path, permissions)
129
+ else
130
+ @file = new_file.copy_to(cache_path, permissions)
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ ##
137
+ # Retrieves the file with the given cache_name from the cache.
138
+ #
139
+ # === Parameters
140
+ #
141
+ # [cache_name (String)] uniquely identifies a cache file
142
+ #
143
+ # === Raises
144
+ #
145
+ # [CarrierWave::InvalidParameter] if the cache_name is incorrectly formatted.
146
+ #
147
+ def retrieve_from_cache!(cache_name)
148
+ with_callbacks(:retrieve_from_cache, cache_name) do
149
+ self.cache_id, self.original_filename = cache_name.to_s.split('/', 2)
150
+ @filename = original_filename
151
+ @file = CarrierWave::SanitizedFile.new(cache_path)
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ def cache_path
158
+ File.expand_path(File.join(cache_dir, cache_name), root)
159
+ end
160
+
161
+ attr_reader :cache_id, :original_filename
162
+
163
+ # We can override the full_original_filename method in other modules
164
+ alias_method :full_original_filename, :original_filename
165
+
166
+ def cache_id=(cache_id)
167
+ raise CarrierWave::InvalidParameter, "invalid cache id" unless cache_id =~ /\A[\d]{8}\-[\d]{4}\-[\d]+\-[\d]{4}\z/
168
+ @cache_id = cache_id
169
+ end
170
+
171
+ def original_filename=(filename)
172
+ raise CarrierWave::InvalidParameter, "invalid filename" if filename =~ CarrierWave::SanitizedFile.sanitize_regexp
173
+ @original_filename = filename
174
+ end
175
+
176
+ end # Cache
177
+ end # Uploader
178
+ end # CarrierWave