# frozen_string_literal: true module Onebox module Engine class GfycatOnebox include Engine include JSON matches_regexp(%r{^https?://gfycat\.com/}) always_https # This engine should have priority over AllowlistedGenericOnebox. def self.priority 1 end def to_html <<-HTML <aside class="onebox gfycat"> <header class="source"> <img src="https://gfycat.com/static/favicons/favicon-96x96.png" class="site-icon" width="64" height="64"> <a href="#{data[:url]}" target="_blank" rel="nofollow ugc noopener">Gfycat.com</a> </header> <article class="onebox-body"> <h4> #{data[:title]} by <a href="https://gfycat.com/@#{data[:author]}" target="_blank" rel="nofollow ugc noopener"> <span>#{data[:author]}</span> </a> </h4> <div class="video" style="--aspect-ratio: #{data[:width]}/#{data[:height]}"> <video controls loop muted poster="#{data[:posterUrl]}"> <source id="webmSource" src="#{data[:webmUrl]}" type="video/webm"> <source id="mp4Source" src="#{data[:mp4Url]}" type="video/mp4"> <img title="Sorry, your browser doesn't support HTML5 video." src="#{data[:posterUrl]}"> </video> </div> <p> <span class="label1">#{data[:keywords]}</span> </p> </article> <div style="clear: both"></div> </aside> HTML end def placeholder_html <<-HTML <a href="#{data[:url]}"> <img src="#{data[:posterUrl]}" width="#{data[:width]}" height="#{data[:height]}"><br/> #{data[:name]} </a> HTML end private def match @match ||= @url.match(%r{^https?://gfycat\.com/(gifs/detail/)?(?<name>.+)}) end def og_data return @og_data if defined?(@og_data) response = begin Onebox::Helpers.fetch_response(url, redirect_limit: 10) rescue StandardError nil end page = Nokogiri.HTML(response) script = page.at_css('script[type="application/ld+json"]') if json_string = script&.text @og_data = ::MultiJson.load(json_string, symbolize_keys: true) else @og_data = {} end end def data return @data if defined?(@data) @data = { name: match[:name], title: og_data[:headline] || "No Title", author: og_data[:author], url: @url, } if keywords = og_data[:keywords]&.split(",") @data[:keywords] = keywords .map { |keyword| "<a href='https://gfycat.com/gifs/search/#{keyword}'>##{keyword}</a>" } .join(" ") end if og_data[:video] content_url = ::Onebox::Helpers.normalize_url_for_output(og_data[:video][:contentUrl]) video_url = Pathname.new(content_url) @data[:webmUrl] = video_url.sub_ext(".webm").to_s @data[:mp4Url] = video_url.sub_ext(".mp4").to_s thumbnail_url = ::Onebox::Helpers.normalize_url_for_output(og_data[:video][:thumbnailUrl]) @data[:posterUrl] = thumbnail_url @data[:width] = og_data[:video][:width] @data[:height] = og_data[:video][:height] end @data end end end end