twitter 6.1.0 → 6.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +22 -15
- data/README.md +69 -394
- data/lib/twitter/base.rb +2 -16
- data/lib/twitter/basic_user.rb +0 -3
- data/lib/twitter/client.rb +5 -19
- data/lib/twitter/configuration.rb +3 -2
- data/lib/twitter/creatable.rb +1 -1
- data/lib/twitter/cursor.rb +0 -1
- data/lib/twitter/entity/uri.rb +0 -4
- data/lib/twitter/error.rb +81 -96
- data/lib/twitter/geo_results.rb +0 -1
- data/lib/twitter/headers.rb +11 -10
- data/lib/twitter/media/photo.rb +4 -0
- data/lib/twitter/media/video.rb +4 -1
- data/lib/twitter/media/video_info.rb +1 -1
- data/lib/twitter/null_object.rb +2 -2
- data/lib/twitter/profile.rb +3 -2
- data/lib/twitter/rate_limit.rb +1 -1
- data/lib/twitter/rest/api.rb +0 -2
- data/lib/twitter/rest/client.rb +0 -78
- data/lib/twitter/rest/direct_messages.rb +3 -3
- data/lib/twitter/rest/favorites.rb +25 -4
- data/lib/twitter/rest/friends_and_followers.rb +1 -3
- data/lib/twitter/rest/lists.rb +18 -29
- data/lib/twitter/rest/oauth.rb +15 -15
- data/lib/twitter/rest/request.rb +105 -16
- data/lib/twitter/rest/saved_searches.rb +0 -2
- data/lib/twitter/rest/search.rb +2 -0
- data/lib/twitter/rest/trends.rb +1 -0
- data/lib/twitter/rest/tweets.rb +80 -15
- data/lib/twitter/rest/undocumented.rb +3 -4
- data/lib/twitter/rest/users.rb +20 -34
- data/lib/twitter/rest/utils.rb +13 -20
- data/lib/twitter/search_results.rb +1 -2
- data/lib/twitter/streaming/client.rb +17 -23
- data/lib/twitter/streaming/connection.rb +23 -10
- data/lib/twitter/streaming/deleted_tweet.rb +0 -1
- data/lib/twitter/streaming/event.rb +6 -6
- data/lib/twitter/streaming/message_parser.rb +1 -1
- data/lib/twitter/streaming/response.rb +2 -2
- data/lib/twitter/trend_results.rb +1 -2
- data/lib/twitter/tweet.rb +1 -5
- data/lib/twitter/user.rb +0 -2
- data/lib/twitter/utils.rb +1 -16
- data/lib/twitter/version.rb +1 -1
- data/twitter.gemspec +13 -13
- metadata +35 -27
- data/lib/twitter/rest/media.rb +0 -30
- data/lib/twitter/rest/request/multipart_with_file.rb +0 -47
- data/lib/twitter/rest/response/parse_error_json.rb +0 -13
- data/lib/twitter/rest/response/parse_json.rb +0 -31
- data/lib/twitter/rest/response/raise_error.rb +0 -32
- data/lib/twitter/token.rb +0 -20
data/lib/twitter/rest/request.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
require 'addressable/uri'
|
2
|
-
require '
|
2
|
+
require 'http'
|
3
|
+
require 'http/form_data'
|
3
4
|
require 'json'
|
4
|
-
require '
|
5
|
+
require 'openssl'
|
5
6
|
require 'twitter/error'
|
6
7
|
require 'twitter/headers'
|
7
8
|
require 'twitter/rate_limit'
|
9
|
+
require 'twitter/utils'
|
8
10
|
|
9
11
|
module Twitter
|
10
12
|
module REST
|
11
13
|
class Request
|
12
|
-
|
13
|
-
|
14
|
+
include Twitter::Utils
|
15
|
+
BASE_URL = 'https://api.twitter.com'.freeze
|
16
|
+
attr_accessor :client, :headers, :options, :path, :rate_limit,
|
17
|
+
:request_method, :uri
|
14
18
|
alias verb request_method
|
15
19
|
|
16
20
|
# @param client [Twitter::Client]
|
@@ -20,24 +24,109 @@ module Twitter
|
|
20
24
|
# @return [Twitter::REST::Request]
|
21
25
|
def initialize(client, request_method, path, options = {})
|
22
26
|
@client = client
|
23
|
-
@
|
24
|
-
|
25
|
-
@
|
27
|
+
@uri = Addressable::URI.parse(path.start_with?('http') ? path : BASE_URL + path)
|
28
|
+
set_multipart_options!(request_method, options)
|
29
|
+
@path = uri.path
|
26
30
|
@options = options
|
27
31
|
end
|
28
32
|
|
29
33
|
# @return [Array, Hash]
|
30
34
|
def perform
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
options_key = @request_method == :get ? :params : :form
|
36
|
+
response = http_client.headers(@headers).public_send(@request_method, @uri.to_s, options_key => @options)
|
37
|
+
response_body = response.body.empty? ? '' : symbolize_keys!(response.parse)
|
38
|
+
response_headers = response.headers
|
39
|
+
fail_or_return_response_body(response.code, response_body, response_headers)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def merge_multipart_file!(options)
|
45
|
+
key = options.delete(:key)
|
46
|
+
file = options.delete(:file)
|
47
|
+
|
48
|
+
options[key] = if file.is_a?(StringIO)
|
49
|
+
HTTP::FormData::File.new(file, mime_type: 'video/mp4')
|
50
|
+
else
|
51
|
+
HTTP::FormData::File.new(file, filename: File.basename(file), mime_type: mime_type(File.basename(file)))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_multipart_options!(request_method, options)
|
56
|
+
if request_method == :multipart_post
|
57
|
+
merge_multipart_file!(options)
|
58
|
+
@request_method = :post
|
59
|
+
@headers = Twitter::Headers.new(@client, @request_method, @uri).request_headers
|
60
|
+
else
|
61
|
+
@request_method = request_method
|
62
|
+
@headers = Twitter::Headers.new(@client, @request_method, @uri, options).request_headers
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def mime_type(basename)
|
67
|
+
case basename
|
68
|
+
when /\.gif$/i
|
69
|
+
'image/gif'
|
70
|
+
when /\.jpe?g/i
|
71
|
+
'image/jpeg'
|
72
|
+
when /\.png$/i
|
73
|
+
'image/png'
|
74
|
+
else
|
75
|
+
'application/octet-stream'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def fail_or_return_response_body(code, body, headers)
|
80
|
+
error = error(code, body, headers)
|
81
|
+
raise(error) if error
|
82
|
+
@rate_limit = Twitter::RateLimit.new(headers)
|
83
|
+
body
|
84
|
+
end
|
85
|
+
|
86
|
+
def error(code, body, headers)
|
87
|
+
klass = Twitter::Error::ERRORS[code]
|
88
|
+
if klass == Twitter::Error::Forbidden
|
89
|
+
forbidden_error(body, headers)
|
90
|
+
elsif !klass.nil?
|
91
|
+
klass.from_response(body, headers)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def forbidden_error(body, headers)
|
96
|
+
error = Twitter::Error::Forbidden.from_response(body, headers)
|
97
|
+
klass = Twitter::Error::FORBIDDEN_MESSAGES[error.message]
|
98
|
+
if klass
|
99
|
+
klass.from_response(body, headers)
|
100
|
+
else
|
101
|
+
error
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def symbolize_keys!(object)
|
106
|
+
if object.is_a?(Array)
|
107
|
+
object.each_with_index do |val, index|
|
108
|
+
object[index] = symbolize_keys!(val)
|
109
|
+
end
|
110
|
+
elsif object.is_a?(Hash)
|
111
|
+
object.dup.each_key do |key|
|
112
|
+
object[key.to_sym] = symbolize_keys!(object.delete(key))
|
113
|
+
end
|
38
114
|
end
|
39
|
-
|
40
|
-
|
115
|
+
object
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [HTTP::Client, HTTP]
|
119
|
+
def http_client
|
120
|
+
client = @client.proxy ? HTTP.via(*proxy) : HTTP
|
121
|
+
client = client.timeout(:per_operation, connect: @client.timeouts[:connect], read: @client.timeouts[:read], write: @client.timeouts[:write]) if @client.timeouts
|
122
|
+
client
|
123
|
+
end
|
124
|
+
|
125
|
+
# Return proxy values as a compacted array
|
126
|
+
#
|
127
|
+
# @return [Array]
|
128
|
+
def proxy
|
129
|
+
@client.proxy.values_at(:host, :port, :username, :password).compact
|
41
130
|
end
|
42
131
|
end
|
43
132
|
end
|
@@ -65,7 +65,6 @@ module Twitter
|
|
65
65
|
def create_saved_search(query, options = {})
|
66
66
|
perform_post_with_object('/1.1/saved_searches/create.json', options.merge(query: query), Twitter::SavedSearch)
|
67
67
|
end
|
68
|
-
deprecate_alias :saved_search_create, :create_saved_search
|
69
68
|
|
70
69
|
# Destroys saved searches for the authenticated user
|
71
70
|
#
|
@@ -86,7 +85,6 @@ module Twitter
|
|
86
85
|
perform_post_with_object("/1.1/saved_searches/destroy/#{id}.json", arguments.options, Twitter::SavedSearch)
|
87
86
|
end
|
88
87
|
end
|
89
|
-
deprecate_alias :saved_search_destroy, :destroy_saved_search
|
90
88
|
end
|
91
89
|
end
|
92
90
|
end
|
data/lib/twitter/rest/search.rb
CHANGED
@@ -24,8 +24,10 @@ module Twitter
|
|
24
24
|
# @option options [String] :until Optional. Returns tweets generated before the given date. Date should be formatted as YYYY-MM-DD.
|
25
25
|
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets which can be accessed through the API. If the limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID available.
|
26
26
|
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
|
27
|
+
# @option options [Boolean] :include_entities The entities node will be disincluded when set to false.
|
27
28
|
# @return [Twitter::SearchResults] Return tweets that match a specified query with search metadata
|
28
29
|
def search(q, options = {})
|
30
|
+
options = options.dup
|
29
31
|
options[:count] ||= MAX_TWEETS_PER_REQUEST
|
30
32
|
request = Twitter::REST::Request.new(self, :get, '/1.1/search/tweets.json', options.merge(q: q))
|
31
33
|
Twitter::SearchResults.new(request)
|
data/lib/twitter/rest/trends.rb
CHANGED
@@ -19,6 +19,7 @@ module Twitter
|
|
19
19
|
# @option options [String] :exclude Setting this equal to 'hashtags' will remove all hashtags from the trends list.
|
20
20
|
# @return [Array<Twitter::Trend>]
|
21
21
|
def trends(id = 1, options = {})
|
22
|
+
options = options.dup
|
22
23
|
options[:id] = id
|
23
24
|
response = perform_get('/1.1/trends/place.json', options).first
|
24
25
|
Twitter::TrendResults.new(response)
|
data/lib/twitter/rest/tweets.rb
CHANGED
@@ -41,6 +41,7 @@ module Twitter
|
|
41
41
|
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
42
42
|
# @option options [Boolean] :ids_only ('false') Only return user IDs instead of full user objects.
|
43
43
|
def retweeters_of(tweet, options = {})
|
44
|
+
options = options.dup
|
44
45
|
ids_only = !!options.delete(:ids_only)
|
45
46
|
retweeters = retweets(tweet, options).collect(&:user)
|
46
47
|
ids_only ? retweeters.collect(&:id) : retweeters
|
@@ -52,7 +53,7 @@ module Twitter
|
|
52
53
|
# @rate_limited Yes
|
53
54
|
# @authentication Requires user context
|
54
55
|
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
55
|
-
# @raise [Twitter::Error::Forbidden] Error raised when supplied status is over
|
56
|
+
# @raise [Twitter::Error::Forbidden] Error raised when supplied status is over 280 characters.
|
56
57
|
# @return [Twitter::Tweet] The requested Tweet.
|
57
58
|
# @param tweet [Integer, String, URI, Twitter::Tweet] A Tweet ID, URI, or object.
|
58
59
|
# @param options [Hash] A customizable set of options.
|
@@ -101,8 +102,6 @@ module Twitter
|
|
101
102
|
end
|
102
103
|
end
|
103
104
|
alias destroy_tweet destroy_status
|
104
|
-
deprecate_alias :status_destroy, :destroy_status
|
105
|
-
deprecate_alias :tweet_destroy, :destroy_status
|
106
105
|
|
107
106
|
# Updates the authenticating user's status
|
108
107
|
#
|
@@ -112,7 +111,7 @@ module Twitter
|
|
112
111
|
# @authentication Requires user context
|
113
112
|
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
114
113
|
# @return [Twitter::Tweet] The created Tweet. When the tweet is deemed a duplicate by Twitter, returns the last Tweet from the user's timeline.
|
115
|
-
# @param status [String] The text of your status update, up to
|
114
|
+
# @param status [String] The text of your status update, up to 280 characters.
|
116
115
|
# @param options [Hash] A customizable set of options.
|
117
116
|
# @option options [Boolean, String, Integer] :possibly_sensitive Set to true for content which may not be suitable for every audience.
|
118
117
|
# @option options [Twitter::Tweet] :in_reply_to_status An existing status that the update is in reply to. If the status being replied to was not originally posted by the authenticated user, the text of the status must begin with an @-mention, or twitter will reject the update.
|
@@ -121,7 +120,6 @@ module Twitter
|
|
121
120
|
# @option options [Float] :long The longitude of the location this tweet refers to. The valid ranges for longitude is -180.0 to +180.0 (East is positive) inclusive. This option will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding :lat option.
|
122
121
|
# @option options [Twitter::Place] :place A place in the world. These can be retrieved from {Twitter::REST::PlacesAndGeo#reverse_geocode}.
|
123
122
|
# @option options [String] :place_id A place in the world. These IDs can be retrieved from {Twitter::REST::PlacesAndGeo#reverse_geocode}.
|
124
|
-
# @option options [String] :media_ids A comma separated list of uploaded media IDs to attach to the Tweet.
|
125
123
|
# @option options [String] :display_coordinates Whether or not to put a pin on the exact coordinates a tweet has been sent from.
|
126
124
|
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
127
125
|
def update(status, options = {})
|
@@ -139,7 +137,7 @@ module Twitter
|
|
139
137
|
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
140
138
|
# @raise [Twitter::Error::DuplicateStatus] Error raised when a duplicate status is posted.
|
141
139
|
# @return [Twitter::Tweet] The created Tweet.
|
142
|
-
# @param status [String] The text of your status update, up to
|
140
|
+
# @param status [String] The text of your status update, up to 280 characters.
|
143
141
|
# @param options [Hash] A customizable set of options.
|
144
142
|
# @option options [Boolean, String, Integer] :possibly_sensitive Set to true for content which may not be suitable for every audience.
|
145
143
|
# @option options [Twitter::Tweet] :in_reply_to_status An existing status that the update is in reply to. If the status being replied to was not originally posted by the authenticated user, the text of the status must begin with an @-mention, or twitter will reject the update.
|
@@ -148,7 +146,6 @@ module Twitter
|
|
148
146
|
# @option options [Float] :long The longitude of the location this tweet refers to. The valid ranges for longitude is -180.0 to +180.0 (East is positive) inclusive. This option will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding :lat option.
|
149
147
|
# @option options [Twitter::Place] :place A place in the world. These can be retrieved from {Twitter::REST::PlacesAndGeo#reverse_geocode}.
|
150
148
|
# @option options [String] :place_id A place in the world. These IDs can be retrieved from {Twitter::REST::PlacesAndGeo#reverse_geocode}.
|
151
|
-
# @option options [String] :media_ids A comma separated list of uploaded media IDs to attach to the Tweet.
|
152
149
|
# @option options [String] :display_coordinates Whether or not to put a pin on the exact coordinates a tweet has been sent from.
|
153
150
|
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
154
151
|
def update!(status, options = {})
|
@@ -211,10 +208,9 @@ module Twitter
|
|
211
208
|
# @rate_limited No
|
212
209
|
# @authentication Requires user context
|
213
210
|
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
214
|
-
# @raise [Twitter::Error::UnacceptableIO] Error when the IO object for the media argument does not have a to_io method.
|
215
211
|
# @return [Twitter::Tweet] The created Tweet.
|
216
|
-
# @param status [String] The text of your status update, up to
|
217
|
-
# @param media [File,
|
212
|
+
# @param status [String] The text of your status update, up to 280 characters.
|
213
|
+
# @param media [File, Array<File>] An image file or array of image files (PNG, JPEG or GIF).
|
218
214
|
# @param options [Hash] A customizable set of options.
|
219
215
|
# @option options [Boolean, String, Integer] :possibly_sensitive Set to true for content which may not be suitable for every audience.
|
220
216
|
# @option options [Twitter::Tweet] :in_reply_to_status An existing status that the update is in reply to.
|
@@ -226,11 +222,11 @@ module Twitter
|
|
226
222
|
# @option options [String] :display_coordinates Whether or not to put a pin on the exact coordinates a tweet has been sent from.
|
227
223
|
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
228
224
|
def update_with_media(status, media, options = {})
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
225
|
+
options = options.dup
|
226
|
+
media_ids = pmap(array_wrap(media)) do |medium|
|
227
|
+
upload(medium)[:media_id]
|
228
|
+
end
|
229
|
+
update!(status, options.merge(media_ids: media_ids.join(',')))
|
234
230
|
end
|
235
231
|
|
236
232
|
# Returns oEmbed for a Tweet
|
@@ -252,6 +248,7 @@ module Twitter
|
|
252
248
|
# @option options [String] :widget_type Set to video to return a Twitter Video embed for the given Tweet.
|
253
249
|
# @option options [Boolean, String] :hide_tweet Applies to video type only. Set to 1 or true to link directly to the Tweet URL instead of displaying a Tweet overlay when a viewer clicks on the Twitter bird logo.
|
254
250
|
def oembed(tweet, options = {})
|
251
|
+
options = options.dup
|
255
252
|
options[:id] = extract_id(tweet)
|
256
253
|
perform_get_with_object('/1.1/statuses/oembed.json', options, Twitter::OEmbed)
|
257
254
|
end
|
@@ -300,12 +297,80 @@ module Twitter
|
|
300
297
|
perform_get_with_cursor('/1.1/statuses/retweeters/ids.json', arguments.options, :ids)
|
301
298
|
end
|
302
299
|
|
300
|
+
# Untweets a retweeted status as the authenticating user
|
301
|
+
#
|
302
|
+
# @see https://dev.twitter.com/rest/reference/post/statuses/unretweet/:id
|
303
|
+
# @rate_limited Yes
|
304
|
+
# @authentication Requires user context
|
305
|
+
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
306
|
+
# @return [Array<Twitter::Tweet>] The original tweets with retweet details embedded.
|
307
|
+
# @overload unretweet(*tweets)
|
308
|
+
# @param tweets [Enumerable<Integer, String, URI, Twitter::Tweet>] A collection of Tweet IDs, URIs, or objects.
|
309
|
+
# @overload unretweet(*tweets, options)
|
310
|
+
# @param tweets [Enumerable<Integer, String, URI, Twitter::Tweet>] A collection of Tweet IDs, URIs, or objects.
|
311
|
+
# @param options [Hash] A customizable set of options.
|
312
|
+
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
313
|
+
def unretweet(*args)
|
314
|
+
arguments = Twitter::Arguments.new(args)
|
315
|
+
pmap(arguments) do |tweet|
|
316
|
+
begin
|
317
|
+
post_unretweet(extract_id(tweet), arguments.options)
|
318
|
+
rescue Twitter::Error::NotFound
|
319
|
+
next
|
320
|
+
end
|
321
|
+
end.compact
|
322
|
+
end
|
323
|
+
|
303
324
|
private
|
304
325
|
|
326
|
+
# Uploads images and videos. Videos require multiple requests and uploads in chunks of 5 Megabytes.
|
327
|
+
# The only supported video format is mp4.
|
328
|
+
#
|
329
|
+
# @see https://dev.twitter.com/rest/public/uploading-media
|
330
|
+
def upload(media) # rubocop:disable MethodLength, AbcSize
|
331
|
+
if File.basename(media) !~ /\.mp4$/
|
332
|
+
Twitter::REST::Request.new(self, :multipart_post, 'https://upload.twitter.com/1.1/media/upload.json', key: :media, file: media).perform
|
333
|
+
else
|
334
|
+
init = Twitter::REST::Request.new(self, :post, 'https://upload.twitter.com/1.1/media/upload.json',
|
335
|
+
command: 'INIT',
|
336
|
+
media_type: 'video/mp4',
|
337
|
+
total_bytes: media.size).perform
|
338
|
+
|
339
|
+
until media.eof?
|
340
|
+
chunk = media.read(5_000_000)
|
341
|
+
seg ||= -1
|
342
|
+
Twitter::REST::Request.new(self, :multipart_post, 'https://upload.twitter.com/1.1/media/upload.json',
|
343
|
+
command: 'APPEND',
|
344
|
+
media_id: init[:media_id],
|
345
|
+
segment_index: seg += 1,
|
346
|
+
key: :media,
|
347
|
+
file: StringIO.new(chunk)).perform
|
348
|
+
end
|
349
|
+
|
350
|
+
media.close
|
351
|
+
|
352
|
+
Twitter::REST::Request.new(self, :post, 'https://upload.twitter.com/1.1/media/upload.json',
|
353
|
+
command: 'FINALIZE', media_id: init[:media_id]).perform
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def array_wrap(object)
|
358
|
+
if object.respond_to?(:to_ary)
|
359
|
+
object.to_ary || [object]
|
360
|
+
else
|
361
|
+
[object]
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
305
365
|
def post_retweet(tweet, options)
|
306
366
|
response = perform_post("/1.1/statuses/retweet/#{extract_id(tweet)}.json", options)
|
307
367
|
Twitter::Tweet.new(response)
|
308
368
|
end
|
369
|
+
|
370
|
+
def post_unretweet(tweet, options)
|
371
|
+
response = perform_post("/1.1/statuses/unretweet/#{extract_id(tweet)}.json", options)
|
372
|
+
Twitter::Tweet.new(response)
|
373
|
+
end
|
309
374
|
end
|
310
375
|
end
|
311
376
|
end
|
@@ -33,11 +33,10 @@ module Twitter
|
|
33
33
|
# @rate_limited No
|
34
34
|
# @authentication Not required
|
35
35
|
# @return [Integer]
|
36
|
-
# @param
|
36
|
+
# @param url [String, URI] A URL.
|
37
37
|
# @param options [Hash] A customizable set of options.
|
38
|
-
def tweet_count(
|
39
|
-
|
40
|
-
connection.get('/1/urls/count.json', options.merge(url: uri.to_s)).body[:count]
|
38
|
+
def tweet_count(url, options = {})
|
39
|
+
HTTP.get('https://cdn.api.twitter.com/1/urls/count.json', params: options.merge(url: url.to_s)).parse['count']
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
data/lib/twitter/rest/users.rb
CHANGED
@@ -30,11 +30,13 @@ module Twitter
|
|
30
30
|
# @option options [Integer] :end_sleep_time The hour that sleep time should end if it is enabled. The value for this parameter should be provided in {http://en.wikipedia.org/wiki/ISO_8601 ISO8601} format (i.e. 00-23). The time is considered to be in the same timezone as the user's time_zone setting.
|
31
31
|
# @option options [String] :time_zone The timezone dates and times should be displayed in for the user. The timezone must be one of the {http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html Rails TimeZone} names.
|
32
32
|
# @option options [String] :lang The language which Twitter should render in for this user. The language must be specified by the appropriate two letter ISO 639-1 representation. Currently supported languages are provided by {https://dev.twitter.com/rest/reference/get/help/languages GET help/languages}.
|
33
|
+
# @option options [String] :allow_contributor_request Whether to allow others to include user as contributor. Possible values include 'all' (anyone can include user), 'following' (only followers can include user) or 'none'. Also note that changes to this field require the request also include a current_password value with the user's password to successfully modify this field.
|
34
|
+
# @option options [String] :current_password The user's password. This is only required when modifying the allow_contributor_request field.
|
33
35
|
def settings(options = {})
|
34
36
|
request_method = options.size.zero? ? :get : :post
|
35
37
|
response = perform_request(request_method.to_sym, '/1.1/account/settings.json', options)
|
36
38
|
# https://dev.twitter.com/issues/59
|
37
|
-
response
|
39
|
+
response[:trend_location] = response.fetch(:trend_location, []).first
|
38
40
|
Twitter::Settings.new(response)
|
39
41
|
end
|
40
42
|
|
@@ -50,7 +52,6 @@ module Twitter
|
|
50
52
|
def verify_credentials(options = {})
|
51
53
|
perform_get_with_object('/1.1/account/verify_credentials.json', options, Twitter::User)
|
52
54
|
end
|
53
|
-
alias current_user verify_credentials
|
54
55
|
|
55
56
|
# Sets which device Twitter delivers updates to for the authenticating user
|
56
57
|
#
|
@@ -78,6 +79,7 @@ module Twitter
|
|
78
79
|
# @option options [String] :url URL associated with the profile. Will be prepended with "http://" if not present. Maximum of 100 characters.
|
79
80
|
# @option options [String] :location The city or country describing where the user of the account is located. The contents are not normalized or geocoded in any way. Maximum of 30 characters.
|
80
81
|
# @option options [String] :description A description of the user owning the account. Maximum of 160 characters.
|
82
|
+
# @option options [String] :profile_link_color A hex value of the color scheme used for links on user's profile page. Must be a valid hexadecimal value, and may be either three or six characters
|
81
83
|
def update_profile(options = {})
|
82
84
|
perform_post_with_object('/1.1/account/update_profile.json', options, Twitter::User)
|
83
85
|
end
|
@@ -93,24 +95,7 @@ module Twitter
|
|
93
95
|
# @param options [Hash] A customizable set of options.
|
94
96
|
# @option options [Boolean] :tile Whether or not to tile the background image. If set to true the background image will be displayed tiled. The image will not be tiled otherwise.
|
95
97
|
def update_profile_background_image(image, options = {})
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
# Sets one or more hex values that control the color scheme of the authenticating user's profile
|
100
|
-
#
|
101
|
-
# @see https://dev.twitter.com/rest/reference/post/account/update_profile_colors
|
102
|
-
# @rate_limited No
|
103
|
-
# @authentication Requires user context
|
104
|
-
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
105
|
-
# @return [Twitter::User] The authenticated user.
|
106
|
-
# @param options [Hash] A customizable set of options.
|
107
|
-
# @option options [String] :profile_background_color Profile background color.
|
108
|
-
# @option options [String] :profile_text_color Profile text color.
|
109
|
-
# @option options [String] :profile_link_color Profile link color.
|
110
|
-
# @option options [String] :profile_sidebar_fill_color Profile sidebar's background color.
|
111
|
-
# @option options [String] :profile_sidebar_border_color Profile sidebar's border color.
|
112
|
-
def update_profile_colors(options = {})
|
113
|
-
perform_post_with_object('/1.1/account/update_profile_colors.json', options, Twitter::User)
|
98
|
+
post_profile_image('/1.1/account/update_profile_background_image.json', image, options)
|
114
99
|
end
|
115
100
|
|
116
101
|
# Updates the authenticating user's profile image
|
@@ -125,7 +110,7 @@ module Twitter
|
|
125
110
|
# @param image [File] The avatar image for the profile, base64-encoded. Must be a valid GIF, JPG, or PNG image of less than 700 kilobytes in size. Images with width larger than 500 pixels will be scaled down. Animated GIFs will be converted to a static GIF of the first frame, removing the animation.
|
126
111
|
# @param options [Hash] A customizable set of options.
|
127
112
|
def update_profile_image(image, options = {})
|
128
|
-
|
113
|
+
post_profile_image('/1.1/account/update_profile_image.json', image, options)
|
129
114
|
end
|
130
115
|
|
131
116
|
# Returns an array of user objects that the authenticating user is blocking
|
@@ -140,7 +125,6 @@ module Twitter
|
|
140
125
|
def blocked(options = {})
|
141
126
|
perform_get_with_cursor('/1.1/blocks/list.json', options, :users, Twitter::User)
|
142
127
|
end
|
143
|
-
deprecate_alias :blocking, :blocked
|
144
128
|
|
145
129
|
# Returns an array of numeric user IDs the authenticating user is blocking
|
146
130
|
#
|
@@ -167,17 +151,12 @@ module Twitter
|
|
167
151
|
# @param user [Integer, String, URI, Twitter::User] A Twitter user ID, screen name, URI, or object.
|
168
152
|
# @param options [Hash] A customizable set of options.
|
169
153
|
def block?(user, options = {})
|
170
|
-
user_id =
|
154
|
+
user_id =
|
171
155
|
case user
|
172
|
-
when Integer
|
173
|
-
|
174
|
-
when
|
175
|
-
user(user).id
|
176
|
-
when Twitter::User
|
177
|
-
user.id
|
156
|
+
when Integer then user
|
157
|
+
when String, URI, Addressable::URI then user(user).id
|
158
|
+
when Twitter::User then user.id
|
178
159
|
end
|
179
|
-
end
|
180
|
-
|
181
160
|
blocked_ids(options).collect(&:to_i).include?(user_id)
|
182
161
|
end
|
183
162
|
|
@@ -229,7 +208,7 @@ module Twitter
|
|
229
208
|
def users(*args)
|
230
209
|
arguments = Twitter::Arguments.new(args)
|
231
210
|
flat_pmap(arguments.each_slice(MAX_USERS_PER_REQUEST)) do |users|
|
232
|
-
|
211
|
+
perform_get_with_objects('/1.1/users/lookup.json', merge_users(arguments.options, users), Twitter::User)
|
233
212
|
end
|
234
213
|
end
|
235
214
|
|
@@ -267,6 +246,7 @@ module Twitter
|
|
267
246
|
# @return [Boolean] true if the user exists, otherwise false.
|
268
247
|
# @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, URI, or object.
|
269
248
|
def user?(user, options = {})
|
249
|
+
options = options.dup
|
270
250
|
merge_user!(options, user)
|
271
251
|
perform_get('/1.1/users/show.json', options)
|
272
252
|
true
|
@@ -286,6 +266,7 @@ module Twitter
|
|
286
266
|
# @option options [Integer] :count The number of people to retrieve. Maxiumum of 20 allowed per page.
|
287
267
|
# @option options [Integer] :page Specifies the page of results to retrieve.
|
288
268
|
def user_search(query, options = {})
|
269
|
+
options = options.dup
|
289
270
|
perform_get_with_objects('/1.1/users/search.json', options.merge(q: query), Twitter::User)
|
290
271
|
end
|
291
272
|
|
@@ -337,7 +318,6 @@ module Twitter
|
|
337
318
|
perform_post('/1.1/account/remove_profile_banner.json', options)
|
338
319
|
true
|
339
320
|
end
|
340
|
-
deprecate_alias :profile_banner_remove, :remove_profile_banner
|
341
321
|
|
342
322
|
# Updates the authenticating user's profile banner image
|
343
323
|
#
|
@@ -422,7 +402,6 @@ module Twitter
|
|
422
402
|
def muted(options = {})
|
423
403
|
perform_get_with_cursor('/1.1/mutes/users/list.json', options, :users, Twitter::User)
|
424
404
|
end
|
425
|
-
deprecate_alias :muting, :muted
|
426
405
|
|
427
406
|
# Returns an array of numeric user IDs the authenticating user is muting
|
428
407
|
#
|
@@ -438,6 +417,13 @@ module Twitter
|
|
438
417
|
merge_user!(arguments.options, arguments.pop)
|
439
418
|
perform_get_with_cursor('/1.1/mutes/users/ids.json', arguments.options, :ids)
|
440
419
|
end
|
420
|
+
|
421
|
+
private
|
422
|
+
|
423
|
+
def post_profile_image(path, image, options)
|
424
|
+
response = Twitter::REST::Request.new(self, :multipart_post, path, options.merge(key: :image, file: image)).perform
|
425
|
+
Twitter::User.new(response)
|
426
|
+
end
|
441
427
|
end
|
442
428
|
end
|
443
429
|
end
|