/
standard_embed.rb
147 lines (109 loc) · 3.94 KB
/
standard_embed.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
# frozen_string_literal: true
require "cgi"
require "onebox/open_graph"
module Onebox
module Engine
module StandardEmbed
def self.oembed_providers
@@oembed_providers ||= {}
end
def self.add_oembed_provider(regexp, endpoint)
oembed_providers[regexp] = endpoint
end
def self.opengraph_providers
@@opengraph_providers ||= []
end
def self.add_opengraph_provider(regexp)
opengraph_providers << regexp
end
# Some oembed providers (like meetup.com) don't provide links to themselves
add_oembed_provider(/www\.meetup\.com\//, 'http://api.meetup.com/oembed')
add_oembed_provider(/www\.mixcloud\.com\//, 'https://www.mixcloud.com/oembed/')
# In order to support Private Videos
add_oembed_provider(/vimeo\.com\//, 'https://vimeo.com/api/oembed.json')
# NYT requires login so use oembed only
add_oembed_provider(/nytimes\.com\//, 'https://www.nytimes.com/svc/oembed/json/')
def always_https?
AllowlistedGenericOnebox.host_matches(uri, AllowlistedGenericOnebox.https_hosts) || super
end
def raw
return @raw if @raw
og = get_opengraph
twitter = get_twitter
oembed = get_oembed
@raw = {}
og.data.each do |k, v|
next if k == "title_attr"
v = og.send(k)
@raw[k] ||= v unless v.nil?
end
twitter.each { |k, v| @raw[k] ||= v unless Onebox::Helpers::blank?(v) }
oembed.data.each do |k, v|
v = oembed.send(k)
@raw[k] ||= v unless v.nil?
end
favicon = get_favicon
@raw["favicon".to_sym] = favicon unless Onebox::Helpers::blank?(favicon)
@raw
end
protected
def html_doc
return @html_doc if @html_doc
headers = nil
headers = { 'Cookie' => options[:cookie] } if options[:cookie]
@html_doc = Onebox::Helpers.fetch_html_doc(url, headers)
end
def get_oembed
@oembed ||= Onebox::Oembed.new(get_json_response)
end
def get_opengraph
@opengraph ||= ::Onebox::OpenGraph.new(html_doc)
end
def get_twitter
return {} unless html_doc
twitter = {}
html_doc.css('meta').each do |m|
if (m["property"] && m["property"][/^twitter:(.+)$/i]) || (m["name"] && m["name"][/^twitter:(.+)$/i])
value = (m["content"] || m["value"]).to_s
twitter[$1.tr('-:' , '_').to_sym] ||= value unless Onebox::Helpers::blank?(value)
end
end
twitter
end
def get_favicon
return nil unless html_doc
favicon = html_doc.css('link[rel="shortcut icon"], link[rel="icon shortcut"], link[rel="shortcut"], link[rel="icon"]').first
favicon = favicon.nil? ? nil : (favicon['href'].nil? ? nil : favicon['href'].strip)
Onebox::Helpers::get_absolute_image_url(favicon, url)
end
def get_json_response
oembed_url = get_oembed_url
return "{}" if Onebox::Helpers.blank?(oembed_url)
Onebox::Helpers.fetch_response(oembed_url) rescue "{}"
rescue Errno::ECONNREFUSED, Net::HTTPError, Net::HTTPFatalError, MultiJson::LoadError
"{}"
end
protected
def get_oembed_url
oembed_url = nil
StandardEmbed.oembed_providers.each do |regexp, endpoint|
if url =~ regexp
oembed_url = "#{endpoint}?url=#{url}"
break
end
end
if html_doc
if Onebox::Helpers.blank?(oembed_url)
application_json = html_doc.at("//link[@type='application/json+oembed']/@href")
oembed_url = application_json.value if application_json
end
if Onebox::Helpers.blank?(oembed_url)
text_json = html_doc.at("//link[@type='text/json+oembed']/@href")
oembed_url ||= text_json.value if text_json
end
end
oembed_url
end
end
end
end