twitter 8.1.0 → 8.3.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
- data/LICENSE.md +1 -1
- data/README.md +173 -11
- data/lib/twitter/arguments.rb +14 -1
- data/lib/twitter/base.rb +72 -11
- data/lib/twitter/basic_user.rb +7 -1
- data/lib/twitter/client.rb +94 -3
- data/lib/twitter/creatable.rb +11 -2
- data/lib/twitter/cursor.rb +58 -11
- data/lib/twitter/direct_message.rb +32 -4
- data/lib/twitter/direct_message_event.rb +34 -10
- data/lib/twitter/direct_messages/welcome_message.rb +22 -1
- data/lib/twitter/direct_messages/welcome_message_rule.rb +7 -0
- data/lib/twitter/direct_messages/welcome_message_rule_wrapper.rb +26 -3
- data/lib/twitter/direct_messages/welcome_message_wrapper.rb +36 -11
- data/lib/twitter/entities.rb +84 -8
- data/lib/twitter/entity/hashtag.rb +7 -1
- data/lib/twitter/entity/symbol.rb +7 -1
- data/lib/twitter/entity/uri.rb +2 -1
- data/lib/twitter/entity/user_mention.rb +20 -1
- data/lib/twitter/entity.rb +7 -1
- data/lib/twitter/enumerable.rb +20 -3
- data/lib/twitter/error.rb +137 -61
- data/lib/twitter/factory.rb +9 -5
- data/lib/twitter/geo/point.rb +37 -5
- data/lib/twitter/geo/polygon.rb +1 -0
- data/lib/twitter/geo.rb +16 -2
- data/lib/twitter/geo_factory.rb +7 -3
- data/lib/twitter/geo_results.rb +39 -8
- data/lib/twitter/headers.rb +44 -7
- data/lib/twitter/identity.rb +13 -3
- data/lib/twitter/language.rb +21 -1
- data/lib/twitter/list.rb +101 -11
- data/lib/twitter/media/animated_gif.rb +1 -0
- data/lib/twitter/media/photo.rb +19 -3
- data/lib/twitter/media/video.rb +21 -3
- data/lib/twitter/media/video_info.rb +15 -1
- data/lib/twitter/media_factory.rb +7 -3
- data/lib/twitter/metadata.rb +14 -1
- data/lib/twitter/null_object.rb +16 -14
- data/lib/twitter/oembed.rb +56 -2
- data/lib/twitter/place.rb +74 -6
- data/lib/twitter/premium_search_results.rb +87 -18
- data/lib/twitter/profile.rb +100 -44
- data/lib/twitter/profile_banner.rb +9 -4
- data/lib/twitter/rate_limit.rb +32 -3
- data/lib/twitter/relationship.rb +8 -5
- data/lib/twitter/rest/account_activity.rb +55 -26
- data/lib/twitter/rest/api.rb +2 -0
- data/lib/twitter/rest/client.rb +18 -0
- data/lib/twitter/rest/direct_messages/welcome_messages.rb +89 -18
- data/lib/twitter/rest/direct_messages.rb +158 -94
- data/lib/twitter/rest/favorites.rb +57 -21
- data/lib/twitter/rest/form_encoder.rb +57 -17
- data/lib/twitter/rest/friends_and_followers.rb +101 -35
- data/lib/twitter/rest/help.rb +13 -3
- data/lib/twitter/rest/lists.rb +133 -45
- data/lib/twitter/rest/oauth.rb +23 -17
- data/lib/twitter/rest/places_and_geo.rb +44 -28
- data/lib/twitter/rest/premium_search.rb +18 -13
- data/lib/twitter/rest/request.rb +171 -53
- data/lib/twitter/rest/saved_searches.rb +22 -7
- data/lib/twitter/rest/search.rb +20 -16
- data/lib/twitter/rest/spam_reporting.rb +5 -1
- data/lib/twitter/rest/suggested_users.rb +14 -5
- data/lib/twitter/rest/timelines.rb +92 -52
- data/lib/twitter/rest/trends.rb +31 -12
- data/lib/twitter/rest/tweets.rb +145 -88
- data/lib/twitter/rest/undocumented.rb +11 -2
- data/lib/twitter/rest/upload_utils.rb +42 -26
- data/lib/twitter/rest/users.rb +150 -71
- data/lib/twitter/rest/utils.rb +135 -39
- data/lib/twitter/saved_search.rb +23 -2
- data/lib/twitter/search_results.rb +62 -17
- data/lib/twitter/settings.rb +37 -11
- data/lib/twitter/size.rb +37 -3
- data/lib/twitter/source_user.rb +4 -3
- data/lib/twitter/streaming/client.rb +60 -8
- data/lib/twitter/streaming/connection.rb +55 -8
- data/lib/twitter/streaming/deleted_tweet.rb +8 -0
- data/lib/twitter/streaming/event.rb +43 -1
- data/lib/twitter/streaming/friend_list.rb +1 -0
- data/lib/twitter/streaming/message_parser.rb +20 -10
- data/lib/twitter/streaming/response.rb +31 -5
- data/lib/twitter/streaming/stall_warning.rb +23 -0
- data/lib/twitter/suggestion.rb +25 -1
- data/lib/twitter/target_user.rb +2 -1
- data/lib/twitter/trend.rb +29 -1
- data/lib/twitter/trend_results.rb +50 -7
- data/lib/twitter/tweet.rb +180 -21
- data/lib/twitter/user.rb +289 -53
- data/lib/twitter/utils.rb +12 -13
- data/lib/twitter/variant.rb +12 -1
- data/lib/twitter/version.rb +66 -29
- data/lib/twitter.rb +6 -1
- metadata +29 -73
- data/.yardopts +0 -16
- data/CHANGELOG.md +0 -1035
- data/CONTRIBUTING.md +0 -49
- data/twitter.gemspec +0 -57
|
@@ -8,13 +8,28 @@ require "twitter/streaming/response"
|
|
|
8
8
|
require "twitter/utils"
|
|
9
9
|
|
|
10
10
|
module Twitter
|
|
11
|
+
# Streaming API modules for Twitter
|
|
11
12
|
module Streaming
|
|
13
|
+
# Client for consuming the Twitter Streaming API
|
|
14
|
+
#
|
|
15
|
+
# @api public
|
|
12
16
|
class Client < Twitter::Client
|
|
13
17
|
include Twitter::Utils
|
|
18
|
+
|
|
19
|
+
# Sets the connection object
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# client.connection = connection
|
|
24
|
+
# @param value [Twitter::Streaming::Connection] The connection to use.
|
|
25
|
+
# @return [Twitter::Streaming::Connection]
|
|
14
26
|
attr_writer :connection
|
|
15
27
|
|
|
16
28
|
# Initializes a new Client object
|
|
17
29
|
#
|
|
30
|
+
# @api public
|
|
31
|
+
# @example
|
|
32
|
+
# client = Twitter::Streaming::Client.new
|
|
18
33
|
# @param options [Hash] A customizable set of options.
|
|
19
34
|
# @option options [String] :tcp_socket_class A class that Connection will use to create a new TCP socket.
|
|
20
35
|
# @option options [String] :ssl_socket_class A class that Connection will use to create a new SSL socket.
|
|
@@ -26,6 +41,9 @@ module Twitter
|
|
|
26
41
|
|
|
27
42
|
# Returns public statuses that match one or more filter predicates
|
|
28
43
|
#
|
|
44
|
+
# @api public
|
|
45
|
+
# @example
|
|
46
|
+
# client.filter(track: 'twitter')
|
|
29
47
|
# @see https://dev.twitter.com/streaming/reference/post/statuses/filter
|
|
30
48
|
# @see https://dev.twitter.com/streaming/overview/request-parameters
|
|
31
49
|
# @note At least one predicate parameter (follow, locations, or track) must be specified.
|
|
@@ -34,33 +52,45 @@ module Twitter
|
|
|
34
52
|
# @option options [String] :track Includes additional Tweets matching the specified keywords. Phrases of keywords are specified by a comma-separated list.
|
|
35
53
|
# @option options [String] :locations Includes additional Tweets falling within the specified bounding boxes.
|
|
36
54
|
# @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects.
|
|
55
|
+
# @return [void]
|
|
37
56
|
def filter(options = {}, &)
|
|
38
57
|
request(:post, "https://stream.twitter.com:443/1.1/statuses/filter.json", options, &)
|
|
39
58
|
end
|
|
40
59
|
|
|
41
60
|
# Returns all public statuses
|
|
42
61
|
#
|
|
62
|
+
# @api public
|
|
63
|
+
# @example
|
|
64
|
+
# client.firehose
|
|
43
65
|
# @see https://dev.twitter.com/streaming/reference/get/statuses/firehose
|
|
44
66
|
# @see https://dev.twitter.com/streaming/overview/request-parameters
|
|
45
67
|
# @note This endpoint requires special permission to access.
|
|
46
68
|
# @param options [Hash] A customizable set of options.
|
|
47
69
|
# @option options [Integer] :count The number of messages to backfill.
|
|
48
70
|
# @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects.
|
|
71
|
+
# @return [void]
|
|
49
72
|
def firehose(options = {}, &)
|
|
50
73
|
request(:get, "https://stream.twitter.com:443/1.1/statuses/firehose.json", options, &)
|
|
51
74
|
end
|
|
52
75
|
|
|
53
76
|
# Returns a small random sample of all public statuses
|
|
54
77
|
#
|
|
78
|
+
# @api public
|
|
79
|
+
# @example
|
|
80
|
+
# client.sample
|
|
55
81
|
# @see https://dev.twitter.com/streaming/reference/get/statuses/sample
|
|
56
82
|
# @see https://dev.twitter.com/streaming/overview/request-parameters
|
|
57
83
|
# @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects.
|
|
84
|
+
# @return [void]
|
|
58
85
|
def sample(options = {}, &)
|
|
59
86
|
request(:get, "https://stream.twitter.com:443/1.1/statuses/sample.json", options, &)
|
|
60
87
|
end
|
|
61
88
|
|
|
62
89
|
# Streams messages for a set of users
|
|
63
90
|
#
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# client.site(7505382)
|
|
64
94
|
# @see https://dev.twitter.com/streaming/reference/get/site
|
|
65
95
|
# @see https://dev.twitter.com/streaming/sitestreams
|
|
66
96
|
# @see https://dev.twitter.com/streaming/overview/request-parameters
|
|
@@ -71,6 +101,7 @@ module Twitter
|
|
|
71
101
|
# @option options [String] :with Specifies whether to return information for just the users specified in the follow parameter, or include messages from accounts they follow.
|
|
72
102
|
# @option options [String] :replies Specifies whether stall warnings should be delivered.
|
|
73
103
|
# @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects.
|
|
104
|
+
# @return [void]
|
|
74
105
|
def site(*args, &)
|
|
75
106
|
arguments = Arguments.new(args)
|
|
76
107
|
user_ids = collect_user_ids(arguments)
|
|
@@ -79,6 +110,9 @@ module Twitter
|
|
|
79
110
|
|
|
80
111
|
# Streams messages for a single user
|
|
81
112
|
#
|
|
113
|
+
# @api public
|
|
114
|
+
# @example
|
|
115
|
+
# client.user
|
|
82
116
|
# @see https://dev.twitter.com/streaming/reference/get/user
|
|
83
117
|
# @see https://dev.twitter.com/streaming/userstreams
|
|
84
118
|
# @see https://dev.twitter.com/streaming/overview/request-parameters
|
|
@@ -89,11 +123,17 @@ module Twitter
|
|
|
89
123
|
# @option options [String] :track Includes additional Tweets matching the specified keywords. Phrases of keywords are specified by a comma-separated list.
|
|
90
124
|
# @option options [String] :locations Includes additional Tweets falling within the specified bounding boxes.
|
|
91
125
|
# @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects.
|
|
126
|
+
# @return [void]
|
|
92
127
|
def user(options = {}, &)
|
|
93
128
|
request(:get, "https://userstream.twitter.com:443/1.1/user.json", options, &)
|
|
94
129
|
end
|
|
95
130
|
|
|
96
|
-
# Set a Proc to be run when connection established
|
|
131
|
+
# Set a Proc to be run when connection established
|
|
132
|
+
#
|
|
133
|
+
# @api public
|
|
134
|
+
# @example
|
|
135
|
+
# client.before_request { puts 'Connected!' }
|
|
136
|
+
# @return [Proc, Twitter::Streaming::Client]
|
|
97
137
|
def before_request(&block)
|
|
98
138
|
if block
|
|
99
139
|
@before_request = block
|
|
@@ -105,12 +145,22 @@ module Twitter
|
|
|
105
145
|
end
|
|
106
146
|
end
|
|
107
147
|
|
|
148
|
+
# Closes the streaming connection
|
|
149
|
+
#
|
|
150
|
+
# @api public
|
|
151
|
+
# @example
|
|
152
|
+
# client.close
|
|
153
|
+
# @return [void]
|
|
108
154
|
def close
|
|
109
155
|
@connection.close
|
|
110
156
|
end
|
|
111
157
|
|
|
112
|
-
|
|
158
|
+
private
|
|
113
159
|
|
|
160
|
+
# Performs the streaming request
|
|
161
|
+
#
|
|
162
|
+
# @api private
|
|
163
|
+
# @return [void]
|
|
114
164
|
def request(method, uri, params)
|
|
115
165
|
before_request.call
|
|
116
166
|
headers = Twitter::Headers.new(self, method, uri, params).request_headers
|
|
@@ -123,21 +173,23 @@ module Twitter
|
|
|
123
173
|
@connection.stream(request, response)
|
|
124
174
|
end
|
|
125
175
|
|
|
176
|
+
# Converts params to URL query string
|
|
177
|
+
#
|
|
178
|
+
# @api private
|
|
179
|
+
# @return [String]
|
|
126
180
|
def to_url_params(params)
|
|
127
|
-
|
|
128
|
-
uri.query_values = params
|
|
129
|
-
uri.query
|
|
181
|
+
URI.encode_www_form(params)
|
|
130
182
|
end
|
|
131
183
|
|
|
132
|
-
# Takes a mixed array of Integers and Twitter::User objects
|
|
133
|
-
# consistent array of Twitter user IDs.
|
|
184
|
+
# Takes a mixed array of Integers and Twitter::User objects
|
|
134
185
|
#
|
|
186
|
+
# @api private
|
|
135
187
|
# @param users [Array]
|
|
136
188
|
# @return [Array<Integer>]
|
|
137
189
|
def collect_user_ids(users)
|
|
138
190
|
users.filter_map do |user|
|
|
139
191
|
case user
|
|
140
|
-
when Integer
|
|
192
|
+
when Integer then user
|
|
141
193
|
when Twitter::User then user.id
|
|
142
194
|
end
|
|
143
195
|
end
|
|
@@ -3,16 +3,46 @@ require "resolv"
|
|
|
3
3
|
|
|
4
4
|
module Twitter
|
|
5
5
|
module Streaming
|
|
6
|
+
# Manages TCP/SSL connections for streaming
|
|
7
|
+
#
|
|
8
|
+
# @api public
|
|
6
9
|
class Connection
|
|
10
|
+
# Returns the TCP socket class
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
13
|
+
# @example
|
|
14
|
+
# connection.tcp_socket_class
|
|
15
|
+
# @return [Class]
|
|
16
|
+
|
|
17
|
+
# Returns the SSL socket class
|
|
18
|
+
#
|
|
19
|
+
# @api public
|
|
20
|
+
# @example
|
|
21
|
+
# connection.ssl_socket_class
|
|
22
|
+
# @return [Class]
|
|
7
23
|
attr_reader :tcp_socket_class, :ssl_socket_class
|
|
8
24
|
|
|
25
|
+
# Initializes a new Connection object
|
|
26
|
+
#
|
|
27
|
+
# @api public
|
|
28
|
+
# @example
|
|
29
|
+
# connection = Twitter::Streaming::Connection.new
|
|
30
|
+
# @param options [Hash] A customizable set of options.
|
|
31
|
+
# @return [Twitter::Streaming::Connection]
|
|
9
32
|
def initialize(options = {})
|
|
10
|
-
@tcp_socket_class = options.fetch(:tcp_socket_class) { TCPSocket }
|
|
11
|
-
@ssl_socket_class = options.fetch(:ssl_socket_class) { OpenSSL::SSL::SSLSocket }
|
|
12
|
-
@using_ssl
|
|
13
|
-
@write_pipe = nil
|
|
33
|
+
@tcp_socket_class = options.fetch(:tcp_socket_class) { TCPSocket } # steep:ignore UnknownConstant
|
|
34
|
+
@ssl_socket_class = options.fetch(:ssl_socket_class) { OpenSSL::SSL::SSLSocket } # steep:ignore UnknownConstant
|
|
35
|
+
@using_ssl = options.fetch(:using_ssl, false)
|
|
14
36
|
end
|
|
15
37
|
|
|
38
|
+
# Streams data from the connection
|
|
39
|
+
#
|
|
40
|
+
# @api public
|
|
41
|
+
# @example
|
|
42
|
+
# connection.stream(request, response)
|
|
43
|
+
# @param request [HTTP::Request] The HTTP request.
|
|
44
|
+
# @param response [Twitter::Streaming::Response] The response handler.
|
|
45
|
+
# @return [void]
|
|
16
46
|
def stream(request, response) # rubocop:disable Metrics/MethodLength
|
|
17
47
|
client = connect(request)
|
|
18
48
|
request.stream(client)
|
|
@@ -29,23 +59,40 @@ module Twitter
|
|
|
29
59
|
client.close
|
|
30
60
|
end
|
|
31
61
|
|
|
62
|
+
# Connects to the specified host and port
|
|
63
|
+
#
|
|
64
|
+
# @api public
|
|
65
|
+
# @example
|
|
66
|
+
# connection.connect(request)
|
|
67
|
+
# @param request [HTTP::Request] The HTTP request.
|
|
68
|
+
# @return [TCPSocket, OpenSSL::SSL::SSLSocket]
|
|
32
69
|
def connect(request)
|
|
33
70
|
client = new_tcp_socket(request.socket_host, request.socket_port)
|
|
34
71
|
return client if !@using_ssl && request.using_proxy?
|
|
35
72
|
|
|
36
|
-
client_context = OpenSSL::SSL::SSLContext.new
|
|
37
|
-
ssl_client
|
|
73
|
+
client_context = OpenSSL::SSL::SSLContext.new # steep:ignore UnknownConstant
|
|
74
|
+
ssl_client = @ssl_socket_class.new(client, client_context)
|
|
38
75
|
ssl_client.connect
|
|
39
76
|
end
|
|
40
77
|
|
|
78
|
+
# Closes the connection
|
|
79
|
+
#
|
|
80
|
+
# @api public
|
|
81
|
+
# @example
|
|
82
|
+
# connection.close
|
|
83
|
+
# @return [Integer, nil]
|
|
41
84
|
def close
|
|
42
85
|
@write_pipe&.write("q")
|
|
43
86
|
end
|
|
44
87
|
|
|
45
|
-
|
|
88
|
+
private
|
|
46
89
|
|
|
90
|
+
# Creates a new TCP socket
|
|
91
|
+
#
|
|
92
|
+
# @api private
|
|
93
|
+
# @return [TCPSocket]
|
|
47
94
|
def new_tcp_socket(host, port)
|
|
48
|
-
@tcp_socket_class.new(Resolv.getaddress(host), port)
|
|
95
|
+
@tcp_socket_class.new(Resolv.getaddress(host), port) # steep:ignore UnknownConstant
|
|
49
96
|
end
|
|
50
97
|
end
|
|
51
98
|
end
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
module Twitter
|
|
2
2
|
module Streaming
|
|
3
|
+
# Represents a deleted tweet from the streaming API
|
|
4
|
+
#
|
|
5
|
+
# @api public
|
|
3
6
|
class DeletedTweet < Twitter::Identity
|
|
7
|
+
# Returns the user ID of the deleted tweet's author
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
# @example
|
|
11
|
+
# deleted_tweet.user_id
|
|
4
12
|
# @return [Integer]
|
|
5
13
|
attr_reader :user_id
|
|
6
14
|
end
|
|
@@ -1,19 +1,57 @@
|
|
|
1
1
|
module Twitter
|
|
2
2
|
module Streaming
|
|
3
|
+
# Represents a streaming event from the Twitter API
|
|
4
|
+
#
|
|
5
|
+
# @api public
|
|
3
6
|
class Event
|
|
7
|
+
# Event names for list-related events
|
|
4
8
|
LIST_EVENTS = %i[
|
|
5
9
|
list_created list_destroyed list_updated list_member_added
|
|
6
10
|
list_member_added list_member_removed list_user_subscribed
|
|
7
11
|
list_user_subscribed list_user_unsubscribed list_user_unsubscribed
|
|
8
12
|
].freeze
|
|
9
13
|
|
|
14
|
+
# Event names for tweet-related events
|
|
10
15
|
TWEET_EVENTS = %i[
|
|
11
16
|
favorite unfavorite quoted_tweet
|
|
12
17
|
].freeze
|
|
13
18
|
|
|
19
|
+
# Returns the event name
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# event.name
|
|
24
|
+
# @return [Symbol]
|
|
25
|
+
|
|
26
|
+
# Returns the source user
|
|
27
|
+
#
|
|
28
|
+
# @api public
|
|
29
|
+
# @example
|
|
30
|
+
# event.source
|
|
31
|
+
# @return [Twitter::User]
|
|
32
|
+
|
|
33
|
+
# Returns the target user
|
|
34
|
+
#
|
|
35
|
+
# @api public
|
|
36
|
+
# @example
|
|
37
|
+
# event.target
|
|
38
|
+
# @return [Twitter::User]
|
|
39
|
+
|
|
40
|
+
# Returns the target object
|
|
41
|
+
#
|
|
42
|
+
# @api public
|
|
43
|
+
# @example
|
|
44
|
+
# event.target_object
|
|
45
|
+
# @return [Twitter::Tweet, Twitter::List, nil]
|
|
14
46
|
attr_reader :name, :source, :target, :target_object
|
|
15
47
|
|
|
48
|
+
# Initializes a new Event object
|
|
49
|
+
#
|
|
50
|
+
# @api public
|
|
51
|
+
# @example
|
|
52
|
+
# Twitter::Streaming::Event.new(data)
|
|
16
53
|
# @param data [Hash]
|
|
54
|
+
# @return [Twitter::Streaming::Event]
|
|
17
55
|
def initialize(data)
|
|
18
56
|
@name = data[:event].to_sym
|
|
19
57
|
@source = Twitter::User.new(data[:source])
|
|
@@ -21,8 +59,12 @@ module Twitter
|
|
|
21
59
|
@target_object = target_object_factory(@name, data[:target_object])
|
|
22
60
|
end
|
|
23
61
|
|
|
24
|
-
|
|
62
|
+
private
|
|
25
63
|
|
|
64
|
+
# Builds the target object based on event type
|
|
65
|
+
#
|
|
66
|
+
# @api private
|
|
67
|
+
# @return [Twitter::Tweet, Twitter::List, nil]
|
|
26
68
|
def target_object_factory(event_name, data)
|
|
27
69
|
if LIST_EVENTS.include?(event_name)
|
|
28
70
|
Twitter::List.new(data)
|
|
@@ -7,20 +7,30 @@ require "twitter/tweet"
|
|
|
7
7
|
|
|
8
8
|
module Twitter
|
|
9
9
|
module Streaming
|
|
10
|
+
# Parses streaming messages from the Twitter API
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
10
13
|
class MessageParser
|
|
14
|
+
# Parses streaming data into appropriate objects
|
|
15
|
+
#
|
|
16
|
+
# @api public
|
|
17
|
+
# @example
|
|
18
|
+
# MessageParser.parse(data)
|
|
19
|
+
# @param data [Hash] The streaming data to parse.
|
|
20
|
+
# @return [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning, nil]
|
|
11
21
|
def self.parse(data) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
12
|
-
if data
|
|
22
|
+
if data.key?(:id)
|
|
13
23
|
Tweet.new(data)
|
|
14
|
-
elsif data
|
|
24
|
+
elsif data.key?(:event)
|
|
15
25
|
Event.new(data)
|
|
16
|
-
elsif data
|
|
17
|
-
DirectMessage.new(data
|
|
18
|
-
elsif data
|
|
19
|
-
FriendList.new(data
|
|
20
|
-
elsif data
|
|
21
|
-
DeletedTweet.new(data
|
|
22
|
-
elsif data
|
|
23
|
-
StallWarning.new(data
|
|
26
|
+
elsif data.key?(:direct_message)
|
|
27
|
+
DirectMessage.new(data.fetch(:direct_message))
|
|
28
|
+
elsif data.key?(:friends)
|
|
29
|
+
FriendList.new(data.fetch(:friends))
|
|
30
|
+
elsif data.key?(:delete) && data.fetch(:delete).key?(:status)
|
|
31
|
+
DeletedTweet.new(data.fetch(:delete).fetch(:status))
|
|
32
|
+
elsif data.key?(:warning)
|
|
33
|
+
StallWarning.new(data.fetch(:warning))
|
|
24
34
|
end
|
|
25
35
|
end
|
|
26
36
|
end
|
|
@@ -2,32 +2,58 @@ require "buftok"
|
|
|
2
2
|
require "http"
|
|
3
3
|
require "json"
|
|
4
4
|
require "twitter/error"
|
|
5
|
-
require "llhttp"
|
|
6
5
|
|
|
7
6
|
module Twitter
|
|
8
7
|
module Streaming
|
|
8
|
+
# Handles streaming response parsing
|
|
9
|
+
#
|
|
10
|
+
# @api public
|
|
9
11
|
class Response
|
|
10
12
|
# Initializes a new Response object
|
|
11
13
|
#
|
|
14
|
+
# @api public
|
|
15
|
+
# @example
|
|
16
|
+
# response = Twitter::Streaming::Response.new { |data| puts data }
|
|
12
17
|
# @return [Twitter::Streaming::Response]
|
|
13
18
|
def initialize(&block)
|
|
14
|
-
@block
|
|
15
|
-
@parser
|
|
16
|
-
@tokenizer = BufferedTokenizer.new("\r\n")
|
|
19
|
+
@block = block
|
|
20
|
+
@parser = LLHttp::Parser.new(self, type: :response) # steep:ignore UnknownConstant
|
|
21
|
+
@tokenizer = BufferedTokenizer.new("\r\n") # steep:ignore UnknownConstant
|
|
17
22
|
end
|
|
18
23
|
|
|
24
|
+
# Appends data to the parser
|
|
25
|
+
#
|
|
26
|
+
# @api public
|
|
27
|
+
# @example
|
|
28
|
+
# response << data
|
|
29
|
+
# @param data [String] The data to append.
|
|
30
|
+
# @return [void]
|
|
19
31
|
def <<(data)
|
|
20
32
|
@parser << data
|
|
21
33
|
end
|
|
22
34
|
|
|
35
|
+
# Handles body data from the response
|
|
36
|
+
#
|
|
37
|
+
# @api public
|
|
38
|
+
# @example
|
|
39
|
+
# response.on_body(data)
|
|
40
|
+
# @param data [String] The body data.
|
|
41
|
+
# @return [void]
|
|
23
42
|
def on_body(data)
|
|
24
43
|
@tokenizer.extract(data).each do |line|
|
|
25
44
|
next if line.empty?
|
|
26
45
|
|
|
27
|
-
@block.call(JSON.parse(line, symbolize_names: true))
|
|
46
|
+
@block.call(JSON.parse(line, symbolize_names: true)) # steep:ignore UnknownConstant
|
|
28
47
|
end
|
|
29
48
|
end
|
|
30
49
|
|
|
50
|
+
# Handles status code from the response
|
|
51
|
+
#
|
|
52
|
+
# @api public
|
|
53
|
+
# @example
|
|
54
|
+
# response.on_status(200)
|
|
55
|
+
# @param _status [Integer] The status code.
|
|
56
|
+
# @return [void]
|
|
31
57
|
def on_status(_status)
|
|
32
58
|
error = Twitter::Error::ERRORS[@parser.status_code]
|
|
33
59
|
raise error if error
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
module Twitter
|
|
2
2
|
module Streaming
|
|
3
|
+
# Represents a Twitter streaming stall warning
|
|
4
|
+
#
|
|
5
|
+
# @api public
|
|
3
6
|
class StallWarning < Twitter::Base
|
|
7
|
+
# Returns the warning code
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
# @example
|
|
11
|
+
# stall_warning.code
|
|
12
|
+
# @return [String]
|
|
13
|
+
|
|
14
|
+
# Returns the warning message
|
|
15
|
+
#
|
|
16
|
+
# @api public
|
|
17
|
+
# @example
|
|
18
|
+
# stall_warning.message
|
|
19
|
+
# @return [String]
|
|
20
|
+
|
|
21
|
+
# Returns the percent full value
|
|
22
|
+
#
|
|
23
|
+
# @api public
|
|
24
|
+
# @example
|
|
25
|
+
# stall_warning.percent_full
|
|
26
|
+
# @return [Integer]
|
|
4
27
|
attr_reader :code, :message, :percent_full
|
|
5
28
|
end
|
|
6
29
|
end
|
data/lib/twitter/suggestion.rb
CHANGED
|
@@ -3,15 +3,39 @@ require "memoizable"
|
|
|
3
3
|
require "twitter/base"
|
|
4
4
|
|
|
5
5
|
module Twitter
|
|
6
|
-
|
|
6
|
+
# Represents a Twitter user suggestion category
|
|
7
|
+
class Suggestion < Base
|
|
7
8
|
include Equalizer.new(:slug)
|
|
8
9
|
include Memoizable
|
|
9
10
|
|
|
11
|
+
# The number of users in this category
|
|
12
|
+
#
|
|
13
|
+
# @api public
|
|
14
|
+
# @example
|
|
15
|
+
# suggestion.size
|
|
10
16
|
# @return [Integer]
|
|
11
17
|
attr_reader :size
|
|
18
|
+
|
|
19
|
+
# The name of the suggestion category
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# suggestion.name
|
|
24
|
+
# @return [String]
|
|
25
|
+
|
|
26
|
+
# The slug of the suggestion category
|
|
27
|
+
#
|
|
28
|
+
# @api public
|
|
29
|
+
# @example
|
|
30
|
+
# suggestion.slug
|
|
12
31
|
# @return [String]
|
|
13
32
|
attr_reader :name, :slug
|
|
14
33
|
|
|
34
|
+
# Returns the users in this suggestion category
|
|
35
|
+
#
|
|
36
|
+
# @api public
|
|
37
|
+
# @example
|
|
38
|
+
# suggestion.users
|
|
15
39
|
# @return [Array<Twitter::User>]
|
|
16
40
|
def users
|
|
17
41
|
@attrs.fetch(:users, []).collect do |user|
|
data/lib/twitter/target_user.rb
CHANGED
data/lib/twitter/trend.rb
CHANGED
|
@@ -2,9 +2,37 @@ require "equalizer"
|
|
|
2
2
|
require "twitter/base"
|
|
3
3
|
|
|
4
4
|
module Twitter
|
|
5
|
-
|
|
5
|
+
# Represents a Twitter trending topic
|
|
6
|
+
class Trend < Base
|
|
6
7
|
include Equalizer.new(:name)
|
|
8
|
+
|
|
9
|
+
# Events associated with this trend
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# trend.events
|
|
14
|
+
# @return [String]
|
|
15
|
+
|
|
16
|
+
# The name of the trend
|
|
17
|
+
#
|
|
18
|
+
# @api public
|
|
19
|
+
# @example
|
|
20
|
+
# trend.name
|
|
7
21
|
# @return [String]
|
|
22
|
+
|
|
23
|
+
# The search query for this trend
|
|
24
|
+
#
|
|
25
|
+
# @api public
|
|
26
|
+
# @example
|
|
27
|
+
# trend.query
|
|
28
|
+
# @return [String]
|
|
29
|
+
|
|
30
|
+
# The tweet volume for this trend
|
|
31
|
+
#
|
|
32
|
+
# @api public
|
|
33
|
+
# @example
|
|
34
|
+
# trend.tweet_volume
|
|
35
|
+
# @return [Integer]
|
|
8
36
|
attr_reader :events, :name, :query, :tweet_volume
|
|
9
37
|
|
|
10
38
|
predicate_attr_reader :promoted_content
|
|
@@ -5,19 +5,43 @@ require "twitter/null_object"
|
|
|
5
5
|
require "twitter/utils"
|
|
6
6
|
|
|
7
7
|
module Twitter
|
|
8
|
+
# Represents a collection of trending topics
|
|
8
9
|
class TrendResults
|
|
9
|
-
include
|
|
10
|
-
include
|
|
11
|
-
include
|
|
10
|
+
include Creatable
|
|
11
|
+
include Enumerable
|
|
12
|
+
include Utils
|
|
12
13
|
include Memoizable
|
|
14
|
+
|
|
15
|
+
# The raw attributes hash
|
|
16
|
+
#
|
|
17
|
+
# @api public
|
|
18
|
+
# @example
|
|
19
|
+
# results.attrs
|
|
13
20
|
# @return [Hash]
|
|
14
21
|
attr_reader :attrs
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
|
|
23
|
+
# @!method to_h
|
|
24
|
+
# Returns the attributes as a hash
|
|
25
|
+
# @api public
|
|
26
|
+
# @example
|
|
27
|
+
# results.to_h
|
|
28
|
+
# @return [Hash]
|
|
29
|
+
alias_method :to_h, :attrs
|
|
30
|
+
|
|
31
|
+
# @!method to_hash
|
|
32
|
+
# Returns the attributes as a hash
|
|
33
|
+
# @api public
|
|
34
|
+
# @example
|
|
35
|
+
# results.to_hash
|
|
36
|
+
# @return [Hash]
|
|
37
|
+
alias_method :to_hash, :to_h
|
|
17
38
|
|
|
18
39
|
# Initializes a new TrendResults object
|
|
19
40
|
#
|
|
20
|
-
# @
|
|
41
|
+
# @api public
|
|
42
|
+
# @example
|
|
43
|
+
# Twitter::TrendResults.new(trends: [])
|
|
44
|
+
# @param attrs [Hash] The attributes hash
|
|
21
45
|
# @return [Twitter::TrendResults]
|
|
22
46
|
def initialize(attrs = {})
|
|
23
47
|
@attrs = attrs
|
|
@@ -26,25 +50,44 @@ module Twitter
|
|
|
26
50
|
end
|
|
27
51
|
end
|
|
28
52
|
|
|
29
|
-
#
|
|
53
|
+
# Returns the time when trends were retrieved
|
|
30
54
|
#
|
|
55
|
+
# @api public
|
|
56
|
+
# @example
|
|
57
|
+
# results.as_of
|
|
31
58
|
# @return [Time]
|
|
32
59
|
def as_of
|
|
33
60
|
Time.parse(@attrs[:as_of]).utc unless @attrs[:as_of].nil?
|
|
34
61
|
end
|
|
35
62
|
memoize :as_of
|
|
36
63
|
|
|
64
|
+
# Returns true if as_of is available
|
|
65
|
+
#
|
|
66
|
+
# @api public
|
|
67
|
+
# @example
|
|
68
|
+
# results.as_of?
|
|
69
|
+
# @return [Boolean]
|
|
37
70
|
def as_of?
|
|
38
71
|
!!@attrs[:as_of]
|
|
39
72
|
end
|
|
40
73
|
memoize :as_of?
|
|
41
74
|
|
|
75
|
+
# Returns the location for these trends
|
|
76
|
+
#
|
|
77
|
+
# @api public
|
|
78
|
+
# @example
|
|
79
|
+
# results.location
|
|
42
80
|
# @return [Twitter::Place, NullObject]
|
|
43
81
|
def location
|
|
44
82
|
location? ? Place.new(@attrs[:locations].first) : NullObject.new
|
|
45
83
|
end
|
|
46
84
|
memoize :location
|
|
47
85
|
|
|
86
|
+
# Returns true if location is available
|
|
87
|
+
#
|
|
88
|
+
# @api public
|
|
89
|
+
# @example
|
|
90
|
+
# results.location?
|
|
48
91
|
# @return [Boolean]
|
|
49
92
|
def location?
|
|
50
93
|
!@attrs[:locations].nil? && !@attrs[:locations].first.nil?
|