link_thumbnailer 2.1.0 → 2.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZmRlNGRiODRmOGM2ZGZmNmVjYzE4M2MwM2NlY2VhMzdmYTdiYzdjNA==
4
+ MmMxNTZhYWFkN2E4N2JjN2NkNjRlMmFlMjU3YWYxMDJlOWVmNzBhMw==
5
5
  data.tar.gz: !binary |-
6
- OGMyMTFjZTg4Y2M1ODQxMmU3ZWU5NjcwMmEzYTU2MzM2MDkyZjllYg==
6
+ MDMwOWQ2NWYyYmUxMGExOWI0MzM5YjA2ZTkwZTNlY2ViZmVlOGFhYQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YmM4YzhlMzcxZWYzZTU5OGE3ZjU2NDRlYmY3MzQwMDUxZDlhNWRlMTdjODYx
10
- NzRjYTk1ZTQzMjJlZGUzYzY5YmM2NzlmMDdjMmViM2M3NGU4MTg3ZGJkMWUx
11
- MDJkNmVlNWFmZGU0ZTYyMjQ4ZjVkZTYzYzFkNjhjOTc1ZTlhOGE=
9
+ YmM4MDg1ZTFlZTJlZGJiZTYxMzc2MWI5N2FkYjkxMDc4NmEzNjdmYjVjMDJj
10
+ ZDQxMTc5YTY3ZjY3MzY5MWRjNjk4ODFmYWJjNTE4ZmQwMGI2YTI2ZjhiMjU3
11
+ ZGFhMzNlNzcwNjIzZWFhYTNkYWQ3NWY5OTU1M2Q0NDM0ZjQxYzU=
12
12
  data.tar.gz: !binary |-
13
- MmUwMTY3NmNjNjU3OTJlOTQyOTQ1YWViZTZlNWNkNDNhYWEyNzg5ZWE5MWE4
14
- NDNmZDdlZjUyOWUwZTgyZjIxMGQxZGRiMTJjMzNjOGI1MTMwNjJiM2E4NmU1
15
- NmY5NWNjNDU4MjgwYzVlMTdkYmVhOWZiMjk5NTg0NTQ3MjJiOTg=
13
+ MDRlNWY3MGQ1ZWI4MTYyNzY0ZmY0MGIxY2U2NDA5NTg4Zjc2MGI5NDgxNzBl
14
+ MzRiOTUwNmVlMTdjZmFiMGFkZThmODFkYjllN2QxMWZlOTI5NWM1MzNmMDA1
15
+ MmU5YjcxYWY3Y2RjZGE5ZjJmNDU5NjBkMzc1MjNiODA5YjIxMGI=
@@ -1,3 +1,29 @@
1
+ # 2.2.0
2
+
3
+ - Add support for `og:video`
4
+ - Add support for multiple `og:video` as well
5
+
6
+ LinkThumbnailer will return the following json for example:
7
+
8
+ ```ruby
9
+ {
10
+ id: 'x7lni3',
11
+ src: 'http://www.dailymotion.com/video/x7lni3',
12
+ size: [640, 360],
13
+ duration: 136,
14
+ provider: 'Dailymotion',
15
+ embed_code: '<iframe src="//www.dailymotion.com/embed/video/x7lni3" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'
16
+ }
17
+ ```
18
+
19
+ Add `:videos` into your `config/initializers/link_thumbnailer.rb` `attributes` config in order to start scraping videos.
20
+
21
+ Ex:
22
+
23
+ ```ruby
24
+ config.attributes = [:title, :images, :description, :videos]
25
+ ```
26
+
1
27
  # 2.1.0
2
28
 
3
29
  - Increased `og:image` scraping performance by parsing `og:image:width` and `og:image:height` attribute if specified
data/README.md CHANGED
@@ -108,7 +108,7 @@ In `config/initializers/link_thumbnailer.rb`
108
108
 
109
109
  # List of attributes you want LinkThumbnailer to fetch on a website.
110
110
  #
111
- # config.attributes = [:title, :images, :description]
111
+ # config.attributes = [:title, :images, :description, :videos]
112
112
 
113
113
  # List of procedures used to rate the website description. Add you custom class
114
114
  # here. Note that the order matter to compute the score. See wiki for more details
@@ -153,6 +153,13 @@ Note that runtime options will override default global configuration.
153
153
 
154
154
  See [Configuration Options Explained](https://github.com/gottfrois/link_thumbnailer/wiki/Configuration-options-explained) for more details on each configuration options.
155
155
 
156
+ ## Exceptions
157
+
158
+ LinkThumbnailer defines a list of custom exceptions you may want to rescue in your code. All the following exceptions inherit from `LinkThumbnailer::Exceptions`:
159
+
160
+ * `RedirectLimit` -- raised when redirection threshold defined in config is reached
161
+ * `BadUriFormat` -- raised when url given is not a valid HTTP url
162
+
156
163
  ## Contributing
157
164
 
158
165
  1. Fork it
@@ -31,7 +31,7 @@ LinkThumbnailer.configure do |config|
31
31
 
32
32
  # List of attributes you want LinkThumbnailer to fetch on a website.
33
33
  #
34
- # config.attributes = [:title, :images, :description]
34
+ # config.attributes = [:title, :images, :description, :videos]
35
35
 
36
36
  # List of procedures used to rate the website description. Add you custom class
37
37
  # here. Note that the order matter to compute the score. See wiki for more details
@@ -41,7 +41,7 @@ module LinkThumbnailer
41
41
  %r{^http://pixel\.quantserve\.com/},
42
42
  %r{^http://s7\.addthis\.com/}
43
43
  ]
44
- @attributes = [:title, :images, :description]
44
+ @attributes = [:title, :images, :description, :videos]
45
45
  @graders = [
46
46
  ->(description) { ::LinkThumbnailer::Graders::Length.new(description) },
47
47
  ->(description) { ::LinkThumbnailer::Graders::HtmlAttribute.new(description, :class) },
@@ -0,0 +1,42 @@
1
+ require 'link_thumbnailer/model'
2
+ require 'link_thumbnailer/video_parser'
3
+
4
+ module LinkThumbnailer
5
+ module Models
6
+ class Video < ::LinkThumbnailer::Model
7
+
8
+ attr_reader :src, :size, :duration, :provider, :id, :embed_code
9
+
10
+ def initialize(src)
11
+ @src = src
12
+ @id = parser.id
13
+ @size = parser.size
14
+ @duration = parser.duration
15
+ @provider = parser.provider
16
+ @embed_code = parser.embed_code
17
+ end
18
+
19
+ def to_s
20
+ src.to_s
21
+ end
22
+
23
+ def as_json(*)
24
+ {
25
+ id: id,
26
+ src: src.to_s,
27
+ size: size,
28
+ duration: duration,
29
+ provider: provider,
30
+ embed_code: embed_code
31
+ }
32
+ end
33
+
34
+ private
35
+
36
+ def parser
37
+ @parser ||= ::LinkThumbnailer::VideoParser.new(self)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -4,10 +4,21 @@ module LinkThumbnailer
4
4
  module Models
5
5
  class Website < ::LinkThumbnailer::Model
6
6
 
7
- attr_accessor :url, :title, :description, :images
7
+ attr_accessor :url, :title, :description, :images, :videos
8
8
 
9
9
  def initialize
10
10
  @images = []
11
+ @videos = []
12
+ end
13
+
14
+ def video=(video)
15
+ self.videos = video
16
+ end
17
+
18
+ def videos=(videos)
19
+ Array(videos).each do |video|
20
+ @videos << video
21
+ end
11
22
  end
12
23
 
13
24
  def image=(image)
@@ -30,7 +41,8 @@ module LinkThumbnailer
30
41
  url: url.to_s,
31
42
  title: title,
32
43
  description: description,
33
- images: images
44
+ images: images,
45
+ videos: videos
34
46
  }
35
47
  end
36
48
 
@@ -10,6 +10,8 @@ require 'link_thumbnailer/scrapers/default/description'
10
10
  require 'link_thumbnailer/scrapers/opengraph/description'
11
11
  require 'link_thumbnailer/scrapers/default/images'
12
12
  require 'link_thumbnailer/scrapers/opengraph/images'
13
+ require 'link_thumbnailer/scrapers/default/videos'
14
+ require 'link_thumbnailer/scrapers/opengraph/videos'
13
15
 
14
16
  module LinkThumbnailer
15
17
  class Scraper < ::SimpleDelegator
@@ -30,9 +32,7 @@ module LinkThumbnailer
30
32
  def call
31
33
  config.attributes.each do |name|
32
34
  scrapers.each do |scraper_prefix|
33
- scraper = scraper_class(scraper_prefix, name).new(document)
34
- scraper.call(website, name.to_s) if scraper.applicable?
35
-
35
+ scraper_class(scraper_prefix, name).new(document).call(website, name.to_s)
36
36
  break unless website.send(name).blank?
37
37
  end
38
38
  end
@@ -44,8 +44,8 @@ module LinkThumbnailer
44
44
 
45
45
  def scrapers
46
46
  [
47
- "::LinkThumbnailer::Scrapers::Opengraph",
48
- "::LinkThumbnailer::Scrapers::Default"
47
+ '::LinkThumbnailer::Scrapers::Opengraph',
48
+ '::LinkThumbnailer::Scrapers::Default'
49
49
  ]
50
50
  end
51
51
 
@@ -2,6 +2,7 @@ require 'delegate'
2
2
  require 'link_thumbnailer/models/title'
3
3
  require 'link_thumbnailer/models/description'
4
4
  require 'link_thumbnailer/models/image'
5
+ require 'link_thumbnailer/models/video'
5
6
 
6
7
  module LinkThumbnailer
7
8
  module Scrapers
@@ -17,6 +18,7 @@ module LinkThumbnailer
17
18
  end
18
19
 
19
20
  def call(website, attribute_name)
21
+ return false unless applicable?
20
22
  @website = website
21
23
  @attribute_name = attribute_name
22
24
 
@@ -0,0 +1,16 @@
1
+ require 'link_thumbnailer/scrapers/default/base'
2
+ require 'link_thumbnailer/models/video'
3
+
4
+ module LinkThumbnailer
5
+ module Scrapers
6
+ module Default
7
+ class Videos < ::LinkThumbnailer::Scrapers::Default::Base
8
+
9
+ def value
10
+ nil
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
@@ -5,12 +5,12 @@ module LinkThumbnailer
5
5
  module Opengraph
6
6
  class Image < ::LinkThumbnailer::Scrapers::Opengraph::Base
7
7
 
8
- private
9
-
10
8
  def value
11
9
  model
12
10
  end
13
11
 
12
+ private
13
+
14
14
  def model
15
15
  nodes.map { |n| modelize(n, n.attributes['content'].to_s) }
16
16
  end
@@ -36,12 +36,16 @@ module LinkThumbnailer
36
36
  Height.new(document).value
37
37
  end
38
38
 
39
- class Width < ::LinkThumbnailer::Scrapers::Opengraph::Base
39
+ class Base < ::LinkThumbnailer::Scrapers::Opengraph::Base
40
40
 
41
41
  def value
42
42
  node.attributes['content'].to_s if node
43
43
  end
44
44
 
45
+ end
46
+
47
+ class Width < Base
48
+
45
49
  private
46
50
 
47
51
  def attribute
@@ -50,11 +54,7 @@ module LinkThumbnailer
50
54
 
51
55
  end
52
56
 
53
- class Height < ::LinkThumbnailer::Scrapers::Opengraph::Base
54
-
55
- def value
56
- node.attributes['content'].to_s if node
57
- end
57
+ class Height < Base
58
58
 
59
59
  private
60
60
 
@@ -0,0 +1,30 @@
1
+ require 'link_thumbnailer/scrapers/opengraph/base'
2
+
3
+ module LinkThumbnailer
4
+ module Scrapers
5
+ module Opengraph
6
+ class Video < ::LinkThumbnailer::Scrapers::Opengraph::Base
7
+
8
+ def value
9
+ model
10
+ end
11
+
12
+ private
13
+
14
+ def model
15
+ nodes.map { |n| modelize(n, n.attributes['content'].to_s) }
16
+ end
17
+
18
+ def modelize(node, text = nil)
19
+ model_class.new(text)
20
+ end
21
+
22
+ def nodes
23
+ nodes = meta_xpaths(attribute: attribute)
24
+ nodes.empty? ? meta_xpaths(attribute: attribute, key: :name) : nodes
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ require 'link_thumbnailer/scrapers/opengraph/base'
2
+ require 'link_thumbnailer/scrapers/opengraph/video'
3
+
4
+ module LinkThumbnailer
5
+ module Scrapers
6
+ module Opengraph
7
+ class Videos < ::LinkThumbnailer::Scrapers::Opengraph::Base
8
+
9
+ def call(website, attribute_name)
10
+ ::LinkThumbnailer::Scrapers::Opengraph::Video.new(document).call(website, 'video')
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module LinkThumbnailer
2
- VERSION = '2.1.0'
2
+ VERSION = '2.2.0'
3
3
  end
@@ -0,0 +1,45 @@
1
+ require 'video_info'
2
+
3
+ module LinkThumbnailer
4
+ class VideoParser
5
+
6
+ attr_reader :parser
7
+
8
+ def initialize(video)
9
+ @parser = ::VideoInfo.new(video.src.to_s)
10
+ rescue ::VideoInfo::UrlError
11
+ @parser = nil
12
+ end
13
+
14
+ def id
15
+ parser.video_id
16
+ rescue NoMethodError
17
+ nil
18
+ end
19
+
20
+ def size
21
+ [parser.width, parser.height]
22
+ rescue NoMethodError
23
+ []
24
+ end
25
+
26
+ def duration
27
+ parser.duration
28
+ rescue NoMethodError
29
+ nil
30
+ end
31
+
32
+ def provider
33
+ parser.provider
34
+ rescue NoMethodError
35
+ nil
36
+ end
37
+
38
+ def embed_code
39
+ parser.embed_code
40
+ rescue NoMethodError
41
+ nil
42
+ end
43
+
44
+ end
45
+ end
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'nokogiri', '~> 1.6'
24
24
  spec.add_dependency 'net-http-persistent', '~> 2.9'
25
25
  spec.add_dependency 'fastimage', '~> 1.6'
26
+ spec.add_dependency 'video_info', '~> 2.3'
26
27
  end
@@ -9,7 +9,7 @@ describe LinkThumbnailer::Configuration do
9
9
  it { expect(instance.verify_ssl).to eq(true) }
10
10
  it { expect(instance.http_timeout).to eq(5) }
11
11
  it { expect(instance.blacklist_urls).to_not be_empty }
12
- it { expect(instance.attributes).to_not be_empty }
12
+ it { expect(instance.attributes).to eq([:title, :images, :description, :videos]) }
13
13
  it { expect(instance.graders).to_not be_empty }
14
14
  it { expect(instance.description_min_length).to eq(25) }
15
15
  it { expect(instance.positive_regex).to_not be_nil }
@@ -4,6 +4,7 @@ describe 'Fixture' do
4
4
 
5
5
  let(:url) { 'http://foo.com' }
6
6
  let(:png_url) { 'http://foo.com/foo.png' }
7
+ let(:video_url) { 'http://foo.com/foo.swf' }
7
8
  let(:png) { File.open(File.dirname(__FILE__) + '/fixtures/foo.png') }
8
9
  let(:action) { LinkThumbnailer.generate(url) }
9
10
 
@@ -26,6 +27,8 @@ describe 'Fixture' do
26
27
  it { expect(action.images.count).to eq(1) }
27
28
  it { expect(action.images.first.src.to_s).to eq(png_url) }
28
29
  it { expect(action.images.first.size).to eq([100, 100]) }
30
+ it { expect(action.videos.count).to eq(1) }
31
+ it { expect(action.videos.first.src.to_s).to eq(video_url) }
29
32
 
30
33
  end
31
34
 
@@ -47,6 +50,19 @@ describe 'Fixture' do
47
50
 
48
51
  end
49
52
 
53
+ context 'with multi video' do
54
+
55
+ let(:video_url_2) { 'http://foo.com/bar.swf' }
56
+ let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_valid_multi_video_example.html').read() }
57
+
58
+ it { expect(action.title).to eq(title) }
59
+ it { expect(action.description).to eq(description) }
60
+ it { expect(action.videos.count).to eq(2) }
61
+ it { expect(action.videos.first.src.to_s).to eq(video_url) }
62
+ it { expect(action.videos.last.src.to_s).to eq(video_url_2) }
63
+
64
+ end
65
+
50
66
  context 'when not valid' do
51
67
 
52
68
  let(:html) { File.open(File.dirname(__FILE__) + '/fixtures/og_not_valid_example.html').read() }
@@ -8,6 +8,7 @@
8
8
  <meta property="og:image" content="http://foo.com/foo.png">
9
9
  <meta property="og:image:width" content="100">
10
10
  <meta property="og:image:height" content="100">
11
+ <meta property="og:video" content="http://foo.com/foo.swf">
11
12
  <title>Title</title>
12
13
  </head>
13
14
 
@@ -0,0 +1,13 @@
1
+ <html xmlns:og="http://opengraphprotocol.org/schema/">
2
+ <head>
3
+ <meta charset="utf-8"/>
4
+ <meta property="og:type" content="website"/>
5
+ <meta property="og:site_name" content="foo.com">
6
+ <meta property="og:title" content="Title from og">
7
+ <meta property="og:description" content="Description from og">
8
+ <meta property="og:video" content="http://foo.com/foo.swf">
9
+ <meta property="og:video" content="http://foo.com/bar.swf">
10
+ <title>Title</title>
11
+ </head>
12
+
13
+ </html>
@@ -68,4 +68,26 @@ describe LinkThumbnailer::Models::Image do
68
68
 
69
69
  end
70
70
 
71
+ describe '#as_json' do
72
+
73
+ let(:action) { instance.as_json }
74
+ let(:size) { [1, 1] }
75
+ let(:type) { 'foo' }
76
+ let(:result) {
77
+ {
78
+ src: src,
79
+ size: size,
80
+ type: type
81
+ }
82
+ }
83
+
84
+ before do
85
+ instance.stub(:size).and_return(size)
86
+ instance.stub(:type).and_return(type)
87
+ end
88
+
89
+ it { expect(action).to eq(result) }
90
+
91
+ end
92
+
71
93
  end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::Models::Video do
4
+
5
+ let(:src) { 'http://foo.com/foo.swf' }
6
+ let(:instance) { described_class.new(src) }
7
+
8
+ describe '#to_s' do
9
+
10
+ let(:action) { instance.to_s }
11
+
12
+ it { expect(action).to eq(src) }
13
+
14
+ end
15
+
16
+ describe '#as_json' do
17
+
18
+ let(:action) { instance.as_json }
19
+ let(:id) { 1 }
20
+ let(:size) { [1, 1] }
21
+ let(:duration) { 10 }
22
+ let(:provider) { 'foo' }
23
+ let(:embed_code) { 'bar' }
24
+ let(:result) {
25
+ {
26
+ id: id,
27
+ src: src,
28
+ size: size,
29
+ duration: duration,
30
+ provider: provider,
31
+ embed_code: embed_code
32
+ }
33
+ }
34
+
35
+ before do
36
+ instance.stub(:id).and_return(id)
37
+ instance.stub(:size).and_return(size)
38
+ instance.stub(:duration).and_return(duration)
39
+ instance.stub(:provider).and_return(provider)
40
+ instance.stub(:embed_code).and_return(embed_code)
41
+ end
42
+
43
+ it { expect(action).to eq(result) }
44
+
45
+ end
46
+
47
+ end
@@ -18,8 +18,7 @@ describe LinkThumbnailer::Scraper do
18
18
  let(:prefix_1) { 'prefix_1' }
19
19
  let(:prefix_2) { 'prefix_2' }
20
20
  let(:scraper_class) { double('scraper_class') }
21
- let(:applicable_scraper) { double(applicable?: true) }
22
- let(:not_applicable_scraper) { double(applicable?: false) }
21
+ let(:scraper) { double('scraper', call: true) }
23
22
  let(:attributes) { [:bar] }
24
23
  let(:scrapers) { [prefix_1, prefix_2] }
25
24
  let(:action) { instance.call }
@@ -29,36 +28,10 @@ describe LinkThumbnailer::Scraper do
29
28
  instance.stub(:scrapers).and_return(scrapers)
30
29
  end
31
30
 
32
- context 'when first scraper not applicable' do
31
+ context 'when first one return a result' do
33
32
 
34
- before do
35
- expect(website).to receive(:bar).and_return('bar')
36
- expect(applicable_scraper).to receive(:call).with(website, 'bar')
37
- expect(scraper_class).to receive(:new).with(document).and_return(applicable_scraper)
38
- expect(instance).to receive(:scraper_class).with(prefix_1, :bar).and_return(scraper_class)
39
- end
40
-
41
- it { expect(action).to eq(website) }
42
-
43
- end
44
-
45
- context 'when first scraper applicable' do
46
-
47
- before do
48
- expect(website).to receive(:bar).and_return('bar')
49
- expect(not_applicable_scraper).to_not receive(:call).with(website, 'bar')
50
- expect(scraper_class).to receive(:new).with(document).and_return(not_applicable_scraper)
51
- expect(instance).to receive(:scraper_class).with(prefix_1, :bar).and_return(scraper_class)
52
- end
53
-
54
- it { expect(action).to eq(website) }
55
-
56
- end
57
-
58
- context 'when all scrapers applicable and first one return a result' do
59
-
60
- let(:valid_scraper) { double('scraper', applicable?: true) }
61
- let(:not_valid_scraper) { double('scraper', applicable?: true) }
33
+ let(:valid_scraper) { double('scraper') }
34
+ let(:not_valid_scraper) { double('scraper') }
62
35
 
63
36
  before do
64
37
  expect(website).to receive(:bar).once.and_return('bar')
@@ -72,10 +45,10 @@ describe LinkThumbnailer::Scraper do
72
45
 
73
46
  end
74
47
 
75
- context 'when all scrapers applicable but first one do not return any result' do
48
+ context 'when first one does not return any result' do
76
49
 
77
- let(:valid_scraper) { double('scraper', applicable?: true) }
78
- let(:not_valid_scraper) { double('scraper', applicable?: true) }
50
+ let(:valid_scraper) { double('scraper') }
51
+ let(:not_valid_scraper) { double('scraper') }
79
52
 
80
53
  before do
81
54
  expect(website).to receive(:bar).and_return('', 'bar')
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::VideoParser do
4
+
5
+ let(:src) { 'http://foo.com/foo.swf' }
6
+ let(:video) { double(src: src) }
7
+ let(:parser) { double('parser') }
8
+ let(:instance) { described_class.new(video) }
9
+
10
+ before do
11
+ instance.stub(:parser).and_return(parser)
12
+ end
13
+
14
+ describe '#id' do
15
+
16
+ let(:action) { instance.id }
17
+
18
+ context 'when respond to video_id' do
19
+
20
+ before do
21
+ parser.stub(:video_id).and_return(1)
22
+ end
23
+
24
+ it { expect(action).to eq(parser.video_id) }
25
+
26
+ end
27
+
28
+ context 'when do not respond to video_id' do
29
+
30
+ before do
31
+ parser.stub(:video_id).and_raise(NoMethodError)
32
+ end
33
+
34
+ it { expect(action).to be_nil }
35
+
36
+ end
37
+
38
+ end
39
+
40
+ describe '#size' do
41
+
42
+ let(:action) { instance.size }
43
+
44
+ context 'when respond to width and height' do
45
+
46
+ before do
47
+ parser.stub(:width).and_return(1)
48
+ parser.stub(:height).and_return(1)
49
+ end
50
+
51
+ it { expect(action).to eq([parser.width, parser.height]) }
52
+
53
+ end
54
+
55
+ context 'when do not respond to width and height' do
56
+
57
+ before do
58
+ parser.stub(:width).and_raise(NoMethodError)
59
+ parser.stub(:height).and_raise(NoMethodError)
60
+ end
61
+
62
+ it { expect(action).to be_empty }
63
+
64
+ end
65
+
66
+ end
67
+
68
+ describe '#duration' do
69
+
70
+ let(:action) { instance.duration }
71
+
72
+ context 'when respond to duration' do
73
+
74
+ before do
75
+ parser.stub(:duration).and_return(1)
76
+ end
77
+
78
+ it { expect(action).to eq(parser.duration) }
79
+
80
+ end
81
+
82
+ context 'when do not respond to duration' do
83
+
84
+ before do
85
+ parser.stub(:duration).and_raise(NoMethodError)
86
+ end
87
+
88
+ it { expect(action).to be_nil }
89
+
90
+ end
91
+
92
+ end
93
+
94
+ describe '#provider' do
95
+
96
+ let(:action) { instance.provider }
97
+
98
+ context 'when respond to provider' do
99
+
100
+ before do
101
+ parser.stub(:provider).and_return(1)
102
+ end
103
+
104
+ it { expect(action).to eq(parser.provider) }
105
+
106
+ end
107
+
108
+ context 'when do not respond to provider' do
109
+
110
+ before do
111
+ parser.stub(:provider).and_raise(NoMethodError)
112
+ end
113
+
114
+ it { expect(action).to be_nil }
115
+
116
+ end
117
+
118
+ end
119
+
120
+ describe '#embed_code' do
121
+
122
+ let(:action) { instance.embed_code }
123
+
124
+ context 'when respond to embed_code' do
125
+
126
+ before do
127
+ parser.stub(:embed_code).and_return('')
128
+ end
129
+
130
+ it { expect(action).to eq(parser.embed_code) }
131
+
132
+ end
133
+
134
+ context 'when do not respond to embed_code' do
135
+
136
+ before do
137
+ parser.stub(:embed_code).and_raise(NoMethodError)
138
+ end
139
+
140
+ it { expect(action).to be_nil }
141
+
142
+ end
143
+
144
+ end
145
+
146
+ end
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: 2.1.0
4
+ version: 2.2.0
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: 2014-06-10 00:00:00.000000000 Z
11
+ date: 2014-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -100,6 +100,20 @@ dependencies:
100
100
  - - ~>
101
101
  - !ruby/object:Gem::Version
102
102
  version: '1.6'
103
+ - !ruby/object:Gem::Dependency
104
+ name: video_info
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '2.3'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ~>
115
+ - !ruby/object:Gem::Version
116
+ version: '2.3'
103
117
  description: Ruby gem generating thumbnail images from a given URL.
104
118
  email:
105
119
  - pierrelouis.gottfrois@gmail.com
@@ -137,6 +151,7 @@ files:
137
151
  - lib/link_thumbnailer/models/description.rb
138
152
  - lib/link_thumbnailer/models/image.rb
139
153
  - lib/link_thumbnailer/models/title.rb
154
+ - lib/link_thumbnailer/models/video.rb
140
155
  - lib/link_thumbnailer/models/website.rb
141
156
  - lib/link_thumbnailer/page.rb
142
157
  - lib/link_thumbnailer/parser.rb
@@ -148,12 +163,16 @@ files:
148
163
  - lib/link_thumbnailer/scrapers/default/description.rb
149
164
  - lib/link_thumbnailer/scrapers/default/images.rb
150
165
  - lib/link_thumbnailer/scrapers/default/title.rb
166
+ - lib/link_thumbnailer/scrapers/default/videos.rb
151
167
  - lib/link_thumbnailer/scrapers/opengraph/base.rb
152
168
  - lib/link_thumbnailer/scrapers/opengraph/description.rb
153
169
  - lib/link_thumbnailer/scrapers/opengraph/image.rb
154
170
  - lib/link_thumbnailer/scrapers/opengraph/images.rb
155
171
  - lib/link_thumbnailer/scrapers/opengraph/title.rb
172
+ - lib/link_thumbnailer/scrapers/opengraph/video.rb
173
+ - lib/link_thumbnailer/scrapers/opengraph/videos.rb
156
174
  - lib/link_thumbnailer/version.rb
175
+ - lib/link_thumbnailer/video_parser.rb
157
176
  - link_thumbnailer.gemspec
158
177
  - spec/configuration_spec.rb
159
178
  - spec/examples/empty_og_image_example.html
@@ -166,6 +185,7 @@ files:
166
185
  - spec/fixtures/og_not_valid_example.html
167
186
  - spec/fixtures/og_valid_example.html
168
187
  - spec/fixtures/og_valid_multi_image_example.html
188
+ - spec/fixtures/og_valid_multi_video_example.html
169
189
  - spec/grader_spec.rb
170
190
  - spec/graders/base_spec.rb
171
191
  - spec/graders/html_attribute_spec.rb
@@ -179,6 +199,7 @@ files:
179
199
  - spec/models/description_spec.rb
180
200
  - spec/models/image_spec.rb
181
201
  - spec/models/title_spec.rb
202
+ - spec/models/video_spec.rb
182
203
  - spec/models/website_spec.rb
183
204
  - spec/page_spec.rb
184
205
  - spec/processor_spec.rb
@@ -186,6 +207,7 @@ files:
186
207
  - spec/scrapers/base_spec.rb
187
208
  - spec/scrapers/opengraph/base_spec.rb
188
209
  - spec/spec_helper.rb
210
+ - spec/video_parser_spec.rb
189
211
  homepage: https://github.com/gottfrois/link_thumbnailer
190
212
  licenses: []
191
213
  metadata: {}
@@ -222,6 +244,7 @@ test_files:
222
244
  - spec/fixtures/og_not_valid_example.html
223
245
  - spec/fixtures/og_valid_example.html
224
246
  - spec/fixtures/og_valid_multi_image_example.html
247
+ - spec/fixtures/og_valid_multi_video_example.html
225
248
  - spec/grader_spec.rb
226
249
  - spec/graders/base_spec.rb
227
250
  - spec/graders/html_attribute_spec.rb
@@ -235,6 +258,7 @@ test_files:
235
258
  - spec/models/description_spec.rb
236
259
  - spec/models/image_spec.rb
237
260
  - spec/models/title_spec.rb
261
+ - spec/models/video_spec.rb
238
262
  - spec/models/website_spec.rb
239
263
  - spec/page_spec.rb
240
264
  - spec/processor_spec.rb
@@ -242,3 +266,4 @@ test_files:
242
266
  - spec/scrapers/base_spec.rb
243
267
  - spec/scrapers/opengraph/base_spec.rb
244
268
  - spec/spec_helper.rb
269
+ - spec/video_parser_spec.rb