2019-05-02 18:17:27 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-07-19 15:08:54 -04:00
|
|
|
class InlineOneboxer
|
|
|
|
|
2018-01-29 16:39:41 -05:00
|
|
|
MIN_TITLE_LENGTH = 2
|
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
def initialize(urls, opts = nil)
|
2017-07-19 15:08:54 -04:00
|
|
|
@urls = urls
|
2017-07-21 15:29:04 -04:00
|
|
|
@opts = opts || {}
|
2017-07-19 15:08:54 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def process
|
2017-07-27 21:20:09 -04:00
|
|
|
@urls.map { |url| InlineOneboxer.lookup(url, @opts) }.compact
|
2017-07-19 15:08:54 -04:00
|
|
|
end
|
|
|
|
|
2017-07-21 15:29:04 -04:00
|
|
|
def self.purge(url)
|
2019-11-26 20:35:14 -05:00
|
|
|
Discourse.cache.delete(cache_key(url))
|
2017-07-19 15:08:54 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.cache_lookup(url)
|
2019-11-26 20:35:14 -05:00
|
|
|
Discourse.cache.read(cache_key(url))
|
2017-07-19 15:08:54 -04:00
|
|
|
end
|
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
def self.lookup(url, opts = nil)
|
2017-07-21 15:29:04 -04:00
|
|
|
opts ||= {}
|
2018-09-03 13:03:43 -04:00
|
|
|
opts = opts.with_indifferent_access
|
2017-07-21 15:29:04 -04:00
|
|
|
|
2018-09-03 13:03:43 -04:00
|
|
|
unless opts[:skip_cache] || opts[:invalidate]
|
2017-07-21 15:29:04 -04:00
|
|
|
cached = cache_lookup(url)
|
|
|
|
return cached if cached.present?
|
|
|
|
end
|
2017-07-19 15:08:54 -04:00
|
|
|
|
2018-03-28 04:20:08 -04:00
|
|
|
return unless url
|
|
|
|
|
2017-07-19 15:08:54 -04:00
|
|
|
if route = Discourse.route_for(url)
|
|
|
|
if route[:controller] == "topics" &&
|
|
|
|
route[:action] == "show" &&
|
2018-03-28 04:20:08 -04:00
|
|
|
topic = Topic.where(id: route[:topic_id].to_i).first
|
2017-07-19 15:08:54 -04:00
|
|
|
|
2017-07-21 15:29:04 -04:00
|
|
|
return onebox_for(url, topic.title, opts) if Guardian.new.can_see?(topic)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-08-02 14:27:21 -04:00
|
|
|
always_allow = SiteSetting.enable_inline_onebox_on_all_domains
|
|
|
|
domains = SiteSetting.inline_onebox_domains_whitelist&.split('|') unless always_allow
|
|
|
|
|
|
|
|
if always_allow || domains
|
2018-03-28 04:20:08 -04:00
|
|
|
uri = begin
|
|
|
|
URI(url)
|
2018-08-14 06:23:32 -04:00
|
|
|
rescue URI::Error
|
2018-03-28 04:20:08 -04:00
|
|
|
end
|
2017-07-21 15:29:04 -04:00
|
|
|
|
|
|
|
if uri.present? &&
|
|
|
|
uri.hostname.present? &&
|
2018-11-12 15:14:20 -05:00
|
|
|
(always_allow || domains.include?(uri.hostname))
|
2017-07-21 15:29:04 -04:00
|
|
|
title = RetrieveTitle.crawl(url)
|
2018-01-29 16:39:41 -05:00
|
|
|
title = nil if title && title.length < MIN_TITLE_LENGTH
|
2017-07-27 21:20:09 -04:00
|
|
|
return onebox_for(url, title, opts)
|
2017-07-19 15:08:54 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2018-06-07 01:28:18 -04:00
|
|
|
def self.onebox_for(url, title, opts)
|
|
|
|
onebox = {
|
|
|
|
url: url,
|
|
|
|
title: title && Emoji.gsub_emoji_to_unicode(title)
|
|
|
|
}
|
|
|
|
unless opts[:skip_cache]
|
2019-11-26 20:35:14 -05:00
|
|
|
Discourse.cache.write(cache_key(url), onebox, expires_in: 1.day)
|
2017-07-21 15:29:04 -04:00
|
|
|
end
|
|
|
|
|
2018-06-07 01:28:18 -04:00
|
|
|
onebox
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.cache_key(url)
|
|
|
|
"inline_onebox:#{url}"
|
|
|
|
end
|
2017-07-19 15:08:54 -04:00
|
|
|
|
|
|
|
end
|