diff options
author | David Yip <yipdw@member.fsf.org> | 2018-05-03 17:23:44 -0500 |
---|---|---|
committer | David Yip <yipdw@member.fsf.org> | 2018-05-03 17:23:44 -0500 |
commit | c816701550d7cdb593371dc47d0b9430c78308b0 (patch) | |
tree | cc4417d14de20e69fd5f9a58d66f84af4a623329 /app/services/fetch_oembed_service.rb | |
parent | 3a47842223ff93d8c057f804809f1b111dfd6f76 (diff) | |
parent | a7e71bbd08e089938fbf20ddef5768c2f3ee0702 (diff) |
Merge remote-tracking branch 'origin/master' into gs-master
Conflicts: .travis.yml Gemfile.lock README.md app/controllers/settings/follower_domains_controller.rb app/controllers/statuses_controller.rb app/javascript/mastodon/locales/ja.json app/lib/feed_manager.rb app/models/media_attachment.rb app/models/mute.rb app/models/status.rb app/services/mute_service.rb app/views/home/index.html.haml app/views/stream_entries/_simple_status.html.haml config/locales/ca.yml config/locales/en.yml config/locales/es.yml config/locales/fr.yml config/locales/nl.yml config/locales/pl.yml config/locales/pt-BR.yml config/themes.yml
Diffstat (limited to 'app/services/fetch_oembed_service.rb')
-rw-r--r-- | app/services/fetch_oembed_service.rb | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/app/services/fetch_oembed_service.rb b/app/services/fetch_oembed_service.rb new file mode 100644 index 000000000..998228517 --- /dev/null +++ b/app/services/fetch_oembed_service.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +class FetchOEmbedService + attr_reader :url, :options, :format, :endpoint_url + + def call(url, options = {}) + @url = url + @options = options + + discover_endpoint! + fetch! + end + + private + + def discover_endpoint! + return if html.nil? + + @format = @options[:format] + page = Nokogiri::HTML(html) + + if @format.nil? || @format == :json + @endpoint_url ||= page.at_xpath('//link[@type="application/json+oembed"]')&.attribute('href')&.value + @format ||= :json if @endpoint_url + end + + if @format.nil? || @format == :xml + @endpoint_url ||= page.at_xpath('//link[@type="text/xml+oembed"]')&.attribute('href')&.value + @format ||= :xml if @endpoint_url + end + + return if @endpoint_url.blank? + + @endpoint_url = Addressable::URI.parse(@endpoint_url).to_s + rescue Addressable::URI::InvalidURIError + @endpoint_url = nil + end + + def fetch! + return if @endpoint_url.blank? + + body = Request.new(:get, @endpoint_url).perform do |res| + res.code != 200 ? nil : res.body_with_limit + end + + validate(parse_for_format(body)) unless body.nil? + rescue Oj::ParseError, Ox::ParseError + nil + end + + def parse_for_format(body) + case @format + when :json + Oj.load(body, mode: :strict)&.with_indifferent_access + when :xml + Ox.load(body, mode: :hash_no_attrs)&.with_indifferent_access&.dig(:oembed) + end + end + + def validate(oembed) + oembed if oembed[:version] == '1.0' && oembed[:type].present? + end + + def html + return @html if defined?(@html) + + @html = @options[:html] || Request.new(:get, @url).perform do |res| + res.code != 200 || res.mime_type != 'text/html' ? nil : res.body_with_limit + end + end +end |