twitter 4.3.0 → 4.4.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/.yardopts +10 -0
- data/CHANGELOG.md +123 -110
- data/CONTRIBUTING.md +51 -0
- data/README.md +17 -2
- data/lib/twitter/api/direct_messages.rb +3 -6
- data/lib/twitter/api/favorites.rb +6 -13
- data/lib/twitter/api/friends_and_followers.rb +76 -8
- data/lib/twitter/api/lists.rb +65 -36
- data/lib/twitter/api/places_and_geo.rb +3 -3
- data/lib/twitter/api/saved_searches.rb +2 -2
- data/lib/twitter/api/spam_reporting.rb +2 -2
- data/lib/twitter/api/suggested_users.rb +1 -1
- data/lib/twitter/api/timelines.rb +12 -8
- data/lib/twitter/api/tweets.rb +8 -12
- data/lib/twitter/api/undocumented.rb +3 -3
- data/lib/twitter/api/users.rb +16 -10
- data/lib/twitter/api/utils.rb +109 -30
- data/lib/twitter/base.rb +15 -5
- data/lib/twitter/basic_user.rb +0 -1
- data/lib/twitter/client.rb +16 -37
- data/lib/twitter/core_ext/enumerable.rb +2 -2
- data/lib/twitter/default.rb +5 -8
- data/lib/twitter/exceptable.rb +36 -0
- data/lib/twitter/factory.rb +4 -4
- data/lib/twitter/list.rb +0 -1
- data/lib/twitter/request/multipart_with_file.rb +5 -7
- data/lib/twitter/search_results.rb +10 -6
- data/lib/twitter/settings.rb +0 -1
- data/lib/twitter/source_user.rb +0 -7
- data/lib/twitter/target_user.rb +0 -1
- data/lib/twitter/tweet.rb +15 -17
- data/lib/twitter/user.rb +4 -14
- data/lib/twitter/version.rb +4 -4
- data/spec/fixtures/followers_list.json +1 -0
- data/spec/fixtures/friends_list.json +1 -0
- data/spec/fixtures/ids_list.json +1 -1
- data/spec/fixtures/ids_list2.json +1 -1
- data/spec/helper.rb +9 -8
- data/spec/twitter/action_factory_spec.rb +1 -1
- data/spec/twitter/api/favorites_spec.rb +2 -2
- data/spec/twitter/api/friends_and_followers_spec.rb +102 -2
- data/spec/twitter/api/spam_reporting_spec.rb +2 -2
- data/spec/twitter/api/tweets_spec.rb +2 -2
- data/spec/twitter/api/users_spec.rb +107 -49
- data/spec/twitter/base_spec.rb +1 -1
- data/spec/twitter/client_spec.rb +4 -4
- data/spec/twitter/cursor_spec.rb +2 -2
- data/spec/twitter/error/client_error_spec.rb +16 -5
- data/spec/twitter/error/server_error_spec.rb +1 -1
- data/spec/twitter/error_spec.rb +2 -2
- data/spec/twitter/geo_factory_spec.rb +1 -1
- data/spec/twitter/identifiable_spec.rb +2 -2
- data/spec/twitter/media_factory_spec.rb +1 -1
- data/spec/twitter/search_results_spec.rb +11 -0
- data/spec/twitter/tweet_spec.rb +11 -0
- data/twitter.gemspec +3 -2
- metadata +190 -173
- data/lib/twitter/core_ext/array.rb +0 -7
- data/lib/twitter/core_ext/hash.rb +0 -100
- data/lib/twitter/core_ext/string.rb +0 -10
data/lib/twitter/basic_user.rb
CHANGED
data/lib/twitter/client.rb
CHANGED
@@ -27,7 +27,6 @@ module Twitter
|
|
27
27
|
# @note All methods have been separated into modules and follow the same grouping used in {http://dev.twitter.com/doc the Twitter API Documentation}.
|
28
28
|
# @see http://dev.twitter.com/pages/every_developer
|
29
29
|
class Client
|
30
|
-
include Twitter::API
|
31
30
|
include Twitter::API::DirectMessages
|
32
31
|
include Twitter::API::Favorites
|
33
32
|
include Twitter::API::FriendsAndFollowers
|
@@ -67,57 +66,37 @@ module Twitter
|
|
67
66
|
|
68
67
|
# Perform an HTTP POST request
|
69
68
|
def post(path, params={})
|
70
|
-
|
69
|
+
signature_params = params.values.any?{|value| value.respond_to?(:to_io)} ? {} : params
|
70
|
+
request(:post, path, params, signature_params)
|
71
71
|
end
|
72
72
|
|
73
|
-
# Perform an HTTP
|
73
|
+
# Perform an HTTP PUT request
|
74
74
|
def put(path, params={})
|
75
75
|
request(:put, path, params)
|
76
76
|
end
|
77
77
|
|
78
78
|
private
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
def connection
|
84
|
-
@connection ||= Faraday.new(@endpoint, @connection_options.merge(:builder => @middleware))
|
85
|
-
end
|
86
|
-
|
87
|
-
# Perform an HTTP request
|
88
|
-
#
|
89
|
-
# @raise [Twitter::Error::ClientError, Twitter::Error::DecodeError]
|
90
|
-
def request(method, path, params={})
|
91
|
-
uri = URI(@endpoint) unless uri.respond_to?(:host)
|
92
|
-
uri += path
|
93
|
-
request_headers = {}
|
94
|
-
if credentials?
|
95
|
-
authorization = auth_header(method, uri, params)
|
96
|
-
request_headers[:authorization] = authorization.to_s
|
97
|
-
end
|
98
|
-
connection.url_prefix = @endpoint
|
99
|
-
response = connection.run_request(method.to_sym, path, nil, request_headers) do |request|
|
100
|
-
unless params.empty?
|
101
|
-
case request.method
|
102
|
-
when :post, :put
|
103
|
-
request.body = params
|
104
|
-
else
|
105
|
-
request.params.update(params)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
yield request if block_given?
|
80
|
+
def request(method, path, params={}, signature_params=params)
|
81
|
+
connection.send(method.to_sym, path, params) do |request|
|
82
|
+
request.headers[:authorization] = auth_header(method.to_sym, path, signature_params).to_s
|
109
83
|
end.env
|
110
|
-
response
|
111
84
|
rescue Faraday::Error::ClientError
|
112
85
|
raise Twitter::Error::ClientError
|
113
86
|
rescue MultiJson::DecodeError
|
114
87
|
raise Twitter::Error::DecodeError
|
115
88
|
end
|
116
89
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
90
|
+
# Returns a Faraday::Connection object
|
91
|
+
#
|
92
|
+
# @return [Faraday::Connection]
|
93
|
+
def connection
|
94
|
+
@connection ||= Faraday.new(@endpoint, @connection_options.merge(:builder => @middleware))
|
95
|
+
end
|
96
|
+
|
97
|
+
def auth_header(method, path, params={})
|
98
|
+
uri = URI(@endpoint + path)
|
99
|
+
SimpleOAuth::Header.new(method, uri, params, credentials)
|
121
100
|
end
|
122
101
|
|
123
102
|
end
|
data/lib/twitter/default.rb
CHANGED
@@ -2,7 +2,6 @@ require 'faraday'
|
|
2
2
|
require 'twitter/configurable'
|
3
3
|
require 'twitter/error/client_error'
|
4
4
|
require 'twitter/error/server_error'
|
5
|
-
require 'twitter/identity_map'
|
6
5
|
require 'twitter/request/multipart_with_file'
|
7
6
|
require 'twitter/response/parse_json'
|
8
7
|
require 'twitter/response/raise_error'
|
@@ -10,7 +9,7 @@ require 'twitter/version'
|
|
10
9
|
|
11
10
|
module Twitter
|
12
11
|
module Default
|
13
|
-
ENDPOINT = 'https://api.twitter.com' unless defined? ENDPOINT
|
12
|
+
ENDPOINT = 'https://api.twitter.com' unless defined? Twitter::Default::ENDPOINT
|
14
13
|
CONNECTION_OPTIONS = {
|
15
14
|
:headers => {
|
16
15
|
:accept => 'application/json',
|
@@ -20,8 +19,8 @@ module Twitter
|
|
20
19
|
:raw => true,
|
21
20
|
:ssl => {:verify => false},
|
22
21
|
:timeout => 10,
|
23
|
-
} unless defined? CONNECTION_OPTIONS
|
24
|
-
IDENTITY_MAP = false unless defined? IDENTITY_MAP
|
22
|
+
} unless defined? Twitter::Default::CONNECTION_OPTIONS
|
23
|
+
IDENTITY_MAP = false unless defined? Twitter::Default::IDENTITY_MAP
|
25
24
|
MIDDLEWARE = Faraday::Builder.new do |builder|
|
26
25
|
# Convert file uploads to Faraday::UploadIO objects
|
27
26
|
builder.use Twitter::Request::MultipartWithFile
|
@@ -37,7 +36,7 @@ module Twitter
|
|
37
36
|
builder.use Twitter::Response::RaiseError, Twitter::Error::ServerError
|
38
37
|
# Set Faraday's HTTP adapter
|
39
38
|
builder.adapter Faraday.default_adapter
|
40
|
-
end
|
39
|
+
end unless defined? Twitter::Default::MIDDLEWARE
|
41
40
|
|
42
41
|
class << self
|
43
42
|
|
@@ -66,7 +65,7 @@ module Twitter
|
|
66
65
|
ENV['TWITTER_OAUTH_TOKEN_SECRET']
|
67
66
|
end
|
68
67
|
|
69
|
-
# @note This is configurable in case you want to use
|
68
|
+
# @note This is configurable in case you want to use a Twitter-compatible endpoint.
|
70
69
|
# @see http://status.net/wiki/Twitter-compatible_API
|
71
70
|
# @see http://en.blog.wordpress.com/2009/12/12/twitter-api/
|
72
71
|
# @see http://staff.tumblr.com/post/287703110/api
|
@@ -76,12 +75,10 @@ module Twitter
|
|
76
75
|
ENDPOINT
|
77
76
|
end
|
78
77
|
|
79
|
-
# @return [Hash]
|
80
78
|
def connection_options
|
81
79
|
CONNECTION_OPTIONS
|
82
80
|
end
|
83
81
|
|
84
|
-
# @return [Twitter::IdentityMap]
|
85
82
|
def identity_map
|
86
83
|
IDENTITY_MAP
|
87
84
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Twitter
|
2
|
+
module Exceptable
|
3
|
+
|
4
|
+
private
|
5
|
+
|
6
|
+
# Return a hash that includes everything but the given keys.
|
7
|
+
#
|
8
|
+
# @param klass [Class]
|
9
|
+
# @param hash [Hash]
|
10
|
+
# @param key1 [Symbol]
|
11
|
+
# @param key2 [Symbol]
|
12
|
+
def fetch_or_new_without_self(klass, hash, key1, key2)
|
13
|
+
klass.fetch_or_new(hash.dup[key1].merge(key2 => except(hash, key1))) unless hash[key1].nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return a hash that includes everything but the given keys.
|
17
|
+
#
|
18
|
+
# @param hash [Hash]
|
19
|
+
# @param key [Symbol]
|
20
|
+
# @return [Hash]
|
21
|
+
def except(hash, key)
|
22
|
+
except!(hash.dup, key)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Replaces the hash without the given keys.
|
26
|
+
#
|
27
|
+
# @param hash [Hash]
|
28
|
+
# @param key [Symbol]
|
29
|
+
# @return [Hash]
|
30
|
+
def except!(hash, key)
|
31
|
+
hash.delete(key)
|
32
|
+
hash
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/lib/twitter/factory.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'twitter/core_ext/string'
|
2
|
-
|
3
1
|
module Twitter
|
4
2
|
class Factory
|
5
3
|
|
@@ -10,8 +8,10 @@ module Twitter
|
|
10
8
|
# @return [Twitter::Action::Favorite, Twitter::Action::Follow, Twitter::Action::ListMemberAdded, Twitter::Action::Mention, Twitter::Action::Reply, Twitter::Action::Retweet]
|
11
9
|
def self.fetch_or_new(method, klass, attrs={})
|
12
10
|
return unless attrs
|
13
|
-
|
14
|
-
|
11
|
+
type = attrs.delete(method.to_sym)
|
12
|
+
if type
|
13
|
+
const_name = type.gsub(/\/(.?)/){"::#{$1.upcase}"}.gsub(/(?:^|_)(.)/){$1.upcase}
|
14
|
+
klass.const_get(const_name.to_sym).fetch_or_new(attrs)
|
15
15
|
else
|
16
16
|
raise ArgumentError, "argument must have :#{method} key"
|
17
17
|
end
|
data/lib/twitter/list.rb
CHANGED
@@ -10,14 +10,12 @@ module Twitter
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def call(env)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
env[:request_headers][CONTENT_TYPE] = self.class.mime_type
|
18
|
-
end
|
13
|
+
env[:body].each do |key, value|
|
14
|
+
if value.respond_to?(:to_io)
|
15
|
+
env[:body][key] = Faraday::UploadIO.new(value, mime_type(value.path), value.path)
|
16
|
+
env[:request_headers][CONTENT_TYPE] = self.class.mime_type
|
19
17
|
end
|
20
|
-
end
|
18
|
+
end if env[:body].is_a?(::Hash)
|
21
19
|
@app.call(env)
|
22
20
|
end
|
23
21
|
|
@@ -15,33 +15,37 @@ module Twitter
|
|
15
15
|
|
16
16
|
# @return [Float]
|
17
17
|
def completed_in
|
18
|
-
@attrs[:search_metadata][:completed_in]
|
18
|
+
@attrs[:search_metadata][:completed_in] if search_metadata?
|
19
19
|
end
|
20
20
|
|
21
21
|
# @return [Integer]
|
22
22
|
def max_id
|
23
|
-
@attrs[:search_metadata][:max_id]
|
23
|
+
@attrs[:search_metadata][:max_id] if search_metadata?
|
24
24
|
end
|
25
25
|
|
26
26
|
# @return [Integer]
|
27
27
|
def page
|
28
|
-
@attrs[:search_metadata][:page]
|
28
|
+
@attrs[:search_metadata][:page] if search_metadata?
|
29
29
|
end
|
30
30
|
|
31
31
|
# @return [String]
|
32
32
|
def query
|
33
|
-
@attrs[:search_metadata][:query]
|
33
|
+
@attrs[:search_metadata][:query] if search_metadata?
|
34
34
|
end
|
35
35
|
|
36
36
|
# @return [Integer]
|
37
37
|
def results_per_page
|
38
|
-
@attrs[:search_metadata][:results_per_page]
|
38
|
+
@attrs[:search_metadata][:results_per_page] if search_metadata?
|
39
39
|
end
|
40
40
|
alias rpp results_per_page
|
41
41
|
|
42
|
+
def search_metadata?
|
43
|
+
!@attrs[:search_metadata].nil?
|
44
|
+
end
|
45
|
+
|
42
46
|
# @return [Integer]
|
43
47
|
def since_id
|
44
|
-
@attrs[:search_metadata][:since_id]
|
48
|
+
@attrs[:search_metadata][:since_id] if search_metadata?
|
45
49
|
end
|
46
50
|
|
47
51
|
end
|
data/lib/twitter/settings.rb
CHANGED
data/lib/twitter/source_user.rb
CHANGED
@@ -4,12 +4,5 @@ module Twitter
|
|
4
4
|
class SourceUser < Twitter::BasicUser
|
5
5
|
attr_reader :all_replies, :blocking, :can_dm, :followed_by, :marked_spam,
|
6
6
|
:notifications_enabled, :want_retweets
|
7
|
-
alias all_replies? all_replies
|
8
|
-
alias blocking? blocking
|
9
|
-
alias can_dm? can_dm
|
10
|
-
alias followed_by? followed_by
|
11
|
-
alias marked_spam? marked_spam
|
12
|
-
alias notifications_enabled? notifications_enabled
|
13
|
-
alias want_retweets? want_retweets
|
14
7
|
end
|
15
8
|
end
|
data/lib/twitter/target_user.rb
CHANGED
data/lib/twitter/tweet.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'twitter/core_ext/hash'
|
2
1
|
require 'twitter/creatable'
|
3
2
|
require 'twitter/entity/hashtag'
|
4
3
|
require 'twitter/entity/url'
|
5
4
|
require 'twitter/entity/user_mention'
|
5
|
+
require 'twitter/exceptable'
|
6
6
|
require 'twitter/geo_factory'
|
7
7
|
require 'twitter/identity'
|
8
8
|
require 'twitter/media_factory'
|
@@ -13,18 +13,21 @@ require 'twitter/user'
|
|
13
13
|
module Twitter
|
14
14
|
class Tweet < Twitter::Identity
|
15
15
|
include Twitter::Creatable
|
16
|
+
include Twitter::Exceptable
|
16
17
|
attr_reader :favorited, :favoriters, :from_user_id, :from_user_name,
|
17
18
|
:in_reply_to_screen_name, :in_reply_to_attrs_id, :in_reply_to_status_id,
|
18
19
|
:in_reply_to_user_id, :iso_language_code, :profile_image_url,
|
19
20
|
:profile_image_url_https, :repliers, :retweeted, :retweeters, :source,
|
20
21
|
:text, :to_user, :to_user_id, :to_user_name, :truncated
|
21
22
|
alias in_reply_to_tweet_id in_reply_to_status_id
|
22
|
-
alias favorited? favorited
|
23
23
|
alias favourited favorited
|
24
|
-
alias favourited? favorited
|
24
|
+
alias favourited? favorited?
|
25
25
|
alias favouriters favoriters
|
26
|
-
|
27
|
-
|
26
|
+
|
27
|
+
# @return [Boolean]
|
28
|
+
def entities?
|
29
|
+
!@attrs[:entities].nil?
|
30
|
+
end
|
28
31
|
|
29
32
|
# @return [Integer]
|
30
33
|
def favoriters_count
|
@@ -121,7 +124,7 @@ module Twitter
|
|
121
124
|
|
122
125
|
# @return [Twitter::User]
|
123
126
|
def user
|
124
|
-
@user ||= Twitter::User
|
127
|
+
@user ||= fetch_or_new_without_self(Twitter::User, @attrs, :user, :status)
|
125
128
|
end
|
126
129
|
|
127
130
|
# @note Must include entities in your request for this method to work
|
@@ -130,30 +133,25 @@ module Twitter
|
|
130
133
|
@user_mentions ||= entities(Twitter::Entity::UserMention, :user_mentions)
|
131
134
|
end
|
132
135
|
|
133
|
-
|
134
|
-
|
135
|
-
!@attrs[:entities].nil?
|
136
|
+
def user?
|
137
|
+
!@attrs[:user].nil?
|
136
138
|
end
|
137
139
|
|
138
140
|
private
|
139
141
|
|
140
142
|
# @param klass [Class]
|
141
|
-
# @param
|
142
|
-
def entities(klass,
|
143
|
+
# @param key [Symbol]
|
144
|
+
def entities(klass, key)
|
143
145
|
if entities?
|
144
|
-
Array(@attrs[:entities][
|
146
|
+
Array(@attrs[:entities][key.to_sym]).map do |user_mention|
|
145
147
|
klass.fetch_or_new(user_mention)
|
146
148
|
end
|
147
149
|
else
|
148
|
-
warn "#{Kernel.caller.first}: To get #{
|
150
|
+
warn "#{Kernel.caller.first}: To get #{key.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class.name}."
|
149
151
|
[]
|
150
152
|
end
|
151
153
|
end
|
152
154
|
|
153
|
-
def user?
|
154
|
-
!@attrs[:user].nil?
|
155
|
-
end
|
156
|
-
|
157
155
|
end
|
158
156
|
|
159
157
|
Status = Tweet
|
data/lib/twitter/user.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'twitter/basic_user'
|
2
|
-
require 'twitter/core_ext/hash'
|
3
2
|
require 'twitter/creatable'
|
3
|
+
require 'twitter/exceptable'
|
4
4
|
require 'twitter/tweet'
|
5
5
|
|
6
6
|
module Twitter
|
7
7
|
class User < Twitter::BasicUser
|
8
8
|
PROFILE_IMAGE_SUFFIX_REGEX = /_normal(\.gif|\.jpe?g|\.png)$/
|
9
9
|
include Twitter::Creatable
|
10
|
+
include Twitter::Exceptable
|
10
11
|
attr_reader :connections, :contributors_enabled, :default_profile,
|
11
12
|
:default_profile_image, :description, :favourites_count,
|
12
13
|
:follow_request_sent, :followers_count, :friends_count, :geo_enabled,
|
@@ -17,10 +18,6 @@ module Twitter
|
|
17
18
|
:profile_sidebar_fill_color, :profile_text_color,
|
18
19
|
:profile_use_background_image, :protected, :statuses_count, :time_zone,
|
19
20
|
:url, :utc_offset, :verified
|
20
|
-
alias contributors_enabled? contributors_enabled
|
21
|
-
alias default_profile? default_profile
|
22
|
-
alias default_profile_image? default_profile_image
|
23
|
-
alias follow_request_sent? follow_request_sent
|
24
21
|
alias favorite_count favourites_count
|
25
22
|
alias favoriters_count favourites_count
|
26
23
|
alias favorites_count favourites_count
|
@@ -28,20 +25,13 @@ module Twitter
|
|
28
25
|
alias favouriters_count favourites_count
|
29
26
|
alias follower_count followers_count
|
30
27
|
alias friend_count friends_count
|
31
|
-
alias geo_enabled? geo_enabled
|
32
|
-
alias is_translator? is_translator
|
33
|
-
alias notifications? notifications
|
34
|
-
alias profile_background_tile? profile_background_tile
|
35
|
-
alias profile_use_background_image? profile_use_background_image
|
36
|
-
alias protected? protected
|
37
28
|
alias status_count statuses_count
|
38
29
|
alias translator is_translator
|
39
|
-
alias translator? is_translator
|
30
|
+
alias translator? is_translator?
|
40
31
|
alias tweet_count statuses_count
|
41
32
|
alias tweets_count statuses_count
|
42
33
|
alias update_count statuses_count
|
43
34
|
alias updates_count statuses_count
|
44
|
-
alias verified? verified
|
45
35
|
|
46
36
|
# Return the URL to the user's profile banner image
|
47
37
|
#
|
@@ -93,7 +83,7 @@ module Twitter
|
|
93
83
|
|
94
84
|
# @return [Twitter::Tweet]
|
95
85
|
def status
|
96
|
-
@status ||= Twitter::Tweet
|
86
|
+
@status ||= fetch_or_new_without_self(Twitter::Tweet, @attrs, :status, :user)
|
97
87
|
end
|
98
88
|
|
99
89
|
def status?
|