active_storage_validations 1.0.4 → 3.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 +785 -245
- data/config/locales/da.yml +63 -0
- data/config/locales/de.yml +60 -19
- data/config/locales/en-GB.yml +63 -0
- data/config/locales/en.yml +60 -20
- data/config/locales/es.yml +60 -19
- data/config/locales/fr.yml +60 -19
- data/config/locales/it.yml +60 -19
- data/config/locales/ja.yml +60 -19
- data/config/locales/nl.yml +60 -19
- data/config/locales/pl.yml +60 -19
- data/config/locales/pt-BR.yml +60 -19
- data/config/locales/ru.yml +60 -19
- data/config/locales/sv.yml +63 -0
- data/config/locales/tr.yml +60 -19
- data/config/locales/uk.yml +60 -19
- data/config/locales/vi.yml +60 -19
- data/config/locales/zh-CN.yml +60 -19
- data/lib/active_storage_validations/analyzer/audio_analyzer.rb +58 -0
- data/lib/active_storage_validations/analyzer/content_type_analyzer.rb +60 -0
- data/lib/active_storage_validations/analyzer/image_analyzer/image_magick.rb +46 -0
- data/lib/active_storage_validations/analyzer/image_analyzer/vips.rb +56 -0
- data/lib/active_storage_validations/analyzer/image_analyzer.rb +49 -0
- data/lib/active_storage_validations/analyzer/null_analyzer.rb +18 -0
- data/lib/active_storage_validations/analyzer/pdf_analyzer.rb +89 -0
- data/lib/active_storage_validations/analyzer/shared/asv_ff_probable.rb +61 -0
- data/lib/active_storage_validations/analyzer/video_analyzer.rb +130 -0
- data/lib/active_storage_validations/analyzer.rb +88 -0
- data/lib/active_storage_validations/aspect_ratio_validator.rb +157 -97
- data/lib/active_storage_validations/attached_validator.rb +22 -5
- data/lib/active_storage_validations/base_comparison_validator.rb +83 -0
- data/lib/active_storage_validations/content_type_validator.rb +219 -31
- data/lib/active_storage_validations/dimension_validator.rb +187 -97
- data/lib/active_storage_validations/duration_validator.rb +70 -0
- data/lib/active_storage_validations/extensors/asv_blob_metadatable.rb +56 -0
- data/lib/active_storage_validations/extensors/asv_marcelable.rb +12 -0
- data/lib/active_storage_validations/limit_validator.rb +76 -9
- data/lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb +119 -0
- data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +48 -25
- data/lib/active_storage_validations/matchers/base_comparison_validator_matcher.rb +150 -0
- data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +98 -39
- data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +93 -55
- data/lib/active_storage_validations/matchers/duration_validator_matcher.rb +39 -0
- data/lib/active_storage_validations/matchers/limit_validator_matcher.rb +127 -0
- data/lib/active_storage_validations/matchers/pages_validator_matcher.rb +39 -0
- data/lib/active_storage_validations/matchers/processable_file_validator_matcher.rb +78 -0
- data/lib/active_storage_validations/matchers/shared/asv_active_storageable.rb +19 -0
- data/lib/active_storage_validations/matchers/shared/asv_allow_blankable.rb +28 -0
- data/lib/active_storage_validations/matchers/shared/asv_attachable.rb +72 -0
- data/lib/active_storage_validations/matchers/shared/asv_contextable.rb +57 -0
- data/lib/active_storage_validations/matchers/shared/asv_messageable.rb +28 -0
- data/lib/active_storage_validations/matchers/shared/asv_rspecable.rb +27 -0
- data/lib/active_storage_validations/matchers/shared/asv_validatable.rb +56 -0
- data/lib/active_storage_validations/matchers/size_validator_matcher.rb +17 -71
- data/lib/active_storage_validations/matchers/total_size_validator_matcher.rb +47 -0
- data/lib/active_storage_validations/matchers.rb +17 -21
- data/lib/active_storage_validations/pages_validator.rb +61 -0
- data/lib/active_storage_validations/processable_file_validator.rb +37 -0
- data/lib/active_storage_validations/railtie.rb +14 -0
- data/lib/active_storage_validations/shared/asv_active_storageable.rb +30 -0
- data/lib/active_storage_validations/shared/asv_analyzable.rb +89 -0
- data/lib/active_storage_validations/shared/asv_attachable.rb +236 -0
- data/lib/active_storage_validations/shared/asv_errorable.rb +64 -0
- data/lib/active_storage_validations/shared/asv_loggable.rb +11 -0
- data/lib/active_storage_validations/shared/asv_optionable.rb +29 -0
- data/lib/active_storage_validations/shared/asv_symbolizable.rb +14 -0
- data/lib/active_storage_validations/size_validator.rb +24 -41
- data/lib/active_storage_validations/total_size_validator.rb +52 -0
- data/lib/active_storage_validations/version.rb +1 -1
- data/lib/active_storage_validations.rb +27 -13
- metadata +113 -31
- data/lib/active_storage_validations/metadata.rb +0 -151
- data/lib/active_storage_validations/option_proc_unfolding.rb +0 -16
- data/lib/active_storage_validations/processable_image_validator.rb +0 -43
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:
|
|
4
|
+
version: 3.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:
|
|
11
|
+
date: 2025-09-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activejob
|
|
@@ -16,56 +16,70 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 6.1.4
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 6.1.4
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: activemodel
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 6.1.4
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 6.1.4
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: activestorage
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
47
|
+
version: 6.1.4
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
54
|
+
version: 6.1.4
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: activesupport
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
61
|
+
version: 6.1.4
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version:
|
|
68
|
+
version: 6.1.4
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: marcel
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 1.0.3
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 1.0.3
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
84
|
name: combustion
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -95,35 +109,61 @@ dependencies:
|
|
|
95
109
|
- !ruby/object:Gem::Version
|
|
96
110
|
version: 4.9.5
|
|
97
111
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
112
|
+
name: minitest-focus
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
100
114
|
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '1.4'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '1.4'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: minitest-mock_expectations
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '1.2'
|
|
101
132
|
- - ">="
|
|
102
133
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 2.
|
|
134
|
+
version: 1.2.0
|
|
104
135
|
type: :development
|
|
105
136
|
prerelease: false
|
|
106
137
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
138
|
requirements:
|
|
139
|
+
- - "~>"
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '1.2'
|
|
108
142
|
- - ">="
|
|
109
143
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 2.
|
|
144
|
+
version: 1.2.0
|
|
111
145
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
146
|
+
name: minitest-stub_any_instance
|
|
113
147
|
requirement: !ruby/object:Gem::Requirement
|
|
114
148
|
requirements:
|
|
149
|
+
- - "~>"
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '1.0'
|
|
115
152
|
- - ">="
|
|
116
153
|
- !ruby/object:Gem::Version
|
|
117
|
-
version:
|
|
154
|
+
version: 1.0.3
|
|
118
155
|
type: :development
|
|
119
156
|
prerelease: false
|
|
120
157
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
158
|
requirements:
|
|
159
|
+
- - "~>"
|
|
160
|
+
- !ruby/object:Gem::Version
|
|
161
|
+
version: '1.0'
|
|
122
162
|
- - ">="
|
|
123
163
|
- !ruby/object:Gem::Version
|
|
124
|
-
version:
|
|
164
|
+
version: 1.0.3
|
|
125
165
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
166
|
+
name: pry
|
|
127
167
|
requirement: !ruby/object:Gem::Requirement
|
|
128
168
|
requirements:
|
|
129
169
|
- - ">="
|
|
@@ -137,21 +177,21 @@ dependencies:
|
|
|
137
177
|
- !ruby/object:Gem::Version
|
|
138
178
|
version: '0'
|
|
139
179
|
- !ruby/object:Gem::Dependency
|
|
140
|
-
name:
|
|
180
|
+
name: ruby-vips
|
|
141
181
|
requirement: !ruby/object:Gem::Requirement
|
|
142
182
|
requirements:
|
|
143
183
|
- - ">="
|
|
144
184
|
- !ruby/object:Gem::Version
|
|
145
|
-
version:
|
|
185
|
+
version: 2.1.0
|
|
146
186
|
type: :development
|
|
147
187
|
prerelease: false
|
|
148
188
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
189
|
requirements:
|
|
150
190
|
- - ">="
|
|
151
191
|
- !ruby/object:Gem::Version
|
|
152
|
-
version:
|
|
192
|
+
version: 2.1.0
|
|
153
193
|
- !ruby/object:Gem::Dependency
|
|
154
|
-
name:
|
|
194
|
+
name: simplecov
|
|
155
195
|
requirement: !ruby/object:Gem::Requirement
|
|
156
196
|
requirements:
|
|
157
197
|
- - ">="
|
|
@@ -165,7 +205,7 @@ dependencies:
|
|
|
165
205
|
- !ruby/object:Gem::Version
|
|
166
206
|
version: '0'
|
|
167
207
|
- !ruby/object:Gem::Dependency
|
|
168
|
-
name:
|
|
208
|
+
name: sqlite3
|
|
169
209
|
requirement: !ruby/object:Gem::Requirement
|
|
170
210
|
requirements:
|
|
171
211
|
- - ">="
|
|
@@ -179,19 +219,19 @@ dependencies:
|
|
|
179
219
|
- !ruby/object:Gem::Version
|
|
180
220
|
version: '0'
|
|
181
221
|
- !ruby/object:Gem::Dependency
|
|
182
|
-
name:
|
|
222
|
+
name: webmock
|
|
183
223
|
requirement: !ruby/object:Gem::Requirement
|
|
184
224
|
requirements:
|
|
185
225
|
- - ">="
|
|
186
226
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: '
|
|
227
|
+
version: '3'
|
|
188
228
|
type: :development
|
|
189
229
|
prerelease: false
|
|
190
230
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
231
|
requirements:
|
|
192
232
|
- - ">="
|
|
193
233
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: '
|
|
234
|
+
version: '3'
|
|
195
235
|
description: Validations for Active Storage (presence)
|
|
196
236
|
email:
|
|
197
237
|
- igorkasyanchuk@gmail.com
|
|
@@ -202,7 +242,9 @@ files:
|
|
|
202
242
|
- MIT-LICENSE
|
|
203
243
|
- README.md
|
|
204
244
|
- Rakefile
|
|
245
|
+
- config/locales/da.yml
|
|
205
246
|
- config/locales/de.yml
|
|
247
|
+
- config/locales/en-GB.yml
|
|
206
248
|
- config/locales/en.yml
|
|
207
249
|
- config/locales/es.yml
|
|
208
250
|
- config/locales/fr.yml
|
|
@@ -212,33 +254,73 @@ files:
|
|
|
212
254
|
- config/locales/pl.yml
|
|
213
255
|
- config/locales/pt-BR.yml
|
|
214
256
|
- config/locales/ru.yml
|
|
257
|
+
- config/locales/sv.yml
|
|
215
258
|
- config/locales/tr.yml
|
|
216
259
|
- config/locales/uk.yml
|
|
217
260
|
- config/locales/vi.yml
|
|
218
261
|
- config/locales/zh-CN.yml
|
|
219
262
|
- lib/active_storage_validations.rb
|
|
263
|
+
- lib/active_storage_validations/analyzer.rb
|
|
264
|
+
- lib/active_storage_validations/analyzer/audio_analyzer.rb
|
|
265
|
+
- lib/active_storage_validations/analyzer/content_type_analyzer.rb
|
|
266
|
+
- lib/active_storage_validations/analyzer/image_analyzer.rb
|
|
267
|
+
- lib/active_storage_validations/analyzer/image_analyzer/image_magick.rb
|
|
268
|
+
- lib/active_storage_validations/analyzer/image_analyzer/vips.rb
|
|
269
|
+
- lib/active_storage_validations/analyzer/null_analyzer.rb
|
|
270
|
+
- lib/active_storage_validations/analyzer/pdf_analyzer.rb
|
|
271
|
+
- lib/active_storage_validations/analyzer/shared/asv_ff_probable.rb
|
|
272
|
+
- lib/active_storage_validations/analyzer/video_analyzer.rb
|
|
220
273
|
- lib/active_storage_validations/aspect_ratio_validator.rb
|
|
221
274
|
- lib/active_storage_validations/attached_validator.rb
|
|
275
|
+
- lib/active_storage_validations/base_comparison_validator.rb
|
|
222
276
|
- lib/active_storage_validations/content_type_validator.rb
|
|
223
277
|
- lib/active_storage_validations/dimension_validator.rb
|
|
278
|
+
- lib/active_storage_validations/duration_validator.rb
|
|
224
279
|
- lib/active_storage_validations/engine.rb
|
|
280
|
+
- lib/active_storage_validations/extensors/asv_blob_metadatable.rb
|
|
281
|
+
- lib/active_storage_validations/extensors/asv_marcelable.rb
|
|
225
282
|
- lib/active_storage_validations/limit_validator.rb
|
|
226
283
|
- lib/active_storage_validations/matchers.rb
|
|
284
|
+
- lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb
|
|
227
285
|
- lib/active_storage_validations/matchers/attached_validator_matcher.rb
|
|
286
|
+
- lib/active_storage_validations/matchers/base_comparison_validator_matcher.rb
|
|
228
287
|
- lib/active_storage_validations/matchers/content_type_validator_matcher.rb
|
|
229
288
|
- lib/active_storage_validations/matchers/dimension_validator_matcher.rb
|
|
289
|
+
- lib/active_storage_validations/matchers/duration_validator_matcher.rb
|
|
290
|
+
- lib/active_storage_validations/matchers/limit_validator_matcher.rb
|
|
291
|
+
- lib/active_storage_validations/matchers/pages_validator_matcher.rb
|
|
292
|
+
- lib/active_storage_validations/matchers/processable_file_validator_matcher.rb
|
|
293
|
+
- lib/active_storage_validations/matchers/shared/asv_active_storageable.rb
|
|
294
|
+
- lib/active_storage_validations/matchers/shared/asv_allow_blankable.rb
|
|
295
|
+
- lib/active_storage_validations/matchers/shared/asv_attachable.rb
|
|
296
|
+
- lib/active_storage_validations/matchers/shared/asv_contextable.rb
|
|
297
|
+
- lib/active_storage_validations/matchers/shared/asv_messageable.rb
|
|
298
|
+
- lib/active_storage_validations/matchers/shared/asv_rspecable.rb
|
|
299
|
+
- lib/active_storage_validations/matchers/shared/asv_validatable.rb
|
|
230
300
|
- lib/active_storage_validations/matchers/size_validator_matcher.rb
|
|
231
|
-
- lib/active_storage_validations/
|
|
232
|
-
- lib/active_storage_validations/
|
|
233
|
-
- lib/active_storage_validations/
|
|
301
|
+
- lib/active_storage_validations/matchers/total_size_validator_matcher.rb
|
|
302
|
+
- lib/active_storage_validations/pages_validator.rb
|
|
303
|
+
- lib/active_storage_validations/processable_file_validator.rb
|
|
234
304
|
- lib/active_storage_validations/railtie.rb
|
|
305
|
+
- lib/active_storage_validations/shared/asv_active_storageable.rb
|
|
306
|
+
- lib/active_storage_validations/shared/asv_analyzable.rb
|
|
307
|
+
- lib/active_storage_validations/shared/asv_attachable.rb
|
|
308
|
+
- lib/active_storage_validations/shared/asv_errorable.rb
|
|
309
|
+
- lib/active_storage_validations/shared/asv_loggable.rb
|
|
310
|
+
- lib/active_storage_validations/shared/asv_optionable.rb
|
|
311
|
+
- lib/active_storage_validations/shared/asv_symbolizable.rb
|
|
235
312
|
- lib/active_storage_validations/size_validator.rb
|
|
313
|
+
- lib/active_storage_validations/total_size_validator.rb
|
|
236
314
|
- lib/active_storage_validations/version.rb
|
|
237
315
|
- lib/tasks/active_storage_validations_tasks.rake
|
|
238
316
|
homepage: https://github.com/igorkasyanchuk/active_storage_validations
|
|
239
317
|
licenses:
|
|
240
318
|
- MIT
|
|
241
|
-
metadata:
|
|
319
|
+
metadata:
|
|
320
|
+
rubygems_mfa_required: 'true'
|
|
321
|
+
changelog_uri: https://github.com/igorkasyanchuk/active_storage_validations/blob/master/CHANGES.md
|
|
322
|
+
source_code_uri: https://github.com/igorkasyanchuk/active_storage_validations
|
|
323
|
+
bug_tracker_uri: https://github.com/igorkasyanchuk/active_storage_validations/issues
|
|
242
324
|
post_install_message:
|
|
243
325
|
rdoc_options: []
|
|
244
326
|
require_paths:
|
|
@@ -247,14 +329,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
247
329
|
requirements:
|
|
248
330
|
- - ">="
|
|
249
331
|
- !ruby/object:Gem::Version
|
|
250
|
-
version:
|
|
332
|
+
version: 2.5.0
|
|
251
333
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
252
334
|
requirements:
|
|
253
335
|
- - ">="
|
|
254
336
|
- !ruby/object:Gem::Version
|
|
255
337
|
version: '0'
|
|
256
338
|
requirements: []
|
|
257
|
-
rubygems_version: 3.
|
|
339
|
+
rubygems_version: 3.5.16
|
|
258
340
|
signing_key:
|
|
259
341
|
specification_version: 4
|
|
260
342
|
summary: Validations for Active Storage
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
module ActiveStorageValidations
|
|
2
|
-
class Metadata
|
|
3
|
-
class InvalidImageError < StandardError; end
|
|
4
|
-
|
|
5
|
-
attr_reader :file
|
|
6
|
-
|
|
7
|
-
def initialize(file)
|
|
8
|
-
require_image_processor
|
|
9
|
-
@file = file
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def image_processor
|
|
13
|
-
Rails.application.config.active_storage.variant_processor
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def exception_class
|
|
17
|
-
if image_processor == :vips && defined?(Vips)
|
|
18
|
-
Vips::Error
|
|
19
|
-
elsif defined?(MiniMagick)
|
|
20
|
-
MiniMagick::Error
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def require_image_processor
|
|
25
|
-
if image_processor == :vips
|
|
26
|
-
require 'vips' unless defined?(Vips)
|
|
27
|
-
else
|
|
28
|
-
require 'mini_magick' unless defined?(MiniMagick)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def metadata
|
|
33
|
-
read_image do |image|
|
|
34
|
-
if rotated_image?(image)
|
|
35
|
-
{ width: image.height, height: image.width }
|
|
36
|
-
else
|
|
37
|
-
{ width: image.width, height: image.height }
|
|
38
|
-
end
|
|
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
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
def read_image
|
|
55
|
-
is_string = file.is_a?(String)
|
|
56
|
-
if is_string || file.is_a?(ActiveStorage::Blob)
|
|
57
|
-
blob =
|
|
58
|
-
if is_string
|
|
59
|
-
if Rails.gem_version < Gem::Version.new('6.1.0')
|
|
60
|
-
ActiveStorage::Blob.find_signed(file)
|
|
61
|
-
else
|
|
62
|
-
ActiveStorage::Blob.find_signed!(file)
|
|
63
|
-
end
|
|
64
|
-
else
|
|
65
|
-
file
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
tempfile = Tempfile.new(["ActiveStorage-#{blob.id}-", blob.filename.extension_with_delimiter])
|
|
69
|
-
tempfile.binmode
|
|
70
|
-
|
|
71
|
-
blob.download do |chunk|
|
|
72
|
-
tempfile.write(chunk)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
tempfile.flush
|
|
76
|
-
tempfile.rewind
|
|
77
|
-
|
|
78
|
-
image = new_image_from_path(tempfile.path)
|
|
79
|
-
else
|
|
80
|
-
file_path = read_file_path
|
|
81
|
-
image = new_image_from_path(file_path)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
raise InvalidImageError unless valid_image?(image)
|
|
86
|
-
yield image if block_given?
|
|
87
|
-
rescue LoadError, NameError
|
|
88
|
-
logger.info "Skipping image analysis because the mini_magick or ruby-vips gem isn't installed"
|
|
89
|
-
{}
|
|
90
|
-
rescue exception_class => error
|
|
91
|
-
logger.error "Skipping image analysis due to an #{exception_class.name.split('::').map(&:downcase).join(' ').capitalize} error: #{error.message}"
|
|
92
|
-
{}
|
|
93
|
-
ensure
|
|
94
|
-
image = nil
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def new_image_from_path(path)
|
|
98
|
-
if image_processor == :vips && defined?(Vips) && (Vips::get_suffixes.include?(File.extname(path).downcase) || !Vips::respond_to?(:vips_foreign_get_suffixes))
|
|
99
|
-
Vips::Image.new_from_file(path)
|
|
100
|
-
elsif defined?(MiniMagick)
|
|
101
|
-
MiniMagick::Image.new(path)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def valid_image?(image)
|
|
106
|
-
return false unless image
|
|
107
|
-
|
|
108
|
-
image_processor == :vips && image.is_a?(Vips::Image) ? image.avg : image.valid?
|
|
109
|
-
rescue exception_class
|
|
110
|
-
false
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def rotated_image?(image)
|
|
114
|
-
if image_processor == :vips && image.is_a?(Vips::Image)
|
|
115
|
-
image.get('exif-ifd0-Orientation').include?('Right-top') ||
|
|
116
|
-
image.get('exif-ifd0-Orientation').include?('Left-bottom')
|
|
117
|
-
else
|
|
118
|
-
%w[ RightTop LeftBottom ].include?(image["%[orientation]"])
|
|
119
|
-
end
|
|
120
|
-
rescue exception_class # field "exif-ifd0-Orientation" not found
|
|
121
|
-
false
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def read_file_path
|
|
125
|
-
case file
|
|
126
|
-
when ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile
|
|
127
|
-
file.path
|
|
128
|
-
when Hash
|
|
129
|
-
io = file.fetch(:io)
|
|
130
|
-
if io.is_a?(StringIO)
|
|
131
|
-
tempfile = Tempfile.new([File.basename(file[:filename], '.*'), File.extname(file[:filename])])
|
|
132
|
-
tempfile.binmode
|
|
133
|
-
IO.copy_stream(io, tempfile)
|
|
134
|
-
io.rewind
|
|
135
|
-
tempfile.flush
|
|
136
|
-
tempfile.rewind
|
|
137
|
-
tempfile.path
|
|
138
|
-
else
|
|
139
|
-
File.open(io).path
|
|
140
|
-
end
|
|
141
|
-
else
|
|
142
|
-
raise "Something wrong with params."
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def logger
|
|
147
|
-
Rails.logger
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
end
|
|
151
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module ActiveStorageValidations
|
|
2
|
-
module OptionProcUnfolding
|
|
3
|
-
|
|
4
|
-
def unfold_procs(record, object, only_keys)
|
|
5
|
-
case object
|
|
6
|
-
when Hash
|
|
7
|
-
object.merge(object) { |key, value| only_keys&.exclude?(key) ? {} : unfold_procs(record, value, nil) }
|
|
8
|
-
when Array
|
|
9
|
-
object.map { |o| unfold_procs(record, o, only_keys) }
|
|
10
|
-
else
|
|
11
|
-
object.is_a?(Proc) ? object.call(record) : object
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
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
|