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 +8 -8
- data/CHANGELOG.md +26 -0
- data/README.md +8 -1
- data/lib/generators/templates/initializer.rb +1 -1
- data/lib/link_thumbnailer/configuration.rb +1 -1
- data/lib/link_thumbnailer/models/video.rb +42 -0
- data/lib/link_thumbnailer/models/website.rb +14 -2
- data/lib/link_thumbnailer/scraper.rb +5 -5
- data/lib/link_thumbnailer/scrapers/base.rb +2 -0
- data/lib/link_thumbnailer/scrapers/default/videos.rb +16 -0
- data/lib/link_thumbnailer/scrapers/opengraph/image.rb +8 -8
- data/lib/link_thumbnailer/scrapers/opengraph/video.rb +30 -0
- data/lib/link_thumbnailer/scrapers/opengraph/videos.rb +16 -0
- data/lib/link_thumbnailer/version.rb +1 -1
- data/lib/link_thumbnailer/video_parser.rb +45 -0
- data/link_thumbnailer.gemspec +1 -0
- data/spec/configuration_spec.rb +1 -1
- data/spec/fixture_spec.rb +16 -0
- data/spec/fixtures/og_valid_example.html +1 -0
- data/spec/fixtures/og_valid_multi_video_example.html +13 -0
- data/spec/models/image_spec.rb +22 -0
- data/spec/models/video_spec.rb +47 -0
- data/spec/scraper_spec.rb +7 -34
- data/spec/video_parser_spec.rb +146 -0
- metadata +27 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MmMxNTZhYWFkN2E4N2JjN2NkNjRlMmFlMjU3YWYxMDJlOWVmNzBhMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDMwOWQ2NWYyYmUxMGExOWI0MzM5YjA2ZTkwZTNlY2ViZmVlOGFhYQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YmM4MDg1ZTFlZTJlZGJiZTYxMzc2MWI5N2FkYjkxMDc4NmEzNjdmYjVjMDJj
|
10
|
+
ZDQxMTc5YTY3ZjY3MzY5MWRjNjk4ODFmYWJjNTE4ZmQwMGI2YTI2ZjhiMjU3
|
11
|
+
ZGFhMzNlNzcwNjIzZWFhYTNkYWQ3NWY5OTU1M2Q0NDM0ZjQxYzU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDRlNWY3MGQ1ZWI4MTYyNzY0ZmY0MGIxY2U2NDA5NTg4Zjc2MGI5NDgxNzBl
|
14
|
+
MzRiOTUwNmVlMTdjZmFiMGFkZThmODFkYjllN2QxMWZlOTI5NWM1MzNmMDA1
|
15
|
+
MmU5YjcxYWY3Y2RjZGE5ZjJmNDU5NjBkMzc1MjNiODA5YjIxMGI=
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
|
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
|
-
|
48
|
-
|
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
|
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 <
|
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
|
@@ -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
|
data/link_thumbnailer.gemspec
CHANGED
data/spec/configuration_spec.rb
CHANGED
@@ -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).
|
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 }
|
data/spec/fixture_spec.rb
CHANGED
@@ -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() }
|
@@ -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>
|
data/spec/models/image_spec.rb
CHANGED
@@ -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
|
data/spec/scraper_spec.rb
CHANGED
@@ -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(:
|
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
|
31
|
+
context 'when first one return a result' do
|
33
32
|
|
34
|
-
|
35
|
-
|
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
|
48
|
+
context 'when first one does not return any result' do
|
76
49
|
|
77
|
-
let(:valid_scraper) { double('scraper'
|
78
|
-
let(:not_valid_scraper) { double('scraper'
|
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.
|
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-
|
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
|