image_vise 0.0.19 → 0.0.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5fd7e2b6f4a49ab832e600a46708d2974b74ed17
4
- data.tar.gz: 1b13d15d9e99308a001ee62aeed21bf3e45c7429
3
+ metadata.gz: ec4d4b81f950cbc31ce3ac5c43d311c0049a5497
4
+ data.tar.gz: d3558ea48e705fe17e18fff1036d48f8c1ecdd3d
5
5
  SHA512:
6
- metadata.gz: 04fcaa4b8fba508845ba29634636edf9f67758d21687754d9d2117d82eefb22282cb22a678de26f4f0e31980a509beb9f6e62b229e08ebfe6dc1b2d5718f83b6
7
- data.tar.gz: 6ac6c1bda81dbfa6b2ce27106277d016ff725ac80a51a116cba447a51fc878cb89393110e53f4c06befc65d617f041d6fc865a824103c1b9d8803ec776408989
6
+ metadata.gz: b21bc99a45b1b6830d7f38b6b507103d50603e5fd370167a9f1d2ba9eb941d332580fa5d713f20a80e58eeb21cb2e0e9a79a2ea8054e12a816d7260a33299d50
7
+ data.tar.gz: e14e15cf5306b14cb53e7f89e306753bc1e4c3db601f689716d7c146636b8d701e02d2f1144fa152c26a4aa1ff07925945a2eae55db608f697d534a8d39b0a0a
data/README.md CHANGED
@@ -23,30 +23,38 @@ take care of encoding the source URL and the commands in the right way, as well
23
23
 
24
24
  Mount ImageVise in your `routes.rb`:
25
25
 
26
- mount '/images' => ImageVise
26
+ ```ruby
27
+ mount '/images' => ImageVise
28
+ ```
27
29
 
28
30
  and add an initializer (like `config/initializers/image_vise_config.rb`) to set up the permitted hosts
29
31
 
30
- ImageVise.add_allowed_host! your_application_hostname
31
- ImageVise.add_secret_key! ENV.fetch('IMAGE_VISE_SECRET')
32
+ ```ruby
33
+ ImageVise.add_allowed_host! your_application_hostname
34
+ ImageVise.add_secret_key! ENV.fetch('IMAGE_VISE_SECRET')
35
+ ```
32
36
 
33
37
  You might want to define a helper method for generating signed URLs as well, which will look something like this:
34
38
 
35
- def thumb_url(source_image_url)
36
- qs_params = ImageVise.image_params(src_url: source_image_url, secret: ENV.fetch('IMAGE_VISE_SECRET')) do |pipeline|
37
- # For example, you can also yield `pipeline` to the caller
38
- pipeline.fit_crop width: 128, height: 128, gravity: 'c'
39
- end
40
- '/images?' + Rack::Utils.build_query(qs_params) # or use url_for...
41
- end
39
+ ```ruby
40
+ def thumb_url(source_image_url)
41
+ qs_params = ImageVise.image_params(src_url: source_image_url, secret: ENV.fetch('IMAGE_VISE_SECRET')) do |pipeline|
42
+ # For example, you can also yield `pipeline` to the caller
43
+ pipeline.fit_crop width: 128, height: 128, gravity: 'c'
44
+ end
45
+ '/images?' + Rack::Utils.build_query(qs_params) # or use url_for...
46
+ end
47
+ ```
42
48
 
43
49
  ## Using ImageVise within a Rack application
44
50
 
45
51
  Mount ImageVise under a script name in your `config.ru`:
46
52
 
47
- map '/images' do
48
- run ImageVise
49
- end
53
+ ```ruby
54
+ map '/images' do
55
+ run ImageVise
56
+ end
57
+ ```
50
58
 
51
59
  and add the initialization code either to `config.ru` proper or to some file in your application:
52
60
 
@@ -55,16 +63,17 @@ and add the initialization code either to `config.ru` proper or to some file in
55
63
 
56
64
  You might want to define a helper method for generating signed URLs as well, which will look something like this:
57
65
 
58
- def thumb_url(source_image_url)
59
- qs_params = ImageVise.image_params(src_url: source_image_url, secret: ENV.fetch('IMAGE_VISE_SECRET')) do |pipe|
60
- pipe.fit_crop width: 256, height: 256, gravity: 'c'
61
- pipe.sharpen sigma: 0.5, radius: 2
62
- pipe.ellipse_stencil
63
- end
64
- # Output a URL to the app
65
- '/images?' + Rack::Utils.build_query(image_request)
66
- end
67
-
66
+ ```ruby
67
+ def thumb_url(source_image_url)
68
+ qs_params = ImageVise.image_params(src_url: source_image_url, secret: ENV.fetch('IMAGE_VISE_SECRET')) do |pipe|
69
+ pipe.fit_crop width: 256, height: 256, gravity: 'c'
70
+ pipe.sharpen sigma: 0.5, radius: 2
71
+ pipe.ellipse_stencil
72
+ end
73
+ # Output a URL to the app
74
+ '/images?' + Rack::Utils.build_query(image_request)
75
+ end
76
+ ```
68
77
 
69
78
  ## Processing files on the local filesystem instead of remote ones
70
79
 
@@ -93,27 +102,32 @@ of decent image filtering choices in ImageMagick proper).
93
102
 
94
103
  Here is an example pipeline, JSON-encoded (this is what is passed in the URL):
95
104
 
96
- [
97
- ["auto_orient", {}],
98
- ["geom", {"geometry_string": "512x512"}],
99
- ["fit_crop", {"width": 32, "height": 32, "gravity": "se"}],
100
- ["sharpen", {"radius": 0.75, "sigma": 0.5}],
101
- ["ellipse_stencil", {}]
102
- ]
105
+ ```json
106
+ [
107
+ ["auto_orient", {}],
108
+ ["geom", {"geometry_string": "512x512"}],
109
+ ["fit_crop", {"width": 32, "height": 32, "gravity": "se"}],
110
+ ["sharpen", {"radius": 0.75, "sigma": 0.5}],
111
+ ["ellipse_stencil", {}]
112
+ ]
113
+ ```
103
114
 
104
115
  The same pipeline can be created using the `Pipeline` DSL:
105
116
 
106
- pipe = Pipeline.new.
107
- auto_orient.
108
- geom(geometry_string: '512x512').
109
- fit_crop(width: 32, height: 32, gravity: 'se').
110
- sharpen(radius: 0.75, sigma: 0.5).
111
- ellipse_stencil
112
-
117
+ ```ruby
118
+ pipe = Pipeline.new.
119
+ auto_orient.
120
+ geom(geometry_string: '512x512').
121
+ fit_crop(width: 32, height: 32, gravity: 'se').
122
+ sharpen(radius: 0.75, sigma: 0.5).
123
+ ellipse_stencil
124
+ ```
113
125
  and can then be applied to a `Magick::Image` object:
114
126
 
115
- image = Magick::Image.read(my_image_path)[0]
116
- pipe.apply!(image)
127
+ ```ruby
128
+ image = Magick::Image.read(my_image_path)[0]
129
+ pipe.apply!(image)
130
+ ```
117
131
 
118
132
  ## Performance and memory
119
133
 
@@ -161,7 +175,9 @@ CDN.
161
175
  To allow `ImageVise` to recognize the signature when the signature is going to be received, add it to the list
162
176
  of the shared keys on the `ImageVise` server:
163
177
 
164
- ImageVise.add_secret_key!('ahoy! this is a secret!')
178
+ ```ruby
179
+ ImageVise.add_secret_key!('ahoy! this is a secret!')
180
+ ```
165
181
 
166
182
  A single `ImageVise` server can maintain multiple signature keys, so that you will be able to generate thumbnails from
167
183
  multiple applications all using different keys for their signatures. Every request will be validated against
@@ -173,18 +189,72 @@ accepted and the request will be allowed to go through.
173
189
  By default, `ImageVise` will refuse to process images from URLs on "unknown" hosts. To mark a host as "known"
174
190
  tell `ImageVise` to
175
191
 
176
- ImageVise.add_allowed_host!('my-image-store.ourcompany.co.uk')
192
+ ```ruby
193
+ ImageVise.add_allowed_host!('my-image-store.ourcompany.co.uk')
194
+ ```
177
195
 
178
196
  If you want to permit images from the local server filesystem to be accessed, add the glob pattern
179
197
  to the set of allowed filesystem patterns:
180
198
 
181
- ImageVise.allow_filesystem_source!(Rails.root + '/public/*.jpg')
199
+ ```ruby
200
+ ImageVise.allow_filesystem_source!(Rails.root + '/public/*.jpg')
201
+ ```
182
202
 
183
203
  Note that these are _glob_ patterns. The image path will be checked against them using `File.fnmatch`.
184
204
 
205
+ ## Handling errors within the rendering Rack app
206
+
207
+ By default, the Rack app within ImageVise swallows all exceptions and returns the error message
208
+ within a machine-readable JSON payload. If that doesn't work for you, or you want to add error
209
+ handling using some error tracking provider, either subclass `ImageVise::RenderEngine` or prepend
210
+ a module into it that will intercept the errors. For example, [Sentry](https://sentry.io) has a neat
211
+ property of picking up `rack.exception` from the Rack request env. Using the hooks in the render engine,
212
+ you can add Sentry support by using the following module:
213
+
214
+ ```ruby
215
+ module ImageViseSentrySupport
216
+ ImageVise::RenderEngine.prepend self
217
+
218
+ def setup_error_handling(rack_env)
219
+ @env = rack_env
220
+ end
221
+
222
+ def handle_request_error(err)
223
+ @env['rack.exception'] = err
224
+ end
225
+
226
+ def handle_generic_error(err)
227
+ @env['rack.exception'] = err
228
+ end
229
+ end
230
+ ```
231
+
232
+ For [Appsignal](https://appsignal.com) you can use the following module instead:
233
+
234
+ ```ruby
235
+ module ImageViseAppsignal
236
+ ImageVise::RenderEngine.prepend self
237
+
238
+ def setup_error_handling(rack_env)
239
+ txn = Appsignal::Transaction.current
240
+ txn.set_action('%s#%s' % [self.class, 'call'])
241
+ end
242
+
243
+ def handle_request_error(err)
244
+ Appsignal.add_exception(err)
245
+ end
246
+
247
+ def handle_generic_error(err)
248
+ Appsignal.add_exception(err)
249
+ end
250
+ end
251
+ ```
252
+
253
+ In both cases you need the overall Rack error handling middleware to be wrapping ImageVise, of course.
254
+
185
255
  ## State
186
256
 
187
- Except for the HTTP cache for redirects et.al no state is stored (`ImageVise` does not care whether you store
257
+ Except for the HTTP cache no state is stored (`ImageVise` does not care whether you store
188
258
  your images using Dragonfly, CarrierWave or some custom handling code). All the app needs is the full URL.
189
259
 
190
260
  ## Running the tests, versioning, contributing
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: image_vise 0.0.19 ruby lib
5
+ # stub: image_vise 0.0.20 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "image_vise"
9
- s.version = "0.0.19"
9
+ s.version = "0.0.20"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Julik Tarkhanov"]
14
- s.date = "2016-10-16"
14
+ s.date = "2016-10-17"
15
15
  s.description = "Image processing via URLs"
16
16
  s.email = "me@julik.nl"
17
17
  s.extra_rdoc_files = [
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
38
38
  "lib/image_vise/sRGB_v4_ICC_preference_displayclass.icc",
39
39
  "lib/image_vise/sharpen.rb",
40
40
  "lib/image_vise/srgb.rb",
41
+ "lib/image_vise/strip_metadata.rb",
41
42
  "spec/image_vise/auto_orient_spec.rb",
42
43
  "spec/image_vise/crop_spec.rb",
43
44
  "spec/image_vise/ellipse_stencil_spec.rb",
@@ -49,6 +50,7 @@ Gem::Specification.new do |s|
49
50
  "spec/image_vise/render_engine_spec.rb",
50
51
  "spec/image_vise/sharpen_spec.rb",
51
52
  "spec/image_vise/srgb_spec.rb",
53
+ "spec/image_vise/strip_metadata_spec.rb",
52
54
  "spec/image_vise_spec.rb",
53
55
  "spec/spec_helper.rb",
54
56
  "spec/test_server.rb",
@@ -4,9 +4,11 @@ require 'patron'
4
4
  require 'rmagick'
5
5
  require 'magic_bytes'
6
6
  require 'thread'
7
+ require 'base64'
8
+ require 'rack'
7
9
 
8
10
  class ImageVise
9
- VERSION = '0.0.19'
11
+ VERSION = '0.0.20'
10
12
  S_MUTEX = Mutex.new
11
13
  private_constant :S_MUTEX
12
14
 
@@ -1,6 +1,3 @@
1
- require 'base64'
2
- require 'rack'
3
-
4
1
  class ImageVise::ImageRequest < Ks.strict(:src_url, :pipeline)
5
2
  class InvalidRequest < ArgumentError; end
6
3
  class SignatureError < InvalidRequest; end
@@ -1,6 +1,4 @@
1
1
  class ImageVise::RenderEngine
2
- require_relative 'image_request'
3
- require_relative 'file_response'
4
2
  class UnsupportedInputFormat < StandardError; end
5
3
  class EmptyRender < StandardError; end
6
4
 
@@ -0,0 +1,10 @@
1
+ # Strips metadata from the image (EXIF, IPTC etc.) using the
2
+ # RMagick `strip!` method
3
+ #
4
+ # The corresponding Pipeline method is `strip_metadata`.
5
+ class ImageVise::StripMetadata
6
+ def apply!(magick_image)
7
+ magick_image.strip!
8
+ end
9
+ ImageVise.add_operator 'strip_metadata', self
10
+ end
@@ -5,6 +5,22 @@ describe ImageVise::Geom do
5
5
  expect { described_class.new(geometry_string: nil) }.to raise_error(ArgumentError)
6
6
  end
7
7
 
8
+ it 'fits to height' do
9
+ image = Magick::Image.read(test_image_path)[0]
10
+ crop = described_class.new(geometry_string: 'x200')
11
+ crop.apply!(image)
12
+ expect(image.rows).to eq(200)
13
+ examine_image(image, 'fit-height-200')
14
+ end
15
+
16
+ it 'fits to width' do
17
+ image = Magick::Image.read(test_image_path)[0]
18
+ crop = described_class.new(geometry_string: '100x')
19
+ crop.apply!(image)
20
+ expect(image.columns).to eq(100)
21
+ examine_image(image, 'fit-width-100')
22
+ end
23
+
8
24
  it 'applies various geometry strings' do
9
25
  %w( ^220x110 !20x20 !10x100 ).each do |geom_string|
10
26
  image = Magick::Image.read(test_image_path)[0]
@@ -37,8 +37,10 @@ describe ImageVise::Pipeline do
37
37
  pipeline = subject.
38
38
  auto_orient.
39
39
  fit_crop(width: 48, height: 48, gravity: 'c').
40
+ srgb.
40
41
  sharpen(radius: 2, sigma: 0.5).
41
- ellipse_stencil
42
+ ellipse_stencil.
43
+ strip_metadata
42
44
 
43
45
  image = Magick::Image.read(test_image_path)[0]
44
46
  pipeline.apply! image
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe ImageVise::StripMetadata do
4
+ it 'applies the strip! method to the image' do
5
+ image = Magick::Image.read(test_image_path).first
6
+ expect(image).to receive(:strip!).and_call_original
7
+ described_class.new.apply!(image)
8
+ end
9
+
10
+ it 'is registered with the operator registry' do
11
+ op = ImageVise.operator_from('strip_metadata')
12
+ expect(op).to eq(described_class)
13
+ end
14
+ end
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.0.19
4
+ version: 0.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-16 00:00:00.000000000 Z
11
+ date: 2016-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -267,6 +267,7 @@ files:
267
267
  - lib/image_vise/sRGB_v4_ICC_preference_displayclass.icc
268
268
  - lib/image_vise/sharpen.rb
269
269
  - lib/image_vise/srgb.rb
270
+ - lib/image_vise/strip_metadata.rb
270
271
  - spec/image_vise/auto_orient_spec.rb
271
272
  - spec/image_vise/crop_spec.rb
272
273
  - spec/image_vise/ellipse_stencil_spec.rb
@@ -278,6 +279,7 @@ files:
278
279
  - spec/image_vise/render_engine_spec.rb
279
280
  - spec/image_vise/sharpen_spec.rb
280
281
  - spec/image_vise/srgb_spec.rb
282
+ - spec/image_vise/strip_metadata_spec.rb
281
283
  - spec/image_vise_spec.rb
282
284
  - spec/spec_helper.rb
283
285
  - spec/test_server.rb