Support OpenGraph video embeds (#4897)
* Support OpenGraph video embeds It's not really OpenGraph, it's twitter:player property, but it's not OEmbed so that fits. For example, this allows Twitch clips to be displayed as embeds. Also, fixes glitch-soc/mastodon#135 * Fix invalid OpenGraph cards being saved through attaching and revisit URLs after 14 days
This commit is contained in:
		
							parent
							
								
									4f0597d579
								
							
						
					
					
						commit
						596dab06e9
					
				
					 1 changed files with 24 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class FetchLinkCardService < BaseService
 | 
			
		||||
  include ActionView::Helpers::TagHelper
 | 
			
		||||
 | 
			
		||||
  URL_PATTERN = %r{https?://\S+}
 | 
			
		||||
 | 
			
		||||
  def call(status)
 | 
			
		||||
| 
						 | 
				
			
			@ -14,11 +16,11 @@ class FetchLinkCardService < BaseService
 | 
			
		|||
    RedisLock.acquire(lock_options) do |lock|
 | 
			
		||||
      if lock.acquired?
 | 
			
		||||
        @card = PreviewCard.find_by(url: @url)
 | 
			
		||||
        process_url if @card.nil?
 | 
			
		||||
        process_url if @card.nil? || @card.updated_at <= 2.weeks.ago
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    attach_card unless @card.nil?
 | 
			
		||||
    attach_card if @card&.persisted?
 | 
			
		||||
  rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
 | 
			
		||||
    nil
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +28,7 @@ class FetchLinkCardService < BaseService
 | 
			
		|||
  private
 | 
			
		||||
 | 
			
		||||
  def process_url
 | 
			
		||||
    @card = PreviewCard.new(url: @url)
 | 
			
		||||
    @card ||= PreviewCard.new(url: @url)
 | 
			
		||||
    res     = Request.new(:head, @url).perform
 | 
			
		||||
 | 
			
		||||
    return if res.code != 200 || res.mime_type != 'text/html'
 | 
			
		||||
| 
						 | 
				
			
			@ -106,12 +108,25 @@ class FetchLinkCardService < BaseService
 | 
			
		|||
    guess = detector.detect(html, response.charset)
 | 
			
		||||
    page  = Nokogiri::HTML(html, nil, guess&.fetch(:encoding))
 | 
			
		||||
 | 
			
		||||
    if meta_property(page, 'twitter:player')
 | 
			
		||||
      @card.type   = :video
 | 
			
		||||
      @card.width  = meta_property(page, 'twitter:player:width') || 0
 | 
			
		||||
      @card.height = meta_property(page, 'twitter:player:height') || 0
 | 
			
		||||
      @card.html   = content_tag(:iframe, nil, src: meta_property(page, 'twitter:player'),
 | 
			
		||||
                                               width: @card.width,
 | 
			
		||||
                                               height: @card.height,
 | 
			
		||||
                                               allowtransparency: 'true',
 | 
			
		||||
                                               scrolling: 'no',
 | 
			
		||||
                                               frameborder: '0')
 | 
			
		||||
    else
 | 
			
		||||
      @card.type             = :link
 | 
			
		||||
    @card.title            = meta_property(page, 'og:title') || page.at_xpath('//title')&.content || ''
 | 
			
		||||
    @card.description      = meta_property(page, 'og:description') || meta_property(page, 'description') || ''
 | 
			
		||||
      @card.image_remote_url = meta_property(page, 'og:image') if meta_property(page, 'og:image')
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return if @card.title.blank?
 | 
			
		||||
    @card.title            = meta_property(page, 'og:title').presence || page.at_xpath('//title')&.content || ''
 | 
			
		||||
    @card.description      = meta_property(page, 'og:description').presence || meta_property(page, 'description') || ''
 | 
			
		||||
 | 
			
		||||
    return if @card.title.blank? && @card.html.blank?
 | 
			
		||||
 | 
			
		||||
    @card.save_with_optional_image!
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue