onebox 2.2.14 → 2.2.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/onebox/engine.rb +6 -10
- data/lib/onebox/engine/allowlisted_generic_onebox.rb +0 -9
- data/lib/onebox/engine/amazon_onebox.rb +23 -16
- data/lib/onebox/engine/flickr_onebox.rb +2 -2
- data/lib/onebox/engine/gfycat_onebox.rb +26 -26
- data/lib/onebox/engine/github_commit_onebox.rb +1 -1
- data/lib/onebox/engine/github_folder_onebox.rb +1 -1
- data/lib/onebox/engine/google_docs_onebox.rb +22 -40
- data/lib/onebox/engine/google_maps_onebox.rb +10 -6
- data/lib/onebox/engine/google_photos_onebox.rb +6 -6
- data/lib/onebox/engine/imgur_onebox.rb +2 -2
- data/lib/onebox/engine/instagram_onebox.rb +2 -3
- data/lib/onebox/engine/pastebin_onebox.rb +11 -15
- data/lib/onebox/engine/pdf_onebox.rb +7 -15
- data/lib/onebox/engine/pubmed_onebox.rb +16 -12
- data/lib/onebox/engine/stack_exchange_onebox.rb +1 -1
- data/lib/onebox/engine/standard_embed.rb +0 -3
- data/lib/onebox/engine/trello_onebox.rb +3 -6
- data/lib/onebox/engine/youku_onebox.rb +0 -6
- data/lib/onebox/helpers.rb +5 -22
- data/lib/onebox/layout.rb +2 -14
- data/lib/onebox/matcher.rb +10 -8
- data/lib/onebox/mixins/git_blob_onebox.rb +3 -5
- data/lib/onebox/open_graph.rb +4 -4
- data/lib/onebox/preview.rb +2 -2
- data/lib/onebox/version.rb +1 -1
- data/onebox.gemspec +1 -1
- data/templates/_layout.mustache +6 -2
- data/templates/allowlistedgeneric.mustache +8 -9
- data/templates/amazon.mustache +5 -2
- data/templates/githubblob.mustache +44 -34
- data/templates/githubcommit.mustache +1 -3
- data/templates/githubfolder.mustache +2 -2
- data/templates/githubgist.mustache +9 -6
- data/templates/githubissue.mustache +3 -3
- data/templates/githubpullrequest.mustache +1 -1
- data/templates/gitlabblob.mustache +11 -4
- data/templates/googledocs.mustache +2 -2
- data/templates/googledrive.mustache +2 -2
- data/templates/googleplayapp.mustache +2 -1
- data/templates/instagram.mustache +1 -1
- data/templates/pastebin.mustache +6 -2
- data/templates/pdf.mustache +6 -3
- data/templates/stackexchange.mustache +1 -0
- data/templates/twitterstatus.mustache +20 -5
- data/templates/wikimedia.mustache +2 -2
- data/templates/wikipedia.mustache +2 -2
- data/templates/xkcd.mustache +2 -2
- metadata +4 -4
@@ -11,9 +11,9 @@ module Onebox
|
|
11
11
|
|
12
12
|
def to_html
|
13
13
|
og = get_opengraph
|
14
|
-
return video_html(og) if
|
15
|
-
return album_html(og) if
|
16
|
-
return image_html(og) if
|
14
|
+
return video_html(og) if og.video_secure_url
|
15
|
+
return album_html(og) if og.type == "google_photos:photo_album"
|
16
|
+
return image_html(og) if og.image
|
17
17
|
nil
|
18
18
|
end
|
19
19
|
|
@@ -32,7 +32,7 @@ module Onebox
|
|
32
32
|
<h3><a href="#{escaped_url}" target="_blank" rel="nofollow ugc noopener">#{og.title}</a></h3>
|
33
33
|
<div class="aspect-image-full-size">
|
34
34
|
<a href="#{escaped_url}" target="_blank" rel="nofollow ugc noopener">
|
35
|
-
<img src="#{og.
|
35
|
+
<img src="#{og.secure_image_url}" class="scale-image"/>
|
36
36
|
<span class="instagram-video-icon"></span>
|
37
37
|
</a>
|
38
38
|
</div>
|
@@ -53,7 +53,7 @@ module Onebox
|
|
53
53
|
<span class='album-title'>#{Onebox::Helpers.truncate(album_title, 80)}</span>
|
54
54
|
</span>
|
55
55
|
</span>
|
56
|
-
<img src='#{og.
|
56
|
+
<img src='#{og.secure_image_url}' #{og.title_attr} height='#{og.image_height}' width='#{og.image_width}'>
|
57
57
|
</a>
|
58
58
|
</div>
|
59
59
|
HTML
|
@@ -64,7 +64,7 @@ module Onebox
|
|
64
64
|
|
65
65
|
<<-HTML
|
66
66
|
<a href='#{escaped_url}' target='_blank' rel='noopener' class="onebox">
|
67
|
-
<img src='#{og.
|
67
|
+
<img src='#{og.secure_image_url}' #{og.title_attr} alt='Google Photos' height='#{og.image_height}' width='#{og.image_width}'>
|
68
68
|
</a>
|
69
69
|
HTML
|
70
70
|
end
|
@@ -40,7 +40,7 @@ module Onebox
|
|
40
40
|
<span class='album-title'>#{album_title}</span>
|
41
41
|
</span>
|
42
42
|
</span>
|
43
|
-
<img src='#{og.
|
43
|
+
<img src='#{og.secure_image_url}' #{og.title_attr} height='#{og.image_height}' width='#{og.image_width}'>
|
44
44
|
</a>
|
45
45
|
</div>
|
46
46
|
HTML
|
@@ -58,7 +58,7 @@ module Onebox
|
|
58
58
|
|
59
59
|
<<-HTML
|
60
60
|
<a href='#{escaped_url}' target='_blank' rel='noopener' class="onebox">
|
61
|
-
<img src='#{og.
|
61
|
+
<img src='#{og.secure_image_url.chomp("?fb")}' #{og.title_attr} alt='Imgur'>
|
62
62
|
</a>
|
63
63
|
HTML
|
64
64
|
end
|
@@ -18,9 +18,8 @@ module Onebox
|
|
18
18
|
oembed = get_oembed
|
19
19
|
raise "No oEmbed data found. Ensure 'facebook_app_access_token' is valid" if oembed.data.empty?
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
{ link: permalink,
|
21
|
+
{
|
22
|
+
link: clean_url.gsub("/#{oembed.author_name}/", "/"),
|
24
23
|
title: "@#{oembed.author_name}",
|
25
24
|
image: oembed.thumbnail_url,
|
26
25
|
description: Onebox::Helpers.truncate(oembed.title, 250),
|
@@ -30,29 +30,25 @@ module Onebox
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def lines
|
33
|
-
return @lines if @lines
|
33
|
+
return @lines if defined?(@lines)
|
34
34
|
response = Onebox::Helpers.fetch_response("http://pastebin.com/raw/#{paste_key}", redirect_limit: 1) rescue ""
|
35
35
|
@lines = response.split("\n")
|
36
36
|
end
|
37
37
|
|
38
38
|
def paste_key
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
match = uri.path.match(/\/embed\/([^\/]+)/)
|
47
|
-
return match[1] if match && match[1]
|
39
|
+
regex = case uri
|
40
|
+
when /\/raw\//
|
41
|
+
/\/raw\/([^\/]+)/
|
42
|
+
when /\/download\//
|
43
|
+
/\/download\/([^\/]+)/
|
44
|
+
when /\/embed\//
|
45
|
+
/\/embed\/([^\/]+)/
|
48
46
|
else
|
49
|
-
|
50
|
-
return match[1] if match && match[1]
|
47
|
+
/\/([^\/]+)/
|
51
48
|
end
|
52
49
|
|
53
|
-
|
54
|
-
|
55
|
-
nil
|
50
|
+
match = uri.path.match(regex)
|
51
|
+
match[1] if match && match[1]
|
56
52
|
end
|
57
53
|
end
|
58
54
|
end
|
@@ -12,25 +12,17 @@ module Onebox
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def data
|
15
|
-
|
16
|
-
|
15
|
+
begin
|
16
|
+
size = Onebox::Helpers.fetch_content_length(@url)
|
17
|
+
rescue
|
18
|
+
raise "Unable to read pdf file: #{@url}"
|
19
|
+
end
|
17
20
|
|
18
|
-
result = { link: link,
|
19
|
-
title: pdf_info[:name],
|
20
|
-
filesize: pdf_info[:filesize]
|
21
|
-
}
|
22
|
-
result
|
23
|
-
end
|
24
|
-
|
25
|
-
def get_pdf_info
|
26
|
-
uri = URI.parse(@url)
|
27
|
-
size = Onebox::Helpers.fetch_content_length(@url)
|
28
21
|
{
|
22
|
+
link: link,
|
23
|
+
title: File.basename(uri.path),
|
29
24
|
filesize: size ? Onebox::Helpers.pretty_filesize(size.to_i) : nil,
|
30
|
-
name: File.basename(uri.path)
|
31
25
|
}
|
32
|
-
rescue
|
33
|
-
nil
|
34
26
|
end
|
35
27
|
end
|
36
28
|
end
|
@@ -10,13 +10,14 @@ module Onebox
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
-
def
|
13
|
+
def xml
|
14
|
+
return @xml if defined?(@xml)
|
14
15
|
doc = Nokogiri::XML(URI.open(URI.join(@url, "?report=xml&format=text")))
|
15
16
|
pre = doc.xpath("//pre")
|
16
|
-
Nokogiri::XML("<root>" + pre.text + "</root>")
|
17
|
+
@xml = Nokogiri::XML("<root>" + pre.text + "</root>")
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
+
def authors
|
20
21
|
initials = xml.css("Initials").map { |x| x.content }
|
21
22
|
last_names = xml.css("LastName").map { |x| x.content }
|
22
23
|
author_list = (initials.zip(last_names)).map { |i, l| i + " " + l }
|
@@ -27,22 +28,25 @@ module Onebox
|
|
27
28
|
author_list.join(", ")
|
28
29
|
end
|
29
30
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
def date
|
32
|
+
xml.css("PubDate")
|
33
|
+
.children
|
34
|
+
.map { |x| x.content }
|
35
|
+
.select { |s| !s.match(/^\s+$/) }
|
36
|
+
.map { |s| s.split }
|
37
|
+
.flatten
|
38
|
+
.sort
|
39
|
+
.reverse
|
40
|
+
.join(" ") # Reverse sort so month before year.
|
35
41
|
end
|
36
42
|
|
37
43
|
def data
|
38
|
-
xml = get_xml
|
39
|
-
|
40
44
|
{
|
41
45
|
title: xml.css("ArticleTitle").text,
|
42
|
-
authors:
|
46
|
+
authors: authors,
|
43
47
|
journal: xml.css("Title").text,
|
44
48
|
abstract: xml.css("AbstractText").text,
|
45
|
-
date:
|
49
|
+
date: date,
|
46
50
|
link: @url,
|
47
51
|
pmid: match[:pmid]
|
48
52
|
}
|
@@ -7,7 +7,6 @@ require 'onebox/oembed'
|
|
7
7
|
module Onebox
|
8
8
|
module Engine
|
9
9
|
module StandardEmbed
|
10
|
-
|
11
10
|
def self.oembed_providers
|
12
11
|
@@oembed_providers ||= {}
|
13
12
|
end
|
@@ -117,8 +116,6 @@ module Onebox
|
|
117
116
|
"{}"
|
118
117
|
end
|
119
118
|
|
120
|
-
protected
|
121
|
-
|
122
119
|
def get_oembed_url
|
123
120
|
oembed_url = nil
|
124
121
|
|
@@ -11,12 +11,11 @@ module Onebox
|
|
11
11
|
always_https
|
12
12
|
|
13
13
|
def to_html
|
14
|
-
|
15
|
-
|
14
|
+
src = "https://trello.com/#{match[:type]}/#{match[:key]}.html"
|
16
15
|
height = match[:type] == 'b' ? 400 : 200
|
17
16
|
|
18
17
|
<<-HTML
|
19
|
-
<iframe src="#{
|
18
|
+
<iframe src="#{src}" width="100%" height="#{height}" frameborder="0" style="border:0"></iframe>
|
20
19
|
HTML
|
21
20
|
end
|
22
21
|
|
@@ -25,12 +24,10 @@ module Onebox
|
|
25
24
|
end
|
26
25
|
|
27
26
|
private
|
27
|
+
|
28
28
|
def match
|
29
29
|
return @match if defined?(@match)
|
30
|
-
|
31
30
|
@match = @url.match(%{trello\.com/(?<type>[^/]+)/(?<key>[^/]+)/?\W*})
|
32
|
-
|
33
|
-
@match
|
34
31
|
end
|
35
32
|
end
|
36
33
|
end
|
data/lib/onebox/helpers.rb
CHANGED
@@ -26,23 +26,7 @@ module Onebox
|
|
26
26
|
|
27
27
|
def self.fetch_html_doc(url, headers = nil, body_cacher = nil)
|
28
28
|
response = (fetch_response(url, headers: headers, body_cacher: body_cacher) rescue nil)
|
29
|
-
|
30
|
-
uri = Addressable::URI.parse(url)
|
31
|
-
|
32
|
-
ignore_canonical_tag = doc.at('meta[property="og:ignore_canonical"]')
|
33
|
-
should_ignore_canonical = IGNORE_CANONICAL_DOMAINS.map { |hostname| uri.hostname.match?(hostname) }.any?
|
34
|
-
|
35
|
-
unless (ignore_canonical_tag && ignore_canonical_tag['content'].to_s == 'true') || should_ignore_canonical
|
36
|
-
# prefer canonical link
|
37
|
-
canonical_link = doc.at('//link[@rel="canonical"]/@href')
|
38
|
-
canonical_uri = Addressable::URI.parse(canonical_link)
|
39
|
-
if canonical_link && "#{canonical_uri.host}#{canonical_uri.path}" != "#{uri.host}#{uri.path}"
|
40
|
-
response = (fetch_response(canonical_uri.to_s, headers: headers, body_cacher: body_cacher) rescue nil)
|
41
|
-
doc = Nokogiri::HTML(response) if response
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
doc
|
29
|
+
Nokogiri::HTML(response)
|
46
30
|
end
|
47
31
|
|
48
32
|
def self.fetch_response(location, redirect_limit: 5, domain: nil, headers: nil, body_cacher: nil)
|
@@ -63,8 +47,7 @@ module Onebox
|
|
63
47
|
end
|
64
48
|
|
65
49
|
result = StringIO.new
|
66
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.normalized_scheme == 'https') do |http|
|
67
|
-
http.open_timeout = Onebox.options.connect_timeout
|
50
|
+
Net::HTTP.start(uri.host, uri.port, open_timeout: Onebox.options.connect_timeout, use_ssl: uri.normalized_scheme == 'https') do |http|
|
68
51
|
http.read_timeout = Onebox.options.timeout
|
69
52
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # Work around path building bugs
|
70
53
|
|
@@ -90,7 +73,8 @@ module Onebox
|
|
90
73
|
|
91
74
|
code = response.code.to_i
|
92
75
|
unless code === 200
|
93
|
-
response.error! unless [301, 302].include?(code)
|
76
|
+
response.error! unless [301, 302, 303, 307, 308].include?(code)
|
77
|
+
|
94
78
|
return fetch_response(
|
95
79
|
response['location'],
|
96
80
|
redirect_limit: redirect_limit - 1,
|
@@ -117,8 +101,7 @@ module Onebox
|
|
117
101
|
def self.fetch_content_length(location)
|
118
102
|
uri = URI(location)
|
119
103
|
|
120
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.is_a?(URI::HTTPS)) do |http|
|
121
|
-
http.open_timeout = Onebox.options.connect_timeout
|
104
|
+
Net::HTTP.start(uri.host, uri.port, open_timeout: Onebox.options.connect_timeout, use_ssl: uri.is_a?(URI::HTTPS)) do |http|
|
122
105
|
http.read_timeout = Onebox.options.timeout
|
123
106
|
if uri.is_a?(URI::HTTPS)
|
124
107
|
http.use_ssl = true
|
data/lib/onebox/layout.rb
CHANGED
@@ -32,19 +32,7 @@ module Onebox
|
|
32
32
|
private
|
33
33
|
|
34
34
|
def uri
|
35
|
-
@uri
|
36
|
-
end
|
37
|
-
|
38
|
-
def checksum
|
39
|
-
@md5.hexdigest("#{VERSION}:#{link}")
|
40
|
-
end
|
41
|
-
|
42
|
-
def link
|
43
|
-
::Onebox::Helpers.normalize_url_for_output(record[:link])
|
44
|
-
end
|
45
|
-
|
46
|
-
def domain
|
47
|
-
record[:domain] || URI(link || '').host.to_s.sub(/^www\./, '')
|
35
|
+
@uri ||= URI(::Onebox::Helpers.normalize_url_for_output(record[:link]))
|
48
36
|
end
|
49
37
|
|
50
38
|
def details
|
@@ -52,7 +40,7 @@ module Onebox
|
|
52
40
|
link: record[:link],
|
53
41
|
title: record[:title],
|
54
42
|
favicon: record[:favicon],
|
55
|
-
domain: domain,
|
43
|
+
domain: record[:domain] || uri.host.to_s.sub(/^www\./, ''),
|
56
44
|
article_published_time: record[:article_published_time],
|
57
45
|
article_published_time_title: record[:article_published_time_title],
|
58
46
|
metadata_1_label: record[:metadata_1_label],
|
data/lib/onebox/matcher.rb
CHANGED
@@ -2,8 +2,12 @@
|
|
2
2
|
|
3
3
|
module Onebox
|
4
4
|
class Matcher
|
5
|
-
def initialize(
|
6
|
-
|
5
|
+
def initialize(url, options = {})
|
6
|
+
begin
|
7
|
+
@uri = URI(url)
|
8
|
+
rescue URI::InvalidURIError
|
9
|
+
end
|
10
|
+
|
7
11
|
@options = options
|
8
12
|
end
|
9
13
|
|
@@ -14,12 +18,10 @@ module Onebox
|
|
14
18
|
end
|
15
19
|
|
16
20
|
def oneboxed
|
17
|
-
|
18
|
-
return
|
19
|
-
return
|
20
|
-
ordered_engines.find { |engine| engine === uri && has_allowed_iframe_origins?(engine) }
|
21
|
-
rescue URI::InvalidURIError
|
22
|
-
nil
|
21
|
+
return if @uri.nil?
|
22
|
+
return if @uri.port && !Onebox.options.allowed_ports.include?(@uri.port)
|
23
|
+
return if @uri.scheme && !Onebox.options.allowed_schemes.include?(@uri.scheme)
|
24
|
+
ordered_engines.find { |engine| engine === @uri && has_allowed_iframe_origins?(engine) }
|
23
25
|
end
|
24
26
|
|
25
27
|
def has_allowed_iframe_origins?(engine)
|
@@ -25,8 +25,8 @@ module Onebox
|
|
25
25
|
}
|
26
26
|
|
27
27
|
module InstanceMethods
|
28
|
-
def initialize(
|
29
|
-
super
|
28
|
+
def initialize(url, timeout = nil)
|
29
|
+
super url, timeout
|
30
30
|
# merge engine options from global Onebox.options interface
|
31
31
|
# self.options = Onebox.options["GithubBlobOnebox"] # self.class.name.split("::").last.to_s
|
32
32
|
# self.options = Onebox.options[self.class.name.split("::").last.to_s] #We can use this a more generic approach. extract the engine class name automatically
|
@@ -163,11 +163,9 @@ module Onebox
|
|
163
163
|
@file = m[:file]
|
164
164
|
@lang = Onebox::FileTypeFinder.from_file_name(m[:file])
|
165
165
|
|
166
|
-
if @lang == "stl" && link.match(/^https?:\/\/(www\.)?github\.com.*\/blob\//)
|
167
|
-
|
166
|
+
if @lang == "stl" && link.match?(/^https?:\/\/(www\.)?github\.com.*\/blob\//)
|
168
167
|
@model_file = @lang.dup
|
169
168
|
@raw = "https://render.githubusercontent.com/view/solid?url=" + self.raw_template(m)
|
170
|
-
|
171
169
|
else
|
172
170
|
contents = URI.open(self.raw_template(m), read_timeout: timeout).read
|
173
171
|
|
data/lib/onebox/open_graph.rb
CHANGED
@@ -17,10 +17,10 @@ module Onebox
|
|
17
17
|
!title.nil? ? "title='#{title}'" : ""
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def secure_image_url
|
21
|
+
secure_url = URI(get(:image))
|
22
|
+
secure_url.scheme = 'https'
|
23
|
+
secure_url.to_s
|
24
24
|
end
|
25
25
|
|
26
26
|
def method_missing(attr, *args, &block)
|
data/lib/onebox/preview.rb
CHANGED
@@ -6,8 +6,8 @@ module Onebox
|
|
6
6
|
client_exception = defined?(Net::HTTPClientException) ? Net::HTTPClientException : Net::HTTPServerException
|
7
7
|
WEB_EXCEPTIONS ||= [client_exception, OpenURI::HTTPError, Timeout::Error, Net::HTTPError, Errno::ECONNREFUSED]
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@url =
|
9
|
+
def initialize(url, options = Onebox.options)
|
10
|
+
@url = url
|
11
11
|
@options = options.dup
|
12
12
|
|
13
13
|
allowed_origins = @options[:allowed_iframe_origins] || Onebox::Engine.all_iframe_origins
|
data/lib/onebox/version.rb
CHANGED