image_vise 0.1.6 → 0.2.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.
- checksums.yaml +4 -4
- data/.gitignore +8 -0
- data/.travis.yml +13 -0
- data/DEVELOPMENT.md +0 -11
- data/Gemfile +2 -20
- data/Rakefile +3 -26
- data/image_vise.gemspec +37 -132
- data/lib/image_vise/file_response.rb +2 -2
- data/lib/image_vise/image_request.rb +2 -0
- data/lib/image_vise/operators/background_fill.rb +18 -0
- data/lib/image_vise/operators/ellipse_stencil.rb +7 -5
- data/lib/image_vise/operators/force_jpg_out.rb +17 -0
- data/lib/image_vise/pipeline.rb +13 -3
- data/lib/image_vise/render_engine.rb +36 -64
- data/lib/image_vise/version.rb +3 -0
- data/lib/image_vise/writers/auto_writer.rb +23 -0
- data/lib/image_vise/writers/jpeg_writer.rb +9 -0
- data/lib/image_vise.rb +19 -19
- metadata +43 -135
- data/spec/image_vise/auto_orient_spec.rb +0 -10
- data/spec/image_vise/crop_spec.rb +0 -20
- data/spec/image_vise/ellipse_stencil_spec.rb +0 -19
- data/spec/image_vise/fetcher_file_spec.rb +0 -48
- data/spec/image_vise/fetcher_http_spec.rb +0 -44
- data/spec/image_vise/file_response_spec.rb +0 -45
- data/spec/image_vise/fit_crop_spec.rb +0 -20
- data/spec/image_vise/geom_spec.rb +0 -33
- data/spec/image_vise/image_request_spec.rb +0 -62
- data/spec/image_vise/pipeline_spec.rb +0 -72
- data/spec/image_vise/render_engine_spec.rb +0 -325
- data/spec/image_vise/sharpen_spec.rb +0 -17
- data/spec/image_vise/srgb_spec.rb +0 -28
- data/spec/image_vise/strip_metadata_spec.rb +0 -14
- data/spec/image_vise_spec.rb +0 -110
- data/spec/layers-with-blending.psd +0 -0
- data/spec/spec_helper.rb +0 -103
- data/spec/test_server.rb +0 -61
- data/spec/waterside_magic_hour.jpg +0 -0
- data/spec/waterside_magic_hour.psd +0 -0
- data/spec/waterside_magic_hour_adobergb.jpg +0 -0
- data/spec/waterside_magic_hour_gray.tif +0 -0
- data/spec/waterside_magic_hour_transp.png +0 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
# Picks the most reasonable "default" output format for web resources. In practice, if the
|
2
|
+
# image contains transparency (an alpha channel) PNG will be chosen, and if not - JPEG will
|
3
|
+
# be chosen. Since ImageVise URLs do not contain a file extension we are free to pick
|
4
|
+
# the suitable format at render time
|
5
|
+
class ImageVise::AutoWriter
|
6
|
+
# The default file type for images with alpha
|
7
|
+
PNG_FILE_TYPE = MagicBytes::FileType.new('png','image/png').freeze
|
8
|
+
|
9
|
+
# Renders the file as a jpg if the custom output filetype operator is used
|
10
|
+
JPG_FILE_TYPE = MagicBytes::FileType.new('jpg','image/jpeg').freeze
|
11
|
+
|
12
|
+
def write_image!(magick_image, _, render_to_path)
|
13
|
+
# If processing the image has created an alpha channel, use PNG always.
|
14
|
+
# Otherwise, keep the original format for as far as the supported formats list goes.
|
15
|
+
render_file_type = if magick_image.alpha?
|
16
|
+
PNG_FILE_TYPE
|
17
|
+
else
|
18
|
+
JPG_FILE_TYPE
|
19
|
+
end
|
20
|
+
magick_image.format = render_file_type.ext
|
21
|
+
magick_image.write(render_to_path)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class ImageVise::JPGWriter < Ks.strict(:quality)
|
2
|
+
JPG_FILE_TYPE = MagicBytes::FileType.new('jpg','image/jpeg').freeze
|
3
|
+
|
4
|
+
def write_image!(magick_image, _, render_to_path)
|
5
|
+
q = self.quality # to avoid the changing "self" context
|
6
|
+
magick_image.format = JPG_FILE_TYPE.ext
|
7
|
+
magick_image.write(render_to_path) { self.quality = q }
|
8
|
+
end
|
9
|
+
end
|
data/lib/image_vise.rb
CHANGED
@@ -8,37 +8,37 @@ require 'base64'
|
|
8
8
|
require 'rack'
|
9
9
|
|
10
10
|
class ImageVise
|
11
|
-
|
11
|
+
require_relative 'image_vise/version'
|
12
12
|
S_MUTEX = Mutex.new
|
13
13
|
private_constant :S_MUTEX
|
14
|
-
|
14
|
+
|
15
15
|
@allowed_hosts = Set.new
|
16
16
|
@keys = Set.new
|
17
17
|
@operators = {}
|
18
18
|
@allowed_glob_patterns = Set.new
|
19
19
|
@fetchers = {}
|
20
|
-
|
20
|
+
|
21
21
|
class << self
|
22
22
|
# Resets all allowed hosts
|
23
23
|
def reset_allowed_hosts!
|
24
24
|
S_MUTEX.synchronize { @allowed_hosts.clear }
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# Add an allowed host
|
28
28
|
def add_allowed_host!(hostname)
|
29
29
|
S_MUTEX.synchronize { @allowed_hosts << hostname }
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# Returns both the allowed hosts added at runtime and the ones set in the constant
|
33
33
|
def allowed_hosts
|
34
34
|
S_MUTEX.synchronize { @allowed_hosts.to_a }
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
# Removes all set keys
|
38
38
|
def reset_secret_keys!
|
39
39
|
S_MUTEX.synchronize { @keys.clear }
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def allow_filesystem_source!(glob_pattern)
|
43
43
|
S_MUTEX.synchronize { @allowed_glob_patterns << glob_pattern }
|
44
44
|
end
|
@@ -52,24 +52,24 @@ class ImageVise
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# Adds a key against which the parameters are going to be verified.
|
55
|
-
# Multiple applications may have their own different keys,
|
55
|
+
# Multiple applications may have their own different keys,
|
56
56
|
# so we need to have multiple keys.
|
57
57
|
def add_secret_key!(key)
|
58
58
|
S_MUTEX.synchronize { @keys << key }
|
59
59
|
self
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
# Returns the array of defined keys or raises an exception if no keys have been set yet
|
63
63
|
def secret_keys
|
64
64
|
keys = S_MUTEX.synchronize { @keys.any? && @keys.to_a }
|
65
65
|
keys or raise "No keys set, add a key using `ImageVise.add_secret_key!(key)'"
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
# Generate a set of querystring params for a resized image. Yields a Pipeline object that
|
69
69
|
# will receive method calls for adding image operations to a stack.
|
70
70
|
#
|
71
71
|
# ImageVise.image_params(src_url: image_url_on_s3, secret: '...') do |p|
|
72
|
-
# p.center_fit width: 128, height: 128
|
72
|
+
# p.center_fit width: 128, height: 128
|
73
73
|
# p.elliptic_stencil
|
74
74
|
# end #=> {q: '...', sig: '...'}
|
75
75
|
#
|
@@ -88,7 +88,7 @@ class ImageVise
|
|
88
88
|
# will receive method calls for adding image operations to a stack.
|
89
89
|
#
|
90
90
|
# ImageVise.image_path(src_url: image_url_on_s3, secret: '...') do |p|
|
91
|
-
# p.center_fit width: 128, height: 128
|
91
|
+
# p.center_fit width: 128, height: 128
|
92
92
|
# p.elliptic_stencil
|
93
93
|
# end #=> "/abcdef/xyz123"
|
94
94
|
#
|
@@ -112,26 +112,26 @@ class ImageVise
|
|
112
112
|
def operator_from(operator_name)
|
113
113
|
@operators.fetch(operator_name.to_s)
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
def defined_operator_names
|
117
117
|
@operators.keys
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
def register_fetcher(scheme, fetcher)
|
121
121
|
S_MUTEX.synchronize { @fetchers[scheme.to_s] = fetcher }
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
def fetcher_for(scheme)
|
125
125
|
S_MUTEX.synchronize { @fetchers[scheme.to_s] or raise "No fetcher registered for #{scheme}" }
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
def operator_name_for(operator)
|
129
129
|
S_MUTEX.synchronize do
|
130
130
|
@operators.key(operator.class) or raise "Operator #{operator.inspect} not registered using ImageVise.add_operator"
|
131
131
|
end
|
132
132
|
end
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
# Made available since the object that is used with `mount()` in Rails
|
136
136
|
# has to, by itself, to respond to `call`.
|
137
137
|
#
|
@@ -146,11 +146,11 @@ class ImageVise
|
|
146
146
|
def self.call(rack_env)
|
147
147
|
ImageVise::RenderEngine.new.call(rack_env)
|
148
148
|
end
|
149
|
-
|
149
|
+
|
150
150
|
def call(rack_env)
|
151
151
|
ImageVise::RenderEngine.new.call(rack_env)
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
# Used as a shorthand to force-destroy Magick images in ensure() blocks. Since
|
155
155
|
# ensure blocks sometimes deal with variables in inconsistent states (variable
|
156
156
|
# in scope but not yet set to an image) we take the possibility of nils into account.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_vise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: patron
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.15'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: exceptional_fork
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '1.2'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.2'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: ks
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,88 +56,60 @@ dependencies:
|
|
70
56
|
name: magic_bytes
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - "
|
59
|
+
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '1'
|
76
62
|
type: :runtime
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - "
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: bundler
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: yard
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
66
|
+
- - "~>"
|
109
67
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
68
|
+
version: '1'
|
111
69
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
70
|
+
name: rack
|
113
71
|
requirement: !ruby/object:Gem::Requirement
|
114
72
|
requirements:
|
115
|
-
- - "
|
73
|
+
- - "~>"
|
116
74
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
118
|
-
type: :
|
75
|
+
version: '1'
|
76
|
+
type: :runtime
|
119
77
|
prerelease: false
|
120
78
|
version_requirements: !ruby/object:Gem::Requirement
|
121
79
|
requirements:
|
122
|
-
- - "
|
80
|
+
- - "~>"
|
123
81
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
82
|
+
version: '1'
|
125
83
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
84
|
+
name: bundler
|
127
85
|
requirement: !ruby/object:Gem::Requirement
|
128
86
|
requirements:
|
129
|
-
- - "
|
87
|
+
- - "~>"
|
130
88
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
89
|
+
version: '1.7'
|
132
90
|
type: :development
|
133
91
|
prerelease: false
|
134
92
|
version_requirements: !ruby/object:Gem::Requirement
|
135
93
|
requirements:
|
136
|
-
- - "
|
94
|
+
- - "~>"
|
137
95
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
96
|
+
version: '1.7'
|
139
97
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
98
|
+
name: rake
|
141
99
|
requirement: !ruby/object:Gem::Requirement
|
142
100
|
requirements:
|
143
|
-
- - "
|
101
|
+
- - "~>"
|
144
102
|
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
103
|
+
version: '10.0'
|
146
104
|
type: :development
|
147
105
|
prerelease: false
|
148
106
|
version_requirements: !ruby/object:Gem::Requirement
|
149
107
|
requirements:
|
150
|
-
- - "
|
108
|
+
- - "~>"
|
151
109
|
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
110
|
+
version: '10.0'
|
153
111
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
112
|
+
name: rack-test
|
155
113
|
requirement: !ruby/object:Gem::Requirement
|
156
114
|
requirements:
|
157
115
|
- - ">="
|
@@ -165,21 +123,21 @@ dependencies:
|
|
165
123
|
- !ruby/object:Gem::Version
|
166
124
|
version: '0'
|
167
125
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
126
|
+
name: rspec
|
169
127
|
requirement: !ruby/object:Gem::Requirement
|
170
128
|
requirements:
|
171
129
|
- - "~>"
|
172
130
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
131
|
+
version: '3.0'
|
174
132
|
type: :development
|
175
133
|
prerelease: false
|
176
134
|
version_requirements: !ruby/object:Gem::Requirement
|
177
135
|
requirements:
|
178
136
|
- - "~>"
|
179
137
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
138
|
+
version: '3.0'
|
181
139
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
140
|
+
name: addressable
|
183
141
|
requirement: !ruby/object:Gem::Requirement
|
184
142
|
requirements:
|
185
143
|
- - ">="
|
@@ -193,7 +151,7 @@ dependencies:
|
|
193
151
|
- !ruby/object:Gem::Version
|
194
152
|
version: '0'
|
195
153
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
154
|
+
name: strenv
|
197
155
|
requirement: !ruby/object:Gem::Requirement
|
198
156
|
requirements:
|
199
157
|
- - ">="
|
@@ -207,41 +165,7 @@ dependencies:
|
|
207
165
|
- !ruby/object:Gem::Version
|
208
166
|
version: '0'
|
209
167
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
211
|
-
requirement: !ruby/object:Gem::Requirement
|
212
|
-
requirements:
|
213
|
-
- - "<"
|
214
|
-
- !ruby/object:Gem::Version
|
215
|
-
version: '3.3'
|
216
|
-
- - "~>"
|
217
|
-
- !ruby/object:Gem::Version
|
218
|
-
version: '3.2'
|
219
|
-
type: :development
|
220
|
-
prerelease: false
|
221
|
-
version_requirements: !ruby/object:Gem::Requirement
|
222
|
-
requirements:
|
223
|
-
- - "<"
|
224
|
-
- !ruby/object:Gem::Version
|
225
|
-
version: '3.3'
|
226
|
-
- - "~>"
|
227
|
-
- !ruby/object:Gem::Version
|
228
|
-
version: '3.2'
|
229
|
-
- !ruby/object:Gem::Dependency
|
230
|
-
name: rake
|
231
|
-
requirement: !ruby/object:Gem::Requirement
|
232
|
-
requirements:
|
233
|
-
- - "~>"
|
234
|
-
- !ruby/object:Gem::Version
|
235
|
-
version: '10'
|
236
|
-
type: :development
|
237
|
-
prerelease: false
|
238
|
-
version_requirements: !ruby/object:Gem::Requirement
|
239
|
-
requirements:
|
240
|
-
- - "~>"
|
241
|
-
- !ruby/object:Gem::Version
|
242
|
-
version: '10'
|
243
|
-
- !ruby/object:Gem::Dependency
|
244
|
-
name: jeweler
|
168
|
+
name: simplecov
|
245
169
|
requirement: !ruby/object:Gem::Requirement
|
246
170
|
requirements:
|
247
171
|
- - ">="
|
@@ -255,13 +179,14 @@ dependencies:
|
|
255
179
|
- !ruby/object:Gem::Version
|
256
180
|
version: '0'
|
257
181
|
description: Image processing via URLs
|
258
|
-
email:
|
182
|
+
email:
|
183
|
+
- me@julik.nl
|
259
184
|
executables: []
|
260
185
|
extensions: []
|
261
|
-
extra_rdoc_files:
|
262
|
-
- LICENSE.txt
|
263
|
-
- README.md
|
186
|
+
extra_rdoc_files: []
|
264
187
|
files:
|
188
|
+
- ".gitignore"
|
189
|
+
- ".travis.yml"
|
265
190
|
- DEVELOPMENT.md
|
266
191
|
- Gemfile
|
267
192
|
- LICENSE.txt
|
@@ -279,9 +204,11 @@ files:
|
|
279
204
|
- lib/image_vise/file_response.rb
|
280
205
|
- lib/image_vise/image_request.rb
|
281
206
|
- lib/image_vise/operators/auto_orient.rb
|
207
|
+
- lib/image_vise/operators/background_fill.rb
|
282
208
|
- lib/image_vise/operators/crop.rb
|
283
209
|
- lib/image_vise/operators/ellipse_stencil.rb
|
284
210
|
- lib/image_vise/operators/fit_crop.rb
|
211
|
+
- lib/image_vise/operators/force_jpg_out.rb
|
285
212
|
- lib/image_vise/operators/geom.rb
|
286
213
|
- lib/image_vise/operators/sRGB_v4_ICC_preference_displayclass.icc
|
287
214
|
- lib/image_vise/operators/sharpen.rb
|
@@ -289,33 +216,14 @@ files:
|
|
289
216
|
- lib/image_vise/operators/strip_metadata.rb
|
290
217
|
- lib/image_vise/pipeline.rb
|
291
218
|
- lib/image_vise/render_engine.rb
|
292
|
-
-
|
293
|
-
-
|
294
|
-
-
|
295
|
-
- spec/image_vise/fetcher_file_spec.rb
|
296
|
-
- spec/image_vise/fetcher_http_spec.rb
|
297
|
-
- spec/image_vise/file_response_spec.rb
|
298
|
-
- spec/image_vise/fit_crop_spec.rb
|
299
|
-
- spec/image_vise/geom_spec.rb
|
300
|
-
- spec/image_vise/image_request_spec.rb
|
301
|
-
- spec/image_vise/pipeline_spec.rb
|
302
|
-
- spec/image_vise/render_engine_spec.rb
|
303
|
-
- spec/image_vise/sharpen_spec.rb
|
304
|
-
- spec/image_vise/srgb_spec.rb
|
305
|
-
- spec/image_vise/strip_metadata_spec.rb
|
306
|
-
- spec/image_vise_spec.rb
|
307
|
-
- spec/layers-with-blending.psd
|
308
|
-
- spec/spec_helper.rb
|
309
|
-
- spec/test_server.rb
|
310
|
-
- spec/waterside_magic_hour.jpg
|
311
|
-
- spec/waterside_magic_hour.psd
|
312
|
-
- spec/waterside_magic_hour_adobergb.jpg
|
313
|
-
- spec/waterside_magic_hour_gray.tif
|
314
|
-
- spec/waterside_magic_hour_transp.png
|
219
|
+
- lib/image_vise/version.rb
|
220
|
+
- lib/image_vise/writers/auto_writer.rb
|
221
|
+
- lib/image_vise/writers/jpeg_writer.rb
|
315
222
|
homepage: https://github.com/WeTransfer/image_vise
|
316
223
|
licenses:
|
317
224
|
- MIT
|
318
|
-
metadata:
|
225
|
+
metadata:
|
226
|
+
allowed_push_host: https://rubygems.org
|
319
227
|
post_install_message:
|
320
228
|
rdoc_options: []
|
321
229
|
require_paths:
|
@@ -332,7 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
332
240
|
version: '0'
|
333
241
|
requirements: []
|
334
242
|
rubyforge_project:
|
335
|
-
rubygems_version: 2.
|
243
|
+
rubygems_version: 2.5.2
|
336
244
|
signing_key:
|
337
245
|
specification_version: 4
|
338
246
|
summary: Runtime thumbnailing proxy
|
@@ -1,10 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ImageVise::AutoOrient do
|
4
|
-
it 'applies auto orient to the image' do
|
5
|
-
image = Magick::Image.read(test_image_path)[0]
|
6
|
-
orient = described_class.new
|
7
|
-
expect(image).to receive(:auto_orient!).and_call_original
|
8
|
-
orient.apply!(image)
|
9
|
-
end
|
10
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ImageVise::Crop do
|
4
|
-
it 'refuses invalid parameters' do
|
5
|
-
expect { described_class.new(width: 0, height: -1, gravity: '') }.to raise_error(ArgumentError)
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'applies the crop with different gravities' do
|
9
|
-
%w( s sw se n ne nw c).each do |gravity|
|
10
|
-
image = Magick::Image.read(test_image_path)[0]
|
11
|
-
crop = described_class.new(width: 120, height: 220, gravity: gravity)
|
12
|
-
|
13
|
-
crop.apply!(image)
|
14
|
-
|
15
|
-
expect(image.columns).to eq(120)
|
16
|
-
expect(image.rows).to eq(220)
|
17
|
-
examine_image(image, "gravity-%s-" % gravity)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ImageVise::EllipseStencil do
|
4
|
-
it 'applies the circle stencil' do
|
5
|
-
image = Magick::Image.read(test_image_path)[0]
|
6
|
-
stencil = described_class.new
|
7
|
-
stencil.apply!(image)
|
8
|
-
examine_image(image, "circle-stencil")
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'applies the circle stencil to a png with transparency' do
|
12
|
-
png_transparent_path = File.expand_path(__dir__ + '/../waterside_magic_hour_transp.png')
|
13
|
-
image = Magick::Image.read(png_transparent_path)[0]
|
14
|
-
stencil = described_class.new
|
15
|
-
stencil.apply!(image)
|
16
|
-
examine_image(image, "circle-stencil-transparent-bg")
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
|
3
|
-
describe ImageVise::FetcherFile do
|
4
|
-
it 'is a class (can be inherited from)' do
|
5
|
-
expect(ImageVise::FetcherFile).to be_kind_of(Class)
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'is registered as a fetcher for file://' do
|
9
|
-
expect(ImageVise.fetcher_for('file')).to eq(ImageVise::FetcherFile)
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'returns a Tempfile containing this test suite' do
|
13
|
-
path = File.expand_path(__FILE__)
|
14
|
-
ruby_files_in_this_directory = __dir__ + '/*.rb'
|
15
|
-
ImageVise.allow_filesystem_source! ruby_files_in_this_directory
|
16
|
-
|
17
|
-
uri = URI('file://' + URI.encode(path))
|
18
|
-
fetched = ImageVise::FetcherFile.fetch_uri_to_tempfile(uri)
|
19
|
-
|
20
|
-
expect(fetched).to be_kind_of(Tempfile)
|
21
|
-
expect(fetched.size).to eq(File.size(__FILE__))
|
22
|
-
expect(fetched.pos).to be_zero
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'raises a meaningful exception if no file sources are permitted' do
|
26
|
-
path = File.expand_path(__FILE__)
|
27
|
-
|
28
|
-
ImageVise.deny_filesystem_sources!
|
29
|
-
|
30
|
-
uri = URI('file://' + URI.encode(path))
|
31
|
-
expect {
|
32
|
-
ImageVise::FetcherFile.fetch_uri_to_tempfile(uri)
|
33
|
-
}.to raise_error(ImageVise::FetcherFile::AccessError)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'raises a meaningful exception if this file is not permitted as source' do
|
37
|
-
path = File.expand_path(__FILE__)
|
38
|
-
|
39
|
-
text_files_in_this_directory = __dir__ + '/*.txt'
|
40
|
-
ImageVise.deny_filesystem_sources!
|
41
|
-
ImageVise.allow_filesystem_source! text_files_in_this_directory
|
42
|
-
|
43
|
-
uri = URI('file://' + URI.encode(path))
|
44
|
-
expect {
|
45
|
-
ImageVise::FetcherFile.fetch_uri_to_tempfile(uri)
|
46
|
-
}.to raise_error(ImageVise::FetcherFile::AccessError)
|
47
|
-
end
|
48
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
|
3
|
-
describe ImageVise::FetcherHTTP do
|
4
|
-
it 'is a class (can be inherited from)' do
|
5
|
-
expect(ImageVise::FetcherHTTP).to be_kind_of(Class)
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'is registered as a fetcher for http:// and https://' do
|
9
|
-
expect(ImageVise.fetcher_for('http')).to eq(ImageVise::FetcherHTTP)
|
10
|
-
expect(ImageVise.fetcher_for('https')).to eq(ImageVise::FetcherHTTP)
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'raises an AccessError if the host of the URL is not on the whitelist' do
|
14
|
-
uri = URI('https://wrong-origin.com/image.psd')
|
15
|
-
expect {
|
16
|
-
ImageVise::FetcherHTTP.fetch_uri_to_tempfile(uri)
|
17
|
-
}.to raise_error(ImageVise::FetcherHTTP::AccessError, /is not permitted as source/)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'raises an UpstreamError if the upstream fetch returns an error-ish status code' do
|
21
|
-
uri = URI('http://localhost:9001/forbidden')
|
22
|
-
ImageVise.add_allowed_host! 'localhost'
|
23
|
-
|
24
|
-
expect {
|
25
|
-
ImageVise::FetcherHTTP.fetch_uri_to_tempfile(uri)
|
26
|
-
}.to raise_error {|e|
|
27
|
-
expect(e).to be_kind_of(ImageVise::FetcherHTTP::UpstreamError)
|
28
|
-
expect(e.message).to include(uri.to_s)
|
29
|
-
expect(e.message).to include('403')
|
30
|
-
expect(e.http_status).to eq(403)
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'fetches the image into a Tempfile' do
|
35
|
-
uri = URI(public_url_psd)
|
36
|
-
ImageVise.add_allowed_host! 'localhost'
|
37
|
-
|
38
|
-
result = ImageVise::FetcherHTTP.fetch_uri_to_tempfile(uri)
|
39
|
-
|
40
|
-
expect(result).to be_kind_of(Tempfile)
|
41
|
-
expect(result.size).to be_nonzero
|
42
|
-
expect(result.pos).to be_zero
|
43
|
-
end
|
44
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
|
3
|
-
describe ImageVise::FileResponse do
|
4
|
-
it 'reads the file in binary mode, closes and unlinks the tempfile when close() is called' do
|
5
|
-
random_data = SecureRandom.random_bytes(1024 * 2048)
|
6
|
-
f = Tempfile.new("experiment")
|
7
|
-
f.binmode
|
8
|
-
f << random_data
|
9
|
-
|
10
|
-
response = described_class.new(f)
|
11
|
-
readback = ''.encode(Encoding::BINARY)
|
12
|
-
response.each do | chunk |
|
13
|
-
expect(chunk.encoding).to eq(Encoding::BINARY)
|
14
|
-
readback << chunk
|
15
|
-
end
|
16
|
-
|
17
|
-
response.close
|
18
|
-
|
19
|
-
expect(readback).to eq(random_data)
|
20
|
-
expect(f).to be_closed
|
21
|
-
expect(f.path).to be_nil
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'only asks for the path of the tempfile and uses a separate file descriptor' do
|
25
|
-
f = Tempfile.new("experiment")
|
26
|
-
f.binmode
|
27
|
-
f << SecureRandom.random_bytes(2048)
|
28
|
-
f.flush
|
29
|
-
|
30
|
-
# Use a double so that all the methods except the ones we mock raise an assertion
|
31
|
-
double = double(path: f.path)
|
32
|
-
expect(double).to receive(:flush)
|
33
|
-
|
34
|
-
read_from_response = ''.encode(Encoding::BINARY)
|
35
|
-
response = described_class.new(double)
|
36
|
-
response.each{|b| read_from_response << b }
|
37
|
-
|
38
|
-
f.rewind
|
39
|
-
|
40
|
-
expect(f.read).to eq(read_from_response)
|
41
|
-
|
42
|
-
f.close
|
43
|
-
f.unlink
|
44
|
-
end
|
45
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ImageVise::FitCrop do
|
4
|
-
it 'refuses invalid arguments' do
|
5
|
-
expect { described_class.new(width: 0, height: -1, gravity: '') }.to raise_error(ArgumentError)
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'applies the crop with different gravities' do
|
9
|
-
%w( s sw se n ne nw c).each do |gravity|
|
10
|
-
image = Magick::Image.read(test_image_path)[0]
|
11
|
-
crop = described_class.new(width: 120, height: 220, gravity: gravity)
|
12
|
-
|
13
|
-
crop.apply!(image)
|
14
|
-
|
15
|
-
expect(image.columns).to eq(120)
|
16
|
-
expect(image.rows).to eq(220)
|
17
|
-
examine_image(image, "gravity-%s-" % gravity)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|