46 行
1.8 KiB
Ruby
46 行
1.8 KiB
Ruby
class PostMetadataFetcher
|
|
def self.fetch raw_url
|
|
uri, = Preview::UrlSafety.validate(raw_url)
|
|
response = Preview::HttpFetcher.fetch(uri.to_s, max_bytes: Preview::ThumbnailFetcher::HTML_MAX_BYTES)
|
|
metadata = Preview::HtmlMetadataExtractor.extract(response)
|
|
document = Nokogiri::HTML.parse(response.body)
|
|
content = -> name { document.at_css("meta[property='#{ name }'], meta[name='#{ name }']")&.[]('content')&.strip.presence }
|
|
duration = content.call('og:video:duration') || content.call('video:duration')
|
|
published = content.call('article:published_time') || content.call('date')
|
|
created_range = original_created_range(published)
|
|
platform_tags = platform_tags(uri)
|
|
{ title: metadata[:title],
|
|
thumbnail_base: Preview::KnownSiteExtractor.thumbnail_url(uri) || metadata[:image_url],
|
|
original_created_from: created_range&.first&.iso8601,
|
|
original_created_before: created_range&.last&.iso8601,
|
|
duration: duration&.to_f&.then { _1.positive? ? (_1 * 1_000).round : nil },
|
|
tags: platform_tags.join(' ') }
|
|
end
|
|
|
|
def self.platform_tags uri
|
|
return ['動画', 'YouTube'] if Preview::KnownSiteExtractor.youtube_video_id(uri)
|
|
return ['動画', 'ニコニコ'] if Preview::KnownSiteExtractor.niconico_video_id(uri)
|
|
|
|
[]
|
|
end
|
|
|
|
def self.original_created_range value
|
|
return nil if value.blank?
|
|
|
|
raw = value.to_s.strip
|
|
from = Time.zone.parse(raw)
|
|
before =
|
|
case raw
|
|
when /\A\d{4}\z/ then from + 1.year
|
|
when /\A\d{4}-\d{2}\z/ then from + 1.month
|
|
when /\A\d{4}-\d{2}-\d{2}\z/ then from + 1.day
|
|
when /:\d{2}(?:Z|[+-]\d{2}:?\d{2})?\z/ then from + 1.second
|
|
else from + 1.minute
|
|
end
|
|
[from, before]
|
|
rescue ArgumentError, TypeError
|
|
nil
|
|
end
|
|
private_class_method :platform_tags, :original_created_range
|
|
end
|