link_thumbnailer 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.rspec +1 -1
- data/CHANGELOG.md +8 -0
- data/README.md +97 -85
- data/lib/link_thumbnailer/models/video.rb +2 -2
- data/lib/link_thumbnailer/models/website.rb +2 -2
- data/lib/link_thumbnailer/scraper.rb +1 -1
- data/lib/link_thumbnailer/scrapers/base.rb +6 -4
- data/lib/link_thumbnailer/scrapers/opengraph/image.rb +57 -26
- data/lib/link_thumbnailer/scrapers/opengraph/images.rb +2 -2
- data/lib/link_thumbnailer/scrapers/opengraph/video.rb +89 -18
- data/lib/link_thumbnailer/scrapers/opengraph/videos.rb +2 -2
- data/lib/link_thumbnailer/version.rb +1 -1
- data/link_thumbnailer.gemspec +2 -2
- data/spec/fixture_spec.rb +1 -0
- data/spec/fixtures/og_valid_example.html +2 -0
- data/spec/fixtures/og_valid_multi_image_example.html +1 -1
- data/spec/fixtures/og_valid_multi_video_example.html +1 -1
- data/spec/graders/length_spec.rb +2 -2
- data/spec/image_validator_spec.rb +2 -2
- data/spec/models/website_spec.rb +1 -1
- data/spec/processor_spec.rb +5 -5
- data/spec/scraper_spec.rb +6 -6
- data/spec/scrapers/base_spec.rb +3 -3
- data/spec/scrapers/opengraph/base_spec.rb +6 -6
- metadata +15 -16
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
OGM1ZDk2ODQ3MTBkMTc4MTAyNzMwMWNmMzQyOGY0YWM2OWQwNTU0Zg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e82e842f04354aa42e0d379f3bb7f1260f9d12ef
|
4
|
+
data.tar.gz: 472731d1a762495f3deef46028d68481a77f1eb3
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MzEyYmNmZTY4YzI3YjUwYzY2Mzk4ZjYwZWE3NmE1OGQxZjI0MDVhNTFjZDQz
|
11
|
-
OTJmMmQyZGNlM2Y0MzBjYWUxMzAyMjZlYjY0ZGFmOGRmZDcyZGQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NTQyMGVmZjkzZmZkOGYxMTkxMGEzZmRkMDlmMzRmZmVlOThhM2IyNjI1ZmY3
|
14
|
-
MjY5MzBjYmQ3MzE0ZmQyYmU1MWY0NmFmMzc4YjUxYzYxZjcyZjgzMzJmYzcz
|
15
|
-
ZGY5MDVmMjM0MjM5Y2Q0NGY5YjM1YjIwZTY5YTJiZGIxYzMwZmY=
|
6
|
+
metadata.gz: 615f8cf840ce82c6080340730f33146732c14d1c32ab11d9c8d71228c9c0cec05f84a55a846f3e55e4b31df91efb0f84854c4e02f033626b95a65888fb8ebd2d
|
7
|
+
data.tar.gz: bb113d233c1296b407d44091d64dd50d6c031eae0eb28f5d816415abdcfea5ffb8c861ea53e36b6be9914c202254db5689f1e545d645cf457ac312f1c5dfddd5
|
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--colour
|
2
|
-
--format=
|
2
|
+
--format=documentation
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# 2.5.0
|
2
|
+
|
3
|
+
- Handles seamlessly `og:image` and `og:image:url`
|
4
|
+
- Handles seamlessly `og:video` and `og:video:url`
|
5
|
+
- Handles `og:video:width` and `og:video:height` for one video only (please create a ticket if you want support for multiple videos/images width & height)
|
6
|
+
- Fix calling `as_json` on `website` to return `as_json` representation of videos and images, not just their urls
|
7
|
+
- Gem updates and fix rspec deprecation warnings
|
8
|
+
|
1
9
|
# 2.4.0
|
2
10
|
|
3
11
|
- Handle connection through proxy automatically using the `ENV['HTTP_PROXY']` variable thanks to [taganaka](https://github.com/taganaka).
|
data/README.md
CHANGED
@@ -28,7 +28,9 @@ Demo Application is [here](http://link-thumbnailer-demo.herokuapp.com/) !
|
|
28
28
|
|
29
29
|
Add this line to your application's Gemfile:
|
30
30
|
|
31
|
-
|
31
|
+
```ruby
|
32
|
+
gem 'link_thumbnailer'
|
33
|
+
```
|
32
34
|
|
33
35
|
And then execute:
|
34
36
|
|
@@ -48,29 +50,35 @@ This will add `link_thumbnailer.rb` to `config/initializers/`.
|
|
48
50
|
|
49
51
|
Run `irb` and require the gem:
|
50
52
|
|
51
|
-
|
53
|
+
```ruby
|
54
|
+
require 'link_thumbnailer'
|
55
|
+
```
|
52
56
|
|
53
57
|
The gem handle regular website but also website that use the [Opengraph](http://ogp.me/) protocol.
|
54
58
|
|
55
|
-
|
56
|
-
|
59
|
+
```ruby
|
60
|
+
object = LinkThumbnailer.generate('http://stackoverflow.com')
|
61
|
+
=> #<LinkThumbnailer::Models::Website:...>
|
57
62
|
|
58
|
-
|
59
|
-
|
63
|
+
object.title
|
64
|
+
=> "Stack Overflow"
|
60
65
|
|
61
|
-
|
62
|
-
|
66
|
+
object.favicon
|
67
|
+
=> "//cdn.sstatic.net/stackoverflow/img/favicon.ico?v=038622610830"
|
63
68
|
|
64
|
-
|
65
|
-
|
69
|
+
object.description
|
70
|
+
=> "Q&A for professional and enthusiast programmers"
|
66
71
|
|
67
|
-
|
68
|
-
|
72
|
+
object.images.first.src.to_s
|
73
|
+
=> "http://cdn.sstatic.net/stackoverflow/img/apple-touch-icon@2.png?v=fde65a5a78c6"
|
74
|
+
```
|
69
75
|
|
70
76
|
LinkThumbnailer `generate` method return an instance of `LinkThumbnailer::Models::Website` that respond to `to_json` and `as_json` as you would expect:
|
71
77
|
|
72
|
-
|
73
|
-
|
78
|
+
```ruby
|
79
|
+
object.to_json
|
80
|
+
=> "{\"url\":\"http://stackoverflow.com\",\"title\":\"Stack Overflow\",\"description\":\"Q&A for professional and enthusiast programmers\",\"images\":[{\"src\":\"http://cdn.sstatic.net/stackoverflow/img/apple-touch-icon@2.png?v=fde65a5a78c6\",\"size\":[316,316],\"type\":\"png\"}]}"
|
81
|
+
```
|
74
82
|
|
75
83
|
|
76
84
|
## Configuration
|
@@ -79,80 +87,84 @@ LinkThumnailer comes with default configuration values. You can change default v
|
|
79
87
|
|
80
88
|
In `config/initializers/link_thumbnailer.rb`
|
81
89
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
90
|
+
```ruby
|
91
|
+
LinkThumbnailer.configure do |config|
|
92
|
+
# Numbers of redirects before raising an exception when trying to parse given url.
|
93
|
+
#
|
94
|
+
# config.redirect_limit = 3
|
95
|
+
|
96
|
+
# Set user agent
|
97
|
+
#
|
98
|
+
# config.user_agent = 'link_thumbnailer'
|
99
|
+
|
100
|
+
# Enable or disable SSL verification
|
101
|
+
#
|
102
|
+
# config.verify_ssl = true
|
103
|
+
|
104
|
+
# The amount of time in seconds to wait for a connection to be opened.
|
105
|
+
# If the HTTP object cannot open a connection in this many seconds,
|
106
|
+
# it raises a Net::OpenTimeout exception.
|
107
|
+
#
|
108
|
+
# See http://www.ruby-doc.org/stdlib-2.1.1/libdoc/net/http/rdoc/Net/HTTP.html#open_timeout
|
109
|
+
#
|
110
|
+
# config.http_timeout = 5
|
111
|
+
|
112
|
+
# List of blacklisted urls you want to skip when searching for images.
|
113
|
+
#
|
114
|
+
# config.blacklist_urls = [
|
115
|
+
# %r{^http://ad\.doubleclick\.net/},
|
116
|
+
# %r{^http://b\.scorecardresearch\.com/},
|
117
|
+
# %r{^http://pixel\.quantserve\.com/},
|
118
|
+
# %r{^http://s7\.addthis\.com/}
|
119
|
+
# ]
|
120
|
+
|
121
|
+
# List of attributes you want LinkThumbnailer to fetch on a website.
|
122
|
+
#
|
123
|
+
# config.attributes = [:title, :images, :description, :videos, :favicon]
|
124
|
+
|
125
|
+
# List of procedures used to rate the website description. Add you custom class
|
126
|
+
# here. Note that the order matter to compute the score. See wiki for more details
|
127
|
+
# on how to build your own graders.
|
128
|
+
#
|
129
|
+
# config.graders = [
|
130
|
+
# ->(description) { ::LinkThumbnailer::Graders::Length.new(description) },
|
131
|
+
# ->(description) { ::LinkThumbnailer::Graders::HtmlAttribute.new(description, :class) },
|
132
|
+
# ->(description) { ::LinkThumbnailer::Graders::HtmlAttribute.new(description, :id) },
|
133
|
+
# ->(description) { ::LinkThumbnailer::Graders::Position.new(description) },
|
134
|
+
# ->(description) { ::LinkThumbnailer::Graders::LinkDensity.new(description) }
|
135
|
+
# ]
|
136
|
+
|
137
|
+
# Minimum description length for a website.
|
138
|
+
#
|
139
|
+
# config.description_min_length = 25
|
140
|
+
|
141
|
+
# Regex of words considered positive to rate website description.
|
142
|
+
#
|
143
|
+
# config.positive_regex = /article|body|content|entry|hentry|main|page|pagination|post|text|blog|story/i
|
144
|
+
|
145
|
+
# Regex of words considered negative to rate website description.
|
146
|
+
#
|
147
|
+
# config.negative_regex = /combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|shoutbox|sidebar|sponsor|shopping|tags|tool|widget|modal/i
|
148
|
+
|
149
|
+
# Numbers of images to fetch. Fetching too many images will be slow.
|
150
|
+
# Note that LinkThumbnailer will only sort fetched images between each other.
|
151
|
+
# Meaning that they could be a "better" image on the page.
|
152
|
+
#
|
153
|
+
# config.image_limit = 5
|
154
|
+
|
155
|
+
# Whether you want LinkThumbnailer to return image size and type or not.
|
156
|
+
# Setting this value to false will increase performance since for each images, LinkThumbnailer
|
157
|
+
# does not have to fetch its size and type.
|
158
|
+
#
|
159
|
+
# config.image_stats = true
|
160
|
+
end
|
161
|
+
```
|
152
162
|
|
153
163
|
Or at runtime:
|
154
164
|
|
155
|
-
|
165
|
+
```ruby
|
166
|
+
object = LinkThumbnailer.generate('http://stackoverflow.com', redirect_limit: 5, user_agent: 'foo')
|
167
|
+
```
|
156
168
|
|
157
169
|
Note that runtime options will override default global configuration.
|
158
170
|
|
@@ -7,10 +7,10 @@ module LinkThumbnailer
|
|
7
7
|
|
8
8
|
attr_reader :src, :size, :duration, :provider, :id, :embed_code
|
9
9
|
|
10
|
-
def initialize(src)
|
10
|
+
def initialize(src, size = nil)
|
11
11
|
@src = src
|
12
12
|
@id = parser.id
|
13
|
-
@size = parser.size
|
13
|
+
@size = size || parser.size
|
14
14
|
@duration = parser.duration
|
15
15
|
@provider = parser.provider
|
16
16
|
@embed_code = parser.embed_code
|
@@ -34,7 +34,7 @@ module LinkThumbnailer
|
|
34
34
|
def call
|
35
35
|
config.attributes.each do |name|
|
36
36
|
scrapers.each do |scraper_prefix|
|
37
|
-
scraper_class(scraper_prefix, name).new(document).call(
|
37
|
+
scraper_class(scraper_prefix, name).new(document, website).call(name.to_s)
|
38
38
|
break unless website.send(name).blank?
|
39
39
|
end
|
40
40
|
end
|
@@ -10,16 +10,18 @@ module LinkThumbnailer
|
|
10
10
|
|
11
11
|
attr_reader :config, :document, :website, :attribute_name
|
12
12
|
|
13
|
-
def initialize(document)
|
13
|
+
def initialize(document, website = nil)
|
14
14
|
@config = ::LinkThumbnailer.page.config
|
15
15
|
@document = document
|
16
|
+
@website = website
|
16
17
|
|
17
18
|
super(config)
|
18
19
|
end
|
19
20
|
|
20
|
-
def call(
|
21
|
+
def call(attribute_name)
|
22
|
+
return false unless website.present?
|
21
23
|
return false unless applicable?
|
22
|
-
|
24
|
+
|
23
25
|
@attribute_name = attribute_name
|
24
26
|
|
25
27
|
website.send("#{attribute_name}=", value)
|
@@ -31,7 +33,7 @@ module LinkThumbnailer
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def value
|
34
|
-
|
36
|
+
fail NotImplementedError
|
35
37
|
end
|
36
38
|
|
37
39
|
private
|
@@ -6,60 +6,91 @@ module LinkThumbnailer
|
|
6
6
|
class Image < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
7
7
|
|
8
8
|
def value
|
9
|
-
|
9
|
+
::LinkThumbnailer::Scrapers::Opengraph::Image::Base.new(document, website).value +
|
10
|
+
::LinkThumbnailer::Scrapers::Opengraph::Image::Url.new(document, website).value
|
10
11
|
end
|
11
12
|
|
12
13
|
private
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
15
|
+
# Handles `og:image` attributes.
|
16
|
+
class Base < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def value
|
19
|
+
model
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
22
|
+
def model
|
23
|
+
nodes.map { |n| modelize(n, n.attributes['content'].to_s) }
|
24
|
+
end
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
def modelize(node, text = nil)
|
27
|
+
model_class.new(text, size)
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
def model_class
|
31
|
+
::LinkThumbnailer::Models::Image
|
32
|
+
end
|
33
|
+
|
34
|
+
def nodes
|
35
|
+
nodes = meta_xpaths(attribute: attribute)
|
36
|
+
nodes.empty? ? meta_xpaths(attribute: attribute, key: :name) : nodes
|
37
|
+
end
|
38
|
+
|
39
|
+
def attribute
|
40
|
+
'og:image'
|
41
|
+
end
|
42
|
+
|
43
|
+
def size
|
44
|
+
[width.to_i, height.to_i] if width && height
|
45
|
+
end
|
46
|
+
|
47
|
+
def width
|
48
|
+
::LinkThumbnailer::Scrapers::Opengraph::Image::Width.new(document).value
|
49
|
+
end
|
50
|
+
|
51
|
+
def height
|
52
|
+
::LinkThumbnailer::Scrapers::Opengraph::Image::Height.new(document).value
|
53
|
+
end
|
34
54
|
|
35
|
-
def height
|
36
|
-
Height.new(document).value
|
37
55
|
end
|
38
56
|
|
39
|
-
|
57
|
+
# Handles `og:image:url` attributes.
|
58
|
+
class Url < ::LinkThumbnailer::Scrapers::Opengraph::Image::Base
|
40
59
|
|
41
|
-
|
42
|
-
|
60
|
+
private
|
61
|
+
|
62
|
+
def attribute
|
63
|
+
'og:image:url'
|
43
64
|
end
|
44
65
|
|
45
66
|
end
|
46
67
|
|
47
|
-
|
68
|
+
# Handles `og:image:width` attributes.
|
69
|
+
class Width < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
70
|
+
|
71
|
+
def value
|
72
|
+
node.attributes['content'].to_s if node
|
73
|
+
end
|
48
74
|
|
49
75
|
private
|
50
76
|
|
51
77
|
def attribute
|
52
|
-
|
78
|
+
'og:image:width'
|
53
79
|
end
|
54
80
|
|
55
81
|
end
|
56
82
|
|
57
|
-
|
83
|
+
# Handles `og:image:height` attributes.
|
84
|
+
class Height < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
85
|
+
|
86
|
+
def value
|
87
|
+
node.attributes['content'].to_s if node
|
88
|
+
end
|
58
89
|
|
59
90
|
private
|
60
91
|
|
61
92
|
def attribute
|
62
|
-
|
93
|
+
'og:image:height'
|
63
94
|
end
|
64
95
|
|
65
96
|
end
|
@@ -6,8 +6,8 @@ module LinkThumbnailer
|
|
6
6
|
module Opengraph
|
7
7
|
class Images < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
8
8
|
|
9
|
-
def call(
|
10
|
-
::LinkThumbnailer::Scrapers::Opengraph::Image.new(document).call(
|
9
|
+
def call(attribute_name)
|
10
|
+
::LinkThumbnailer::Scrapers::Opengraph::Image.new(document, website).call('image')
|
11
11
|
end
|
12
12
|
|
13
13
|
end
|
@@ -6,34 +6,105 @@ module LinkThumbnailer
|
|
6
6
|
class Video < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
7
7
|
|
8
8
|
def value
|
9
|
-
|
9
|
+
::LinkThumbnailer::Scrapers::Opengraph::Video::Base.new(document, website).value +
|
10
|
+
::LinkThumbnailer::Scrapers::Opengraph::Video::Url.new(document, website).value
|
10
11
|
end
|
11
12
|
|
12
13
|
private
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
|
15
|
+
# Handles `og:video` attributes.
|
16
|
+
class Base < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
17
|
+
|
18
|
+
def value
|
19
|
+
model
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def model
|
25
|
+
nodes.map { |n| modelize(n, n.attributes['content'].to_s) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def modelize(node, text = nil)
|
29
|
+
model_class.new(text, size)
|
30
|
+
end
|
31
|
+
|
32
|
+
def model_class
|
33
|
+
::LinkThumbnailer::Models::Video
|
34
|
+
end
|
35
|
+
|
36
|
+
def nodes
|
37
|
+
nodes = meta_xpaths(attribute: attribute)
|
38
|
+
nodes.empty? ? meta_xpaths(attribute: attribute, key: :name) : nodes
|
39
|
+
end
|
40
|
+
|
41
|
+
def attribute
|
42
|
+
return 'og:url' if vimeo?
|
43
|
+
'og:video'
|
44
|
+
end
|
45
|
+
|
46
|
+
# Vimeo uses a SWF file for its og:video property which doesn't
|
47
|
+
# provide any metadata for the VideoInfo gem downstream. Using
|
48
|
+
# og:url means VideoInfo is passed a webpage URL with metadata
|
49
|
+
# it can parse.
|
50
|
+
def vimeo?
|
51
|
+
website.url.host =~ /vimeo/
|
52
|
+
end
|
53
|
+
|
54
|
+
def size
|
55
|
+
[width.to_i, height.to_i] if width && height
|
56
|
+
end
|
57
|
+
|
58
|
+
def width
|
59
|
+
::LinkThumbnailer::Scrapers::Opengraph::Video::Width.new(document).value
|
23
60
|
end
|
61
|
+
|
62
|
+
def height
|
63
|
+
::LinkThumbnailer::Scrapers::Opengraph::Video::Height.new(document).value
|
64
|
+
end
|
65
|
+
|
24
66
|
end
|
25
67
|
|
26
|
-
|
27
|
-
|
68
|
+
# Handles `og:video:url` attributes.
|
69
|
+
class Url < ::LinkThumbnailer::Scrapers::Opengraph::Video::Base
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def attribute
|
74
|
+
super
|
75
|
+
'og:video:url'
|
76
|
+
end
|
77
|
+
|
28
78
|
end
|
29
79
|
|
30
|
-
|
31
|
-
|
80
|
+
# Handles `og:video:width` attributes.
|
81
|
+
class Width < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
82
|
+
|
83
|
+
def value
|
84
|
+
node.attributes['content'].to_s if node
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def attribute
|
90
|
+
'og:video:width'
|
91
|
+
end
|
92
|
+
|
32
93
|
end
|
33
94
|
|
34
|
-
|
35
|
-
|
36
|
-
|
95
|
+
# Handles `og:video:height` attributes.
|
96
|
+
class Height < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
97
|
+
|
98
|
+
def value
|
99
|
+
node.attributes['content'].to_s if node
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def attribute
|
105
|
+
'og:video:height'
|
106
|
+
end
|
107
|
+
|
37
108
|
end
|
38
109
|
|
39
110
|
end
|
@@ -6,8 +6,8 @@ module LinkThumbnailer
|
|
6
6
|
module Opengraph
|
7
7
|
class Videos < ::LinkThumbnailer::Scrapers::Opengraph::Base
|
8
8
|
|
9
|
-
def call(
|
10
|
-
::LinkThumbnailer::Scrapers::Opengraph::Video.new(document).call(
|
9
|
+
def call(attribute_name)
|
10
|
+
::LinkThumbnailer::Scrapers::Opengraph::Video.new(document, website).call('video')
|
11
11
|
end
|
12
12
|
|
13
13
|
end
|
data/link_thumbnailer.gemspec
CHANGED
@@ -18,10 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
20
|
spec.add_dependency 'activesupport', '>= 3.0'
|
21
|
-
spec.add_dependency 'json', ['>= 1.7.7', '~> 1.
|
21
|
+
spec.add_dependency 'json', ['>= 1.7.7', '~> 1.8']
|
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
25
|
spec.add_dependency 'fastimage', '~> 1.6'
|
26
|
-
spec.add_dependency 'video_info', '~> 2.
|
26
|
+
spec.add_dependency 'video_info', '~> 2.4'
|
27
27
|
end
|
data/spec/fixture_spec.rb
CHANGED
@@ -31,6 +31,7 @@ describe 'Fixture' do
|
|
31
31
|
it { expect(action.images.first.size).to eq([100, 100]) }
|
32
32
|
it { expect(action.videos.count).to eq(1) }
|
33
33
|
it { expect(action.videos.first.src.to_s).to eq(video_url) }
|
34
|
+
it { expect(action.videos.first.size).to eq([100, 100]) }
|
34
35
|
|
35
36
|
end
|
36
37
|
|
@@ -9,6 +9,8 @@
|
|
9
9
|
<meta property="og:image:width" content="100">
|
10
10
|
<meta property="og:image:height" content="100">
|
11
11
|
<meta property="og:video" content="http://foo.com/foo.swf">
|
12
|
+
<meta property="og:video:width" content="100">
|
13
|
+
<meta property="og:video:height" content="100">
|
12
14
|
<link rel="icon" href="http://foo.com/foo.ico">
|
13
15
|
<title>Title</title>
|
14
16
|
</head>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<meta property="og:title" content="Title from og">
|
7
7
|
<meta property="og:description" content="Description from og">
|
8
8
|
<meta property="og:image" content="http://foo.com/foo.png">
|
9
|
-
<meta property="og:image" content="http://foo.com/bar.png">
|
9
|
+
<meta property="og:image:url" content="http://foo.com/bar.png">
|
10
10
|
<title>Title</title>
|
11
11
|
</head>
|
12
12
|
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<meta property="og:title" content="Title from og">
|
7
7
|
<meta property="og:description" content="Description from og">
|
8
8
|
<meta property="og:video" content="http://foo.com/foo.swf">
|
9
|
-
<meta property="og:video" content="http://foo.com/bar.swf">
|
9
|
+
<meta property="og:video:url" content="http://foo.com/bar.swf">
|
10
10
|
<title>Title</title>
|
11
11
|
</head>
|
12
12
|
|
data/spec/graders/length_spec.rb
CHANGED
@@ -64,7 +64,7 @@ describe LinkThumbnailer::Graders::Length do
|
|
64
64
|
|
65
65
|
let(:text) { 'f' * 9 }
|
66
66
|
|
67
|
-
it { expect(action).to
|
67
|
+
it { expect(action).to be_truthy }
|
68
68
|
|
69
69
|
end
|
70
70
|
|
@@ -72,7 +72,7 @@ describe LinkThumbnailer::Graders::Length do
|
|
72
72
|
|
73
73
|
let(:text) { 'f' * 10 }
|
74
74
|
|
75
|
-
it { expect(action).to
|
75
|
+
it { expect(action).to be_falsey }
|
76
76
|
|
77
77
|
end
|
78
78
|
|
@@ -18,7 +18,7 @@ describe LinkThumbnailer::ImageValidator do
|
|
18
18
|
|
19
19
|
let(:blacklist_urls) { [src] }
|
20
20
|
|
21
|
-
it { expect(action).to
|
21
|
+
it { expect(action).to be_falsey }
|
22
22
|
|
23
23
|
end
|
24
24
|
|
@@ -26,7 +26,7 @@ describe LinkThumbnailer::ImageValidator do
|
|
26
26
|
|
27
27
|
let(:blacklist_urls) { [] }
|
28
28
|
|
29
|
-
it { expect(action).to
|
29
|
+
it { expect(action).to be_truthy }
|
30
30
|
|
31
31
|
end
|
32
32
|
|
data/spec/models/website_spec.rb
CHANGED
data/spec/processor_spec.rb
CHANGED
@@ -286,7 +286,7 @@ describe LinkThumbnailer::Processor do
|
|
286
286
|
instance.stub(:url).and_return("http://foo.com")
|
287
287
|
end
|
288
288
|
|
289
|
-
it { expect(action).to
|
289
|
+
it { expect(action).to be_falsey }
|
290
290
|
|
291
291
|
end
|
292
292
|
|
@@ -296,7 +296,7 @@ describe LinkThumbnailer::Processor do
|
|
296
296
|
instance.stub(:url).and_return(URI("http://foo.com"))
|
297
297
|
end
|
298
298
|
|
299
|
-
it { expect(action).to
|
299
|
+
it { expect(action).to be_truthy }
|
300
300
|
|
301
301
|
end
|
302
302
|
|
@@ -313,7 +313,7 @@ describe LinkThumbnailer::Processor do
|
|
313
313
|
instance.stub(:redirect_limit).and_return(4)
|
314
314
|
end
|
315
315
|
|
316
|
-
it { expect(action).to
|
316
|
+
it { expect(action).to be_truthy }
|
317
317
|
|
318
318
|
end
|
319
319
|
|
@@ -324,7 +324,7 @@ describe LinkThumbnailer::Processor do
|
|
324
324
|
instance.stub(:redirect_limit).and_return(5)
|
325
325
|
end
|
326
326
|
|
327
|
-
it { expect(action).to
|
327
|
+
it { expect(action).to be_falsey }
|
328
328
|
|
329
329
|
end
|
330
330
|
|
@@ -335,7 +335,7 @@ describe LinkThumbnailer::Processor do
|
|
335
335
|
instance.stub(:redirect_limit).and_return(5)
|
336
336
|
end
|
337
337
|
|
338
|
-
it { expect(action).to
|
338
|
+
it { expect(action).to be_falsey }
|
339
339
|
|
340
340
|
end
|
341
341
|
|
data/spec/scraper_spec.rb
CHANGED
@@ -35,9 +35,9 @@ describe LinkThumbnailer::Scraper do
|
|
35
35
|
|
36
36
|
before do
|
37
37
|
expect(website).to receive(:bar).once.and_return('bar')
|
38
|
-
expect(valid_scraper).to receive(:call).once.with(
|
39
|
-
expect(not_valid_scraper).to_not receive(:call).with(
|
40
|
-
expect(scraper_class).to receive(:new).with(document).once.and_return(valid_scraper)
|
38
|
+
expect(valid_scraper).to receive(:call).once.with('bar')
|
39
|
+
expect(not_valid_scraper).to_not receive(:call).with('bar')
|
40
|
+
expect(scraper_class).to receive(:new).with(document, website).once.and_return(valid_scraper)
|
41
41
|
expect(instance).to receive(:scraper_class).with(prefix_1, :bar).and_return(scraper_class)
|
42
42
|
end
|
43
43
|
|
@@ -52,9 +52,9 @@ describe LinkThumbnailer::Scraper do
|
|
52
52
|
|
53
53
|
before do
|
54
54
|
expect(website).to receive(:bar).and_return('', 'bar')
|
55
|
-
expect(valid_scraper).to receive(:call).once.with(
|
56
|
-
expect(not_valid_scraper).to receive(:call).once.with(
|
57
|
-
expect(scraper_class).to receive(:new).with(document).and_return(not_valid_scraper, valid_scraper)
|
55
|
+
expect(valid_scraper).to receive(:call).once.with('bar')
|
56
|
+
expect(not_valid_scraper).to receive(:call).once.with('bar')
|
57
|
+
expect(scraper_class).to receive(:new).with(document, website).and_return(not_valid_scraper, valid_scraper)
|
58
58
|
expect(instance).to receive(:scraper_class).with(prefix_1, :bar).and_return(scraper_class)
|
59
59
|
expect(instance).to receive(:scraper_class).with(prefix_2, :bar).and_return(scraper_class)
|
60
60
|
end
|
data/spec/scrapers/base_spec.rb
CHANGED
@@ -3,14 +3,14 @@ require 'spec_helper'
|
|
3
3
|
describe LinkThumbnailer::Scrapers::Base do
|
4
4
|
|
5
5
|
let(:document) { double('document') }
|
6
|
-
let(:
|
6
|
+
let(:website) { LinkThumbnailer::Models::Website.new }
|
7
|
+
let(:instance) { described_class.new(document, website) }
|
7
8
|
|
8
9
|
describe '#call' do
|
9
10
|
|
10
|
-
let(:website) { LinkThumbnailer::Models::Website.new }
|
11
11
|
let(:attr) { :title }
|
12
12
|
let(:value) { 'foo' }
|
13
|
-
let(:action) { instance.call(
|
13
|
+
let(:action) { instance.call(attr) }
|
14
14
|
|
15
15
|
before do
|
16
16
|
instance.stub(:value).and_return(value)
|
@@ -21,7 +21,7 @@ describe LinkThumbnailer::Scrapers::Opengraph::Base do
|
|
21
21
|
instance.stub(:opengraph_node?).and_return(true, true)
|
22
22
|
end
|
23
23
|
|
24
|
-
it { expect(action).to
|
24
|
+
it { expect(action).to be_truthy }
|
25
25
|
|
26
26
|
end
|
27
27
|
|
@@ -31,7 +31,7 @@ describe LinkThumbnailer::Scrapers::Opengraph::Base do
|
|
31
31
|
instance.stub(:opengraph_node?).and_return(true, false)
|
32
32
|
end
|
33
33
|
|
34
|
-
it { expect(action).to
|
34
|
+
it { expect(action).to be_truthy }
|
35
35
|
|
36
36
|
end
|
37
37
|
|
@@ -41,7 +41,7 @@ describe LinkThumbnailer::Scrapers::Opengraph::Base do
|
|
41
41
|
instance.stub(:opengraph_node?).and_return(false, false)
|
42
42
|
end
|
43
43
|
|
44
|
-
it { expect(action).to
|
44
|
+
it { expect(action).to be_falsey }
|
45
45
|
|
46
46
|
end
|
47
47
|
|
@@ -59,7 +59,7 @@ describe LinkThumbnailer::Scrapers::Opengraph::Base do
|
|
59
59
|
|
60
60
|
let(:attribute_from_name) { 'og:foo' }
|
61
61
|
|
62
|
-
it { expect(action).to
|
62
|
+
it { expect(action).to be_truthy }
|
63
63
|
|
64
64
|
end
|
65
65
|
|
@@ -75,7 +75,7 @@ describe LinkThumbnailer::Scrapers::Opengraph::Base do
|
|
75
75
|
|
76
76
|
let(:attribute_from_property) { 'og:bar' }
|
77
77
|
|
78
|
-
it { expect(action).to
|
78
|
+
it { expect(action).to be_truthy }
|
79
79
|
|
80
80
|
end
|
81
81
|
|
@@ -83,7 +83,7 @@ describe LinkThumbnailer::Scrapers::Opengraph::Base do
|
|
83
83
|
|
84
84
|
let(:attribute_from_property) { 'bar' }
|
85
85
|
|
86
|
-
it { expect(action).to
|
86
|
+
it { expect(action).to be_falsey }
|
87
87
|
|
88
88
|
end
|
89
89
|
|
metadata
CHANGED
@@ -1,61 +1,61 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: link_thumbnailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.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: 2015-
|
11
|
+
date: 2015-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '3.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.7.7
|
34
34
|
- - ~>
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '1.
|
36
|
+
version: '1.8'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
|
-
- -
|
41
|
+
- - '>='
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: 1.7.7
|
44
44
|
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '1.
|
46
|
+
version: '1.8'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '0.9'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- -
|
58
|
+
- - '>='
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0.9'
|
61
61
|
- !ruby/object:Gem::Dependency
|
@@ -106,14 +106,14 @@ dependencies:
|
|
106
106
|
requirements:
|
107
107
|
- - ~>
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: '2.
|
109
|
+
version: '2.4'
|
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.
|
116
|
+
version: '2.4'
|
117
117
|
description: Ruby gem generating thumbnail images from a given URL.
|
118
118
|
email:
|
119
119
|
- pierrelouis.gottfrois@gmail.com
|
@@ -220,17 +220,17 @@ require_paths:
|
|
220
220
|
- lib
|
221
221
|
required_ruby_version: !ruby/object:Gem::Requirement
|
222
222
|
requirements:
|
223
|
-
- -
|
223
|
+
- - '>='
|
224
224
|
- !ruby/object:Gem::Version
|
225
225
|
version: '0'
|
226
226
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
227
|
requirements:
|
228
|
-
- -
|
228
|
+
- - '>='
|
229
229
|
- !ruby/object:Gem::Version
|
230
230
|
version: '0'
|
231
231
|
requirements: []
|
232
232
|
rubyforge_project:
|
233
|
-
rubygems_version: 2.4.
|
233
|
+
rubygems_version: 2.4.3
|
234
234
|
signing_key:
|
235
235
|
specification_version: 4
|
236
236
|
summary: Ruby gem ranking images from a given URL returning an object containing images
|
@@ -269,4 +269,3 @@ test_files:
|
|
269
269
|
- spec/scrapers/opengraph/base_spec.rb
|
270
270
|
- spec/spec_helper.rb
|
271
271
|
- spec/video_parser_spec.rb
|
272
|
-
has_rdoc:
|