mirror of
https://github.com/discourse/discourse.git
synced 2024-12-02 03:53:38 +08:00
283b08d45f
* Move onebox gem in core library * Update template file path * Remove warning for onebox gem caching * Remove onebox version file * Remove onebox gem * Add sanitize gem * Require onebox library in lazy-yt plugin * Remove onebox web specific code This code was used in standalone onebox Sinatra application * Merge Discourse specific AllowlistedGenericOnebox engine in core * Fix onebox engine filenames to match class name casing * Move onebox specs from gem into core * DEV: Rename `response` helper to `onebox_response` Fixes a naming collision. * Require rails_helper * Don't use `before/after(:all)` * Whitespace * Remove fakeweb * Remove poor unit tests * DEV: Re-add fakeweb, plugins are using it * Move onebox helpers * Stub Instagram API * FIX: Follow additional redirect status codes (#476) Don’t throw errors if we encounter 303, 307 or 308 HTTP status codes in responses * Remove an empty file * DEV: Update the license file Using the copy from https://choosealicense.com/licenses/gpl-2.0/# Hopefully this will enable GitHub to show the license UI? * DEV: Update embedded copyrights * DEV: Add Onebox copyright notice * DEV: Add MIT license, convert COPYRIGHT.txt to md * DEV: Remove an incorrect copyright claim Co-authored-by: Jarek Radosz <jradosz@gmail.com> Co-authored-by: jbrw <jamie@goatforce5.org>
146 lines
4.0 KiB
Ruby
146 lines
4.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "cgi"
|
|
require "onebox/open_graph"
|
|
require 'onebox/oembed'
|
|
|
|
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 defined?(@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 defined?(@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) || value == "0 minutes")
|
|
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
|
|
|
|
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
|