Skip to content

Commit

Permalink
Use expanded URIs when available
Browse files Browse the repository at this point in the history
Closes #543.
  • Loading branch information
sferik committed Mar 19, 2014
1 parent c9cfca9 commit f1d5d1f
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 70 deletions.
6 changes: 5 additions & 1 deletion lib/twitter/entities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Entities

# @return [Boolean]
def entities?
!@attrs[:entities].nil? && @attrs[:entities].any? { |_, array| !array.empty? }
!@attrs[:entities].nil? && @attrs[:entities].any? { |_, array| array.any? }
end
memoize :entities?

Expand All @@ -26,6 +26,7 @@ def hashtags
def hashtags?
hashtags.any?
end
memoize :hashtags?

# @note Must include entities in your request for this method to work
# @return [Array<Twitter::Media>]
Expand All @@ -38,6 +39,7 @@ def media
def media?
media.any?
end
memoize :media?

# @note Must include entities in your request for this method to work
# @return [Array<Twitter::Entity::Symbol>]
Expand All @@ -50,6 +52,7 @@ def symbols
def symbols?
symbols.any?
end
memoize :symbols?

# @note Must include entities in your request for this method to work
# @return [Array<Twitter::Entity::URI>]
Expand All @@ -76,6 +79,7 @@ def user_mentions
def user_mentions?
user_mentions.any?
end
memoize :user_mentions?

private

Expand Down
56 changes: 48 additions & 8 deletions lib/twitter/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,50 @@ class User < Twitter::BasicUser
alias_method :tweet?, :status?
alias_method :tweeted?, :status?

# @return [Array<Twitter::Entity::URI>]
def description_uris
Array(@attrs[:entities][:description][:urls]).collect do |entity|
Entity::URI.new(entity)
class << self

private

# Dynamically define a method for entity URIs
#
# @param key1 [Symbol]
# @param key2 [Symbol]
def define_entity_uris_methods(key1, key2)
array = key1.to_s.split('_')
index = array.index('uris')
array[index] = 'urls'
url_key = array.join('_').to_sym
define_entity_uris_method(key1, key2)
alias_method(url_key, key1)
define_entity_uris_predicate_method(key1)
alias_method(:"#{url_key}?", :"#{key1}?")
end

def define_entity_uris_method(key1, key2)
define_method(key1) do ||
Array(@attrs[:entities] && @attrs[:entities][key2] && @attrs[:entities][key2][:urls]).collect do |url|
Entity::URI.new(url)
end
end
memoize(key1)
end

def define_entity_uris_predicate_method(key1)
define_method(:"#{key1}?") do ||
send(:"#{key1}").any?
end
memoize(:"#{key1}?")
end
end
memoize :description_uris
alias_method :description_urls, :description_uris

define_entity_uris_methods :description_uris, :description
define_entity_uris_methods :website_uris, :url

# @return [Boolean]
def entities?
!@attrs[:entities].nil? && @attrs[:entities].any? { |_, hash| hash[:urls].any? }
end
memoize :entities?

# @return [String] The URL to the user.
def uri
Expand All @@ -50,12 +86,16 @@ def uri

# @return [String] The URL to the user's website.
def website
Addressable::URI.parse(@attrs[:url]) unless @attrs[:url].nil?
if website_urls?
website_urls.first.expanded_url
elsif @attrs[:url]
Addressable::URI.parse(@attrs[:url])
end
end
memoize :website

def website?
!!@attrs[:url]
!!(website_uris? || @attrs[:url])
end
memoize :website?
end
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/sferik.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"San Francisco","description":"An ingredient in your recipe.","url":"https:\/\/github.com\/sferik","entities":{"url":{"urls":[{"url":"https:\/\/github.com\/sferik","expanded_url":null,"indices":[0,25]}]},"description":{"urls":[]}},"protected":false,"followers_count":2449,"friends_count":203,"listed_count":130,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":4306,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":8554,"lang":"en","status":{"created_at":"Tue Oct 02 23:21:06 +0000 2012","id":253273430739283969,"id_str":"253273430739283969","text":"@dakami RAM drives are the new SSDs","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":253272860473298944,"in_reply_to_status_id_str":"253272860473298944","in_reply_to_user_id":8917142,"in_reply_to_user_id_str":"8917142","in_reply_to_screen_name":"dakami","geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[],"urls":[],"user_mentions":[{"screen_name":"dakami","name":"Dan Kaminsky","id":8917142,"id_str":"8917142","indices":[0,7]}]},"favorited":false,"retweeted":false},"contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/665875854\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/665875854\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_banner_url":"https:\/\/si0.twimg.com\/profile_banners\/7505382\/1348266581","profile_link_color":"0084B4","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false}
{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"","description":"May contain forward-looking statements.","url":"https:\/\/t.co\/L2xIBazMPf","entities":{"url":{"urls":[{"url":"https:\/\/t.co\/L2xIBazMPf","expanded_url":"https:\/\/github.com\/sferik","display_url":"github.com\/sferik","indices":[0,23]}]},"description":{"urls":[]}},"protected":false,"followers_count":4051,"friends_count":361,"listed_count":238,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":8976,"utc_offset":3600,"time_zone":"Berlin","geo_enabled":true,"verified":false,"statuses_count":13844,"lang":"en","status":{"created_at":"Wed Mar 19 00:50:35 +0000 2014","id":446086297866993665,"id_str":"446086297866993665","text":"RT @AntonWSJ: Okean Elzy, #Ukraine's biggest rock band, performed in Berlin tonight amid many \"Glory to Ukraine!\" chants http:\/\/t.co\/dkIF8X\u2026","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Tue Mar 18 23:56:08 +0000 2014","id":446072592227909632,"id_str":"446072592227909632","text":"Okean Elzy, #Ukraine's biggest rock band, performed in Berlin tonight amid many \"Glory to Ukraine!\" chants http:\/\/t.co\/dkIF8XvFyw","source":"\u003ca href=\"http:\/\/www.apple.com\" rel=\"nofollow\"\u003eiOS\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":4,"favorite_count":2,"entities":{"hashtags":[{"text":"Ukraine","indices":[12,20]}],"symbols":[],"urls":[],"user_mentions":[],"media":[{"id":446072592047538176,"id_str":"446072592047538176","indices":[107,129],"media_url":"http:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","url":"http:\/\/t.co\/dkIF8XvFyw","display_url":"pic.twitter.com\/dkIF8XvFyw","expanded_url":"http:\/\/twitter.com\/AntonWSJ\/status\/446072592227909632\/photo\/1","type":"photo","sizes":{"medium":{"w":600,"h":450,"resize":"fit"},"large":{"w":1024,"h":768,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"small":{"w":340,"h":255,"resize":"fit"}}}]},"favorited":true,"retweeted":true,"possibly_sensitive":false,"lang":"en"},"retweet_count":4,"favorite_count":0,"entities":{"hashtags":[{"text":"Ukraine","indices":[26,34]}],"symbols":[],"urls":[],"user_mentions":[{"screen_name":"AntonWSJ","name":"Anton Troianovski","id":76773876,"id_str":"76773876","indices":[3,12]}],"media":[{"id":446072592047538176,"id_str":"446072592047538176","indices":[139,140],"media_url":"http:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","url":"http:\/\/t.co\/dkIF8XvFyw","display_url":"pic.twitter.com\/dkIF8XvFyw","expanded_url":"http:\/\/twitter.com\/AntonWSJ\/status\/446072592227909632\/photo\/1","type":"photo","sizes":{"medium":{"w":600,"h":450,"resize":"fit"},"large":{"w":1024,"h":768,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"small":{"w":340,"h":255,"resize":"fit"}}}]},"favorited":true,"retweeted":true,"possibly_sensitive":false,"lang":"en"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/pbs.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/pbs.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_tile":false,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/378800000757402331\/d8dfba561e2e94112a737f17e7d138ca_normal.jpeg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/378800000757402331\/d8dfba561e2e94112a737f17e7d138ca_normal.jpeg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/7505382\/1385736840","profile_link_color":"0084B4","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false,"suspended":false,"needs_phone_verification":false}
25 changes: 12 additions & 13 deletions spec/twitter/direct_message_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,26 @@
end

describe '#entities?' do
it 'returns false if there are no entities set' do
tweet = Twitter::DirectMessage.new(:id => 1_825_786_345)
expect(tweet.entities?).to be false
end

it 'returns false if there are blank lists of entities set' do
tweet = Twitter::DirectMessage.new(:id => 1_825_786_345, :entities => {:urls => []})
expect(tweet.entities?).to be false
end
it 'returns true if there are entities set' do
urls_array = [
{
:url => 'http://example.com/t.co',
:url => 'https://t.co/L2xIBazMPf',
:expanded_url => 'http://example.com/expanded',
:display_url => 'example.com/expandedâ¦',
:display_url => 'example.com/expanded…',
:indices => [10, 33],
}
]
tweet = Twitter::DirectMessage.new(:id => 1_825_786_345, :entities => {:urls => urls_array})
expect(tweet.entities?).to be true
end
it 'returns false if there are blank lists of entities set' do
tweet = Twitter::DirectMessage.new(:id => 1_825_786_345, :entities => {:urls => []})
expect(tweet.entities?).to be false
end
it 'returns false if there are no entities set' do
tweet = Twitter::DirectMessage.new(:id => 1_825_786_345)
expect(tweet.entities?).to be false
end
end

describe '#recipient' do
Expand Down Expand Up @@ -187,7 +186,7 @@
it 'returns an array of Entity::URIs when entities are set' do
urls_array = [
{
:url => 'http://example.com/t.co',
:url => 'https://t.co/L2xIBazMPf',
:expanded_url => 'http://example.com/expanded',
:display_url => 'example.com/expanded…',
:indices => [10, 33],
Expand All @@ -211,7 +210,7 @@
it 'can handle strange urls' do
urls_array = [
{
:url => 'http://with_underscore.example.com/t.co',
:url => 'https://t.co/L2xIBazMPf',
:expanded_url => 'http://with_underscore.example.com/expanded',
:display_url => 'with_underscore.example.com/expanded…',
:indices => [10, 33],
Expand Down
4 changes: 2 additions & 2 deletions spec/twitter/entity/uri_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
describe '#expanded_uri' do
it 'returns a URI when the expanded_url is set' do
uri = Twitter::Entity::URI.new(:expanded_url => 'https://github.com/sferik')
expect(uri.expanded_uri).to be_a Addressable::URI
expect(uri.expanded_uri).to be_an Addressable::URI
expect(uri.expanded_uri.to_s).to eq('https://github.com/sferik')
end
it 'returns nil when the expanded_url is not set' do
Expand All @@ -52,7 +52,7 @@
describe '#uri' do
it 'returns a URI when the url is set' do
uri = Twitter::Entity::URI.new(:url => 'https://github.com/sferik')
expect(uri.uri).to be_a Addressable::URI
expect(uri.uri).to be_an Addressable::URI
expect(uri.uri.to_s).to eq('https://github.com/sferik')
end
it 'returns nil when the url is not set' do
Expand Down
8 changes: 4 additions & 4 deletions spec/twitter/media/photo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
describe '#expanded_uri' do
it 'returns a URI when the expanded_url is set' do
photo = Twitter::Media::Photo.new(:id => 1, :expanded_url => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
expect(photo.expanded_uri).to be_a Addressable::URI
expect(photo.expanded_uri).to be_an Addressable::URI
expect(photo.expanded_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
end
it 'returns nil when the expanded_url is not set' do
Expand All @@ -82,7 +82,7 @@
describe '#media_uri' do
it 'returns a URI when the media_url is set' do
photo = Twitter::Media::Photo.new(:id => 1, :media_url => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
expect(photo.media_uri).to be_a Addressable::URI
expect(photo.media_uri).to be_an Addressable::URI
expect(photo.media_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
end
it 'returns nil when the media_url is not set' do
Expand All @@ -105,7 +105,7 @@
describe '#media_uri_https' do
it 'returns a URI when the media_url_https is set' do
photo = Twitter::Media::Photo.new(:id => 1, :media_url_https => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
expect(photo.media_uri_https).to be_a Addressable::URI
expect(photo.media_uri_https).to be_an Addressable::URI
expect(photo.media_uri_https.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
end
it 'returns nil when the media_url_https is not set' do
Expand All @@ -128,7 +128,7 @@
describe '#uri' do
it 'returns a URI when the url is set' do
photo = Twitter::Media::Photo.new(:id => 1, :url => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
expect(photo.uri).to be_a Addressable::URI
expect(photo.uri).to be_an Addressable::URI
expect(photo.uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
end
it 'returns nil when the url is not set' do
Expand Down
6 changes: 3 additions & 3 deletions spec/twitter/oembed_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
describe '#author_uri' do
it 'returns a URI when the author_url is set' do
oembed = Twitter::OEmbed.new(:author_url => 'https://twitter.com/sferik')
expect(oembed.author_uri).to be_a Addressable::URI
expect(oembed.author_uri).to be_an Addressable::URI
expect(oembed.author_uri.to_s).to eq('https://twitter.com/sferik')
end
it 'returns nil when the author_uri is not set' do
Expand Down Expand Up @@ -87,7 +87,7 @@
describe '#provider_uri' do
it 'returns a URI when the provider_url is set' do
oembed = Twitter::OEmbed.new(:provider_url => 'http://twitter.com')
expect(oembed.provider_uri).to be_a Addressable::URI
expect(oembed.provider_uri).to be_an Addressable::URI
expect(oembed.provider_uri.to_s).to eq('http://twitter.com')
end
it 'returns nil when the provider_uri is not set' do
Expand Down Expand Up @@ -136,7 +136,7 @@
describe '#uri' do
it 'returns a URI when the url is set' do
oembed = Twitter::OEmbed.new(:url => 'https://twitter.com/twitterapi/status/133640144317198338')
expect(oembed.uri).to be_a Addressable::URI
expect(oembed.uri).to be_an Addressable::URI
expect(oembed.uri.to_s).to eq('https://twitter.com/twitterapi/status/133640144317198338')
end
it 'returns nil when the url is not set' do
Expand Down
2 changes: 1 addition & 1 deletion spec/twitter/place_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
describe '#uri' do
it 'returns a URI when the url is set' do
place = Twitter::Place.new(:woeid => '247f43d441defc03', :url => 'https://api.twitter.com/1.1/geo/id/247f43d441defc03.json')
expect(place.uri).to be_a Addressable::URI
expect(place.uri).to be_an Addressable::URI
expect(place.uri.to_s).to eq('https://api.twitter.com/1.1/geo/id/247f43d441defc03.json')
end
it 'returns nil when the url is not set' do
Expand Down
2 changes: 1 addition & 1 deletion spec/twitter/trend_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
describe '#uri' do
it 'returns a URI when the url is set' do
trend = Twitter::Trend.new(:url => 'http://twitter.com/search/?q=%23sevenwordsaftersex')
expect(trend.uri).to be_a Addressable::URI
expect(trend.uri).to be_an Addressable::URI
expect(trend.uri.to_s).to eq('http://twitter.com/search/?q=%23sevenwordsaftersex')
end
it 'returns nil when the url is not set' do
Expand Down
Loading

0 comments on commit f1d5d1f

Please sign in to comment.