twitter 5.17.0 → 7.0.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 +37 -10
- data/LICENSE.md +1 -1
- data/README.md +78 -407
- data/lib/twitter/base.rb +5 -19
- data/lib/twitter/basic_user.rb +0 -3
- data/lib/twitter/client.rb +9 -23
- data/lib/twitter/configuration.rb +4 -4
- data/lib/twitter/creatable.rb +5 -1
- data/lib/twitter/cursor.rb +13 -4
- data/lib/twitter/direct_message.rb +2 -0
- data/lib/twitter/direct_message_event.rb +44 -0
- data/lib/twitter/direct_messages/welcome_message.rb +17 -0
- data/lib/twitter/direct_messages/welcome_message_rule.rb +12 -0
- data/lib/twitter/direct_messages/welcome_message_rule_wrapper.rb +36 -0
- data/lib/twitter/direct_messages/welcome_message_wrapper.rb +42 -0
- data/lib/twitter/entity/uri.rb +0 -4
- data/lib/twitter/enumerable.rb +14 -3
- data/lib/twitter/error.rb +122 -95
- data/lib/twitter/geo_results.rb +0 -1
- data/lib/twitter/headers.rb +11 -15
- data/lib/twitter/media/photo.rb +5 -2
- data/lib/twitter/media/video.rb +5 -2
- data/lib/twitter/media/video_info.rb +1 -1
- data/lib/twitter/null_object.rb +20 -7
- data/lib/twitter/premium_search_results.rb +67 -0
- data/lib/twitter/profile.rb +5 -4
- data/lib/twitter/profile_banner.rb +1 -2
- data/lib/twitter/rate_limit.rb +3 -3
- data/lib/twitter/rest/account_activity.rb +99 -0
- data/lib/twitter/rest/api.rb +6 -2
- data/lib/twitter/rest/client.rb +0 -78
- data/lib/twitter/rest/direct_messages/welcome_messages.rb +90 -0
- data/lib/twitter/rest/direct_messages.rb +133 -44
- data/lib/twitter/rest/favorites.rb +29 -8
- data/lib/twitter/rest/friends_and_followers.rb +1 -3
- data/lib/twitter/rest/lists.rb +20 -30
- data/lib/twitter/rest/oauth.rb +15 -15
- data/lib/twitter/rest/premium_search.rb +34 -0
- data/lib/twitter/rest/request.rb +133 -18
- data/lib/twitter/rest/saved_searches.rb +1 -3
- data/lib/twitter/rest/search.rb +6 -3
- data/lib/twitter/rest/timelines.rb +1 -0
- data/lib/twitter/rest/trends.rb +1 -0
- data/lib/twitter/rest/tweets.rb +54 -18
- data/lib/twitter/rest/undocumented.rb +3 -4
- data/lib/twitter/rest/upload_utils.rb +68 -0
- data/lib/twitter/rest/users.rb +23 -37
- data/lib/twitter/rest/utils.rb +38 -28
- data/lib/twitter/search_results.rb +4 -4
- data/lib/twitter/streaming/client.rb +23 -25
- data/lib/twitter/streaming/connection.rb +37 -11
- 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 +7 -3
- data/lib/twitter/trend_results.rb +1 -2
- data/lib/twitter/tweet.rb +11 -6
- data/lib/twitter/user.rb +2 -4
- data/lib/twitter/utils.rb +5 -18
- data/lib/twitter/version.rb +6 -6
- data/lib/twitter.rb +5 -0
- data/twitter.gemspec +10 -11
- metadata +31 -42
- 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/base.rb
CHANGED
@@ -13,7 +13,6 @@ module Twitter
|
|
13
13
|
attr_reader :attrs
|
14
14
|
alias to_h attrs
|
15
15
|
alias to_hash to_h
|
16
|
-
deprecate_alias :to_hsh, :to_hash
|
17
16
|
|
18
17
|
class << self
|
19
18
|
# Define methods that retrieve the value from attributes
|
@@ -29,7 +28,6 @@ module Twitter
|
|
29
28
|
def predicate_attr_reader(*attrs)
|
30
29
|
attrs.each do |attr|
|
31
30
|
define_predicate_method(attr)
|
32
|
-
deprecate_attribute_method(attr)
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
@@ -72,7 +70,7 @@ module Twitter
|
|
72
70
|
# @param key1 [Symbol]
|
73
71
|
# @param key2 [Symbol]
|
74
72
|
def define_uri_method(key1, key2)
|
75
|
-
define_method(key1) do
|
73
|
+
define_method(key1) do
|
76
74
|
Addressable::URI.parse(@attrs[key2].chomp('#')) unless @attrs[key2].nil?
|
77
75
|
end
|
78
76
|
memoize(key1)
|
@@ -84,34 +82,22 @@ module Twitter
|
|
84
82
|
# @param klass [Symbol]
|
85
83
|
# @param key2 [Symbol]
|
86
84
|
def define_attribute_method(key1, klass = nil, key2 = nil)
|
87
|
-
define_method(key1) do
|
85
|
+
define_method(key1) do
|
88
86
|
if attr_falsey_or_empty?(key1)
|
89
87
|
NullObject.new
|
90
|
-
elsif klass.nil?
|
91
|
-
@attrs[key1]
|
92
88
|
else
|
93
|
-
attrs
|
94
|
-
Twitter.const_get(klass).new(attrs)
|
89
|
+
klass.nil? ? @attrs[key1] : Twitter.const_get(klass).new(attrs_for_object(key1, key2))
|
95
90
|
end
|
96
91
|
end
|
97
92
|
memoize(key1)
|
98
93
|
end
|
99
94
|
|
100
|
-
# @param key [Symbol]
|
101
|
-
def deprecate_attribute_method(key)
|
102
|
-
define_method(key) do ||
|
103
|
-
warn "#{Kernel.caller.first}: [DEPRECATION] ##{key} is deprecated. Use ##{key}? instead."
|
104
|
-
@attrs[key]
|
105
|
-
end
|
106
|
-
memoize(key)
|
107
|
-
end
|
108
|
-
|
109
95
|
# Dynamically define a predicate method for an attribute
|
110
96
|
#
|
111
97
|
# @param key1 [Symbol]
|
112
98
|
# @param key2 [Symbol]
|
113
99
|
def define_predicate_method(key1, key2 = key1)
|
114
|
-
define_method(:"#{key1}?") do
|
100
|
+
define_method(:"#{key1}?") do
|
115
101
|
!attr_falsey_or_empty?(key2)
|
116
102
|
end
|
117
103
|
memoize(:"#{key1}?")
|
@@ -139,7 +125,7 @@ module Twitter
|
|
139
125
|
private
|
140
126
|
|
141
127
|
def attr_falsey_or_empty?(key)
|
142
|
-
|
128
|
+
!@attrs[key] || @attrs[key].respond_to?(:empty?) && @attrs[key].empty?
|
143
129
|
end
|
144
130
|
|
145
131
|
def attrs_for_object(key1, key2 = nil)
|
data/lib/twitter/basic_user.rb
CHANGED
@@ -5,9 +5,6 @@ module Twitter
|
|
5
5
|
class BasicUser < Twitter::Identity
|
6
6
|
# @return [String]
|
7
7
|
attr_reader :screen_name
|
8
|
-
deprecate_alias :handle, :screen_name
|
9
|
-
deprecate_alias :username, :screen_name
|
10
|
-
deprecate_alias :user_name, :screen_name
|
11
8
|
predicate_attr_reader :following
|
12
9
|
end
|
13
10
|
end
|
data/lib/twitter/client.rb
CHANGED
@@ -5,12 +5,8 @@ require 'twitter/version'
|
|
5
5
|
module Twitter
|
6
6
|
class Client
|
7
7
|
include Twitter::Utils
|
8
|
-
attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret, :proxy
|
8
|
+
attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret, :proxy, :timeouts, :dev_environment
|
9
9
|
attr_writer :user_agent
|
10
|
-
deprecate_alias :oauth_token, :access_token
|
11
|
-
deprecate_alias :oauth_token=, :access_token=
|
12
|
-
deprecate_alias :oauth_token_secret, :access_token_secret
|
13
|
-
deprecate_alias :oauth_token_secret=, :access_token_secret=
|
14
10
|
|
15
11
|
# Initializes a new Client object
|
16
12
|
#
|
@@ -21,12 +17,11 @@ module Twitter
|
|
21
17
|
instance_variable_set("@#{key}", value)
|
22
18
|
end
|
23
19
|
yield(self) if block_given?
|
24
|
-
validate_credentials!
|
25
20
|
end
|
26
21
|
|
27
22
|
# @return [Boolean]
|
28
23
|
def user_token?
|
29
|
-
|
24
|
+
!(blank_string?(access_token) || blank_string?(access_token_secret))
|
30
25
|
end
|
31
26
|
|
32
27
|
# @return [String]
|
@@ -37,31 +32,22 @@ module Twitter
|
|
37
32
|
# @return [Hash]
|
38
33
|
def credentials
|
39
34
|
{
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:ignore_extra_keys => true,
|
35
|
+
consumer_key: consumer_key,
|
36
|
+
consumer_secret: consumer_secret,
|
37
|
+
token: access_token,
|
38
|
+
token_secret: access_token_secret,
|
45
39
|
}
|
46
40
|
end
|
47
41
|
|
48
42
|
# @return [Boolean]
|
49
43
|
def credentials?
|
50
|
-
credentials.values.
|
44
|
+
credentials.values.none? { |v| blank_string?(v) }
|
51
45
|
end
|
52
46
|
|
53
47
|
private
|
54
48
|
|
55
|
-
|
56
|
-
|
57
|
-
#
|
58
|
-
# @raise [Twitter::Error::ConfigurationError] Error is raised when
|
59
|
-
# supplied twitter credentials are not a String or Boolean.
|
60
|
-
def validate_credentials!
|
61
|
-
credentials.each do |credential, value|
|
62
|
-
next if value.nil? || value == true || value == false || value.is_a?(String)
|
63
|
-
raise(Twitter::Error::ConfigurationError.new("Invalid #{credential} specified: #{value.inspect} must be a String."))
|
64
|
-
end
|
49
|
+
def blank_string?(string)
|
50
|
+
string.respond_to?(:empty?) ? string.empty? : !string
|
65
51
|
end
|
66
52
|
end
|
67
53
|
end
|
@@ -8,8 +8,9 @@ module Twitter
|
|
8
8
|
# @return [Array<String>]
|
9
9
|
attr_reader :non_username_paths
|
10
10
|
# @return [Integer]
|
11
|
-
attr_reader :characters_reserved_per_media, :
|
12
|
-
:photo_size_limit, :short_url_length,
|
11
|
+
attr_reader :characters_reserved_per_media, :dm_text_character_limit,
|
12
|
+
:max_media_per_upload, :photo_size_limit, :short_url_length,
|
13
|
+
:short_url_length_https
|
13
14
|
alias short_uri_length short_url_length
|
14
15
|
alias short_uri_length_https short_url_length_https
|
15
16
|
|
@@ -17,9 +18,8 @@ module Twitter
|
|
17
18
|
#
|
18
19
|
# @return [Array<Twitter::Size>]
|
19
20
|
def photo_sizes
|
20
|
-
@attrs.fetch(:photo_sizes, []).
|
21
|
+
@attrs.fetch(:photo_sizes, []).each_with_object({}) do |(key, value), object|
|
21
22
|
object[key] = Size.new(value)
|
22
|
-
object
|
23
23
|
end
|
24
24
|
end
|
25
25
|
memoize :photo_sizes
|
data/lib/twitter/creatable.rb
CHANGED
@@ -9,7 +9,11 @@ module Twitter
|
|
9
9
|
#
|
10
10
|
# @return [Time]
|
11
11
|
def created_at
|
12
|
-
|
12
|
+
time = @attrs[:created_at]
|
13
|
+
return if time.nil?
|
14
|
+
|
15
|
+
time = Time.parse(time) unless time.is_a?(Time)
|
16
|
+
time.utc
|
13
17
|
end
|
14
18
|
memoize :created_at
|
15
19
|
|
data/lib/twitter/cursor.rb
CHANGED
@@ -10,15 +10,15 @@ module Twitter
|
|
10
10
|
attr_reader :attrs
|
11
11
|
alias to_h attrs
|
12
12
|
alias to_hash to_h
|
13
|
-
deprecate_alias :to_hsh, :to_hash
|
14
13
|
|
15
14
|
# Initializes a new Cursor
|
16
15
|
#
|
17
16
|
# @param key [String, Symbol] The key to fetch the data from the response
|
18
17
|
# @param klass [Class] The class to instantiate objects in the response
|
19
18
|
# @param request [Twitter::REST::Request]
|
19
|
+
# @param limit [Integer] After reaching the limit, we stop fetching next page
|
20
20
|
# @return [Twitter::Cursor]
|
21
|
-
def initialize(key, klass, request)
|
21
|
+
def initialize(key, klass, request, limit = nil)
|
22
22
|
@key = key.to_sym
|
23
23
|
@klass = klass
|
24
24
|
@client = request.client
|
@@ -26,6 +26,7 @@ module Twitter
|
|
26
26
|
@path = request.path
|
27
27
|
@options = request.options
|
28
28
|
@collection = []
|
29
|
+
@limit = limit
|
29
30
|
self.attrs = request.perform
|
30
31
|
end
|
31
32
|
|
@@ -33,18 +34,26 @@ module Twitter
|
|
33
34
|
|
34
35
|
# @return [Integer]
|
35
36
|
def next_cursor
|
36
|
-
@attrs[:next_cursor]
|
37
|
+
@attrs[:next_cursor]
|
37
38
|
end
|
38
39
|
alias next next_cursor
|
39
40
|
|
40
41
|
# @return [Boolean]
|
41
42
|
def last?
|
43
|
+
return false if next_cursor.is_a?(String)
|
44
|
+
return true if next_cursor.nil?
|
45
|
+
|
42
46
|
next_cursor.zero?
|
43
47
|
end
|
44
48
|
|
49
|
+
# @return [Boolean]
|
50
|
+
def reached_limit?
|
51
|
+
@limit && @limit <= attrs[@key].count
|
52
|
+
end
|
53
|
+
|
45
54
|
# @return [Hash]
|
46
55
|
def fetch_next_page
|
47
|
-
response = Twitter::REST::Request.new(@client, @request_method, @path, @options.merge(:
|
56
|
+
response = Twitter::REST::Request.new(@client, @request_method, @path, @options.merge(cursor: next_cursor)).perform
|
48
57
|
self.attrs = response
|
49
58
|
end
|
50
59
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'twitter/creatable'
|
2
|
+
require 'twitter/entities'
|
3
|
+
require 'twitter/identity'
|
4
|
+
|
5
|
+
module Twitter
|
6
|
+
class DirectMessageEvent < Twitter::Identity
|
7
|
+
include Twitter::Creatable
|
8
|
+
include Twitter::Entities
|
9
|
+
|
10
|
+
attr_reader :created_timestamp
|
11
|
+
|
12
|
+
object_attr_reader :DirectMessage, :direct_message
|
13
|
+
|
14
|
+
def initialize(attrs)
|
15
|
+
attrs = read_from_response(attrs)
|
16
|
+
text = attrs.dig(:message_create, :message_data, :text)
|
17
|
+
urls = attrs.dig(:message_create, :message_data, :entities, :urls)
|
18
|
+
|
19
|
+
text.gsub!(urls[0][:url], urls[0][:expanded_url]) if urls.any?
|
20
|
+
|
21
|
+
attrs[:direct_message] = build_direct_message(attrs, text)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# @return [Hash] Normalized hash of attrs
|
28
|
+
def read_from_response(attrs)
|
29
|
+
attrs[:event].nil? ? attrs : attrs[:event]
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_direct_message(attrs, text)
|
33
|
+
recipient_id = attrs[:message_create][:target][:recipient_id].to_i
|
34
|
+
sender_id = attrs[:message_create][:sender_id].to_i
|
35
|
+
{id: attrs[:id].to_i,
|
36
|
+
created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
|
37
|
+
sender: {id: sender_id},
|
38
|
+
sender_id: sender_id,
|
39
|
+
recipient: {id: recipient_id},
|
40
|
+
recipient_id: recipient_id,
|
41
|
+
text: text}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'twitter/creatable'
|
2
|
+
require 'twitter/entities'
|
3
|
+
require 'twitter/identity'
|
4
|
+
|
5
|
+
module Twitter
|
6
|
+
module DirectMessages
|
7
|
+
class WelcomeMessage < Twitter::Identity
|
8
|
+
include Twitter::Creatable
|
9
|
+
include Twitter::Entities
|
10
|
+
# @return [String]
|
11
|
+
attr_reader :text
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :name
|
14
|
+
alias full_text text
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'twitter/creatable'
|
2
|
+
require 'twitter/identity'
|
3
|
+
|
4
|
+
module Twitter
|
5
|
+
module DirectMessages
|
6
|
+
class WelcomeMessageRuleWrapper < Twitter::Identity
|
7
|
+
attr_reader :created_timestamp
|
8
|
+
|
9
|
+
object_attr_reader 'DirectMessages::WelcomeMessageRule', :welcome_message_rule
|
10
|
+
|
11
|
+
def initialize(attrs)
|
12
|
+
attrs = read_from_response(attrs)
|
13
|
+
|
14
|
+
attrs[:welcome_message_rule] = build_welcome_message_rule(attrs)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# @return [Hash] Normalized hash of attrs
|
21
|
+
def read_from_response(attrs)
|
22
|
+
return attrs[:welcome_message_rule] unless attrs[:welcome_message_rule].nil?
|
23
|
+
|
24
|
+
attrs
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_welcome_message_rule(attrs)
|
28
|
+
{
|
29
|
+
id: attrs[:id].to_i,
|
30
|
+
created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
|
31
|
+
welcome_message_id: attrs[:welcome_message_id].to_i,
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'twitter/creatable'
|
2
|
+
require 'twitter/identity'
|
3
|
+
|
4
|
+
module Twitter
|
5
|
+
module DirectMessages
|
6
|
+
class WelcomeMessageWrapper < Twitter::Identity
|
7
|
+
attr_reader :created_timestamp
|
8
|
+
|
9
|
+
object_attr_reader 'DirectMessages::WelcomeMessage', :welcome_message
|
10
|
+
|
11
|
+
def initialize(attrs)
|
12
|
+
attrs = read_from_response(attrs)
|
13
|
+
text = attrs.dig(:message_data, :text)
|
14
|
+
urls = attrs.dig(:message_data, :entities, :urls)
|
15
|
+
|
16
|
+
text.gsub!(urls[0][:url], urls[0][:expanded_url]) if urls.any?
|
17
|
+
|
18
|
+
attrs[:welcome_message] = build_welcome_message(attrs, text)
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# @return [Hash] Normalized hash of attrs
|
25
|
+
def read_from_response(attrs)
|
26
|
+
return attrs[:welcome_message] unless attrs[:welcome_message].nil?
|
27
|
+
|
28
|
+
attrs
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_welcome_message(attrs, text)
|
32
|
+
{
|
33
|
+
id: attrs[:id].to_i,
|
34
|
+
created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
|
35
|
+
text: text,
|
36
|
+
name: attrs[:name],
|
37
|
+
entities: attrs.dig(:message_data, :entities),
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/twitter/entity/uri.rb
CHANGED
data/lib/twitter/enumerable.rb
CHANGED
@@ -3,15 +3,16 @@ module Twitter
|
|
3
3
|
include ::Enumerable
|
4
4
|
|
5
5
|
# @return [Enumerator]
|
6
|
-
def each(start = 0)
|
6
|
+
def each(start = 0, &block)
|
7
7
|
return to_enum(:each, start) unless block_given?
|
8
|
+
|
8
9
|
Array(@collection[start..-1]).each do |element|
|
9
10
|
yield(element)
|
10
11
|
end
|
11
|
-
unless
|
12
|
+
unless finished?
|
12
13
|
start = [@collection.size, start].max
|
13
14
|
fetch_next_page
|
14
|
-
each(start, &
|
15
|
+
each(start, &block)
|
15
16
|
end
|
16
17
|
self
|
17
18
|
end
|
@@ -22,5 +23,15 @@ module Twitter
|
|
22
23
|
def last?
|
23
24
|
true
|
24
25
|
end
|
26
|
+
|
27
|
+
# @return [Boolean]
|
28
|
+
def reached_limit?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Boolean]
|
33
|
+
def finished?
|
34
|
+
last? || reached_limit?
|
35
|
+
end
|
25
36
|
end
|
26
37
|
end
|