link_thumbnailer 3.0.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3677cdb11ee3930b3fac0464c6daf3262a8114fe
4
- data.tar.gz: dfe19706e2e54885d2935573460de7959fe191dc
3
+ metadata.gz: bd2de89ee93a079ce228bbf77fd1362e359f5ce8
4
+ data.tar.gz: db435fc9864ba56d81d16425802f625e2faeeaf7
5
5
  SHA512:
6
- metadata.gz: 885d0d41e9c0553885c519dc8008c8203b70e9645d6c3089398e8b2179c047feb8a22fecf478f50feb7e9949d5208e73e67ff21d9b00b1430d1292db6abe0532
7
- data.tar.gz: 499caa974e1723f66657870cb18a32ffb950a8334308afd8f892f55a1c342a01e05882a9b58d868b7d13aefc2e269ef10d0ff613717013923bae1e3df192a561
6
+ metadata.gz: 32bf121c87417dfb69a716a3ebb912367b1eb107794d268f342b8eb9bda090b986faea21ff2d2e9db2a4546cca0d39e9d833ec75d719c08b89776ca98fbbfa05
7
+ data.tar.gz: 5ece7aa51e0a7211e0ac92e15c364591497f622dbfdd09d1525bb5aeca1cd4f14f65d1e67d2c89c86ca5eb9ee737b4f878ccac59be95548ff0170191616b4018
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 3.0.2
2
+
3
+ - Replace FastImage gem dependency by [ImageInfo](https://github.com/gottfrois/image_info) to improve performances when
4
+ fetching multiple images size information. Benchmark shows an order of magnitude improvement response time.
5
+ - Fixes [#57](https://github.com/gottfrois/link_thumbnailer/issues/57)
6
+
1
7
  # 3.0.1
2
8
 
3
9
  - Remove useless dependencies
data/Gemfile CHANGED
@@ -4,8 +4,6 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :development, :test do
7
- gem 'coveralls', require: false
8
- gem 'simplecov', require: false
9
7
  gem 'rspec', '~> 2.14'
10
8
  gem 'webmock', '~> 1.14'
11
9
  gem 'pry', '~> 0.9'
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # LinkThumbnailer
2
2
 
3
3
  [![Code Climate](https://codeclimate.com/github/gottfrois/link_thumbnailer.png)](https://codeclimate.com/github/gottfrois/link_thumbnailer)
4
- [![Coverage Status](https://coveralls.io/repos/gottfrois/link_thumbnailer/badge.png?branch=master)](https://coveralls.io/r/gottfrois/link_thumbnailer?branch=master)
5
4
  [![Build Status](https://travis-ci.org/gottfrois/link_thumbnailer.png?branch=master)](https://travis-ci.org/gottfrois/link_thumbnailer)
6
5
  [![Gem Version](https://badge.fury.io/rb/link_thumbnailer.svg)](http://badge.fury.io/rb/link_thumbnailer)
7
6
  [![Dependency Status](https://gemnasium.com/gottfrois/link_thumbnailer.svg)](https://gemnasium.com/gottfrois/link_thumbnailer)
@@ -162,6 +161,10 @@ LinkThumbnailer.configure do |config|
162
161
  # is not an html or xml.
163
162
  #
164
163
  # config.raise_on_invalid_format = false
164
+ #
165
+ # Sets number of concurrent http connections that can be opened to fetch images informations such as size and type.
166
+ #
167
+ # config.max_concurrency = 20
165
168
  end
166
169
  ```
167
170
 
@@ -72,4 +72,8 @@ LinkThumbnailer.configure do |config|
72
72
  # is not an html or xml.
73
73
  #
74
74
  # config.raise_on_invalid_format = false
75
+ #
76
+ # Sets number of concurrent http connections that can be opened to fetch images informations such as size and type.
77
+ #
78
+ # config.max_concurrency = 20
75
79
  end
@@ -25,7 +25,7 @@ module LinkThumbnailer
25
25
  attr_accessor :redirect_limit, :blacklist_urls, :user_agent,
26
26
  :verify_ssl, :http_open_timeout, :http_read_timeout, :attributes,
27
27
  :graders, :description_min_length, :positive_regex, :negative_regex,
28
- :image_limit, :image_stats, :raise_on_invalid_format
28
+ :image_limit, :image_stats, :raise_on_invalid_format, :max_concurrency
29
29
 
30
30
  alias_method :http_timeout, :http_open_timeout
31
31
  alias_method :http_timeout=, :http_open_timeout=
@@ -59,6 +59,7 @@ module LinkThumbnailer
59
59
  @image_limit = 5
60
60
  @image_stats = true
61
61
  @raise_on_invalid_format = false
62
+ @max_concurrency = 20
62
63
  end
63
64
 
64
65
  end
@@ -1,18 +1,50 @@
1
- require 'link_thumbnailer/image_parsers/size'
2
- require 'link_thumbnailer/image_parsers/type'
1
+ require 'image_info'
3
2
 
4
3
  module LinkThumbnailer
5
4
  class ImageParser
6
- class << self
7
5
 
8
- def size(image)
9
- ::LinkThumbnailer::ImageParsers::Size.perform(image)
6
+ attr_reader :images
7
+
8
+ def initialize(urls)
9
+ @images = perform? ? ::ImageInfo.from(urls, max_concurrency: max_concurrency) : Array(urls).map(&method(:build_default_image))
10
+ end
11
+
12
+ def size
13
+ images.first.size
14
+ end
15
+
16
+ def type
17
+ images.first.type
18
+ end
19
+
20
+ private
21
+
22
+ def build_default_image(uri)
23
+ NullImage.new(uri)
24
+ end
25
+
26
+ def perform?
27
+ ::LinkThumbnailer.page.config.image_stats
28
+ end
29
+
30
+ def max_concurrency
31
+ ::LinkThumbnailer.page.config.max_concurrency
32
+ end
33
+
34
+ class NullImage
35
+ attr_reader :uri
36
+
37
+ def initialize(uri)
38
+ @uri = uri
10
39
  end
11
40
 
12
- def type(image)
13
- ::LinkThumbnailer::ImageParsers::Type.perform(image)
41
+ def size
42
+ [0, 0]
14
43
  end
15
44
 
45
+ def type
46
+ end
16
47
  end
48
+
17
49
  end
18
50
  end
@@ -11,8 +11,8 @@ module LinkThumbnailer
11
11
 
12
12
  def initialize(src, size = nil, type = nil)
13
13
  @src = src
14
- @size = size || parser.size(self)
15
- @type = type || parser.type(self)
14
+ @size = size || parser.size
15
+ @type = type || parser.type
16
16
  end
17
17
 
18
18
  def to_s
@@ -38,7 +38,7 @@ module LinkThumbnailer
38
38
  private
39
39
 
40
40
  def parser
41
- ::LinkThumbnailer::ImageParser
41
+ @parser ||= ::LinkThumbnailer::ImageParser.new(src)
42
42
  end
43
43
 
44
44
  def validator
@@ -7,11 +7,21 @@ module LinkThumbnailer
7
7
  class Images < ::LinkThumbnailer::Scrapers::Default::Base
8
8
 
9
9
  def value
10
- abs_urls.each_with_index.take_while { |_, i| i < config.image_limit }.map { |e| modelize(e.first) }
10
+ images.map do |image|
11
+ modelize(image.uri, image.size, image.type)
12
+ end
11
13
  end
12
14
 
13
15
  private
14
16
 
17
+ def images
18
+ ::LinkThumbnailer::ImageParser.new(allowed_urls).images
19
+ end
20
+
21
+ def allowed_urls
22
+ abs_urls.shift(config.image_limit)
23
+ end
24
+
15
25
  def urls
16
26
  document.search('//img').map { |i| i['src'] }.compact
17
27
  end
@@ -54,8 +64,8 @@ module LinkThumbnailer
54
64
  ::LinkThumbnailer::Models::Image
55
65
  end
56
66
 
57
- def modelize(uri)
58
- model_class.new(uri)
67
+ def modelize(uri, size = nil, type = nil)
68
+ model_class.new(uri, size, type)
59
69
  end
60
70
 
61
71
  end
@@ -1,3 +1,3 @@
1
1
  module LinkThumbnailer
2
- VERSION = '3.0.1'
2
+ VERSION = '3.0.2'
3
3
  end
@@ -22,6 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency 'rake', '>= 0.9'
23
23
  spec.add_dependency 'nokogiri', '~> 1.6'
24
24
  spec.add_dependency 'net-http-persistent', '~> 2.9'
25
- spec.add_dependency 'fastimage', '~> 1.6'
26
25
  spec.add_dependency 'video_info', '~> 2.4'
26
+ spec.add_dependency 'image_info', '~> 1.0'
27
27
  end
@@ -17,6 +17,7 @@ describe LinkThumbnailer::Configuration do
17
17
  it { expect(instance.negative_regex).to_not be_nil }
18
18
  it { expect(instance.image_limit).to eq(5) }
19
19
  it { expect(instance.image_stats).to eq(true) }
20
+ it { expect(instance.max_concurrency).to eq(20) }
20
21
 
21
22
  describe "#http_timeout" do
22
23
  it { expect(instance.method(:http_timeout)).to eq(instance.method(:http_open_timeout)) }
data/spec/fixture_spec.rb CHANGED
@@ -21,7 +21,7 @@ describe 'Fixture' do
21
21
 
22
22
  context 'when valid' do
23
23
 
24
- let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_valid_example.html').read() }
24
+ let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_valid_example.html').read }
25
25
 
26
26
  it { expect(action.favicon).to eq(favicon) }
27
27
  it { expect(action.title).to eq(title) }
@@ -38,8 +38,8 @@ describe 'Fixture' do
38
38
  context 'with multi image' do
39
39
 
40
40
  let(:png_url_2) { 'http://foo.com/bar.png' }
41
- let(:png_2) { File.open(File.dirname(__FILE__) + '/fixtures/bar.png') }
42
- let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_valid_multi_image_example.html').read() }
41
+ let(:png_2) { File.open(File.dirname(__FILE__) + '/fixtures/foo.png') }
42
+ let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_valid_multi_image_example.html').read }
43
43
 
44
44
  before do
45
45
  stub_request(:get, png_url_2).to_return(status: 200, body: png_2, headers: {})
@@ -57,7 +57,7 @@ describe 'Fixture' do
57
57
  context 'with multi video' do
58
58
 
59
59
  let(:video_url_2) { 'http://foo.com/bar.swf' }
60
- let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_valid_multi_video_example.html').read() }
60
+ let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_valid_multi_video_example.html').read }
61
61
 
62
62
  it { expect(action.favicon).to eq('') }
63
63
  it { expect(action.title).to eq(title) }
@@ -70,7 +70,7 @@ describe 'Fixture' do
70
70
 
71
71
  context 'when not valid' do
72
72
 
73
- let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_not_valid_example.html').read() }
73
+ let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_not_valid_example.html').read }
74
74
 
75
75
  it { expect(action.title).to eq(title) }
76
76
  it { expect(action.description).to eq(description) }
@@ -85,7 +85,7 @@ describe 'Fixture' do
85
85
 
86
86
  context 'from meta' do
87
87
 
88
- let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/default_from_meta.html').read() }
88
+ let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/default_from_meta.html').read }
89
89
  let(:title) { 'Title from meta' }
90
90
  let(:description) { 'Description from meta' }
91
91
 
@@ -97,7 +97,7 @@ describe 'Fixture' do
97
97
 
98
98
  context 'from body' do
99
99
 
100
- let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/default_from_body.html').read() }
100
+ let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/default_from_body.html').read }
101
101
  let(:description) { 'Description from body' }
102
102
 
103
103
  it { expect(action.favicon).to eq(favicon) }
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,7 @@
1
- require 'simplecov'
2
- require 'coveralls'
3
- Coveralls.wear!
4
-
5
1
  require 'link_thumbnailer'
6
2
  require 'rspec'
7
3
  require 'webmock/rspec'
8
4
 
9
- SimpleCov.formatter = Coveralls::SimpleCov::Formatter
10
-
11
5
  RSpec.configure do |config|
12
6
  config.expect_with :rspec do |c|
13
7
  c.syntax = :expect
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: link_thumbnailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pierre-Louis Gottfrois
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-26 00:00:00.000000000 Z
11
+ date: 2015-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -87,33 +87,33 @@ dependencies:
87
87
  - !ruby/object:Gem::Version
88
88
  version: '2.9'
89
89
  - !ruby/object:Gem::Dependency
90
- name: fastimage
90
+ name: video_info
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - ~>
94
94
  - !ruby/object:Gem::Version
95
- version: '1.6'
95
+ version: '2.4'
96
96
  type: :runtime
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - ~>
101
101
  - !ruby/object:Gem::Version
102
- version: '1.6'
102
+ version: '2.4'
103
103
  - !ruby/object:Gem::Dependency
104
- name: video_info
104
+ name: image_info
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ~>
108
108
  - !ruby/object:Gem::Version
109
- version: '2.4'
109
+ version: '1.0'
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ~>
115
115
  - !ruby/object:Gem::Version
116
- version: '2.4'
116
+ version: '1.0'
117
117
  description: Ruby gem generating thumbnail images from a given URL.
118
118
  email:
119
119
  - pierrelouis.gottfrois@gmail.com
@@ -122,7 +122,6 @@ extensions: []
122
122
  extra_rdoc_files: []
123
123
  files:
124
124
  - .gitignore
125
- - .hound.yml
126
125
  - .rspec
127
126
  - .travis.yml
128
127
  - CHANGELOG.md
@@ -145,8 +144,6 @@ files:
145
144
  - lib/link_thumbnailer/image_comparators/base.rb
146
145
  - lib/link_thumbnailer/image_comparators/size.rb
147
146
  - lib/link_thumbnailer/image_parser.rb
148
- - lib/link_thumbnailer/image_parsers/size.rb
149
- - lib/link_thumbnailer/image_parsers/type.rb
150
147
  - lib/link_thumbnailer/image_validator.rb
151
148
  - lib/link_thumbnailer/model.rb
152
149
  - lib/link_thumbnailer/models/description.rb
@@ -195,8 +192,6 @@ files:
195
192
  - spec/graders/link_density_spec.rb
196
193
  - spec/graders/position_spec.rb
197
194
  - spec/image_comparators/size_spec.rb
198
- - spec/image_parsers/size_spec.rb
199
- - spec/image_parsers/type_spec.rb
200
195
  - spec/image_validator_spec.rb
201
196
  - spec/model_spec.rb
202
197
  - spec/models/description_spec.rb
@@ -254,8 +249,6 @@ test_files:
254
249
  - spec/graders/link_density_spec.rb
255
250
  - spec/graders/position_spec.rb
256
251
  - spec/image_comparators/size_spec.rb
257
- - spec/image_parsers/size_spec.rb
258
- - spec/image_parsers/type_spec.rb
259
252
  - spec/image_validator_spec.rb
260
253
  - spec/model_spec.rb
261
254
  - spec/models/description_spec.rb
data/.hound.yml DELETED
@@ -1,2 +0,0 @@
1
- ruby:
2
- enabled: true
@@ -1,22 +0,0 @@
1
- require 'fastimage'
2
-
3
- module LinkThumbnailer
4
- module ImageParsers
5
- class Size
6
-
7
- def self.perform(image)
8
- return [0, 0] unless perform?
9
- ::FastImage.size(image.src.to_s, raise_on_failure: true)
10
- rescue ::FastImage::FastImageException, ::Errno::ENAMETOOLONG
11
- [0, 0]
12
- end
13
-
14
- private
15
-
16
- def self.perform?
17
- ::LinkThumbnailer.page.config.image_stats
18
- end
19
-
20
- end
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- require 'fastimage'
2
-
3
- module LinkThumbnailer
4
- module ImageParsers
5
- class Type
6
-
7
- def self.perform(image)
8
- return unless perform?
9
- ::FastImage.type(image.src.to_s, raise_on_failure: true)
10
- rescue ::FastImage::FastImageException, ::Errno::ENAMETOOLONG
11
- nil
12
- end
13
-
14
- private
15
-
16
- def self.perform?
17
- ::LinkThumbnailer.page.config.image_stats
18
- end
19
-
20
- end
21
- end
22
- end
@@ -1,34 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe LinkThumbnailer::ImageParsers::Size do
4
-
5
- describe '.perform' do
6
-
7
- let(:size) { [10, 10] }
8
- let(:src) { 'http://foo.com' }
9
- let(:image) { double(src: src) }
10
- let(:action) { described_class.perform(image) }
11
-
12
- context 'when no exception is raised' do
13
-
14
- before do
15
- expect(FastImage).to receive(:size).with(src, raise_on_failure: true).and_return(size)
16
- end
17
-
18
- it { expect(action).to eq(size) }
19
-
20
- end
21
-
22
- context 'when an exception is raised' do
23
-
24
- before do
25
- expect(FastImage).to receive(:size).with(src, raise_on_failure: true).and_raise(FastImage::FastImageException)
26
- end
27
-
28
- it { expect(action).to eq([0, 0]) }
29
-
30
- end
31
-
32
- end
33
-
34
- end
@@ -1,34 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe LinkThumbnailer::ImageParsers::Type do
4
-
5
- describe '.perform' do
6
-
7
- let(:type) { 'png' }
8
- let(:src) { 'http://foo.com' }
9
- let(:image) { double(src: src) }
10
- let(:action) { described_class.perform(image) }
11
-
12
- context 'when no exception is raised' do
13
-
14
- before do
15
- expect(FastImage).to receive(:type).with(src, raise_on_failure: true).and_return(type)
16
- end
17
-
18
- it { expect(action).to eq(type) }
19
-
20
- end
21
-
22
- context 'when an exception is raised' do
23
-
24
- before do
25
- expect(FastImage).to receive(:type).with(src, raise_on_failure: true).and_raise(FastImage::FastImageException)
26
- end
27
-
28
- it { expect(action).to be_nil }
29
-
30
- end
31
-
32
- end
33
-
34
- end