@ -1,6 +1,8 @@
# frozen_string_literal: true
# frozen_string_literal: true
class FetchLinkCardService < BaseService
class FetchLinkCardService < BaseService
include ActionView :: Helpers :: TagHelper
URL_PATTERN = %r{ https?:// \ S+ }
URL_PATTERN = %r{ https?:// \ S+ }
def call ( status )
def call ( status )
@ -14,11 +16,11 @@ class FetchLinkCardService < BaseService
RedisLock . acquire ( lock_options ) do | lock |
RedisLock . acquire ( lock_options ) do | lock |
if lock . acquired?
if lock . acquired?
@card = PreviewCard . find_by ( url : @url )
@card = PreviewCard . find_by ( url : @url )
process_url if @card . nil?
process_url if @card . nil? || @card . updated_at < = 2 . weeks . ago
end
end
end
end
attach_card unless @card . nil ?
attach_card if @card & . persisted ?
rescue HTTP :: ConnectionError , OpenSSL :: SSL :: SSLError
rescue HTTP :: ConnectionError , OpenSSL :: SSL :: SSLError
nil
nil
end
end
@ -26,7 +28,7 @@ class FetchLinkCardService < BaseService
private
private
def process_url
def process_url
@card = PreviewCard . new ( url : @url )
@card || = PreviewCard . new ( url : @url )
res = Request . new ( :head , @url ) . perform
res = Request . new ( :head , @url ) . perform
return if res . code != 200 || res . mime_type != 'text/html'
return if res . code != 200 || res . mime_type != 'text/html'
@ -106,12 +108,25 @@ class FetchLinkCardService < BaseService
guess = detector . detect ( html , response . charset )
guess = detector . detect ( html , response . charset )
page = Nokogiri :: HTML ( html , nil , guess & . fetch ( :encoding ) )
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 . 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' )
@card . image_remote_url = meta_property ( page , 'og:image' ) if meta_property ( page , 'og:image' )
end
@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?
return if @card . title . blank? && @card . html . blank?
@card . save_with_optional_image!
@card . save_with_optional_image!
end
end