mirror of
https://github.com/discourse/discourse.git
synced 2024-12-16 16:43:44 +08:00
142571bba0
* `rescue nil` is a really bad pattern to use in our code base. We should rescue errors that we expect the code to throw and not rescue everything because we're unsure of what errors the code would throw. This would reduce the amount of pain we face when debugging why something isn't working as expexted. I've been bitten countless of times by errors being swallowed as a result during debugging sessions.
83 lines
1.7 KiB
Ruby
83 lines
1.7 KiB
Ruby
require_dependency 'retrieve_title'
|
|
|
|
class InlineOneboxer
|
|
|
|
MIN_TITLE_LENGTH = 2
|
|
|
|
def initialize(urls, opts = nil)
|
|
@urls = urls
|
|
@opts = opts || {}
|
|
end
|
|
|
|
def process
|
|
@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
|
|
|
|
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
|
|
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
|