refactor twitter service to handle cards (fixes #3031)

This commit is contained in:
r888888888
2017-05-09 12:46:40 -07:00
parent 2b74fe669e
commit ff5586cb01
3 changed files with 97 additions and 27 deletions

View File

@@ -64,7 +64,7 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.5.0)
addressable (2.5.1)
public_suffix (~> 2.0, >= 2.0.2)
arel (6.0.4)
awesome_print (1.7.0)
@@ -127,7 +127,7 @@ GEM
factory_girl (4.8.0)
activesupport (>= 3.0.0)
fakeweb (1.3.0)
faraday (0.9.2)
faraday (0.10.1)
multipart-post (>= 1.2, < 3)
ffaker (2.5.0)
ffi (1.9.10-x64-mingw32)
@@ -155,10 +155,14 @@ GEM
signet (~> 0.7)
highline (1.7.8)
hike (1.2.3)
http (0.6.4)
http (2.2.2)
addressable (~> 2.3)
http-cookie (~> 1.0)
http-form_data (~> 1.0.1)
http_parser.rb (~> 0.6.0)
http-cookie (1.0.2)
domain_name (~> 0.5)
http-form_data (1.0.2)
http_parser.rb (0.6.0)
httpclient (2.8.0)
hurley (0.2)
@@ -200,7 +204,7 @@ GEM
multi_json (1.12.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
naught (1.0.0)
naught (1.1.0)
net-http-digest_auth (1.4.1)
net-http-persistent (2.9.4)
net-scp (1.2.1)
@@ -341,17 +345,16 @@ GEM
tilt (1.4.1)
timecop (0.8.1)
tins (1.6.0)
twitter (5.14.0)
addressable (~> 2.3)
twitter (6.0.0)
addressable (~> 2.5)
buftok (~> 0.2.0)
equalizer (~> 0.0.9)
faraday (~> 0.9.0)
http (~> 0.6.0)
equalizer (= 0.0.11)
faraday (~> 0.10.0)
http (~> 2.1)
http_parser.rb (~> 0.6.0)
json (~> 1.8)
memoizable (~> 0.4.0)
naught (~> 1.0)
simple_oauth (~> 0.3.0)
memoizable (~> 0.4.2)
naught (~> 1.1)
simple_oauth (~> 0.3.1)
tzinfo (1.2.2)
thread_safe (~> 0.1)
tzinfo-data (1.2015.6)

View File

@@ -17,25 +17,59 @@ class TwitterService
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)
url = attrs.urls.map {|x| x.expanded_url}.reject {|x| x.host == "twitter.com"}.first
[extract_og_image_from_page(url)].compact
end
def image_urls(tweet_url)
tweet_url =~ %r{/status/(\d+)}
twitter_id = $1
attrs = client.status(twitter_id).attrs
tweet = client.status(twitter_id)
urls = []
attrs[:entities][:media].each do |obj|
urls << obj[:media_url] + ":orig"
end
attrs[:extended_entities][:media].each do |obj|
if obj[:video_info]
largest = obj[:video_info][:variants].select {|x| x[:url] =~ /\.mp4$/}.max_by {|x| x[:bitrate]}
urls.clear
urls << largest[:url] if largest
else
urls << obj[:media_url] + ":orig"
end
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
[]
# rescue => e
# []
end
end

View File

@@ -2,6 +2,39 @@ require 'test_helper'
module Sources
class TwitterTest < ActiveSupport::TestCase
context "A video" do
setup do
@site = Sources::Site.new("https://twitter.com/CincinnatiZoo/status/859073537713328129")
@site.get
end
should "get the image url" do
assert_equal("https://video.twimg.com/ext_tw_video/859073467769126913/pu/vid/1280x720/cPGgVROXHy3yrK6u.mp4", @site.image_url)
end
end
context "An animated gif" do
setup do
@site = Sources::Site.new("https://twitter.com/DaniStrawberry1/status/859435334765088769")
@site.get
end
should "get the image url" do
assert_equal("https://video.twimg.com/tweet_video/C-1Tns7WsAAqvqn.mp4", @site.image_url)
end
end
context "A twitter summary card" do
setup do
@site = Sources::Site.new("https://twitter.com/NatGeo/status/787654447937847296")
@site.get
end
should "get the image url" do
assert_equal("http://yourshot.nationalgeographic.com/u/fQYSUbVfts-T7odkrFJckdiFeHvab0GWOfzhj7tYdC0uglagsDcUxj3Tf7HBF3kZEj7S5m-zeDmZP6DBxBJlyJX_1mFp-hGf4JPt97xp0QJkwf4po1MmnZH73WC3a2Pa1Ky62C-v0cYXTur3-QwD3Pz5UI_cKIi81GABTXII8VwKUopxlNW2MYAR8kPYU2IoUhOjlvVefNcLYI74J-0IpI4tHDXE/", @site.image_url)
end
end
context "The source site for a restricted twitter" do
setup do
@site = Sources::Site.new("https://mobile.twitter.com/Strangestone/status/556440271961858051")