twitter 5.5.1 → 5.6.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +12 -0
- data/README.md +8 -10
- data/lib/twitter/base.rb +4 -2
- data/lib/twitter/client.rb +7 -5
- data/lib/twitter/configuration.rb +1 -1
- data/lib/twitter/cursor.rb +18 -17
- data/lib/twitter/entities.rb +27 -1
- data/lib/twitter/error.rb +1 -1
- data/lib/twitter/error/request_timeout.rb +10 -0
- data/lib/twitter/geo_results.rb +5 -3
- data/lib/twitter/media/photo.rb +1 -1
- data/lib/twitter/null_object.rb +8 -20
- data/lib/twitter/profile_banner.rb +1 -1
- data/lib/twitter/request.rb +47 -0
- data/lib/twitter/rest/api/direct_messages.rb +7 -5
- data/lib/twitter/rest/api/favorites.rb +7 -7
- data/lib/twitter/rest/api/friends_and_followers.rb +11 -9
- data/lib/twitter/rest/api/help.rb +4 -3
- data/lib/twitter/rest/api/lists.rb +9 -7
- data/lib/twitter/rest/api/oauth.rb +11 -5
- data/lib/twitter/rest/api/places_and_geo.rb +6 -5
- data/lib/twitter/rest/api/saved_searches.rb +8 -6
- data/lib/twitter/rest/api/search.rb +4 -10
- data/lib/twitter/rest/api/spam_reporting.rb +1 -0
- data/lib/twitter/rest/api/suggested_users.rb +4 -3
- data/lib/twitter/rest/api/timelines.rb +5 -4
- data/lib/twitter/rest/api/trends.rb +5 -4
- data/lib/twitter/rest/api/tweets.rb +19 -24
- data/lib/twitter/rest/api/users.rb +17 -16
- data/lib/twitter/rest/api/utils.rb +45 -73
- data/lib/twitter/rest/client.rb +34 -34
- data/lib/twitter/rest/request/multipart_with_file.rb +2 -0
- data/lib/twitter/rest/response/parse_json.rb +2 -0
- data/lib/twitter/rest/response/raise_error.rb +2 -0
- data/lib/twitter/search_results.rb +28 -60
- data/lib/twitter/streaming/client.rb +4 -4
- data/lib/twitter/suggestion.rb +1 -1
- data/lib/twitter/trend_results.rb +6 -4
- data/lib/twitter/tweet.rb +3 -3
- data/lib/twitter/user.rb +1 -1
- data/lib/twitter/utils.rb +18 -3
- data/lib/twitter/version.rb +2 -2
- data/spec/helper.rb +1 -1
- data/spec/twitter/error_spec.rb +1 -1
- data/spec/twitter/geo_factory_spec.rb +1 -1
- data/spec/twitter/identifiable_spec.rb +1 -1
- data/spec/twitter/media_factory_spec.rb +1 -1
- data/spec/twitter/rest/api/favorites_spec.rb +2 -2
- data/spec/twitter/rest/api/tweets_spec.rb +4 -4
- data/spec/twitter/rest/client_spec.rb +13 -25
- data/spec/twitter/tweet_spec.rb +69 -0
- data/twitter.gemspec +2 -1
- metadata +23 -15
- metadata.gz.sig +0 -0
- data/spec/twitter/null_object_spec.rb +0 -90
data/lib/twitter/rest/client.rb
CHANGED
@@ -2,9 +2,11 @@ require 'base64'
|
|
2
2
|
require 'faraday'
|
3
3
|
require 'faraday/request/multipart'
|
4
4
|
require 'json'
|
5
|
+
require 'timeout'
|
5
6
|
require 'twitter/client'
|
6
7
|
require 'twitter/error'
|
7
8
|
require 'twitter/error/configuration_error'
|
9
|
+
require 'twitter/error/request_timeout'
|
8
10
|
require 'twitter/rest/api/direct_messages'
|
9
11
|
require 'twitter/rest/api/favorites'
|
10
12
|
require 'twitter/rest/api/friends_and_followers'
|
@@ -60,8 +62,8 @@ module Twitter
|
|
60
62
|
:user_agent => user_agent,
|
61
63
|
},
|
62
64
|
:request => {
|
63
|
-
:open_timeout =>
|
64
|
-
:timeout =>
|
65
|
+
:open_timeout => 10,
|
66
|
+
:timeout => 30,
|
65
67
|
},
|
66
68
|
}
|
67
69
|
end
|
@@ -69,29 +71,24 @@ module Twitter
|
|
69
71
|
# @note Faraday's middleware stack implementation is comparable to that of Rack middleware. The order of middleware is important: the first middleware on the list wraps all others, while the last middleware is the innermost one.
|
70
72
|
# @see https://github.com/technoweenie/faraday#advanced-middleware-usage
|
71
73
|
# @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
|
72
|
-
# @return [Faraday::
|
74
|
+
# @return [Faraday::RackBuilder]
|
73
75
|
def middleware
|
74
|
-
@middleware ||= Faraday::
|
76
|
+
@middleware ||= Faraday::RackBuilder.new do |faraday|
|
75
77
|
# Convert file uploads to Faraday::UploadIO objects
|
76
|
-
|
77
|
-
# Checks for files in the payload
|
78
|
-
|
79
|
-
#
|
80
|
-
|
78
|
+
faraday.request :multipart_with_file
|
79
|
+
# Checks for files in the payload, otherwise leaves everything untouched
|
80
|
+
faraday.request :multipart
|
81
|
+
# Encodes as "application/x-www-form-urlencoded" if not already encoded
|
82
|
+
faraday.request :url_encoded
|
81
83
|
# Handle error responses
|
82
|
-
|
84
|
+
faraday.response :raise_error
|
83
85
|
# Parse JSON response bodies
|
84
|
-
|
85
|
-
# Set
|
86
|
-
|
86
|
+
faraday.response :parse_json
|
87
|
+
# Set default HTTP adapter
|
88
|
+
faraday.adapter :net_http
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
90
|
-
# Perform an HTTP DELETE request
|
91
|
-
def delete(path, params = {})
|
92
|
-
request(:delete, path, params)
|
93
|
-
end
|
94
|
-
|
95
92
|
# Perform an HTTP GET request
|
96
93
|
def get(path, params = {})
|
97
94
|
request(:get, path, params)
|
@@ -103,11 +100,6 @@ module Twitter
|
|
103
100
|
request(:post, path, params, signature_params)
|
104
101
|
end
|
105
102
|
|
106
|
-
# Perform an HTTP PUT request
|
107
|
-
def put(path, params = {})
|
108
|
-
request(:put, path, params)
|
109
|
-
end
|
110
|
-
|
111
103
|
# @return [Boolean]
|
112
104
|
def bearer_token?
|
113
105
|
!!bearer_token
|
@@ -127,23 +119,31 @@ module Twitter
|
|
127
119
|
@connection ||= Faraday.new(ENDPOINT, connection_options)
|
128
120
|
end
|
129
121
|
|
130
|
-
def request(method, path, params = {}, signature_params = params)
|
122
|
+
def request(method, path, params = {}, signature_params = params)
|
131
123
|
response = connection.send(method.to_sym, path, params) do |request|
|
132
|
-
|
133
|
-
if bearer_token_request
|
134
|
-
request.headers[:accept] = '*/*' # It is important we set this, otherwise we get an error.
|
135
|
-
request.headers[:authorization] = bearer_token_credentials_auth_header
|
136
|
-
request.headers[:content_type] = 'application/x-www-form-urlencoded; charset=UTF-8'
|
137
|
-
else
|
138
|
-
request.headers[:authorization] = auth_token(method, path, params, signature_params)
|
139
|
-
end
|
124
|
+
request.headers.update(request_headers(method, path, params, signature_params))
|
140
125
|
end
|
141
126
|
response.env
|
127
|
+
rescue Faraday::Error::TimeoutError, Timeout::Error => error
|
128
|
+
raise(Twitter::Error::RequestTimeout.new(error))
|
142
129
|
rescue Faraday::Error::ClientError, JSON::ParserError => error
|
143
|
-
|
130
|
+
fail(Twitter::Error.new(error))
|
131
|
+
end
|
132
|
+
|
133
|
+
def request_headers(method, path, params = {}, signature_params = params)
|
134
|
+
bearer_token_request = params.delete(:bearer_token_request)
|
135
|
+
headers = {}
|
136
|
+
if bearer_token_request
|
137
|
+
headers[:accept] = '*/*'
|
138
|
+
headers[:authorization] = bearer_token_credentials_auth_header
|
139
|
+
headers[:content_type] = 'application/x-www-form-urlencoded; charset=UTF-8'
|
140
|
+
else
|
141
|
+
headers[:authorization] = auth_token(method, path, params, signature_params)
|
142
|
+
end
|
143
|
+
headers
|
144
144
|
end
|
145
145
|
|
146
|
-
def auth_token(method, path, params = {}, signature_params = params)
|
146
|
+
def auth_token(method, path, params = {}, signature_params = params)
|
147
147
|
if !user_token?
|
148
148
|
@bearer_token = token unless bearer_token?
|
149
149
|
bearer_auth_header
|
@@ -1,38 +1,38 @@
|
|
1
|
+
require 'cgi'
|
1
2
|
require 'twitter/enumerable'
|
3
|
+
require 'twitter/utils'
|
4
|
+
require 'uri'
|
2
5
|
|
3
6
|
module Twitter
|
4
7
|
class SearchResults
|
5
8
|
include Twitter::Enumerable
|
9
|
+
include Twitter::Utils
|
6
10
|
attr_reader :attrs
|
7
11
|
alias_method :to_h, :attrs
|
8
|
-
|
9
|
-
|
12
|
+
deprecate_alias :to_hash, :to_h
|
13
|
+
deprecate_alias :to_hsh, :to_h
|
10
14
|
|
11
15
|
class << self
|
12
16
|
# Construct a new SearchResults object from a response hash
|
13
17
|
#
|
14
18
|
# @param response [Hash]
|
15
|
-
# @param
|
16
|
-
# @param path [String]
|
19
|
+
# @param request [Twitter::Request]
|
17
20
|
# @return [Twitter::SearchResults]
|
18
|
-
def from_response(response,
|
19
|
-
new(response[:body],
|
21
|
+
def from_response(response, request)
|
22
|
+
new(response[:body], request)
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
26
|
# Initializes a new SearchResults object
|
24
27
|
#
|
25
28
|
# @param attrs [Hash]
|
26
|
-
# @param
|
27
|
-
# @param request_method [String, Symbol]
|
28
|
-
# @param path [String]
|
29
|
-
# @param options [Hash]
|
29
|
+
# @param request [Twitter::Request]
|
30
30
|
# @return [Twitter::SearchResults]
|
31
|
-
def initialize(attrs,
|
32
|
-
@client = client
|
33
|
-
@request_method =
|
34
|
-
@path = path
|
35
|
-
@options = options
|
31
|
+
def initialize(attrs, request)
|
32
|
+
@client = request.client
|
33
|
+
@request_method = request.verb
|
34
|
+
@path = request.path
|
35
|
+
@options = request.options
|
36
36
|
@collection = []
|
37
37
|
self.attrs = attrs
|
38
38
|
end
|
@@ -41,60 +41,38 @@ module Twitter
|
|
41
41
|
|
42
42
|
# @return [Boolean]
|
43
43
|
def last?
|
44
|
-
!
|
44
|
+
!next_page?
|
45
45
|
end
|
46
46
|
|
47
47
|
# @return [Boolean]
|
48
|
-
def
|
49
|
-
|
48
|
+
def next_page?
|
49
|
+
!!@attrs[:search_metadata][:next_results] unless @attrs[:search_metadata].nil?
|
50
50
|
end
|
51
|
-
alias_method :next_page?, :next_results?
|
52
|
-
alias_method :next?, :next_results?
|
53
51
|
|
54
52
|
# Returns a Hash of query parameters for the next result in the search
|
55
53
|
#
|
56
54
|
# @note Returned Hash can be merged into the previous search options list to easily access the next page.
|
57
55
|
# @return [Hash] The parameters needed to fetch the next page.
|
58
|
-
def
|
59
|
-
if
|
60
|
-
|
61
|
-
query_string_to_hash(query_string)
|
56
|
+
def next_page
|
57
|
+
if next_page?
|
58
|
+
query_string_to_hash(@attrs[:search_metadata][:next_results])
|
62
59
|
end
|
63
60
|
end
|
64
|
-
alias_method :next_page, :next_results
|
65
|
-
alias_method :next, :next_results
|
66
61
|
|
62
|
+
# @return [Hash]
|
67
63
|
def fetch_next_page
|
68
64
|
response = @client.send(@request_method, @path, next_page)
|
69
65
|
self.attrs = response[:body]
|
70
66
|
end
|
71
67
|
|
68
|
+
# @param attrs [Hash]
|
69
|
+
# @return [Hash]
|
72
70
|
def attrs=(attrs)
|
73
71
|
@attrs = attrs
|
74
|
-
Array(@attrs[:statuses]).
|
72
|
+
Array(@attrs[:statuses]).collect do |tweet|
|
75
73
|
@collection << Tweet.new(tweet)
|
76
74
|
end
|
77
|
-
|
78
|
-
|
79
|
-
# Returns the string with the first character removed
|
80
|
-
#
|
81
|
-
# @param string [String]
|
82
|
-
# @return [String] A copy of string without the first character.
|
83
|
-
# @example Returns the query string with the question mark removed
|
84
|
-
# strip_first_character("?foo=bar&baz=qux") #=> "foo=bar&baz=qux"
|
85
|
-
def strip_first_character(string)
|
86
|
-
strip_first_character!(string.dup)
|
87
|
-
end
|
88
|
-
|
89
|
-
# Removes the first character from a string
|
90
|
-
#
|
91
|
-
# @param string [String]
|
92
|
-
# @return [String] The string without the first character.
|
93
|
-
# @example Remove the first character from a query string
|
94
|
-
# strip_first_character!("?foo=bar&baz=qux") #=> "foo=bar&baz=qux"
|
95
|
-
def strip_first_character!(string)
|
96
|
-
string[0] = ''
|
97
|
-
string
|
75
|
+
@attrs
|
98
76
|
end
|
99
77
|
|
100
78
|
# Converts query string to a hash
|
@@ -104,18 +82,8 @@ module Twitter
|
|
104
82
|
# @example Convert query string to a hash
|
105
83
|
# query_string_to_hash("foo=bar&baz=qux") #=> {:foo=>"bar", :baz=>"qux"}
|
106
84
|
def query_string_to_hash(query_string)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
# Converts hash's keys to symbols
|
111
|
-
#
|
112
|
-
# @note Does not support nested hashes.
|
113
|
-
# @param hash [Hash]
|
114
|
-
# @return [Hash] The hash with symbols as keys.
|
115
|
-
# @example Convert hash's keys to symbols
|
116
|
-
# symbolize_keys({"foo"=>"bar", "baz"=>"qux"}) #=> {:foo=>"bar", :baz=>"qux"}
|
117
|
-
def symbolize_keys(hash)
|
118
|
-
Hash[hash.map { |key, value| [key.to_sym, value] }]
|
85
|
+
query = CGI.parse(URI.parse(query_string).query)
|
86
|
+
Hash[query.collect { |key, value| [key.to_sym, value.first] }]
|
119
87
|
end
|
120
88
|
end
|
121
89
|
end
|
@@ -13,7 +13,7 @@ module Twitter
|
|
13
13
|
# Initializes a new Client object
|
14
14
|
#
|
15
15
|
# @return [Twitter::Streaming::Client]
|
16
|
-
def initialize(options = {}
|
16
|
+
def initialize(options = {})
|
17
17
|
super
|
18
18
|
@connection = Streaming::Connection.new
|
19
19
|
end
|
@@ -99,20 +99,20 @@ module Twitter
|
|
99
99
|
|
100
100
|
private
|
101
101
|
|
102
|
-
def request(method, uri, params
|
102
|
+
def request(method, uri, params)
|
103
103
|
before_request.call
|
104
104
|
headers = default_headers.merge(:authorization => oauth_auth_header(method, uri, params).to_s)
|
105
105
|
request = HTTP::Request.new(method, uri + '?' + to_url_params(params), headers)
|
106
106
|
response = Streaming::Response.new do |data|
|
107
107
|
if item = Streaming::MessageParser.parse(data) # rubocop:disable AssignmentInCondition, IfUnlessModifier
|
108
|
-
|
108
|
+
yield(item)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
@connection.stream(request, response)
|
112
112
|
end
|
113
113
|
|
114
114
|
def to_url_params(params)
|
115
|
-
params.
|
115
|
+
params.collect do |param, value|
|
116
116
|
[param, URI.encode(value)].join('=')
|
117
117
|
end.sort.join('&')
|
118
118
|
end
|
data/lib/twitter/suggestion.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
+
require 'memoizable'
|
1
2
|
require 'twitter/creatable'
|
2
3
|
require 'twitter/enumerable'
|
3
|
-
require 'memoizable'
|
4
4
|
require 'twitter/null_object'
|
5
|
+
require 'twitter/utils'
|
5
6
|
|
6
7
|
module Twitter
|
7
8
|
class TrendResults
|
8
9
|
include Twitter::Creatable
|
9
10
|
include Twitter::Enumerable
|
11
|
+
include Twitter::Utils
|
10
12
|
include Memoizable
|
11
13
|
attr_reader :attrs
|
12
14
|
alias_method :to_h, :attrs
|
13
|
-
|
14
|
-
|
15
|
+
deprecate_alias :to_hash, :to_h
|
16
|
+
deprecate_alias :to_hsh, :to_h
|
15
17
|
|
16
18
|
class << self
|
17
19
|
# Construct a new TrendResults object from a response hash
|
@@ -29,7 +31,7 @@ module Twitter
|
|
29
31
|
# @return [Twitter::TrendResults]
|
30
32
|
def initialize(attrs = {})
|
31
33
|
@attrs = attrs
|
32
|
-
@collection = Array(@attrs[:trends]).
|
34
|
+
@collection = Array(@attrs[:trends]).collect do |trend|
|
33
35
|
Trend.new(trend)
|
34
36
|
end
|
35
37
|
end
|
data/lib/twitter/tweet.rb
CHANGED
@@ -10,11 +10,11 @@ module Twitter
|
|
10
10
|
:in_reply_to_screen_name, :in_reply_to_attrs_id,
|
11
11
|
:in_reply_to_status_id, :in_reply_to_user_id, :lang,
|
12
12
|
:retweet_count, :retweeted, :source, :text, :truncated
|
13
|
-
|
14
|
-
|
13
|
+
deprecate_alias :favorites_count, :favorite_count
|
14
|
+
deprecate_alias :favoriters_count, :favorite_count
|
15
15
|
alias_method :in_reply_to_tweet_id, :in_reply_to_status_id
|
16
16
|
alias_method :reply?, :in_reply_to_status_id?
|
17
|
-
|
17
|
+
deprecate_alias :retweeters_count, :retweet_count
|
18
18
|
object_attr_reader :GeoFactory, :geo
|
19
19
|
object_attr_reader :Metadata, :metadata
|
20
20
|
object_attr_reader :Place, :place
|
data/lib/twitter/user.rb
CHANGED
data/lib/twitter/utils.rb
CHANGED
@@ -1,13 +1,28 @@
|
|
1
1
|
module Twitter
|
2
2
|
module Utils
|
3
|
-
|
3
|
+
class << self
|
4
|
+
def included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def deprecate_alias(new_name, old_name)
|
11
|
+
define_method(new_name) do |*args, &block|
|
12
|
+
warn "#{Kernel.caller.first}: [DEPRECATION] ##{new_name} is deprecated. Use ##{old_name} instead."
|
13
|
+
send(old_name, *args, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
4
18
|
def parallel_map(enumerable)
|
5
19
|
# Don't bother spawning a new thread if there's only one item
|
6
20
|
if enumerable.count == 1
|
7
|
-
enumerable.
|
21
|
+
enumerable.collect { |object| yield object }
|
8
22
|
else
|
9
|
-
enumerable.
|
23
|
+
enumerable.collect { |object| Thread.new { yield object } }.collect(&:value)
|
10
24
|
end
|
11
25
|
end
|
26
|
+
module_function :parallel_map
|
12
27
|
end
|
13
28
|
end
|
data/lib/twitter/version.rb
CHANGED
data/spec/helper.rb
CHANGED
data/spec/twitter/error_spec.rb
CHANGED
@@ -36,7 +36,7 @@ describe Twitter::Error do
|
|
36
36
|
stub_get('/1.1/statuses/user_timeline.json').with(:query => {:screen_name => 'sferik'}).to_return(:status => status, :body => body_message)
|
37
37
|
end
|
38
38
|
it "raises #{exception.name}" do
|
39
|
-
expect { @client.user_timeline('sferik') }.to raise_error
|
39
|
+
expect { @client.user_timeline('sferik') }.to raise_error(exception)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|