file_validators 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d9d77f05c14b168f172952bf2e4418b22e7d716c
4
+ data.tar.gz: 6686bd542bacb69ff3a0db1e7304b8b2ab4d55a4
5
+ SHA512:
6
+ metadata.gz: d5f7393b1bc42819e548ed6f0cbc0633ab66ea5a87451c0ab60c8d50dc2b2036615a88f3548653603010d6661318017869c03d6b472a6338fc470e2e81acc5fc
7
+ data.tar.gz: d602cf19ecae5107bb10148bc7d105118e7c5610f5a099658870c63cb6ecbab4c115e26bc552400499284cecc393ce320fe62c49d1e9b7b723c260594bfbe5dc
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ spec/dummy/db/*.sqlite3
5
+ spec/dummy/db/*.sqlite3-journal
6
+ spec/dummy/log/*.log
7
+ spec/dummy/tmp/
8
+ spec/dummy/.sass-cache
9
+ Gemfile.lock
10
+ gemfiles/*.lock
11
+ coverage/
12
+ /.idea
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ - 2.0.0
5
+ - 1.9.3
6
+ gemfile:
7
+ - gemfiles/activemodel_4.1.gemfile
8
+ - gemfiles/activemodel_4.0.gemfile
9
+ - gemfiles/activemodel_3.2.gemfile
10
+ - gemfiles/activemodel_3.1.gemfile
11
+ - gemfiles/activemodel_3.0.gemfile
data/Appraisals ADDED
@@ -0,0 +1,19 @@
1
+ appraise 'activemodel-3.0' do
2
+ gem 'activemodel', '3.0.20'
3
+ end
4
+
5
+ appraise 'activemodel-3.1' do
6
+ gem 'activemodel', '3.1.12'
7
+ end
8
+
9
+ appraise 'activemodel-3.2' do
10
+ gem 'activemodel', '3.2.18'
11
+ end
12
+
13
+ appraise 'activemodel-4.0' do
14
+ gem 'activemodel', '4.0.10'
15
+ end
16
+
17
+ appraise 'activemodel-4.1' do
18
+ gem 'activemodel', '4.1.6'
19
+ end
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Declare your gem's dependencies in file_validators.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # Declare any dependencies that are still in development here instead of in
9
+ # your gemspec. These might include edge Rails or gems from your path or
10
+ # Git. Remember to move these dependencies to your gemspec before releasing
11
+ # your gem to rubygems.org.
12
+
13
+ # To use debugger
14
+ # gem 'debugger'
15
+ gem 'appraisal'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,216 @@
1
+ # File Validators
2
+
3
+ [![Gem Version](http://img.shields.io/gem/v/file_validators.svg)](https://rubygems.org/gems/file_validators)
4
+ [![Build Status](https://travis-ci.org/musaffa/file_validators.svg)](https://travis-ci.org/musaffa/file_validators)
5
+ [![Dependency Status](http://img.shields.io/gemnasium/musaffa/file_validators.svg)](https://gemnasium.com/musaffa/file_validators)
6
+ [![Coverage Status](http://img.shields.io/coveralls/musaffa/file_validators.svg)](https://coveralls.io/r/musaffa/file_validators)
7
+ [![Code Climate](http://img.shields.io/codeclimate/github/musaffa/file_validators.svg)](https://codeclimate.com/github/musaffa/file_validators)
8
+
9
+ File Validators gem adds file size and content type validations to ActiveModel. Any module that uses ActiveModel, for example ActiveRecord, can use these file validators.
10
+
11
+ ## Support
12
+
13
+ * ActiveModel versions: 3 and 4.
14
+ * Rails versions: 3 and 4.
15
+
16
+ ## Installation
17
+
18
+ Add the following to your Gemfile:
19
+
20
+ ```ruby
21
+ gem 'file_validators'
22
+ ```
23
+
24
+ ## Examples
25
+
26
+ ActiveModel example:
27
+
28
+ ```ruby
29
+ class Profile
30
+ include ActiveModel::Validations
31
+
32
+ attr_accessor :avatar
33
+ validates :avatar, file_size: { less_than_or_equal_to: 100.kilobytes },
34
+ file_content_type: { allow: ['image/jpeg', 'image/png', 'image/gif'] }
35
+ end
36
+ ```
37
+ ActiveRecord example:
38
+
39
+ ```ruby
40
+ class Profile < ActiveRecord::Base
41
+ validates :avatar, file_size: { less_than_or_equal_to: 100.kilobytes },
42
+ file_content_type: { allow: ['image/jpeg', 'image/png', 'image/gif'] }
43
+ end
44
+ ```
45
+
46
+ ## API
47
+
48
+ ### File Size Validator:
49
+
50
+ * `in`: A range of bytes
51
+ ```ruby
52
+ validates :avatar, file_size: { in: 100.kilobytes..1.megabyte }
53
+ ```
54
+ * `less_than_or_equal_to`: Less than or equal to a number in bytes
55
+ ```ruby
56
+ validates :avatar, file_size: { less_than_or_equal_to: 50.bytes }
57
+ ```
58
+ * `greater_than_or_equal_to`: Greater than or equal to a number in bytes
59
+ ```ruby
60
+ validates :avatar, file_size: { greater_than_or_equal_to: 50.bytes }
61
+ ```
62
+ * `less_than`: Less than a number in bytes
63
+ ```ruby
64
+ validates :avatar, file_size: { less_than: 2.gigabytes }
65
+ ```
66
+ * `greater_than`: greater than a number in bytes
67
+ ```ruby
68
+ validates :avatar, file_size: { greater_than: 1.byte }
69
+ ```
70
+ You can also combine these options.
71
+ ```ruby
72
+ validates :avatar, file_size: { less_than: 1.megabyte,
73
+ greater_than_or_equal_to: 20.kilobytes }
74
+ ```
75
+ The following two examples are equivalent:
76
+ ```ruby
77
+ validates :avatar, file_size: { greater_than_or_equal_to: 500.kilobytes,
78
+ less_than_or_equal_to: 3.megabytes }
79
+ ```
80
+ ```ruby
81
+ validates :avatar, file_size: { in: 500.kilobytes..3.megabytes }
82
+ ```
83
+ If you use `:in`, then the other options will be neglected.
84
+ * `message`: Error message to display. With all the options above except `:in`, you will get `count` as a replacement.
85
+ With `:in` you will get `min` and `max` as replacements.
86
+ `count`, `min` and `max` each will have its value and unit together.
87
+ You can write error messages without using any replacement.
88
+ ```ruby
89
+ validates :avatar, file_size: { less_than: 100.kilobytes,
90
+ message: 'avatar file size should be less than %{count}' }
91
+ ```
92
+ ```ruby
93
+ validates :document, file_size: { in: 1.kilobyte..1.megabyte,
94
+ message: 'document should be within %{min} and %{max}' }
95
+ ```
96
+ * `if`: A lambda or name of an instance method. Validation will only be run if this lambda or method returns true.
97
+ * `unless`: Same as `if` but validates if lambda or method returns false.
98
+
99
+ ### File Content Type Validator
100
+
101
+ * `allow`: Allowed content types. Can be a single content type or an array. Each type can be a String or a Regexp. Allows all by default.
102
+ ```ruby
103
+ # string
104
+ validates :avatar, file_content_type: { allow: 'image/jpeg' }
105
+ ```
106
+ ```ruby
107
+ # array of strings
108
+ validates :attachment, file_content_type: { allow: ['image/jpeg', 'image/png', 'text/plain'] }
109
+ ```
110
+ ```ruby
111
+ # regexp
112
+ validates :avatar, file_content_type: { allow: /^image\/.*/ }
113
+ ```
114
+ ```ruby
115
+ # array of regexps
116
+ validates :attachment, file_content_type: { allow: [/^image\/.*/, /^text\/.*/] }
117
+ ```
118
+ ```ruby
119
+ # array of regexps and strings
120
+ validates :attachment, file_content_type: { allow: [/^image\/.*/, 'video/mp4'] }
121
+ ```
122
+ * `exclude`: Forbidden content types. Can be a single content type or an array. Each type can be a String or a Regexp.
123
+ ```ruby
124
+ # string
125
+ validates :avatar, file_content_type: { exclude: 'image/jpeg' }
126
+ ```
127
+ ```ruby
128
+ # array of strings
129
+ validates :attachment, file_content_type: { exclude: ['image/jpeg', 'text/plain'] }
130
+ ```
131
+ ```ruby
132
+ # regexp
133
+ validates :avatar, file_content_type: { exclude: /^image\/.*/ }
134
+ ```
135
+ ```ruby
136
+ # array of regexps
137
+ validates :attachment, file_content_type: { exclude: [/^image\/.*/, /^text\/.*/] }
138
+ ```
139
+ ```ruby
140
+ # array of regexps and strings
141
+ validates :attachment, file_content_type: { exclude: [/^text\/.*/, 'image/gif'] }
142
+ ```
143
+ You can also combine `:allow` and `:exclude`:
144
+ ```ruby
145
+ # this will allow all the image types except gif
146
+ validates :avatar, file_content_type: { allow: /^image\/.*/, exclude: 'image/gif' }
147
+ ```
148
+ * `message`: The message to display when the uploaded file has an invalid content type.
149
+ You will get `types` as a replacement. You can write error messages without using any replacement.
150
+ ```ruby
151
+ validates :avatar, file_content_type: { allow: ['image/jpeg', 'image/gif'],
152
+ message: 'should have content type %{types}' }
153
+ ```
154
+ ```ruby
155
+ validates :avatar, file_content_type: { allow: ['image/jpeg', 'image/gif'],
156
+ message: 'Avatar only allows jpeg and gif image files' }
157
+ ```
158
+ * `if`: A lambda or name of an instance method. Validation will only be run is this lambda or method returns true.
159
+ * `unless`: Same as `if` but validates if lambda or method returns false.
160
+
161
+ ## i18n Translations
162
+
163
+ By default, `FileSizeValidator` will use the error messages of `:less_than`, `:greater_than_or_equal_to` etc from `errors.messages` of your locale. `errors.messages` translation is available under ActiveModel's locale.
164
+
165
+ For `:in`, `:allow` and `:exclude` you will have to write your own error messages under `errors.messages`.
166
+
167
+ You can override all of them with the `:message` option.
168
+
169
+ For unit format, it will use `number.human.storage_units.format` from your locale.
170
+ For unit translation, it will use `number.human.storage_units`.
171
+ Rails applications already have these translations either in ActiveSupport's locale (Rails 4) or in ActionView's locale (Rails 3).
172
+ In case your setup doesn't have the translations, here's an example for `en`:
173
+
174
+ ```yml
175
+ en:
176
+ number:
177
+ human:
178
+ storage_units:
179
+ format: "%n %u"
180
+ units:
181
+ byte:
182
+ one: "Byte"
183
+ other: "Bytes"
184
+ kb: "KB"
185
+ mb: "MB"
186
+ gb: "GB"
187
+ tb: "TB"
188
+ ```
189
+
190
+ ## Tests
191
+
192
+ ```ruby
193
+ rake
194
+ rake test:unit
195
+ rake test:integration
196
+ ```
197
+
198
+ ## Problems
199
+
200
+ Please use GitHub's [issue tracker](http://github.com/musaffa/file_validations/issues).
201
+
202
+ ## Contributing
203
+
204
+ 1. Fork it
205
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
206
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
207
+ 4. Push to the branch (`git push origin my-new-feature`)
208
+ 5. Create a new Pull Request
209
+
210
+ ## Inspirations
211
+
212
+ * [PaperClip](https://github.com/thoughtbot/paperclip)
213
+
214
+ ## License
215
+
216
+ This project rocks and uses MIT-LICENSE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = FileValidators
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rspec/core/rake_task'
8
+
9
+ namespace :test do
10
+ RSpec::Core::RakeTask.new(:unit) do |t|
11
+ t.pattern = ['spec/lib/**/*_spec.rb']
12
+ end
13
+
14
+ RSpec::Core::RakeTask.new(:integration) do |t|
15
+ t.pattern = ['spec/integration/**/*_spec.rb']
16
+ end
17
+ end
18
+
19
+ task :default => ['test:unit', 'test:integration']
20
+
21
+ # require 'rdoc/task'
22
+
23
+ # RDoc::Task.new(:rdoc) do |rdoc|
24
+ # rdoc.rdoc_dir = 'rdoc'
25
+ # rdoc.title = 'FileValidators'
26
+ # rdoc.options << '--line-numbers'
27
+ # rdoc.rdoc_files.include('README.rdoc')
28
+ # rdoc.rdoc_files.include('lib/**/*.rb')
29
+ # end
30
+
31
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,26 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+
3
+ require 'file_validators/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'file_validators'
7
+ s.version = FileValidators::VERSION
8
+ s.authors = ['Ahmad Musaffa']
9
+ s.email = ['musaffa_csemm@yahoo.com']
10
+ s.summary = 'ActiveModel file validators'
11
+ s.description = 'Adds file validators to ActiveModel'
12
+ s.homepage = 'https://github.com/musaffa/file_validators'
13
+ s.license = 'MIT'
14
+
15
+ s.files = `git ls-files`.split($/)
16
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ s.test_files = s.files.grep(%r{^spec/})
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_dependency 'activemodel', '>= 3.0'
21
+
22
+ s.add_development_dependency 'rake'
23
+ s.add_development_dependency 'rspec', '~> 3.1.0'
24
+ s.add_development_dependency 'coveralls'
25
+ s.add_development_dependency 'rack-test'
26
+ end
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "activemodel", "3.0.20"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "activemodel", "3.1.12"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "activemodel", "3.2.18"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "activemodel", "4.0.10"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "activemodel", "4.1.6"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,73 @@
1
+ module ActiveModel
2
+ module Validations
3
+
4
+ class FileContentTypeValidator < ActiveModel::EachValidator
5
+ def initialize(options)
6
+ super
7
+ end
8
+
9
+ def self.helper_method_name
10
+ :validates_file_content_type
11
+ end
12
+
13
+ def validate_each(record, attribute, value)
14
+ unless value.blank?
15
+ content_type = value.content_type
16
+ validate_whitelist(record, attribute, content_type)
17
+ validate_blacklist(record, attribute, content_type)
18
+ end
19
+ end
20
+
21
+ def validate_whitelist(record, attribute, value)
22
+ if allowed_types.present? && allowed_types.none? { |type| type === value }
23
+ mark_invalid record, attribute, allowed_types
24
+ end
25
+ end
26
+
27
+ def validate_blacklist(record, attribute, value)
28
+ if forbidden_types.present? && forbidden_types.any? { |type| type === value }
29
+ mark_invalid record, attribute, forbidden_types
30
+ end
31
+ end
32
+
33
+ def mark_invalid(record, attribute, types)
34
+ record.errors.add attribute, :invalid, options.merge(:types => types.join(', '))
35
+ end
36
+
37
+ def allowed_types
38
+ [options[:allow]].flatten.compact
39
+ end
40
+
41
+ def forbidden_types
42
+ [options[:exclude]].flatten.compact
43
+ end
44
+
45
+ def check_validity!
46
+ unless options.has_key?(:allow) || options.has_key?(:exclude)
47
+ raise ArgumentError, 'You must pass in either :allow or :exclude to the validator'
48
+ end
49
+ end
50
+ end
51
+
52
+ module HelperMethods
53
+ # Places ActiveModel validations on the content type of the file
54
+ # assigned. The possible options are:
55
+ # * +allow+: Allowed content types. Can be a single content type
56
+ # or an array. Each type can be a String or a Regexp. It should be
57
+ # noted that Internet Explorer uploads files with content_types that you
58
+ # may not expect. For example, JPEG images are given image/pjpeg and
59
+ # PNGs are image/x-png, so keep that in mind when determining how you
60
+ # match. Allows all by default.
61
+ # * +exclude+: Forbidden content types.
62
+ # * +message+: The message to display when the uploaded file has an invalid
63
+ # content type.
64
+ # * +if+: A lambda or name of an instance method. Validation will only
65
+ # be run is this lambda or method returns true.
66
+ # * +unless+: Same as +if+ but validates if lambda or method returns false.
67
+ def validates_file_content_type(*attr_names)
68
+ validates_with FileContentTypeValidator, _merge_attributes(attr_names)
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,89 @@
1
+ module ActiveModel
2
+ module Validations
3
+
4
+ class FileSizeValidator < ActiveModel::Validations::NumericalityValidator
5
+ AVAILABLE_CHECKS = [:less_than, :less_than_or_equal_to, :greater_than, :greater_than_or_equal_to].freeze
6
+
7
+ def initialize(options)
8
+ extract_options(options)
9
+ super
10
+ end
11
+
12
+ def self.helper_method_name
13
+ :validates_file_size
14
+ end
15
+
16
+ def validate_each(record, attribute, value)
17
+ unless value.blank?
18
+ options.slice(*AVAILABLE_CHECKS).each do |option, option_value|
19
+ unless value.size.send(CHECKS[option], option_value)
20
+ error_message_key = options[:in] ? :in : option
21
+ record.errors.add(attribute, error_message_key, filtered_options(value).merge!(detect_error_options(option, option_value)))
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def check_validity!
28
+ unless (AVAILABLE_CHECKS + [:in]).any? { |argument| options.has_key?(argument) }
29
+ raise ArgumentError, 'List of allowed options - [:in, :less_than, :greater_than, :less_than_or_equal_to, :greater_than_or_equal_to]'
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def extract_options(options)
36
+ if range = options[:in]
37
+ raise ArgumentError, ':in must be a Range' unless range.is_a?(Range)
38
+ clear_options(options)
39
+ options[:less_than_or_equal_to], options[:greater_than_or_equal_to] = range.max, range.min
40
+ end
41
+ end
42
+
43
+ def clear_options(options)
44
+ AVAILABLE_CHECKS.each do |option|
45
+ options.delete(option)
46
+ end
47
+ end
48
+
49
+ def detect_error_options(option, option_value)
50
+ if options[:in]
51
+ max = options[:less_than_or_equal_to]
52
+ min = options[:greater_than_or_equal_to]
53
+ error_options = { min: human_size(min), max: human_size(max) }
54
+ else
55
+ error_options = { count: human_size(option_value) }
56
+ end
57
+ end
58
+
59
+ def human_size(size)
60
+ if defined?(ActiveSupport::NumberHelper) # Rails 4.0+
61
+ ActiveSupport::NumberHelper.number_to_human_size(size)
62
+ else
63
+ storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
64
+ unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => size.to_i, :raise => true)
65
+ storage_units_format.gsub(/%n/, size.to_i.to_s).gsub(/%u/, unit).html_safe
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ module HelperMethods
72
+ # Places ActiveModel validations on the size of the file assigned. The
73
+ # possible options are:
74
+ # * +in+: a Range of bytes (i.e. +1..1.megabyte+),
75
+ # * +less_than_or_equal_to+: equivalent to :in => 0..options[:less_than_or_equal_to]
76
+ # * +greater_than_or_equal_to+: equivalent to :in => options[:greater_than_or_equal_to]..Infinity
77
+ # * +less_than+: less than a number in bytes
78
+ # * +greater_than+: greater than a number in bytes
79
+ # * +message+: error message to display, use :min and :max as replacements
80
+ # * +if+: A lambda or name of an instance method. Validation will only
81
+ # be run if this lambda or method returns true.
82
+ # * +unless+: Same as +if+ but validates if lambda or method returns false.
83
+ def validates_file_size(*attr_names)
84
+ validates_with FileSizeValidator, _merge_attributes(attr_names)
85
+ end
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,3 @@
1
+ module FileValidators
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'active_model'
2
+ require 'file_validators/validators/file_size_validator'
3
+ require 'file_validators/validators/file_content_type_validator'
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ a sample text