active_storage_validations 1.0.0 → 1.0.2
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.
- checksums.yaml +4 -4
- data/README.md +6 -1
- data/config/locales/en.yml +1 -0
- data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +12 -34
- data/lib/active_storage_validations/metadata.rb +18 -7
- data/lib/active_storage_validations/option_proc_unfolding.rb +2 -2
- data/lib/active_storage_validations/processable_image_validator.rb +43 -0
- data/lib/active_storage_validations/version.rb +1 -1
- data/lib/active_storage_validations.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7b0998dd3938eee42be49dc3d831eaea8482001a0e03227f61cc0330050a3a1
|
4
|
+
data.tar.gz: 72a82d3965c026f118bd1d4bc7e0338a2313c43394f780577cbbe944356caf39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0117ebfeed615802b45e4f341eea6e5676d8189e4a4bf81faa565e8e49f418142a7aa3466a6cd3f92761e029ff54f58298259ae390682649d5ad5950e52d787
|
7
|
+
data.tar.gz: e6ab73fe085110abe6b346e3eb837a59ca81b499707cdbf8df9773647feefd7b11ca4e5be03329226954a43756a5ceda9550169ff5402a6f275cfc7b4865f6b9
|
data/README.md
CHANGED
@@ -19,6 +19,7 @@ This gems doing it for you. Just use `attached: true` or `content_type: 'image/p
|
|
19
19
|
* validates dimension of images/videos
|
20
20
|
* validates number of uploaded files (min/max required)
|
21
21
|
* validates aspect ratio (if square, portrait, landscape, is_16_9, ...)
|
22
|
+
* validates if file can be processed by MiniMagick or Vips
|
22
23
|
* custom error messages
|
23
24
|
* allow procs for dynamic determination of values
|
24
25
|
|
@@ -40,6 +41,7 @@ class User < ApplicationRecord
|
|
40
41
|
dimension: { width: { min: 800, max: 2400 },
|
41
42
|
height: { min: 600, max: 1800 }, message: 'is not given between dimension' }
|
42
43
|
validates :image, attached: true,
|
44
|
+
processable_image: true,
|
43
45
|
content_type: ['image/png', 'image/jpeg'],
|
44
46
|
aspect_ratio: :landscape
|
45
47
|
end
|
@@ -164,6 +166,7 @@ en:
|
|
164
166
|
aspect_ratio_not_landscape: "must be a landscape image"
|
165
167
|
aspect_ratio_is_not: "must have an aspect ratio of %{aspect_ratio}"
|
166
168
|
aspect_ratio_unknown: "has an unknown aspect ratio"
|
169
|
+
image_not_processable: "is not a valid image"
|
167
170
|
```
|
168
171
|
|
169
172
|
In some cases, Active Storage Validations provides variables to help you customize messages:
|
@@ -311,9 +314,9 @@ end
|
|
311
314
|
|
312
315
|
To run tests in root folder of gem:
|
313
316
|
|
314
|
-
* `BUNDLE_GEMFILE=gemfiles/rails_5_2.gemfile bundle exec rake test` to run for Rails 5.2
|
315
317
|
* `BUNDLE_GEMFILE=gemfiles/rails_6_0.gemfile bundle exec rake test` to run for Rails 6.0
|
316
318
|
* `BUNDLE_GEMFILE=gemfiles/rails_6_1.gemfile bundle exec rake test` to run for Rails 6.1
|
319
|
+
* `BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle exec rake test` to run for Rails 7.0
|
317
320
|
* `BUNDLE_GEMFILE=gemfiles/rails_next.gemfile bundle exec rake test` to run for Rails main branch
|
318
321
|
|
319
322
|
Snippet to run in console:
|
@@ -395,6 +398,8 @@ You are welcome to contribute.
|
|
395
398
|
= https://github.com/gr8bit
|
396
399
|
= https://github.com/codegeek319
|
397
400
|
= https://github.com/clwy-cn
|
401
|
+
= https://github.com/kukicola
|
402
|
+
= https://github.com/sobrinho
|
398
403
|
|
399
404
|
## License
|
400
405
|
|
data/config/locales/en.yml
CHANGED
@@ -33,15 +33,19 @@ module ActiveStorageValidations
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def failure_message
|
36
|
-
|
37
|
-
Expected #{@attribute_name}
|
36
|
+
message = ["Expected #{@attribute_name}"]
|
38
37
|
|
39
|
-
|
40
|
-
|
38
|
+
if @allowed_types
|
39
|
+
message << "Accept content types: #{allowed_types.join(", ")}"
|
40
|
+
message << "#{@missing_allowed_types.join(", ")} were rejected"
|
41
|
+
end
|
42
|
+
|
43
|
+
if @rejected_types
|
44
|
+
message << "Reject content types: #{rejected_types.join(", ")}"
|
45
|
+
message << "#{@missing_rejected_types.join(", ")} were accepted"
|
46
|
+
end
|
41
47
|
|
42
|
-
|
43
|
-
#{rejected_types_and_failures}
|
44
|
-
MESSAGE
|
48
|
+
message.join("\n")
|
45
49
|
end
|
46
50
|
|
47
51
|
protected
|
@@ -57,7 +61,7 @@ module ActiveStorageValidations
|
|
57
61
|
end
|
58
62
|
|
59
63
|
def rejected_types
|
60
|
-
@rejected_types ||
|
64
|
+
@rejected_types || []
|
61
65
|
end
|
62
66
|
|
63
67
|
def allowed_types_allowed?
|
@@ -70,22 +74,6 @@ module ActiveStorageValidations
|
|
70
74
|
@missing_rejected_types.none?
|
71
75
|
end
|
72
76
|
|
73
|
-
def accepted_types_and_failures
|
74
|
-
if @missing_allowed_types.present?
|
75
|
-
"#{@missing_allowed_types.join(", ")} were rejected."
|
76
|
-
else
|
77
|
-
"All were accepted successfully."
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def rejected_types_and_failures
|
82
|
-
if @missing_rejected_types.present?
|
83
|
-
"#{@missing_rejected_types.join(", ")} were accepted."
|
84
|
-
else
|
85
|
-
"All were rejected successfully."
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
77
|
def type_allowed?(type)
|
90
78
|
@subject.public_send(@attribute_name).attach(attachment_for(type))
|
91
79
|
@subject.validate
|
@@ -96,16 +84,6 @@ module ActiveStorageValidations
|
|
96
84
|
suffix = type.to_s.split('/').last
|
97
85
|
{ io: Tempfile.new('.'), filename: "test.#{suffix}", content_type: type }
|
98
86
|
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def content_type_keys
|
103
|
-
if Rails.gem_version < Gem::Version.new('6.1.0')
|
104
|
-
Mime::LOOKUP.keys
|
105
|
-
else
|
106
|
-
Marcel::TYPES.keys
|
107
|
-
end
|
108
|
-
end
|
109
87
|
end
|
110
88
|
end
|
111
89
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module ActiveStorageValidations
|
2
2
|
class Metadata
|
3
|
+
class InvalidImageError < StandardError; end
|
4
|
+
|
3
5
|
attr_reader :file
|
4
6
|
|
5
7
|
def initialize(file)
|
@@ -10,7 +12,7 @@ module ActiveStorageValidations
|
|
10
12
|
def image_processor
|
11
13
|
Rails.application.config.active_storage.variant_processor
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
def exception_class
|
15
17
|
if image_processor == :vips && defined?(Vips)
|
16
18
|
Vips::Error
|
@@ -35,6 +37,16 @@ module ActiveStorageValidations
|
|
35
37
|
{ width: image.width, height: image.height }
|
36
38
|
end
|
37
39
|
end
|
40
|
+
rescue InvalidImageError
|
41
|
+
logger.info "Skipping image analysis because ImageMagick or Vips doesn't support the file"
|
42
|
+
{}
|
43
|
+
end
|
44
|
+
|
45
|
+
def valid?
|
46
|
+
read_image
|
47
|
+
true
|
48
|
+
rescue InvalidImageError
|
49
|
+
false
|
38
50
|
end
|
39
51
|
|
40
52
|
private
|
@@ -76,12 +88,9 @@ module ActiveStorageValidations
|
|
76
88
|
end
|
77
89
|
end
|
78
90
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
logger.info "Skipping image analysis because ImageMagick or Vips doesn't support the file"
|
83
|
-
{}
|
84
|
-
end
|
91
|
+
|
92
|
+
raise InvalidImageError unless valid_image?(image)
|
93
|
+
yield image
|
85
94
|
rescue LoadError, NameError
|
86
95
|
logger.info "Skipping image analysis because the mini_magick or ruby-vips gem isn't installed"
|
87
96
|
{}
|
@@ -93,6 +102,8 @@ module ActiveStorageValidations
|
|
93
102
|
end
|
94
103
|
|
95
104
|
def valid_image?(image)
|
105
|
+
return false unless image
|
106
|
+
|
96
107
|
image_processor == :vips && image.is_a?(Vips::Image) ? image.avg : image.valid?
|
97
108
|
rescue exception_class
|
98
109
|
false
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module ActiveStorageValidations
|
2
2
|
module OptionProcUnfolding
|
3
3
|
|
4
|
-
def unfold_procs(record, object, only_keys
|
4
|
+
def unfold_procs(record, object, only_keys)
|
5
5
|
case object
|
6
6
|
when Hash
|
7
|
-
object.merge(object) { |key, value| only_keys&.exclude?(key) ?
|
7
|
+
object.merge(object) { |key, value| only_keys&.exclude?(key) ? {} : unfold_procs(record, value, nil) }
|
8
8
|
when Array
|
9
9
|
object.map { |o| unfold_procs(record, o, only_keys) }
|
10
10
|
else
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'metadata.rb'
|
4
|
+
|
5
|
+
module ActiveStorageValidations
|
6
|
+
class ProcessableImageValidator < ActiveModel::EachValidator # :nodoc
|
7
|
+
include OptionProcUnfolding
|
8
|
+
|
9
|
+
if Rails.gem_version >= Gem::Version.new('6.0.0')
|
10
|
+
def validate_each(record, attribute, _value)
|
11
|
+
return true unless record.send(attribute).attached?
|
12
|
+
|
13
|
+
changes = record.attachment_changes[attribute.to_s]
|
14
|
+
return true if changes.blank?
|
15
|
+
|
16
|
+
files = Array.wrap(changes.is_a?(ActiveStorage::Attached::Changes::CreateMany) ? changes.attachables : changes.attachable)
|
17
|
+
|
18
|
+
files.each do |file|
|
19
|
+
add_error(record, attribute, :image_not_processable) unless Metadata.new(file).valid?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
else
|
23
|
+
# Rails 5
|
24
|
+
def validate_each(record, attribute, _value)
|
25
|
+
return true unless record.send(attribute).attached?
|
26
|
+
|
27
|
+
files = Array.wrap(record.send(attribute))
|
28
|
+
|
29
|
+
files.each do |file|
|
30
|
+
add_error(record, attribute, :image_not_processable) unless Metadata.new(file).valid?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def add_error(record, attribute, default_message)
|
38
|
+
message = options[:message].presence || default_message
|
39
|
+
return if record.errors.added?(attribute, message)
|
40
|
+
record.errors.add(attribute, message)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -9,6 +9,7 @@ require 'active_storage_validations/size_validator'
|
|
9
9
|
require 'active_storage_validations/limit_validator'
|
10
10
|
require 'active_storage_validations/dimension_validator'
|
11
11
|
require 'active_storage_validations/aspect_ratio_validator'
|
12
|
+
require 'active_storage_validations/processable_image_validator'
|
12
13
|
|
13
14
|
ActiveSupport.on_load(:active_record) do
|
14
15
|
send :include, ActiveStorageValidations
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_storage_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -216,6 +216,7 @@ files:
|
|
216
216
|
- lib/active_storage_validations/matchers/size_validator_matcher.rb
|
217
217
|
- lib/active_storage_validations/metadata.rb
|
218
218
|
- lib/active_storage_validations/option_proc_unfolding.rb
|
219
|
+
- lib/active_storage_validations/processable_image_validator.rb
|
219
220
|
- lib/active_storage_validations/railtie.rb
|
220
221
|
- lib/active_storage_validations/size_validator.rb
|
221
222
|
- lib/active_storage_validations/version.rb
|