twitter 4.8.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +36 -0
- data/CONTRIBUTING.md +13 -15
- data/LICENSE.md +1 -1
- data/README.md +401 -261
- data/Rakefile +6 -0
- data/lib/twitter/arguments.rb +14 -0
- data/lib/twitter/base.rb +109 -89
- data/lib/twitter/client.rb +38 -115
- data/lib/twitter/configuration.rb +5 -2
- data/lib/twitter/core_ext/kernel.rb +5 -1
- data/lib/twitter/creatable.rb +7 -4
- data/lib/twitter/cursor.rb +57 -45
- data/lib/twitter/direct_message.rb +2 -11
- data/lib/twitter/entity/uri.rb +14 -0
- data/lib/twitter/enumerable.rb +15 -0
- data/lib/twitter/error/already_favorited.rb +1 -1
- data/lib/twitter/error/already_posted.rb +10 -0
- data/lib/twitter/error/already_retweeted.rb +1 -1
- data/lib/twitter/error/bad_gateway.rb +2 -3
- data/lib/twitter/error/bad_request.rb +2 -2
- data/lib/twitter/error/forbidden.rb +2 -2
- data/lib/twitter/error/gateway_timeout.rb +2 -3
- data/lib/twitter/error/internal_server_error.rb +2 -3
- data/lib/twitter/error/not_acceptable.rb +2 -2
- data/lib/twitter/error/not_found.rb +2 -2
- data/lib/twitter/error/service_unavailable.rb +2 -3
- data/lib/twitter/error/too_many_requests.rb +2 -2
- data/lib/twitter/error/unauthorized.rb +2 -2
- data/lib/twitter/error/unprocessable_entity.rb +2 -2
- data/lib/twitter/error.rb +65 -14
- data/lib/twitter/factory.rb +13 -12
- data/lib/twitter/geo.rb +2 -7
- data/lib/twitter/geo_factory.rb +11 -7
- data/lib/twitter/geo_results.rb +40 -0
- data/lib/twitter/identity.rb +4 -34
- data/lib/twitter/list.rb +21 -4
- data/lib/twitter/media/photo.rb +6 -4
- data/lib/twitter/media_factory.rb +11 -7
- data/lib/twitter/null_object.rb +25 -0
- data/lib/twitter/oembed.rb +3 -2
- data/lib/twitter/place.rb +15 -15
- data/lib/twitter/profile_banner.rb +3 -2
- data/lib/twitter/rate_limit.rb +4 -17
- data/lib/twitter/relationship.rb +2 -19
- data/lib/twitter/rest/api/direct_messages.rb +138 -0
- data/lib/twitter/rest/api/favorites.rb +115 -0
- data/lib/twitter/rest/api/friends_and_followers.rb +287 -0
- data/lib/twitter/rest/api/help.rb +58 -0
- data/lib/twitter/rest/api/lists.rb +498 -0
- data/lib/twitter/rest/api/oauth.rb +62 -0
- data/lib/twitter/rest/api/places_and_geo.rb +86 -0
- data/lib/twitter/rest/api/saved_searches.rb +93 -0
- data/lib/twitter/rest/api/search.rb +37 -0
- data/lib/twitter/rest/api/spam_reporting.rb +29 -0
- data/lib/twitter/rest/api/suggested_users.rb +51 -0
- data/lib/twitter/rest/api/timelines.rb +202 -0
- data/lib/twitter/rest/api/trends.rb +58 -0
- data/lib/twitter/rest/api/tweets.rb +291 -0
- data/lib/twitter/rest/api/undocumented.rb +52 -0
- data/lib/twitter/rest/api/users.rb +383 -0
- data/lib/twitter/rest/api/utils.rb +246 -0
- data/lib/twitter/rest/client.rb +175 -0
- data/lib/twitter/rest/request/multipart_with_file.rb +36 -0
- data/lib/twitter/rest/response/parse_error_json.rb +15 -0
- data/lib/twitter/rest/response/parse_json.rb +31 -0
- data/lib/twitter/{response → rest/response}/raise_error.rb +8 -11
- data/lib/twitter/search_results.rb +37 -21
- data/lib/twitter/settings.rb +1 -6
- data/lib/twitter/size.rb +2 -15
- data/lib/twitter/streaming/client.rb +89 -0
- data/lib/twitter/streaming/connection.rb +22 -0
- data/lib/twitter/streaming/event.rb +35 -0
- data/lib/twitter/streaming/friend_list.rb +13 -0
- data/lib/twitter/streaming/message_parser.rb +18 -0
- data/lib/twitter/streaming/response.rb +34 -0
- data/lib/twitter/suggestion.rb +5 -8
- data/lib/twitter/token.rb +11 -1
- data/lib/twitter/trend.rb +4 -8
- data/lib/twitter/trend_results.rb +65 -0
- data/lib/twitter/tweet.rb +43 -92
- data/lib/twitter/user.rb +72 -47
- data/lib/twitter/version.rb +4 -4
- data/lib/twitter.rb +4 -39
- data/spec/fixtures/already_posted.json +1 -0
- data/spec/fixtures/ids_list.json +1 -1
- data/spec/fixtures/ids_list2.json +1 -1
- data/spec/fixtures/request_token.txt +6 -0
- data/spec/fixtures/search.json +1 -1
- data/spec/fixtures/search_malformed.json +1 -1
- data/spec/fixtures/track_streaming.json +3 -0
- data/spec/fixtures/track_streaming_user.json +5 -0
- data/spec/helper.rb +8 -13
- data/spec/twitter/base_spec.rb +13 -103
- data/spec/twitter/basic_user_spec.rb +3 -3
- data/spec/twitter/configuration_spec.rb +1 -1
- data/spec/twitter/cursor_spec.rb +17 -35
- data/spec/twitter/direct_message_spec.rb +44 -11
- data/spec/twitter/entity/uri_spec.rb +75 -0
- data/spec/twitter/error_spec.rb +59 -11
- data/spec/twitter/geo/point_spec.rb +6 -6
- data/spec/twitter/geo/polygon_spec.rb +5 -5
- data/spec/twitter/geo_factory_spec.rb +4 -4
- data/spec/twitter/geo_results_spec.rb +35 -0
- data/spec/twitter/geo_spec.rb +6 -6
- data/spec/twitter/identifiable_spec.rb +5 -26
- data/spec/twitter/list_spec.rb +54 -11
- data/spec/twitter/media/photo_spec.rb +122 -6
- data/spec/twitter/media_factory_spec.rb +3 -3
- data/spec/twitter/null_object_spec.rb +27 -0
- data/spec/twitter/oembed_spec.rb +69 -45
- data/spec/twitter/place_spec.rb +84 -28
- data/spec/twitter/profile_banner_spec.rb +1 -1
- data/spec/twitter/rate_limit_spec.rb +8 -25
- data/spec/twitter/relationship_spec.rb +26 -12
- data/spec/twitter/{api → rest/api}/direct_messages_spec.rb +28 -15
- data/spec/twitter/{api → rest/api}/favorites_spec.rb +80 -7
- data/spec/twitter/{api → rest/api}/friends_and_followers_spec.rb +121 -152
- data/spec/twitter/{api → rest/api}/geo_spec.rb +9 -23
- data/spec/twitter/{api → rest/api}/help_spec.rb +6 -6
- data/spec/twitter/{api → rest/api}/lists_spec.rb +116 -95
- data/spec/twitter/{api → rest/api}/oauth_spec.rb +21 -10
- data/spec/twitter/{api → rest/api}/saved_searches_spec.rb +13 -13
- data/spec/twitter/{api → rest/api}/search_spec.rb +8 -9
- data/spec/twitter/{api → rest/api}/spam_reporting_spec.rb +3 -3
- data/spec/twitter/{api → rest/api}/suggested_users_spec.rb +5 -5
- data/spec/twitter/{api → rest/api}/timelines_spec.rb +9 -9
- data/spec/twitter/{api → rest/api}/trends_spec.rb +6 -6
- data/spec/twitter/rest/api/tweets_spec.rb +503 -0
- data/spec/twitter/{api → rest/api}/undocumented_spec.rb +19 -45
- data/spec/twitter/{api → rest/api}/users_spec.rb +64 -39
- data/spec/twitter/rest/client_spec.rb +193 -0
- data/spec/twitter/saved_search_spec.rb +14 -3
- data/spec/twitter/search_results_spec.rb +32 -45
- data/spec/twitter/settings_spec.rb +17 -6
- data/spec/twitter/size_spec.rb +5 -15
- data/spec/twitter/source_user_spec.rb +3 -3
- data/spec/twitter/streaming/client_spec.rb +92 -0
- data/spec/twitter/streaming/event_spec.rb +45 -0
- data/spec/twitter/suggestion_spec.rb +5 -15
- data/spec/twitter/target_user_spec.rb +3 -3
- data/spec/twitter/token_spec.rb +16 -0
- data/spec/twitter/trend_results_spec.rb +89 -0
- data/spec/twitter/trend_spec.rb +26 -13
- data/spec/twitter/tweet_spec.rb +137 -124
- data/spec/twitter/user_spec.rb +139 -80
- data/spec/twitter_spec.rb +0 -119
- data/twitter.gemspec +12 -6
- data.tar.gz.sig +0 -0
- metadata +197 -138
- metadata.gz.sig +0 -0
- data/lib/twitter/action/favorite.rb +0 -19
- data/lib/twitter/action/follow.rb +0 -30
- data/lib/twitter/action/list_member_added.rb +0 -39
- data/lib/twitter/action/mention.rb +0 -46
- data/lib/twitter/action/reply.rb +0 -27
- data/lib/twitter/action/retweet.rb +0 -27
- data/lib/twitter/action/tweet.rb +0 -20
- data/lib/twitter/action_factory.rb +0 -22
- data/lib/twitter/api/arguments.rb +0 -13
- data/lib/twitter/api/direct_messages.rb +0 -148
- data/lib/twitter/api/favorites.rb +0 -126
- data/lib/twitter/api/friends_and_followers.rb +0 -334
- data/lib/twitter/api/help.rb +0 -64
- data/lib/twitter/api/lists.rb +0 -618
- data/lib/twitter/api/oauth.rb +0 -44
- data/lib/twitter/api/places_and_geo.rb +0 -121
- data/lib/twitter/api/saved_searches.rb +0 -99
- data/lib/twitter/api/search.rb +0 -37
- data/lib/twitter/api/spam_reporting.rb +0 -30
- data/lib/twitter/api/suggested_users.rb +0 -55
- data/lib/twitter/api/timelines.rb +0 -214
- data/lib/twitter/api/trends.rb +0 -63
- data/lib/twitter/api/tweets.rb +0 -304
- data/lib/twitter/api/undocumented.rb +0 -97
- data/lib/twitter/api/users.rb +0 -439
- data/lib/twitter/api/utils.rb +0 -187
- data/lib/twitter/configurable.rb +0 -96
- data/lib/twitter/default.rb +0 -102
- data/lib/twitter/entity/url.rb +0 -9
- data/lib/twitter/error/client_error.rb +0 -35
- data/lib/twitter/error/decode_error.rb +0 -9
- data/lib/twitter/error/identity_map_key_error.rb +0 -9
- data/lib/twitter/error/server_error.rb +0 -28
- data/lib/twitter/exceptable.rb +0 -36
- data/lib/twitter/identity_map.rb +0 -22
- data/lib/twitter/request/multipart_with_file.rb +0 -34
- data/lib/twitter/response/parse_json.rb +0 -25
- data/spec/fixtures/about_me.json +0 -1
- data/spec/fixtures/activity_summary.json +0 -1
- data/spec/fixtures/bad_gateway.json +0 -1
- data/spec/fixtures/bad_request.json +0 -1
- data/spec/fixtures/by_friends.json +0 -1
- data/spec/fixtures/end_session.json +0 -1
- data/spec/fixtures/forbidden.json +0 -1
- data/spec/fixtures/internal_server_error.json +0 -1
- data/spec/fixtures/not_acceptable.json +0 -1
- data/spec/fixtures/phoenix_search.phoenix +0 -1
- data/spec/fixtures/resolve.json +0 -1
- data/spec/fixtures/service_unavailable.json +0 -1
- data/spec/fixtures/totals.json +0 -1
- data/spec/fixtures/trends.json +0 -1
- data/spec/fixtures/unauthorized.json +0 -1
- data/spec/fixtures/video_facets.json +0 -1
- data/spec/twitter/action/favorite_spec.rb +0 -29
- data/spec/twitter/action/follow_spec.rb +0 -29
- data/spec/twitter/action/list_member_added_spec.rb +0 -41
- data/spec/twitter/action/mention_spec.rb +0 -52
- data/spec/twitter/action/reply_spec.rb +0 -41
- data/spec/twitter/action/retweet_spec.rb +0 -41
- data/spec/twitter/action_factory_spec.rb +0 -35
- data/spec/twitter/action_spec.rb +0 -16
- data/spec/twitter/api/tweets_spec.rb +0 -285
- data/spec/twitter/client_spec.rb +0 -223
- data/spec/twitter/error/client_error_spec.rb +0 -23
- data/spec/twitter/error/server_error_spec.rb +0 -20
data/lib/twitter/token.rb
CHANGED
|
@@ -2,6 +2,16 @@ require 'twitter/base'
|
|
|
2
2
|
|
|
3
3
|
module Twitter
|
|
4
4
|
class Token < Twitter::Base
|
|
5
|
-
attr_reader :
|
|
5
|
+
attr_reader :access_token, :token_type
|
|
6
|
+
alias to_s access_token
|
|
7
|
+
|
|
8
|
+
BEARER_TYPE = "bearer"
|
|
9
|
+
|
|
10
|
+
# @return [Boolean]
|
|
11
|
+
def bearer?
|
|
12
|
+
@attrs[:token_type] == BEARER_TYPE
|
|
13
|
+
end
|
|
14
|
+
memoize :bearer?
|
|
15
|
+
|
|
6
16
|
end
|
|
7
17
|
end
|
data/lib/twitter/trend.rb
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
+
require 'equalizer'
|
|
1
2
|
require 'twitter/base'
|
|
2
3
|
|
|
3
4
|
module Twitter
|
|
4
5
|
class Trend < Twitter::Base
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# @return [Boolean]
|
|
9
|
-
def ==(other)
|
|
10
|
-
super || attr_equal(:name, other) || attrs_equal(other)
|
|
11
|
-
end
|
|
12
|
-
|
|
6
|
+
include Equalizer.new(:name)
|
|
7
|
+
attr_reader :events, :name, :promoted_content, :query
|
|
8
|
+
uri_attr_reader :uri
|
|
13
9
|
end
|
|
14
10
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'twitter/creatable'
|
|
2
|
+
require 'twitter/enumerable'
|
|
3
|
+
require 'memoizable'
|
|
4
|
+
require 'twitter/null_object'
|
|
5
|
+
|
|
6
|
+
module Twitter
|
|
7
|
+
class TrendResults
|
|
8
|
+
include Twitter::Creatable
|
|
9
|
+
include Twitter::Enumerable
|
|
10
|
+
include Memoizable
|
|
11
|
+
attr_reader :attrs
|
|
12
|
+
alias to_h attrs
|
|
13
|
+
alias to_hash attrs
|
|
14
|
+
alias to_hsh attrs
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
|
|
18
|
+
# Construct a new TrendResults object from a response hash
|
|
19
|
+
#
|
|
20
|
+
# @param response [Hash]
|
|
21
|
+
# @return [Twitter::Base]
|
|
22
|
+
def from_response(response={})
|
|
23
|
+
new(response[:body].first)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Initializes a new TrendResults object
|
|
29
|
+
#
|
|
30
|
+
# @param attrs [Hash]
|
|
31
|
+
# @return [Twitter::TrendResults]
|
|
32
|
+
def initialize(attrs={})
|
|
33
|
+
@attrs = attrs
|
|
34
|
+
@collection = Array(@attrs[:trends]).map do |trend|
|
|
35
|
+
Trend.new(trend)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Time when the object was created on Twitter
|
|
40
|
+
#
|
|
41
|
+
# @return [Time]
|
|
42
|
+
def as_of
|
|
43
|
+
Time.parse(@attrs[:as_of]) if @attrs[:as_of]
|
|
44
|
+
end
|
|
45
|
+
memoize :as_of
|
|
46
|
+
|
|
47
|
+
def as_of?
|
|
48
|
+
!!@attrs[:as_of]
|
|
49
|
+
end
|
|
50
|
+
memoize :as_of?
|
|
51
|
+
|
|
52
|
+
# @return [Twitter::Place, NullObject]
|
|
53
|
+
def location
|
|
54
|
+
location? ? Place.new(@attrs[:locations].first) : NullObject.new
|
|
55
|
+
end
|
|
56
|
+
memoize :location
|
|
57
|
+
|
|
58
|
+
# @return [Boolean]
|
|
59
|
+
def location?
|
|
60
|
+
!@attrs[:locations].nil? && !@attrs[:locations].first.nil?
|
|
61
|
+
end
|
|
62
|
+
memoize :location?
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/twitter/tweet.rb
CHANGED
|
@@ -1,145 +1,96 @@
|
|
|
1
|
-
require 'forwardable'
|
|
2
1
|
require 'twitter/creatable'
|
|
3
|
-
require 'twitter/exceptable'
|
|
4
|
-
require 'twitter/identity'
|
|
5
2
|
|
|
6
3
|
module Twitter
|
|
7
4
|
class Tweet < Twitter::Identity
|
|
8
|
-
extend Forwardable
|
|
9
5
|
include Twitter::Creatable
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
:
|
|
13
|
-
:in_reply_to_status_id, :in_reply_to_user_id, :lang, :repliers,
|
|
14
|
-
:retweeted, :retweeters, :source, :text, :to_user, :to_user_id,
|
|
15
|
-
:to_user_name, :truncated
|
|
16
|
-
alias in_reply_to_tweet_id in_reply_to_status_id
|
|
6
|
+
attr_reader :favorite_count, :favorited, :in_reply_to_screen_name,
|
|
7
|
+
:in_reply_to_attrs_id, :in_reply_to_status_id, :in_reply_to_user_id,
|
|
8
|
+
:lang, :retweet_count, :retweeted, :source, :text, :truncated
|
|
17
9
|
alias favorites_count favorite_count
|
|
18
|
-
alias
|
|
19
|
-
alias
|
|
20
|
-
alias
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
alias favoriters_count favorite_count
|
|
11
|
+
alias in_reply_to_tweet_id in_reply_to_status_id
|
|
12
|
+
alias retweeters_count retweet_count
|
|
13
|
+
object_attr_reader :GeoFactory, :geo
|
|
14
|
+
object_attr_reader :Metadata, :metadata
|
|
15
|
+
object_attr_reader :Place, :place
|
|
16
|
+
object_attr_reader :Tweet, :retweeted_status
|
|
17
|
+
alias retweet retweeted_status
|
|
18
|
+
alias retweeted_tweet retweeted_status
|
|
19
|
+
alias retweet? retweeted_status?
|
|
20
|
+
alias retweeted_tweet? retweeted_status?
|
|
21
|
+
object_attr_reader :User, :user, :status
|
|
25
22
|
|
|
26
23
|
# @return [Boolean]
|
|
27
24
|
def entities?
|
|
28
|
-
!@attrs[:entities].nil?
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @return [Integer]
|
|
32
|
-
def favoriters_count
|
|
33
|
-
favoriters_count = @attrs[:favoriters_count]
|
|
34
|
-
favoriters_count.to_i if favoriters_count
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# @return [String]
|
|
38
|
-
def from_user
|
|
39
|
-
@attrs[:from_user] || user && user.screen_name
|
|
25
|
+
!@attrs[:entities].nil? && @attrs[:entities].any?{|_, array| !array.empty?}
|
|
40
26
|
end
|
|
27
|
+
memoize :entities?
|
|
41
28
|
|
|
42
29
|
def filter_level
|
|
43
30
|
@attrs[:filter_level] || "none"
|
|
44
31
|
end
|
|
32
|
+
memoize :filter_level
|
|
45
33
|
|
|
46
34
|
# @return [String]
|
|
47
35
|
# @note May be > 140 characters.
|
|
48
36
|
def full_text
|
|
49
|
-
if retweeted_status
|
|
37
|
+
if retweeted_status?
|
|
50
38
|
prefix = text[/\A(RT @[a-z0-9_]{1,20}: )/i, 1]
|
|
51
39
|
[prefix, retweeted_status.text].compact.join
|
|
52
40
|
else
|
|
53
41
|
text
|
|
54
42
|
end
|
|
55
43
|
end
|
|
56
|
-
|
|
57
|
-
# @return [Twitter::Geo]
|
|
58
|
-
def geo
|
|
59
|
-
@geo ||= Twitter::GeoFactory.fetch_or_new(@attrs[:geo])
|
|
60
|
-
end
|
|
44
|
+
memoize :full_text
|
|
61
45
|
|
|
62
46
|
# @note Must include entities in your request for this method to work
|
|
63
47
|
# @return [Array<Twitter::Entity::Hashtag>]
|
|
64
48
|
def hashtags
|
|
65
|
-
|
|
49
|
+
entities(Entity::Hashtag, :hashtags)
|
|
66
50
|
end
|
|
51
|
+
memoize :hashtags
|
|
67
52
|
|
|
68
53
|
# @note Must include entities in your request for this method to work
|
|
69
54
|
# @return [Array<Twitter::Media>]
|
|
70
55
|
def media
|
|
71
|
-
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# @return [Twitter::Metadata]
|
|
75
|
-
def metadata
|
|
76
|
-
@metadata ||= Twitter::Metadata.fetch_or_new(@attrs[:metadata])
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# @return [Twitter::Place]
|
|
80
|
-
def place
|
|
81
|
-
@place ||= Twitter::Place.fetch_or_new(@attrs[:place])
|
|
56
|
+
entities(MediaFactory, :media)
|
|
82
57
|
end
|
|
83
|
-
|
|
84
|
-
# @return [Integer]
|
|
85
|
-
def repliers_count
|
|
86
|
-
repliers_count = @attrs[:repliers_count]
|
|
87
|
-
repliers_count.to_i if repliers_count
|
|
88
|
-
end
|
|
89
|
-
alias reply_count repliers_count
|
|
58
|
+
memoize :media
|
|
90
59
|
|
|
91
60
|
# @return [Boolean]
|
|
92
61
|
def reply?
|
|
93
|
-
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# @return [Boolean]
|
|
97
|
-
def retweet?
|
|
98
|
-
!!retweeted_status
|
|
62
|
+
!!@attrs[:in_reply_to_status_id]
|
|
99
63
|
end
|
|
100
|
-
|
|
101
|
-
# If this Tweet is a retweet, the original Tweet is available here.
|
|
102
|
-
#
|
|
103
|
-
# @return [Twitter::Tweet]
|
|
104
|
-
def retweeted_status
|
|
105
|
-
@retweeted_status ||= self.class.fetch_or_new(@attrs[:retweeted_status])
|
|
106
|
-
end
|
|
107
|
-
alias retweeted_tweet retweeted_status
|
|
108
|
-
alias retweet retweeted_status
|
|
109
|
-
|
|
110
|
-
# @return [String]
|
|
111
|
-
def retweeters_count
|
|
112
|
-
retweeters_count = (@attrs[:retweet_count] || @attrs[:retweeters_count])
|
|
113
|
-
retweeters_count.to_i if retweeters_count
|
|
114
|
-
end
|
|
115
|
-
alias retweet_count retweeters_count
|
|
64
|
+
memoize :reply?
|
|
116
65
|
|
|
117
66
|
# @note Must include entities in your request for this method to work
|
|
118
67
|
# @return [Array<Twitter::Entity::Symbol>]
|
|
119
68
|
def symbols
|
|
120
|
-
|
|
69
|
+
entities(Entity::Symbol, :symbols)
|
|
121
70
|
end
|
|
71
|
+
memoize :symbols
|
|
122
72
|
|
|
123
|
-
# @
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
@urls ||= entities(Twitter::Entity::Url, :urls)
|
|
73
|
+
# @return [String] The URL to the tweet.
|
|
74
|
+
def uri
|
|
75
|
+
URI.parse("https://twitter.com/#{user.screen_name}/status/#{id}")
|
|
127
76
|
end
|
|
77
|
+
memoize :uri
|
|
78
|
+
alias url uri
|
|
128
79
|
|
|
129
|
-
# @
|
|
130
|
-
|
|
131
|
-
|
|
80
|
+
# @note Must include entities in your request for this method to work
|
|
81
|
+
# @return [Array<Twitter::Entity::URI>]
|
|
82
|
+
def uris
|
|
83
|
+
entities(Entity::URI, :urls)
|
|
132
84
|
end
|
|
85
|
+
memoize :uris
|
|
86
|
+
alias urls uris
|
|
133
87
|
|
|
134
88
|
# @note Must include entities in your request for this method to work
|
|
135
89
|
# @return [Array<Twitter::Entity::UserMention>]
|
|
136
90
|
def user_mentions
|
|
137
|
-
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def user?
|
|
141
|
-
!@attrs[:user].nil?
|
|
91
|
+
entities(Entity::UserMention, :user_mentions)
|
|
142
92
|
end
|
|
93
|
+
memoize :user_mentions
|
|
143
94
|
|
|
144
95
|
private
|
|
145
96
|
|
|
@@ -148,10 +99,10 @@ module Twitter
|
|
|
148
99
|
def entities(klass, key)
|
|
149
100
|
if entities?
|
|
150
101
|
Array(@attrs[:entities][key.to_sym]).map do |entity|
|
|
151
|
-
klass.
|
|
102
|
+
klass.new(entity)
|
|
152
103
|
end
|
|
153
104
|
else
|
|
154
|
-
warn "#{Kernel.caller.first}: To get #{key.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class
|
|
105
|
+
warn "#{Kernel.caller.first}: To get #{key.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class}."
|
|
155
106
|
[]
|
|
156
107
|
end
|
|
157
108
|
end
|
data/lib/twitter/user.rb
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
require 'twitter/basic_user'
|
|
2
2
|
require 'twitter/creatable'
|
|
3
|
-
require 'twitter/exceptable'
|
|
4
3
|
|
|
5
4
|
module Twitter
|
|
6
5
|
class User < Twitter::BasicUser
|
|
7
6
|
PROFILE_IMAGE_SUFFIX_REGEX = /_normal(\.gif|\.jpe?g|\.png)$/i
|
|
7
|
+
PREDICATE_URI_METHOD_REGEX = /_uri\?$/
|
|
8
8
|
include Twitter::Creatable
|
|
9
|
-
include Twitter::Exceptable
|
|
10
9
|
attr_reader :connections, :contributors_enabled, :default_profile,
|
|
11
10
|
:default_profile_image, :description, :favourites_count,
|
|
12
11
|
:follow_request_sent, :followers_count, :friends_count, :geo_enabled,
|
|
@@ -16,102 +15,128 @@ module Twitter
|
|
|
16
15
|
:profile_link_color, :profile_sidebar_border_color,
|
|
17
16
|
:profile_sidebar_fill_color, :profile_text_color,
|
|
18
17
|
:profile_use_background_image, :protected, :statuses_count, :time_zone,
|
|
19
|
-
:
|
|
20
|
-
alias favorite_count favourites_count
|
|
21
|
-
alias favoriters_count favourites_count
|
|
18
|
+
:utc_offset, :verified
|
|
22
19
|
alias favorites_count favourites_count
|
|
23
|
-
|
|
24
|
-
alias
|
|
25
|
-
alias
|
|
26
|
-
alias
|
|
27
|
-
alias status_count statuses_count
|
|
28
|
-
alias translator is_translator
|
|
29
|
-
alias translator? is_translator?
|
|
30
|
-
alias tweet_count statuses_count
|
|
20
|
+
remove_method :favourites_count
|
|
21
|
+
alias profile_background_image_uri profile_background_image_url
|
|
22
|
+
alias profile_background_image_uri_https profile_background_image_url_https
|
|
23
|
+
alias translator? is_translator
|
|
31
24
|
alias tweets_count statuses_count
|
|
32
|
-
|
|
33
|
-
alias
|
|
25
|
+
object_attr_reader :Tweet, :status, :user
|
|
26
|
+
alias tweet status
|
|
27
|
+
alias tweet? status?
|
|
28
|
+
alias tweeted? status?
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
class << self
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def alias_predicate_uri_methods(method)
|
|
35
|
+
for replacement in %w(_url? _uri_https? _url_https?)
|
|
36
|
+
alias_method_sub(method, PREDICATE_URI_METHOD_REGEX, replacement)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def alias_method_sub(method, pattern, replacement)
|
|
41
|
+
alias_method(method.to_s.sub(pattern, replacement).to_sym, method)
|
|
39
42
|
end
|
|
43
|
+
|
|
40
44
|
end
|
|
41
45
|
|
|
46
|
+
# @return [Array<Twitter::Entity::URI>]
|
|
47
|
+
def description_uris
|
|
48
|
+
Array(@attrs[:entities][:description][:urls]).map do |entity|
|
|
49
|
+
Entity::URI.new(entity)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
memoize :description_uris
|
|
53
|
+
alias description_urls description_uris
|
|
54
|
+
|
|
42
55
|
# Return the URL to the user's profile banner image
|
|
43
56
|
#
|
|
44
57
|
# @param size [String, Symbol] The size of the image. Must be one of: 'mobile', 'mobile_retina', 'web', 'web_retina', 'ipad', or 'ipad_retina'
|
|
45
58
|
# @return [String]
|
|
46
|
-
def
|
|
47
|
-
|
|
59
|
+
def profile_banner_uri(size=:web)
|
|
60
|
+
parse_encoded_uri(insecure_uri([@attrs[:profile_banner_url], size].join('/'))) if @attrs[:profile_banner_url]
|
|
48
61
|
end
|
|
62
|
+
alias profile_banner_url profile_banner_uri
|
|
49
63
|
|
|
50
64
|
# Return the secure URL to the user's profile banner image
|
|
51
65
|
#
|
|
52
66
|
# @param size [String, Symbol] The size of the image. Must be one of: 'mobile', 'mobile_retina', 'web', 'web_retina', 'ipad', or 'ipad_retina'
|
|
53
67
|
# @return [String]
|
|
54
|
-
def
|
|
55
|
-
[@attrs[:profile_banner_url], size].join('/') if profile_banner_url
|
|
68
|
+
def profile_banner_uri_https(size=:web)
|
|
69
|
+
parse_encoded_uri([@attrs[:profile_banner_url], size].join('/')) if @attrs[:profile_banner_url]
|
|
56
70
|
end
|
|
71
|
+
alias profile_banner_url_https profile_banner_uri_https
|
|
57
72
|
|
|
58
|
-
|
|
59
|
-
|
|
73
|
+
# @return [Boolean]
|
|
74
|
+
def profile_banner_uri?
|
|
75
|
+
!!@attrs[:profile_banner_url]
|
|
60
76
|
end
|
|
61
|
-
|
|
77
|
+
memoize :profile_banner_uri?
|
|
78
|
+
alias_predicate_uri_methods :profile_banner_uri?
|
|
62
79
|
|
|
63
80
|
# Return the URL to the user's profile image
|
|
64
81
|
#
|
|
65
82
|
# @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
|
|
66
83
|
# @return [String]
|
|
67
|
-
def
|
|
68
|
-
|
|
84
|
+
def profile_image_uri(size=:normal)
|
|
85
|
+
parse_encoded_uri(insecure_uri(profile_image_uri_https(size))) if @attrs[:profile_image_url_https]
|
|
69
86
|
end
|
|
87
|
+
alias profile_image_url profile_image_uri
|
|
70
88
|
|
|
71
89
|
# Return the secure URL to the user's profile image
|
|
72
90
|
#
|
|
73
91
|
# @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
|
|
74
92
|
# @return [String]
|
|
75
|
-
def
|
|
93
|
+
def profile_image_uri_https(size=:normal)
|
|
76
94
|
# The profile image URL comes in looking like like this:
|
|
77
95
|
# https://a0.twimg.com/profile_images/1759857427/image1326743606_normal.png
|
|
78
96
|
# It can be converted to any of the following sizes:
|
|
79
97
|
# https://a0.twimg.com/profile_images/1759857427/image1326743606.png
|
|
80
98
|
# https://a0.twimg.com/profile_images/1759857427/image1326743606_mini.png
|
|
81
99
|
# https://a0.twimg.com/profile_images/1759857427/image1326743606_bigger.png
|
|
82
|
-
|
|
100
|
+
parse_encoded_uri(@attrs[:profile_image_url_https].sub(PROFILE_IMAGE_SUFFIX_REGEX, profile_image_suffix(size))) if @attrs[:profile_image_url_https]
|
|
83
101
|
end
|
|
102
|
+
alias profile_image_url_https profile_image_uri_https
|
|
84
103
|
|
|
85
|
-
def
|
|
86
|
-
|
|
104
|
+
def profile_image_uri?
|
|
105
|
+
!!@attrs[:profile_image_url_https]
|
|
87
106
|
end
|
|
88
|
-
|
|
107
|
+
memoize :profile_image_uri?
|
|
108
|
+
alias_predicate_uri_methods :profile_image_uri?
|
|
89
109
|
|
|
90
|
-
# @return [
|
|
91
|
-
def
|
|
92
|
-
|
|
110
|
+
# @return [String] The URL to the user.
|
|
111
|
+
def uri
|
|
112
|
+
URI.parse("https://twitter.com/#{screen_name}")
|
|
93
113
|
end
|
|
114
|
+
memoize :uri
|
|
115
|
+
alias url uri
|
|
94
116
|
|
|
95
|
-
|
|
96
|
-
|
|
117
|
+
# @return [String] The URL to the user's website.
|
|
118
|
+
def website
|
|
119
|
+
URI.parse(@attrs[:url]) if @attrs[:url]
|
|
97
120
|
end
|
|
121
|
+
memoize :website
|
|
122
|
+
|
|
123
|
+
def website?
|
|
124
|
+
!!@attrs[:url]
|
|
125
|
+
end
|
|
126
|
+
memoize :website?
|
|
98
127
|
|
|
99
128
|
private
|
|
100
129
|
|
|
101
|
-
def
|
|
102
|
-
|
|
130
|
+
def parse_encoded_uri(uri)
|
|
131
|
+
URI.parse(URI.encode(uri))
|
|
103
132
|
end
|
|
104
133
|
|
|
105
|
-
def
|
|
106
|
-
|
|
134
|
+
def insecure_uri(uri)
|
|
135
|
+
uri.to_s.sub(/^https/i, 'http')
|
|
107
136
|
end
|
|
108
137
|
|
|
109
138
|
def profile_image_suffix(size)
|
|
110
|
-
|
|
111
|
-
"\\1"
|
|
112
|
-
else
|
|
113
|
-
"_#{size}\\1"
|
|
114
|
-
end
|
|
139
|
+
:original == size.to_sym ? "\\1" : "_#{size}\\1"
|
|
115
140
|
end
|
|
116
141
|
|
|
117
142
|
end
|
data/lib/twitter/version.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module Twitter
|
|
2
2
|
class Version
|
|
3
|
-
MAJOR =
|
|
4
|
-
MINOR =
|
|
5
|
-
PATCH =
|
|
6
|
-
PRE = nil
|
|
3
|
+
MAJOR = 5
|
|
4
|
+
MINOR = 0
|
|
5
|
+
PATCH = 0
|
|
6
|
+
PRE = nil
|
|
7
7
|
|
|
8
8
|
class << self
|
|
9
9
|
|
data/lib/twitter.rb
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
require 'twitter/action_factory'
|
|
2
|
-
require 'twitter/client'
|
|
3
|
-
require 'twitter/configurable'
|
|
4
1
|
require 'twitter/configuration'
|
|
5
2
|
require 'twitter/cursor'
|
|
6
|
-
require 'twitter/default'
|
|
7
3
|
require 'twitter/direct_message'
|
|
8
4
|
require 'twitter/entity'
|
|
9
5
|
require 'twitter/entity/hashtag'
|
|
10
6
|
require 'twitter/entity/symbol'
|
|
11
|
-
require 'twitter/entity/
|
|
7
|
+
require 'twitter/entity/uri'
|
|
12
8
|
require 'twitter/entity/user_mention'
|
|
13
9
|
require 'twitter/geo_factory'
|
|
14
10
|
require 'twitter/language'
|
|
@@ -20,47 +16,16 @@ require 'twitter/place'
|
|
|
20
16
|
require 'twitter/profile_banner'
|
|
21
17
|
require 'twitter/rate_limit'
|
|
22
18
|
require 'twitter/relationship'
|
|
19
|
+
require 'twitter/rest/client'
|
|
23
20
|
require 'twitter/saved_search'
|
|
24
21
|
require 'twitter/search_results'
|
|
25
22
|
require 'twitter/settings'
|
|
26
23
|
require 'twitter/size'
|
|
27
24
|
require 'twitter/source_user'
|
|
25
|
+
require 'twitter/streaming/client'
|
|
28
26
|
require 'twitter/suggestion'
|
|
29
27
|
require 'twitter/target_user'
|
|
30
28
|
require 'twitter/trend'
|
|
31
29
|
require 'twitter/tweet'
|
|
32
30
|
require 'twitter/user'
|
|
33
|
-
|
|
34
|
-
module Twitter
|
|
35
|
-
class << self
|
|
36
|
-
include Twitter::Configurable
|
|
37
|
-
|
|
38
|
-
# Delegate to a Twitter::Client
|
|
39
|
-
#
|
|
40
|
-
# @return [Twitter::Client]
|
|
41
|
-
def client
|
|
42
|
-
@client = Twitter::Client.new(options) unless defined?(@client) && @client.hash == options.hash
|
|
43
|
-
@client
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Has a client been initialized on the Twitter module
|
|
47
|
-
#
|
|
48
|
-
# @return [Boolean]
|
|
49
|
-
def client?
|
|
50
|
-
!!@client
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def respond_to_missing?(method_name, include_private=false); client.respond_to?(method_name, include_private); end if RUBY_VERSION >= "1.9"
|
|
54
|
-
def respond_to?(method_name, include_private=false); client.respond_to?(method_name, include_private) || super; end if RUBY_VERSION < "1.9"
|
|
55
|
-
|
|
56
|
-
private
|
|
57
|
-
|
|
58
|
-
def method_missing(method_name, *args, &block)
|
|
59
|
-
return super unless client.respond_to?(method_name)
|
|
60
|
-
client.send(method_name, *args, &block)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
Twitter.setup
|
|
31
|
+
require 'uri'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"errors":"Status is a duplicate"}
|
data/spec/fixtures/ids_list.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"previous_cursor":0,"next_cursor_str":"1305102810874389703","ids":[
|
|
1
|
+
{"previous_cursor":0,"next_cursor_str":"1305102810874389703","ids":[20009713,22469930,351223419],"previous_cursor_str":"0","next_cursor":1305102810874389703}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"previous_cursor":-1305101990888327757,"next_cursor_str":"0","ids":[
|
|
1
|
+
{"previous_cursor":-1305101990888327757,"next_cursor_str":"0","ids":[14100886,23621851,14509199],"previous_cursor_str":"-1305101990888327757","next_cursor":0}
|
data/spec/fixtures/search.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"statuses":[{"metadata":{"result_type":"recent","iso_language_code":"en"},"created_at":"Mon Sep 17 22:41:52 +0000 2012","id":247827742178021376,"id_str":"247827742178021376","text":"Bubble Mailer #freebandnames","source":"\u003ca href=\"http:\/\/tapbots.com\" rel=\"nofollow\"\u003eTweetbot 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,"user":{"id":671293,"id_str":"671293","name":"Richard Allen","screen_name":"richrad","location":"Kansas City","url":"http:\/\/richardallen.me","description":"Give me a break, Jeffery.","protected":false,"followers_count":174,"friends_count":273,"listed_count":2,"created_at":"Sat Jan 20 16:02:45 +0000 2007","favourites_count":383,"utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":false,"verified":false,"statuses_count":1370,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"0099B9","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_link_color":"0099B9","profile_sidebar_border_color":"5ED4DC","profile_sidebar_fill_color":"95E8EC","profile_text_color":"3C3940","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[{"text":"freebandnames","indices":[14,28]}],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}],"search_metadata":{"completed_in":0.029,"max_id":250126199840518145,"max_id_str":"250126199840518145","next_page":"?page=2&max_id=250126199840518145&q=%23freebandnames&rpp=4&include_entities=1&result_type=mixed","page":1,"query":"%23freebandnames","refresh_url":"?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1","
|
|
1
|
+
{"statuses":[{"metadata":{"result_type":"recent","iso_language_code":"en"},"created_at":"Mon Sep 17 22:41:52 +0000 2012","id":247827742178021376,"id_str":"247827742178021376","text":"Bubble Mailer #freebandnames","source":"\u003ca href=\"http:\/\/tapbots.com\" rel=\"nofollow\"\u003eTweetbot 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,"user":{"id":671293,"id_str":"671293","name":"Richard Allen","screen_name":"richrad","location":"Kansas City","url":"http:\/\/richardallen.me","description":"Give me a break, Jeffery.","protected":false,"followers_count":174,"friends_count":273,"listed_count":2,"created_at":"Sat Jan 20 16:02:45 +0000 2007","favourites_count":383,"utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":false,"verified":false,"statuses_count":1370,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"0099B9","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_link_color":"0099B9","profile_sidebar_border_color":"5ED4DC","profile_sidebar_fill_color":"95E8EC","profile_text_color":"3C3940","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[{"text":"freebandnames","indices":[14,28]}],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}],"search_metadata":{"completed_in":0.029,"max_id":250126199840518145,"max_id_str":"250126199840518145","next_page":"?page=2&max_id=250126199840518145&q=%23freebandnames&rpp=4&include_entities=1&result_type=mixed","page":1,"query":"%23freebandnames","refresh_url":"?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1","count":4,"since_id":24012619984051000,"since_id_str":"24012619984051000"}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"max_id":28857935752,"since_id":0,"refresh_url":"?since_id=28857935752&q=twitter","next_page":"?page=2&max_id=28857935752&q=twitter","
|
|
1
|
+
{"max_id":28857935752,"since_id":0,"refresh_url":"?since_id=28857935752&q=twitter","next_page":"?page=2&max_id=28857935752&q=twitter","count":15,"page":1,"completed_in":0.017349,"since_id_str":"0","max_id_str":"28857935752","query":"twitter"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"created_at":"Wed Apr 06 19:13:37 +0000 2011","id":55709764298092545,"id_str":"55709764298092545","text":"The problem with your code is that it's doing exactly what you told it to do.","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\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,"user":{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"San Francisco","description":"Write code. Not too much. Mostly Ruby.","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":2479,"friends_count":200,"listed_count":132,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":4421,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":8730,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/677717672\/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\/1349499693","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},"geo":{"type":"Point","coordinates":[37.78349999,-122.39362884]},"coordinates":{"type":"Point","coordinates":[-122.39362884,37.78349999]},"place":{"id":"5c92ab5379de3839","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/5c92ab5379de3839.json","place_type":"neighborhood","name":"South Beach","full_name":"South Beach, San Francisco","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-122.403482,37.777529],[-122.387436,37.777529],[-122.387436,37.794486],[-122.403482,37.794486]]]},"attributes":{}},"contributors":null,"retweet_count":316,"entities":{"hashtags":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}
|
|
2
|
+
{"created_at":"Wed Apr 06 19:13:37 +0000 2011","id":55709764298092545,"id_str":"55709764298092545","text":"The problem with your code is that it's doing exactly what you told it to do.","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\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,"user":{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"San Francisco","description":"Write code. Not too much. Mostly Ruby.","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":2479,"friends_count":200,"listed_count":132,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":4421,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":8730,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/677717672\/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\/1349499693","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},"geo":{"type":"Point","coordinates":[37.78349999,-122.39362884]},"coordinates":{"type":"Point","coordinates":[-122.39362884,37.78349999]},"place":{"id":"5c92ab5379de3839","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/5c92ab5379de3839.json","place_type":"neighborhood","name":"South Beach","full_name":"South Beach, San Francisco","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-122.403482,37.777529],[-122.387436,37.777529],[-122.387436,37.794486],[-122.403482,37.794486]]]},"attributes":{}},"contributors":null,"retweet_count":316,"entities":{"hashtags":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}
|
|
3
|
+
|