image_vise 0.6.0 → 0.8.2

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
- SHA1:
3
- metadata.gz: 1be0d4d8682d0436356b4ea5e0023869b50709dd
4
- data.tar.gz: de463d93ee8e7e55c0cfa59db9a5c0dee9b91a25
2
+ SHA256:
3
+ metadata.gz: 448a0d9a3decdcb6af4a3c0dc52fbed811bca85a8ba1df2775916ee164dffdcf
4
+ data.tar.gz: 3bb7300d2622d442ebe559195276e1ab753a9f1268b955fe2427362041f35036
5
5
  SHA512:
6
- metadata.gz: e93df7c9c8723663ab09a7ba09916f5327ec7b2a71e63818b7e4bf72d851dcb119fd21c9133bd6e97158fc672e9ac64043db9f6f897a5dd9b051dd7e706c5315
7
- data.tar.gz: 15e293b3e33026a78f486ba2921a8df5a1af1b51fb08c3984864b81316697c14979715148e39eaa00f0b85a7228cc0a79f19a7b8f41002558f6e86ceaec507cd
6
+ metadata.gz: c71485f40a843adfc42887ef0d3766df61c83457bb3cbc92763e1c172c82a74ba7b1aba8472f9f16e79a2a35469648d361e7f6a0c85f5bfddba2f8f662283b5d
7
+ data.tar.gz: 6863b83f51d044589e20c6cf40ff6e6843f148374cea3a8c036a9af8fef99f626f6ef941a83bd80a44159eaed2a1a85122c7a2444510a006fddf8825f3195954
data/.gitignore CHANGED
@@ -6,3 +6,4 @@ Gemfile.lock
6
6
  *.log
7
7
  pkg
8
8
  coverage
9
+ .ruby-version
@@ -1,13 +1,10 @@
1
1
  rvm:
2
- - 2.2.10
3
- - 2.3.7
4
2
  - 2.4.4
5
3
  - 2.5.1
4
+ - 2.6.2
6
5
  sudo: false
7
6
  cache: bundler
8
-
9
7
  env:
10
8
  global:
11
9
  - SKIP_INTERACTIVE=yes
12
- before_install: gem install bundler
13
10
  script: bundle exec rspec
@@ -0,0 +1,2 @@
1
+ ## 0.8.2
2
+ * Change format_parser required version to allow > 0.24
@@ -1,7 +1,7 @@
1
1
  # Anywhere in your app code
2
2
  module ImageViseAppsignal
3
3
  ImageVise::RenderEngine.prepend self
4
- ImageVise::Measurometer.drivers << Appsignal # to obtain ImageVise instrumentation
4
+ Measurometer.drivers << Appsignal # to obtain ImageVise instrumentation
5
5
  def setup_error_handling(rack_env)
6
6
  txn = Appsignal::Transaction.current
7
7
  txn.set_action('%s#%s' % [self.class, 'call'])
@@ -21,20 +21,21 @@ Gem::Specification.new do |spec|
21
21
  else
22
22
  raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
23
  end
24
-
24
+
25
25
  spec.files = `git ls-files -z`.split("\x0")
26
26
  spec.bindir = "exe"
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
30
  spec.add_dependency 'patron', '~> 0.9'
31
- spec.add_dependency 'rmagick', '~> 2.15'
31
+ spec.add_dependency 'rmagick', '~> 3'
32
32
  spec.add_dependency 'ks'
33
33
  spec.add_dependency 'rack', '>= 1', '< 3'
34
- spec.add_dependency 'format_parser', '>= 0.12.1', '< 1.0'
34
+ spec.add_dependency 'format_parser', '~> 0.25'
35
+ spec.add_dependency 'measurometer', '~> 1'
35
36
 
36
37
  spec.add_development_dependency 'magic_bytes', '~> 1'
37
- spec.add_development_dependency "bundler", "~> 1.7"
38
+ spec.add_development_dependency "bundler"
38
39
  spec.add_development_dependency "rake", "~> 12.2"
39
40
  spec.add_development_dependency "rack-test"
40
41
  spec.add_development_dependency "rspec", "~> 3"
@@ -2,10 +2,10 @@ require 'ks'
2
2
  require 'json'
3
3
  require 'patron'
4
4
  require 'rmagick'
5
- require 'magic_bytes'
6
5
  require 'thread'
7
6
  require 'base64'
8
7
  require 'rack'
8
+ require 'measurometer'
9
9
  require 'format_parser'
10
10
 
11
11
  class ImageVise
@@ -27,7 +27,9 @@ class ImageVise
27
27
  @allowed_glob_patterns = Set.new
28
28
  @fetchers = {}
29
29
  @cache_lifetime = DEFAULT_CACHE_LIFETIME
30
-
30
+
31
+ const_set(:Measurometer, ::Measurometer)
32
+
31
33
  class << self
32
34
  # Resets all allowed hosts
33
35
  def reset_allowed_hosts!
@@ -165,7 +167,7 @@ class ImageVise
165
167
  return unless maybe_image
166
168
  return unless maybe_image.respond_to?(:destroy!)
167
169
  return if maybe_image.destroyed?
168
- ImageVise::Measurometer.instrument('image_vise.image_destroy_dealloc') do
170
+ Measurometer.instrument('image_vise.image_destroy_dealloc') do
169
171
  maybe_image.destroy!
170
172
  end
171
173
  end
@@ -175,7 +177,7 @@ class ImageVise
175
177
  # in scope but not yet set to an image) we take the possibility of nils into account.
176
178
  def self.close_and_unlink(maybe_tempfile)
177
179
  return unless maybe_tempfile
178
- ImageVise::Measurometer.instrument('image_vise.tempfile_unlink') do
180
+ Measurometer.instrument('image_vise.tempfile_unlink') do
179
181
  maybe_tempfile.close unless maybe_tempfile.closed?
180
182
  maybe_tempfile.unlink if maybe_tempfile.respond_to?(:unlink)
181
183
  end
@@ -14,11 +14,11 @@ class ImageVise::ImageRequest < Ks.strict(:src_url, :pipeline)
14
14
 
15
15
  # Check the signature before decoding JSON (since we will be creating symbols)
16
16
  unless valid_signature?(base64_encoded_params, given_signature, secrets)
17
- ImageVise::Measurometer.increment_counter('image_vise.params.invalid_signatures', 1)
17
+ Measurometer.increment_counter('image_vise.params.invalid_signatures', 1)
18
18
  raise SignatureError, "Invalid or missing signature"
19
19
  end
20
20
 
21
- ImageVise::Measurometer.increment_counter('image_vise.params.valid_signatures', 1)
21
+ Measurometer.increment_counter('image_vise.params.valid_signatures', 1)
22
22
 
23
23
  # Decode the JSON - only AFTER the signature has been validated,
24
24
  # so we can use symbol keys
@@ -47,7 +47,7 @@ class ImageVise::Pipeline
47
47
  def apply!(magick_image, image_metadata)
48
48
  @ops.each do |operator|
49
49
  operator_short_classname = operator.class.to_s.split('::').pop
50
- ImageVise::Measurometer.instrument('image_vise.op.%s' % operator_short_classname) do
50
+ Measurometer.instrument('image_vise.op.%s' % operator_short_classname) do
51
51
  apply_operator_passing_metadata(magick_image, operator, image_metadata)
52
52
  end
53
53
  end
@@ -13,7 +13,8 @@
13
13
  end
14
14
 
15
15
  DEFAULT_HEADERS = {
16
- 'Allow' => "GET"
16
+ 'Allow' => 'GET',
17
+ 'X-Content-Type-Options' => 'nosniff',
17
18
  }.freeze
18
19
 
19
20
  # Headers for error responses that denote an invalid or
@@ -152,7 +153,7 @@
152
153
 
153
154
  # Download/copy the original into a Tempfile
154
155
  fetcher = ImageVise.fetcher_for(source_image_uri.scheme)
155
- source_file = ImageVise::Measurometer.instrument('image_vise.fetch') do
156
+ source_file = Measurometer.instrument('image_vise.fetch') do
156
157
  fetcher.fetch_uri_to_tempfile(source_image_uri)
157
158
  end
158
159
  file_format = FormatParser.parse(source_file, natures: [:image]).tap { source_file.rewind }
@@ -162,7 +163,7 @@
162
163
  render_destination_file = Tempfile.new('imagevise-render').tap{|f| f.binmode }
163
164
 
164
165
  # Do the actual imaging stuff
165
- expire_after = ImageVise::Measurometer.instrument('image_vise.render_engine.apply_pipeline') do
166
+ expire_after = Measurometer.instrument('image_vise.render_engine.apply_pipeline') do
166
167
  apply_pipeline(source_file.path, pipeline, file_format, render_destination_file.path)
167
168
  end
168
169
 
@@ -295,7 +296,7 @@
295
296
  def apply_pipeline(source_file_path, pipeline, source_format_parser_result, render_to_path)
296
297
 
297
298
  # Load the first frame of the animated GIF _or_ the blended compatibility layer from Photoshop
298
- image_list = ImageVise::Measurometer.instrument('image_vise.load_pixbuf') do
299
+ image_list = Measurometer.instrument('image_vise.load_pixbuf') do
299
300
  Magick::Image.read(source_file_path)
300
301
  end
301
302
 
@@ -312,7 +313,7 @@
312
313
  # it so that we get a KeyError if some operator has deleted it without providing a replacement.
313
314
  # If no operators touched the writer we are going to use the automatic format selection
314
315
  writer = metadata.fetch(:writer, ImageVise::AutoWriter.new)
315
- ImageVise::Measurometer.instrument('image_vise.write_image') do
316
+ Measurometer.instrument('image_vise.write_image') do
316
317
  writer.write_image!(magick_image, metadata, render_to_path)
317
318
  end
318
319
 
@@ -1,3 +1,3 @@
1
1
  class ImageVise
2
- VERSION = '0.6.0'
2
+ VERSION = '0.8.2'
3
3
  end
@@ -110,6 +110,8 @@ describe ImageVise::RenderEngine do
110
110
  expect(last_response.headers['Cache-Control']).to match(/public/)
111
111
 
112
112
  expect(last_response.headers['Content-Type']).to eq('application/json')
113
+ expect(last_response['X-Content-Type-Options']).to eq('nosniff')
114
+
113
115
  parsed = JSON.load(last_response.body)
114
116
  expect(parsed['errors'].to_s).to include("Unfortunate upstream response")
115
117
  end
@@ -182,6 +184,8 @@ describe ImageVise::RenderEngine do
182
184
  expect(last_response.status).to eq(200)
183
185
 
184
186
  expect(last_response.headers['Content-Type']).to eq('image/jpeg')
187
+ expect(last_response['X-Content-Type-Options']).to eq('nosniff')
188
+
185
189
  expect(last_response.headers).to have_key('Content-Length')
186
190
  parsed_image = Magick::Image.from_blob(last_response.body)[0]
187
191
  expect(parsed_image.columns).to eq(10)
@@ -11,6 +11,7 @@ require 'securerandom'
11
11
  require 'addressable/uri'
12
12
  require 'strenv'
13
13
  require 'pry'
14
+ require 'magic_bytes'
14
15
  require_relative 'test_server'
15
16
 
16
17
  TEST_RENDERS_DIR = Dir.mktmpdir
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.6.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-04 00:00:00.000000000 Z
11
+ date: 2020-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: patron
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.15'
33
+ version: '3'
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: '2.15'
40
+ version: '3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: ks
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -76,22 +76,30 @@ dependencies:
76
76
  name: format_parser
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: 0.12.1
82
- - - "<"
79
+ - - "~>"
83
80
  - !ruby/object:Gem::Version
84
- version: '1.0'
81
+ version: '0.25'
85
82
  type: :runtime
86
83
  prerelease: false
87
84
  version_requirements: !ruby/object:Gem::Requirement
88
85
  requirements:
89
- - - ">="
86
+ - - "~>"
90
87
  - !ruby/object:Gem::Version
91
- version: 0.12.1
92
- - - "<"
88
+ version: '0.25'
89
+ - !ruby/object:Gem::Dependency
90
+ name: measurometer
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
93
94
  - !ruby/object:Gem::Version
94
- version: '1.0'
95
+ version: '1'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1'
95
103
  - !ruby/object:Gem::Dependency
96
104
  name: magic_bytes
97
105
  requirement: !ruby/object:Gem::Requirement
@@ -110,16 +118,16 @@ dependencies:
110
118
  name: bundler
111
119
  requirement: !ruby/object:Gem::Requirement
112
120
  requirements:
113
- - - "~>"
121
+ - - ">="
114
122
  - !ruby/object:Gem::Version
115
- version: '1.7'
123
+ version: '0'
116
124
  type: :development
117
125
  prerelease: false
118
126
  version_requirements: !ruby/object:Gem::Requirement
119
127
  requirements:
120
- - - "~>"
128
+ - - ">="
121
129
  - !ruby/object:Gem::Version
122
- version: '1.7'
130
+ version: '0'
123
131
  - !ruby/object:Gem::Dependency
124
132
  name: rake
125
133
  requirement: !ruby/object:Gem::Requirement
@@ -227,6 +235,7 @@ extra_rdoc_files: []
227
235
  files:
228
236
  - ".gitignore"
229
237
  - ".travis.yml"
238
+ - CHANGELOG.md
230
239
  - DEVELOPMENT.md
231
240
  - Gemfile
232
241
  - LICENSE.txt
@@ -260,7 +269,6 @@ files:
260
269
  - lib/image_vise/version.rb
261
270
  - lib/image_vise/writers/auto_writer.rb
262
271
  - lib/image_vise/writers/jpeg_writer.rb
263
- - lib/measurometer.rb
264
272
  - spec/image_vise/auto_orient_spec.rb
265
273
  - spec/image_vise/background_fill_spec.rb
266
274
  - spec/image_vise/crop_spec.rb
@@ -282,7 +290,6 @@ files:
282
290
  - spec/image_vise/writers/jpeg_writer_spec.rb
283
291
  - spec/image_vise_spec.rb
284
292
  - spec/layers-with-blending.psd
285
- - spec/measurometer_spec.rb
286
293
  - spec/spec_helper.rb
287
294
  - spec/test_server.rb
288
295
  - spec/waterside_magic_hour.jpg
@@ -311,8 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
311
318
  - !ruby/object:Gem::Version
312
319
  version: '0'
313
320
  requirements: []
314
- rubyforge_project:
315
- rubygems_version: 2.5.2
321
+ rubygems_version: 3.1.2
316
322
  signing_key:
317
323
  specification_version: 4
318
324
  summary: Runtime thumbnailing proxy
@@ -1,92 +0,0 @@
1
- # Measurometer is 1-1 API compatible with Appsignal,
2
- # which we use a lot
3
- class ImageVise::Measurometer
4
- class << self
5
- # Permits adding instrumentation drivers. To magically
6
- # obtain all Appsignal instrumentation, add the Appsignal module
7
- # as a driver.
8
- #
9
- # Measurometer.drivers << Appsignal
10
- #
11
- # A driver must be reentrant and thread-safe - it should be possible
12
- # to have multiple `instrument` calls open from different threads at the
13
- # same time.
14
- #
15
- # The driver must support the same interface as the Measurometer class
16
- # itself, minus the `drivers` and `instrument_instance_method` methods.
17
- #
18
- # @return Array
19
- def drivers
20
- @drivers ||= []
21
- @drivers
22
- end
23
-
24
- # Runs a given block within a cascade of `instrument` blocks of all the
25
- # added drivers.
26
- #
27
- # Measurometer.instrument('do_foo') { compute! }
28
- #
29
- # unfolds to
30
- #
31
- # Appsignal.instrument('do_foo') do
32
- # Statsd.timing('do_foo') do
33
- # compute!
34
- # end
35
- # end
36
- #
37
- # Note that it is _imperative_ that the block return value is preserved
38
- # by the drivers and passed as the result of the block.
39
- #
40
- # @param block_name[String] under which path to push the metric
41
- # @param blk[#call] the block to instrument
42
- # @return [Object] the return value of &blk
43
- def instrument(block_name, &blk)
44
- return yield unless @drivers && @drivers.any? # The block wrapping business is not free
45
- @drivers.inject(blk) { |outer_block, driver|
46
- -> {
47
- driver.instrument(block_name, &outer_block)
48
- }
49
- }.call
50
- end
51
-
52
- # Adds a distribution value (sample) under a given path
53
- #
54
- # @param value_path[String] under which path to push the metric
55
- # @param value[Numeric] distribution value
56
- # @return nil
57
- def add_distribution_value(value_path, value)
58
- (@drivers || []).each { |d| d.add_distribution_value(value_path, value) }
59
- nil
60
- end
61
-
62
- # Increment a named counter under a given path
63
- #
64
- # @param counter_path[String] under which path to push the metric
65
- # @param by[Integer] the counter increment to apply
66
- # @return nil
67
- def increment_counter(counter_path, by)
68
- (@drivers || []).each { |d| d.increment_counter(counter_path, by) }
69
- nil
70
- end
71
-
72
- # Wrap an anonymous module around an instance method in the given class to have
73
- # it instrumented automatically. The name of the measurement will be interpolated as:
74
- #
75
- # "#{prefix}.#{rightmost_class_constant_name}.#{instance_method_name}"
76
- #
77
- # @param target_class[Class] the class to instrument
78
- # @param instance_method_name_to_instrument[Symbol] the method name to instrument
79
- # @param path_prefix[String] under which path to push the instrumented metric
80
- # @return void
81
- def instrument_instance_method(target_class, instance_method_name_to_instrument, path_prefix)
82
- short_class_name = target_class.to_s.split('::').last
83
- instrumentation_name = [path_prefix, short_class_name, instance_method_name_to_instrument].join('.')
84
- instrumenter_module = Module.new do
85
- define_method(instance_method_name_to_instrument) do |*any|
86
- ::ImageVise::Measurometer.instrument(instrumentation_name) { super(*any) }
87
- end
88
- end
89
- target_class.prepend(instrumenter_module)
90
- end
91
- end
92
- end
@@ -1,58 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ImageVise::Measurometer do
4
- RSpec::Matchers.define :include_counter_or_measurement_named do |named|
5
- match do |actual|
6
- actual.any? do |e|
7
- e[0] == named && e[1] > 0
8
- end
9
- end
10
- end
11
-
12
- it 'instruments a full cycle FormatParser.parse' do
13
- driver_class = Class.new do
14
- attr_accessor :timings, :counters, :distributions
15
- def initialize
16
- @timings = []
17
- @distributions = []
18
- @counters = []
19
- end
20
-
21
- def instrument(block_name)
22
- s = Process.clock_gettime(Process::CLOCK_MONOTONIC)
23
- yield.tap do
24
- delta = Process.clock_gettime(Process::CLOCK_MONOTONIC) - s
25
- @timings << [block_name, delta * 1000]
26
- end
27
- end
28
-
29
- def add_distribution_value(value_path, value)
30
- @distributions << [value_path, value]
31
- end
32
-
33
- def increment_counter(value_path, value)
34
- @counters << [value_path, value]
35
- end
36
- end
37
-
38
- instrumenter = driver_class.new
39
- described_class.drivers << instrumenter
40
-
41
- builder = ImageVise::Pipeline.new
42
- pipeline = builder.
43
- auto_orient.
44
- fit_crop(width: 48, height: 48, gravity: 'c').
45
- sharpen(radius: 2, sigma: 0.5).
46
- ellipse_stencil.
47
- strip_metadata
48
-
49
- image = Magick::Image.read(test_image_path)[0]
50
- pipeline.apply! image, {}
51
-
52
- described_class.drivers.delete(instrumenter)
53
- expect(described_class.drivers).not_to include(instrumenter)
54
-
55
- expect(instrumenter.timings).to include_counter_or_measurement_named('image_vise.op.AutoOrient')
56
- expect(instrumenter.timings).to include_counter_or_measurement_named('image_vise.op.StripMetadata')
57
- end
58
- end