80 lines
2.3 KiB
Ruby
80 lines
2.3 KiB
Ruby
class TwitterService
|
|
def client
|
|
raise "Twitter API keys not set" if Danbooru.config.twitter_api_key.nil?
|
|
|
|
@client ||= begin
|
|
rest_client = Twitter::REST::Client.new do |config|
|
|
config.consumer_key = Danbooru.config.twitter_api_key
|
|
config.consumer_secret = Danbooru.config.twitter_api_secret
|
|
if bearer_token = Cache.get("twitter-api-token")
|
|
config.bearer_token = bearer_token
|
|
end
|
|
end
|
|
|
|
Cache.put("twitter-api-token", rest_client.bearer_token)
|
|
|
|
rest_client
|
|
end
|
|
end
|
|
|
|
def extract_urls_for_status(tweet)
|
|
tweet.media.map do |obj|
|
|
if obj.is_a?(Twitter::Media::Photo)
|
|
obj.media_url.to_s + ":orig"
|
|
elsif obj.is_a?(Twitter::Media::Video)
|
|
video = obj.video_info.variants.select do |x|
|
|
x.content_type == "video/mp4"
|
|
end.max_by {|y| y.bitrate}
|
|
if video
|
|
video.url.to_s
|
|
end
|
|
end
|
|
end.compact
|
|
end
|
|
|
|
def extract_og_image_from_page(url, n = 5)
|
|
raise "too many redirects" if n == 0
|
|
|
|
Net::HTTP.start(url.host, url.port, :use_ssl => (url.normalized_scheme == "https")) do |http|
|
|
resp = http.request_get(url.request_uri)
|
|
if resp.is_a?(Net::HTTPMovedPermanently) && resp["Location"]
|
|
redirect_url = Addressable::URI.parse(resp["Location"])
|
|
redirect_url.host = url.host if redirect_url.host.nil?
|
|
redirect_url.scheme = url.scheme if redirect_url.scheme.nil?
|
|
redirect_url.port = url.port if redirect_url.port.nil?
|
|
return extract_og_image_from_page(redirect_url, n - 1)
|
|
elsif resp.is_a?(Net::HTTPSuccess)
|
|
doc = Nokogiri::HTML(resp.body)
|
|
images = doc.css("meta[property='og:image']")
|
|
return images.first.attr("content")
|
|
end
|
|
end
|
|
end
|
|
|
|
def extract_urls_for_card(attrs)
|
|
urls = attrs.urls.map {|x| x.expanded_url}
|
|
url = urls.reject {|x| x.host == "twitter.com"}.first
|
|
if url.nil?
|
|
url = urls.first
|
|
end
|
|
[extract_og_image_from_page(url)].compact
|
|
end
|
|
|
|
def image_urls(tweet_url)
|
|
tweet_url =~ %r{/status/(\d+)}
|
|
twitter_id = $1
|
|
tweet = client.status(twitter_id)
|
|
urls = []
|
|
|
|
if tweet.media.any?
|
|
urls = extract_urls_for_status(tweet)
|
|
elsif tweet.urls.any?
|
|
urls = extract_urls_for_card(tweet)
|
|
end
|
|
|
|
urls.uniq
|
|
rescue => e
|
|
[]
|
|
end
|
|
end
|