salebot_uploader 1.0.0

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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +0 -0
  3. data/lib/generators/templates/uploader.rb.erb +9 -0
  4. data/lib/generators/uploader_generator.rb +7 -0
  5. data/lib/salebot_uploader/compatibility/paperclip.rb +104 -0
  6. data/lib/salebot_uploader/downloader/base.rb +101 -0
  7. data/lib/salebot_uploader/downloader/remote_file.rb +68 -0
  8. data/lib/salebot_uploader/error.rb +8 -0
  9. data/lib/salebot_uploader/locale/en.yml +17 -0
  10. data/lib/salebot_uploader/mount.rb +446 -0
  11. data/lib/salebot_uploader/mounter.rb +255 -0
  12. data/lib/salebot_uploader/orm/activerecord.rb +68 -0
  13. data/lib/salebot_uploader/processing/mini_magick.rb +194 -0
  14. data/lib/salebot_uploader/processing/rmagick.rb +402 -0
  15. data/lib/salebot_uploader/processing/vips.rb +284 -0
  16. data/lib/salebot_uploader/processing.rb +3 -0
  17. data/lib/salebot_uploader/sanitized_file.rb +357 -0
  18. data/lib/salebot_uploader/storage/abstract.rb +41 -0
  19. data/lib/salebot_uploader/storage/file.rb +124 -0
  20. data/lib/salebot_uploader/storage/fog.rb +547 -0
  21. data/lib/salebot_uploader/storage.rb +3 -0
  22. data/lib/salebot_uploader/test/matchers.rb +398 -0
  23. data/lib/salebot_uploader/uploader/cache.rb +223 -0
  24. data/lib/salebot_uploader/uploader/callbacks.rb +33 -0
  25. data/lib/salebot_uploader/uploader/configuration.rb +184 -0
  26. data/lib/salebot_uploader/uploader/content_type_allowlist.rb +61 -0
  27. data/lib/salebot_uploader/uploader/content_type_denylist.rb +62 -0
  28. data/lib/salebot_uploader/uploader/default_url.rb +17 -0
  29. data/lib/salebot_uploader/uploader/dimension.rb +66 -0
  30. data/lib/salebot_uploader/uploader/download.rb +24 -0
  31. data/lib/salebot_uploader/uploader/extension_allowlist.rb +63 -0
  32. data/lib/salebot_uploader/uploader/extension_denylist.rb +64 -0
  33. data/lib/salebot_uploader/uploader/file_size.rb +43 -0
  34. data/lib/salebot_uploader/uploader/mountable.rb +44 -0
  35. data/lib/salebot_uploader/uploader/processing.rb +125 -0
  36. data/lib/salebot_uploader/uploader/proxy.rb +99 -0
  37. data/lib/salebot_uploader/uploader/remove.rb +21 -0
  38. data/lib/salebot_uploader/uploader/serialization.rb +28 -0
  39. data/lib/salebot_uploader/uploader/store.rb +142 -0
  40. data/lib/salebot_uploader/uploader/url.rb +44 -0
  41. data/lib/salebot_uploader/uploader/versions.rb +350 -0
  42. data/lib/salebot_uploader/uploader.rb +53 -0
  43. data/lib/salebot_uploader/utilities/file_name.rb +47 -0
  44. data/lib/salebot_uploader/utilities/uri.rb +26 -0
  45. data/lib/salebot_uploader/utilities.rb +7 -0
  46. data/lib/salebot_uploader/validations/active_model.rb +76 -0
  47. data/lib/salebot_uploader/version.rb +3 -0
  48. data/lib/salebot_uploader.rb +62 -0
  49. metadata +392 -0
@@ -0,0 +1,184 @@
1
+ require 'salebot_uploader/downloader/base'
2
+
3
+ module SalebotUploader
4
+
5
+ module Uploader
6
+ module Configuration
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ class_attribute :_storage, :_cache_storage, :instance_writer => false
11
+
12
+ add_config :root
13
+ add_config :base_path
14
+ add_config :asset_host
15
+ add_config :permissions
16
+ add_config :directory_permissions
17
+ add_config :storage_engines
18
+ add_config :store_dir
19
+ add_config :cache_dir
20
+ add_config :enable_processing
21
+ add_config :ensure_multipart_form
22
+ add_config :delete_tmp_file_after_storage
23
+ add_config :move_to_cache
24
+ add_config :move_to_store
25
+ add_config :remove_previously_stored_files_after_update
26
+ add_config :downloader
27
+ add_config :force_extension
28
+
29
+ # fog
30
+ add_deprecated_config :fog_provider
31
+ add_config :fog_attributes
32
+ add_config :fog_credentials
33
+ add_config :fog_directory
34
+ add_config :fog_public
35
+ add_config :fog_authenticated_url_expiration
36
+ add_config :fog_use_ssl_for_aws
37
+ add_config :fog_aws_accelerate
38
+
39
+ # Mounting
40
+ add_config :ignore_integrity_errors
41
+ add_config :ignore_processing_errors
42
+ add_config :ignore_download_errors
43
+ add_config :validate_integrity
44
+ add_config :validate_processing
45
+ add_config :validate_download
46
+ add_config :mount_on
47
+ add_config :cache_only
48
+ add_config :download_retry_count
49
+ add_config :download_retry_wait_time
50
+ add_config :skip_ssrf_protection
51
+
52
+ # set default values
53
+ reset_config
54
+ end
55
+
56
+ module ClassMethods
57
+ def storage(storage = nil)
58
+ case storage
59
+ when Symbol
60
+ if (storage_engine = storage_engines[storage])
61
+ self._storage = eval storage_engine
62
+ else
63
+ raise SalebotUploader::UnknownStorageError, "Unknown storage: #{storage}"
64
+ end
65
+ when nil
66
+ storage
67
+ else
68
+ self._storage = storage
69
+ end
70
+ _storage
71
+ end
72
+ alias_method :storage=, :storage
73
+
74
+ def cache_storage(storage = false)
75
+ unless storage == false
76
+ self._cache_storage = storage.is_a?(Symbol) ? eval(storage_engines[storage]) : storage
77
+ end
78
+ _cache_storage
79
+ end
80
+ alias_method :cache_storage=, :cache_storage
81
+
82
+ def add_config(name)
83
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
84
+ @#{name} = nil
85
+
86
+ def self.#{name}(value=nil)
87
+ @#{name} = value unless value.nil?
88
+ return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
89
+ name = superclass.#{name}
90
+ return nil if name.nil? && !instance_variable_defined?(:@#{name})
91
+ @#{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
92
+ end
93
+
94
+ def self.#{name}=(value)
95
+ @#{name} = value
96
+ end
97
+
98
+ def #{name}=(value)
99
+ @#{name} = value
100
+ end
101
+
102
+ def #{name}
103
+ value = @#{name} if instance_variable_defined?(:@#{name})
104
+ value = self.class.#{name} unless instance_variable_defined?(:@#{name})
105
+ if value.instance_of?(Proc)
106
+ value.arity >= 1 ? value.call(self) : value.call
107
+ else
108
+ value
109
+ end
110
+ end
111
+ RUBY
112
+ end
113
+
114
+ def add_deprecated_config(name)
115
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
116
+ def self.#{name}(value=nil)
117
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
118
+ end
119
+
120
+ def self.#{name}=(value)
121
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
122
+ end
123
+
124
+ def #{name}=(value)
125
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
126
+ end
127
+
128
+ def #{name}
129
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
130
+ end
131
+ RUBY
132
+ end
133
+
134
+ def configure
135
+ yield self
136
+ end
137
+
138
+ ##
139
+ # sets configuration back to default
140
+ #
141
+ def reset_config
142
+ configure do |config|
143
+ config.permissions = 0o644
144
+ config.directory_permissions = 0o755
145
+ config.storage_engines = {
146
+ :file => "SalebotUploader::Storage::File",
147
+ :fog => "SalebotUploader::Storage::Fog"
148
+ }
149
+ config.storage = :file
150
+ config.cache_storage = nil
151
+ config.fog_attributes = {}
152
+ config.fog_credentials = {}
153
+ config.fog_public = true
154
+ config.fog_authenticated_url_expiration = 600
155
+ config.fog_use_ssl_for_aws = true
156
+ config.fog_aws_accelerate = false
157
+ config.store_dir = 'uploads'
158
+ config.cache_dir = 'uploads/tmp'
159
+ config.delete_tmp_file_after_storage = true
160
+ config.move_to_cache = false
161
+ config.move_to_store = false
162
+ config.remove_previously_stored_files_after_update = true
163
+ config.downloader = SalebotUploader::Downloader::Base
164
+ config.force_extension = false
165
+ config.ignore_integrity_errors = true
166
+ config.ignore_processing_errors = true
167
+ config.ignore_download_errors = true
168
+ config.validate_integrity = true
169
+ config.validate_processing = true
170
+ config.validate_download = true
171
+ config.root = lambda { SalebotUploader.root }
172
+ config.base_path = SalebotUploader.base_path
173
+ config.enable_processing = true
174
+ config.ensure_multipart_form = true
175
+ config.download_retry_count = 0
176
+ config.download_retry_wait_time = 5
177
+ config.skip_ssrf_protection = false
178
+ end
179
+ end
180
+ end
181
+
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,61 @@
1
+ module SalebotUploader
2
+ module Uploader
3
+ module ContentTypeAllowlist
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before :cache, :check_content_type_allowlist!
8
+ end
9
+
10
+ ##
11
+ # Override this method in your uploader to provide an allowlist of files content types
12
+ # which are allowed to be uploaded.
13
+ # Not only strings but Regexp are allowed as well.
14
+ #
15
+ # === Returns
16
+ #
17
+ # [NilClass, String, Regexp, Array[String, Regexp]] an allowlist of content types which are allowed to be uploaded
18
+ #
19
+ # === Examples
20
+ #
21
+ # def content_type_allowlist
22
+ # %w(text/json application/json)
23
+ # end
24
+ #
25
+ # Basically the same, but using a Regexp:
26
+ #
27
+ # def content_type_allowlist
28
+ # [/(text|application)\/json/]
29
+ # end
30
+ #
31
+ def content_type_allowlist; end
32
+
33
+ private
34
+
35
+ def check_content_type_allowlist!(new_file)
36
+ allowlist = content_type_allowlist
37
+ if !allowlist && respond_to?(:content_type_whitelist) && content_type_whitelist
38
+ ActiveSupport::Deprecation.warn "#content_type_whitelist is deprecated, use #content_type_allowlist instead." unless instance_variable_defined?(:@content_type_whitelist_warned)
39
+ @content_type_whitelist_warned = true
40
+ allowlist = content_type_whitelist
41
+ end
42
+
43
+ return unless allowlist
44
+
45
+ content_type = new_file.content_type
46
+ if !allowlisted_content_type?(allowlist, content_type)
47
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.content_type_allowlist_error", content_type: content_type,
48
+ allowed_types: Array(allowlist).join(", "), default: :"errors.messages.content_type_whitelist_error")
49
+ end
50
+ end
51
+
52
+ def allowlisted_content_type?(allowlist, content_type)
53
+ Array(allowlist).any? do |item|
54
+ item = Regexp.quote(item) if item.class != Regexp
55
+ content_type =~ /\A#{item}/
56
+ end
57
+ end
58
+
59
+ end # ContentTypeAllowlist
60
+ end # Uploader
61
+ end # SalebotUploader
@@ -0,0 +1,62 @@
1
+ module SalebotUploader
2
+ module Uploader
3
+ module ContentTypeDenylist
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before :cache, :check_content_type_denylist!
8
+ end
9
+
10
+ ##
11
+ # Override this method in your uploader to provide a denylist of files content types
12
+ # which are not allowed to be uploaded.
13
+ # Not only strings but Regexp are allowed as well.
14
+ #
15
+ # === Returns
16
+ #
17
+ # [NilClass, String, Regexp, Array[String, Regexp]] a denylist of content types which are not allowed to be uploaded
18
+ #
19
+ # === Examples
20
+ #
21
+ # def content_type_denylist
22
+ # %w(text/json application/json)
23
+ # end
24
+ #
25
+ # Basically the same, but using a Regexp:
26
+ #
27
+ # def content_type_denylist
28
+ # [/(text|application)\/json/]
29
+ # end
30
+ #
31
+ def content_type_denylist
32
+ end
33
+
34
+ private
35
+
36
+ def check_content_type_denylist!(new_file)
37
+ denylist = content_type_denylist
38
+ if !denylist && respond_to?(:content_type_blacklist) && content_type_blacklist
39
+ ActiveSupport::Deprecation.warn "#content_type_blacklist is deprecated, use #content_type_denylist instead." unless instance_variable_defined?(:@content_type_blacklist_warned)
40
+ @content_type_blacklist_warned = true
41
+ denylist = content_type_blacklist
42
+ end
43
+
44
+ return unless denylist
45
+
46
+ ActiveSupport::Deprecation.warn "Use of #content_type_denylist is deprecated for the security reason, use #content_type_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@content_type_denylist_warned)
47
+ @content_type_denylist_warned = true
48
+
49
+ content_type = new_file.content_type
50
+ if denylisted_content_type?(denylist, content_type)
51
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.content_type_denylist_error",
52
+ content_type: content_type, default: :"errors.messages.content_type_blacklist_error")
53
+ end
54
+ end
55
+
56
+ def denylisted_content_type?(denylist, content_type)
57
+ Array(denylist).any? { |item| content_type =~ /#{item}/ }
58
+ end
59
+
60
+ end # ContentTypeDenylist
61
+ end # Uploader
62
+ end # SalebotUploader
@@ -0,0 +1,17 @@
1
+ module SalebotUploader
2
+ module Uploader
3
+ module DefaultUrl
4
+
5
+ def url(*args)
6
+ super || default_url(*args)
7
+ end
8
+
9
+ ##
10
+ # Override this method in your uploader to provide a default url
11
+ # in case no file has been cached/stored yet.
12
+ #
13
+ def default_url(*args); end
14
+
15
+ end # DefaultPath
16
+ end # Uploader
17
+ end # SalebotUploader
@@ -0,0 +1,66 @@
1
+ require 'active_support'
2
+
3
+ module SalebotUploader
4
+ module Uploader
5
+ module Dimension
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ before :cache, :check_dimensions!
10
+ end
11
+
12
+ ##
13
+ # Override this method in your uploader to provide a Range of width which
14
+ # are allowed to be uploaded.
15
+ # === Returns
16
+ #
17
+ # [NilClass, Range] a width range which are permitted to be uploaded
18
+ #
19
+ # === Examples
20
+ #
21
+ # def width_range
22
+ # 1000..2000
23
+ # end
24
+ #
25
+ def width_range; end
26
+
27
+ ##
28
+ # Override this method in your uploader to provide a Range of height which
29
+ # are allowed to be uploaded.
30
+ # === Returns
31
+ #
32
+ # [NilClass, Range] a height range which are permitted to be uploaded
33
+ #
34
+ # === Examples
35
+ #
36
+ # def height_range
37
+ # 1000..
38
+ # end
39
+ #
40
+ def height_range; end
41
+
42
+ private
43
+
44
+ def check_dimensions!(new_file)
45
+ # NOTE: Skip the check for resized images
46
+ return if version_name.present?
47
+ return unless width_range || height_range
48
+
49
+ unless respond_to?(:width) || respond_to?(:height)
50
+ raise 'You need to include one of SalebotUploader::MiniMagick, SalebotUploader::RMagick, or SalebotUploader::Vips to perform image dimension validation'
51
+ end
52
+
53
+ if width_range&.begin && width < width_range.begin
54
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.min_width_error", :min_width => ActiveSupport::NumberHelper.number_to_delimited(width_range.begin))
55
+ elsif width_range&.end && width > width_range.end
56
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.max_width_error", :max_width => ActiveSupport::NumberHelper.number_to_delimited(width_range.end))
57
+ elsif height_range&.begin && height < height_range.begin
58
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.min_height_error", :min_height => ActiveSupport::NumberHelper.number_to_delimited(height_range.begin))
59
+ elsif height_range&.end && height > height_range.end
60
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.max_height_error", :max_height => ActiveSupport::NumberHelper.number_to_delimited(height_range.end))
61
+ end
62
+ end
63
+
64
+ end # Dimension
65
+ end # Uploader
66
+ end # SalebotUploader
@@ -0,0 +1,24 @@
1
+ module SalebotUploader
2
+ module Uploader
3
+ module Download
4
+ extend ActiveSupport::Concern
5
+
6
+ include SalebotUploader::Uploader::Callbacks
7
+ include SalebotUploader::Uploader::Configuration
8
+ include SalebotUploader::Uploader::Cache
9
+
10
+ ##
11
+ # Caches the file by downloading it from the given URL, using downloader.
12
+ #
13
+ # === Parameters
14
+ #
15
+ # [url (String)] The URL where the remote file is stored
16
+ # [remote_headers (Hash)] Request headers
17
+ #
18
+ def download!(uri, remote_headers = {})
19
+ file = downloader.new(self).download(uri, remote_headers)
20
+ cache!(file)
21
+ end
22
+ end # Download
23
+ end # Uploader
24
+ end # SalebotUploader
@@ -0,0 +1,63 @@
1
+ module SalebotUploader
2
+ module Uploader
3
+ module ExtensionAllowlist
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before :cache, :check_extension_allowlist!
8
+ end
9
+
10
+ ##
11
+ # Override this method in your uploader to provide an allowlist of extensions which
12
+ # are allowed to be uploaded. Compares the file's extension case insensitive.
13
+ # Furthermore, not only strings but Regexp are allowed as well.
14
+ #
15
+ # When using a Regexp in the allowlist, `\A` and `\z` are automatically added to
16
+ # the Regexp expression, also case insensitive.
17
+ #
18
+ # === Returns
19
+ #
20
+ # [NilClass, String, Regexp, Array[String, Regexp]] an allowlist of extensions which are allowed to be uploaded
21
+ #
22
+ # === Examples
23
+ #
24
+ # def extension_allowlist
25
+ # %w(jpg jpeg gif png)
26
+ # end
27
+ #
28
+ # Basically the same, but using a Regexp:
29
+ #
30
+ # def extension_allowlist
31
+ # [/jpe?g/, 'gif', 'png']
32
+ # end
33
+ #
34
+ def extension_allowlist
35
+ end
36
+
37
+ private
38
+
39
+ def check_extension_allowlist!(new_file)
40
+ allowlist = extension_allowlist
41
+ if !allowlist && respond_to?(:extension_whitelist) && extension_whitelist
42
+ ActiveSupport::Deprecation.warn "#extension_whitelist is deprecated, use #extension_allowlist instead." unless instance_variable_defined?(:@extension_whitelist_warned)
43
+ @extension_whitelist_warned = true
44
+ allowlist = extension_whitelist
45
+ end
46
+
47
+ return unless allowlist
48
+
49
+ extension = new_file.extension.to_s
50
+ if !allowlisted_extension?(allowlist, extension)
51
+ # Look for whitelist first, then fallback to allowlist
52
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.extension_allowlist_error", extension: new_file.extension.inspect,
53
+ allowed_types: Array(allowlist).join(", "), default: :"errors.messages.extension_whitelist_error")
54
+ end
55
+ end
56
+
57
+ def allowlisted_extension?(allowlist, extension)
58
+ downcase_extension = extension.downcase
59
+ Array(allowlist).any? { |item| downcase_extension =~ /\A#{item}\z/i }
60
+ end
61
+ end # ExtensionAllowlist
62
+ end # Uploader
63
+ end # SalebotUploader
@@ -0,0 +1,64 @@
1
+ module SalebotUploader
2
+ module Uploader
3
+ module ExtensionDenylist
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before :cache, :check_extension_denylist!
8
+ end
9
+
10
+ ##
11
+ # Override this method in your uploader to provide a denylist of extensions which
12
+ # are prohibited to be uploaded. Compares the file's extension case insensitive.
13
+ # Furthermore, not only strings but Regexp are allowed as well.
14
+ #
15
+ # When using a Regexp in the denylist, `\A` and `\z` are automatically added to
16
+ # the Regexp expression, also case insensitive.
17
+ #
18
+ # === Returns
19
+
20
+ # [NilClass, String, Regexp, Array[String, Regexp]] a deny list of extensions which are prohibited to be uploaded
21
+ #
22
+ # === Examples
23
+ #
24
+ # def extension_denylist
25
+ # %w(swf tiff)
26
+ # end
27
+ #
28
+ # Basically the same, but using a Regexp:
29
+ #
30
+ # def extension_denylist
31
+ # [/swf/, 'tiff']
32
+ # end
33
+ #
34
+ def extension_denylist
35
+ end
36
+
37
+ private
38
+
39
+ def check_extension_denylist!(new_file)
40
+ denylist = extension_denylist
41
+ if !denylist && respond_to?(:extension_blacklist) && extension_blacklist
42
+ ActiveSupport::Deprecation.warn "#extension_blacklist is deprecated, use #extension_denylist instead." unless instance_variable_defined?(:@extension_blacklist_warned)
43
+ @extension_blacklist_warned = true
44
+ denylist = extension_blacklist
45
+ end
46
+
47
+ return unless denylist
48
+
49
+ ActiveSupport::Deprecation.warn "Use of #extension_denylist is deprecated for the security reason, use #extension_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@extension_denylist_warned)
50
+ @extension_denylist_warned = true
51
+
52
+ extension = new_file.extension.to_s
53
+ if denylisted_extension?(denylist, extension)
54
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.extension_denylist_error", extension: new_file.extension.inspect,
55
+ prohibited_types: Array(extension_denylist).join(", "), default: :"errors.messages.extension_blacklist_error")
56
+ end
57
+ end
58
+
59
+ def denylisted_extension?(denylist, extension)
60
+ Array(denylist).any? { |item| extension =~ /\A#{item}\z/i }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,43 @@
1
+ require 'active_support'
2
+
3
+ module SalebotUploader
4
+ module Uploader
5
+ module FileSize
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ before :cache, :check_size!
10
+ end
11
+
12
+ ##
13
+ # Override this method in your uploader to provide a Range of Size which
14
+ # are allowed to be uploaded.
15
+ # === Returns
16
+ #
17
+ # [NilClass, Range] a size range (in bytes) which are permitted to be uploaded
18
+ #
19
+ # === Examples
20
+ #
21
+ # def size_range
22
+ # 3256...5748
23
+ # end
24
+ #
25
+ def size_range; end
26
+
27
+ private
28
+
29
+ def check_size!(new_file)
30
+ size = new_file.size
31
+ expected_size_range = size_range
32
+ if expected_size_range.is_a?(::Range)
33
+ if size < expected_size_range.min
34
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.min_size_error", :min_size => ActiveSupport::NumberHelper.number_to_human_size(expected_size_range.min))
35
+ elsif size > expected_size_range.max
36
+ raise SalebotUploader::IntegrityError, I18n.translate(:"errors.messages.max_size_error", :max_size => ActiveSupport::NumberHelper.number_to_human_size(expected_size_range.max))
37
+ end
38
+ end
39
+ end
40
+
41
+ end # FileSize
42
+ end # Uploader
43
+ end # SalebotUploader
@@ -0,0 +1,44 @@
1
+ module SalebotUploader
2
+ module Uploader
3
+ module Mountable
4
+
5
+ attr_reader :model, :mounted_as
6
+
7
+ ##
8
+ # If a model is given as the first parameter, it will be stored in the
9
+ # uploader, and available through +#model+. Likewise, mounted_as stores
10
+ # the name of the column where this instance of the uploader is mounted.
11
+ # These values can then be used inside your uploader.
12
+ #
13
+ # If you do not wish to mount your uploaders with the ORM extensions in
14
+ # -more then you can override this method inside your uploader. Just be
15
+ # sure to call +super+
16
+ #
17
+ # === Parameters
18
+ #
19
+ # [model (Object)] Any kind of model object
20
+ # [mounted_as (Symbol)] The name of the column where this uploader is mounted
21
+ #
22
+ # === Examples
23
+ #
24
+ # class MyUploader < SalebotUploader::Uploader::Base
25
+ #
26
+ # def store_dir
27
+ # File.join('public', 'files', mounted_as, model.permalink)
28
+ # end
29
+ # end
30
+ #
31
+ def initialize(model=nil, mounted_as=nil)
32
+ @model = model
33
+ @mounted_as = mounted_as
34
+ end
35
+
36
+ ##
37
+ # Returns array index of given uploader within currently mounted uploaders
38
+ #
39
+ def index
40
+ model.__send__(:_mounter, mounted_as).uploaders.index(self)
41
+ end
42
+ end # Mountable
43
+ end # Uploader
44
+ end # SalebotUploader