discourse/lib/inline_oneboxer.rb

83 lines
1.7 KiB
Ruby
Raw Normal View History

require_dependency 'retrieve_title'
class InlineOneboxer
MIN_TITLE_LENGTH = 2
2017-07-28 09:20:09 +08:00
def initialize(urls, opts = nil)
@urls = urls
@opts = opts || {}
end
def process
2017-07-28 09:20:09 +08:00
@urls.map { |url| InlineOneboxer.lookup(url, @opts) }.compact
end
def self.purge(url)
Rails.cache.delete(cache_key(url))
end
def self.cache_lookup(url)
Rails.cache.read(cache_key(url))
end
2017-07-28 09:20:09 +08:00
def self.lookup(url, opts = nil)
opts ||= {}
unless opts[:skip_cache]
cached = cache_lookup(url)
return cached if cached.present?
end
return unless url
if route = Discourse.route_for(url)
if route[:controller] == "topics" &&
route[:action] == "show" &&
topic = Topic.where(id: route[:topic_id].to_i).first
return onebox_for(url, topic.title, opts) if Guardian.new.can_see?(topic)
end
end
always_allow = SiteSetting.enable_inline_onebox_on_all_domains
domains = SiteSetting.inline_onebox_domains_whitelist&.split('|') unless always_allow
if always_allow || domains
uri = begin
URI(url)
rescue URI::InvalidURIError
end
if uri.present? &&
uri.hostname.present? &&
(always_allow || domains.include?(uri.hostname)) &&
title = RetrieveTitle.crawl(url)
title = nil if title && title.length < MIN_TITLE_LENGTH
2017-07-28 09:20:09 +08:00
return onebox_for(url, title, opts)
end
end
nil
end
private
def self.onebox_for(url, title, opts)
onebox = {
url: url,
title: title && Emoji.gsub_emoji_to_unicode(title)
}
unless opts[:skip_cache]
Rails.cache.write(cache_key(url), onebox, expires_in: 1.day)
end
onebox
end
def self.cache_key(url)
"inline_onebox:#{url}"
end
end