twitter 8.2.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 +172 -10
- 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 +23 -57
- data/.yardopts +0 -16
- data/CHANGELOG.md +0 -1040
- data/CONTRIBUTING.md +0 -49
- data/twitter.gemspec +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e3e51290f1c00a7cccecb877674612cb6738dc57f0875b39e0ceed19665741cd
|
|
4
|
+
data.tar.gz: edb56f6daf0b68b9e9825235cfd8ed11ac0a829b06a13126974495705874a54c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce9c4b4231288f4889726413ab97baab2905fc3e2d66dd50d3ac90fb6378019088b4c25d9cca4c62406fd91d2387020cdaaf604ec182c663be2cdfcc1c098739
|
|
7
|
+
data.tar.gz: af70e5b070b1c17f565057712c292a71449384b651803932b0fadba22fb4e76131f1e1b9a1d103bdaed0201ee300957dc83d7cb8850e514daa47a615040aa65d
|
data/LICENSE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (c) 2006-
|
|
1
|
+
Copyright (c) 2006-2026 Erik Berlin, John Nunemaker, Wynn Netherland, Steve Richert, Steve Agalloco
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
4
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
# The Twitter Ruby Gem
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://github.com/sferik/twitter-ruby/actions/workflows/lint.yml)
|
|
4
|
+
[](https://github.com/sferik/twitter-ruby/actions/workflows/test.yml)
|
|
5
|
+
[](https://github.com/sferik/twitter-ruby/actions/workflows/mutant.yml)
|
|
6
|
+
[](https://github.com/sferik/twitter-ruby/actions/workflows/typecheck.yml)
|
|
7
|
+
[](https://github.com/sferik/twitter-ruby/actions/workflows/yardstick.yml)
|
|
8
|
+
[][gem]
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
The Twitter Ruby Gem provides a Ruby interface to the X (Twitter) API v1.1.
|
|
11
|
+
|
|
12
|
+
For new projects, or if you need API v2 support, use the [X gem][x] as a more
|
|
13
|
+
modern alternative. It supports both API v1.1 and API v2.
|
|
10
14
|
|
|
11
15
|
[x]: https://sferik.github.io/x-ruby/
|
|
16
|
+
[gem]: https://rubygems.org/gems/twitter
|
|
12
17
|
|
|
13
18
|
## 💖 Sponsoring
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
Open source maintenance takes real time and effort. By sponsoring development,
|
|
20
|
+
you help us:
|
|
16
21
|
|
|
17
22
|
1. 🛠 Maintain the library: Keeping it up-to-date and secure.
|
|
18
23
|
2. 🌈 Add new features: Enhancements that make your life easier.
|
|
@@ -32,13 +37,170 @@ Thanks for considering sponsorship. Together we can make the X gem even better!
|
|
|
32
37
|
[sponsor]: https://github.com/sponsors/sferik
|
|
33
38
|
|
|
34
39
|
## Announcements
|
|
35
|
-
You should [follow @gem][follow] on
|
|
40
|
+
You should [follow @gem][follow] on X for announcements and updates about
|
|
36
41
|
this library.
|
|
37
42
|
|
|
38
43
|
[follow]: https://x.com/gem
|
|
39
44
|
|
|
45
|
+
## Configuration
|
|
46
|
+
Twitter API v1.1 requests require OAuth credentials, so you'll need to
|
|
47
|
+
[register an app in the X developer portal][register] first.
|
|
48
|
+
|
|
49
|
+
[register]: https://developer.x.com/en/portal/dashboard
|
|
50
|
+
|
|
51
|
+
After creating an app, you'll have a consumer key/secret pair and an access
|
|
52
|
+
token/secret pair. Configure these before making requests.
|
|
53
|
+
|
|
54
|
+
You can pass configuration options as a block to `Twitter::REST::Client.new`.
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
client = Twitter::REST::Client.new do |config|
|
|
58
|
+
config.consumer_key = "YOUR_CONSUMER_KEY"
|
|
59
|
+
config.consumer_secret = "YOUR_CONSUMER_SECRET"
|
|
60
|
+
config.access_token = "YOUR_ACCESS_TOKEN"
|
|
61
|
+
config.access_token_secret = "YOUR_ACCESS_SECRET"
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Usage Examples
|
|
66
|
+
After configuring a `client`, you can do the following things.
|
|
67
|
+
|
|
68
|
+
**Tweet (as the authenticated user)**
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
client.update("I'm tweeting with @gem!")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Follow a user (by screen name or user ID)**
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
client.follow("gem")
|
|
78
|
+
client.follow(213747670)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Fetch a user (by screen name or user ID)**
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
client.user("gem")
|
|
85
|
+
client.user(213747670)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Fetch a cursored list of followers (by screen name, user ID, or the authenticated user)**
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
client.followers("gem")
|
|
92
|
+
client.followers(213747670)
|
|
93
|
+
client.followers
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Fetch a cursored list of friends (by screen name, user ID, or the authenticated user)**
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
client.friends("gem")
|
|
100
|
+
client.friends(213747670)
|
|
101
|
+
client.friends
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Fetch the timeline of Tweets by a user**
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
client.user_timeline("gem")
|
|
108
|
+
client.user_timeline(213747670)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Fetch the home timeline**
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
client.home_timeline
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Fetch the mentions timeline**
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
client.mentions_timeline
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Fetch a Tweet by ID**
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
client.status(27558893223)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Search recent matching Tweets**
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
client.search("to:justinbieber marry me", result_type: "recent").take(3).map do |tweet|
|
|
133
|
+
"#{tweet.user.screen_name}: #{tweet.text}"
|
|
134
|
+
end
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Find a Japanese-language Tweet tagged #ruby (excluding retweets)**
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
client.search("#ruby -rt", lang: "ja").first.text
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
For more usage examples, see the full [documentation][].
|
|
144
|
+
|
|
145
|
+
[documentation]: https://rubydoc.info/gems/twitter
|
|
146
|
+
|
|
147
|
+
## Streaming
|
|
148
|
+
This gem includes streaming clients for legacy API v1.1 streaming endpoints.
|
|
149
|
+
Endpoint availability and access requirements depend on your developer account.
|
|
150
|
+
|
|
151
|
+
**Configuration works just like `Twitter::REST::Client`**
|
|
152
|
+
|
|
153
|
+
```ruby
|
|
154
|
+
client = Twitter::Streaming::Client.new do |config|
|
|
155
|
+
config.consumer_key = "YOUR_CONSUMER_KEY"
|
|
156
|
+
config.consumer_secret = "YOUR_CONSUMER_SECRET"
|
|
157
|
+
config.access_token = "YOUR_ACCESS_TOKEN"
|
|
158
|
+
config.access_token_secret = "YOUR_ACCESS_SECRET"
|
|
159
|
+
end
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Stream a random sample of Tweets**
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
client.sample do |object|
|
|
166
|
+
puts object.text if object.is_a?(Twitter::Tweet)
|
|
167
|
+
end
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Stream mentions of coffee or tea**
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
topics = ["coffee", "tea"]
|
|
174
|
+
client.filter(track: topics.join(",")) do |object|
|
|
175
|
+
puts object.text if object.is_a?(Twitter::Tweet)
|
|
176
|
+
end
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Stream Tweets, events, and direct messages for the authenticated user**
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
client.user do |object|
|
|
183
|
+
case object
|
|
184
|
+
when Twitter::Tweet
|
|
185
|
+
puts "It's a tweet!"
|
|
186
|
+
when Twitter::DirectMessage
|
|
187
|
+
puts "It's a direct message!"
|
|
188
|
+
when Twitter::Streaming::StallWarning
|
|
189
|
+
warn "Falling behind!"
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
An `object` may be one of the following:
|
|
195
|
+
* `Twitter::Tweet`
|
|
196
|
+
* `Twitter::DirectMessage`
|
|
197
|
+
* `Twitter::Streaming::DeletedTweet`
|
|
198
|
+
* `Twitter::Streaming::Event`
|
|
199
|
+
* `Twitter::Streaming::FriendList`
|
|
200
|
+
* `Twitter::Streaming::StallWarning`
|
|
201
|
+
|
|
40
202
|
## Copyright
|
|
41
|
-
Copyright (c) 2006-
|
|
203
|
+
Copyright (c) 2006-2026 Erik Berlin, John Nunemaker, Wynn Netherland, Steve Richert, Steve Agalloco.
|
|
42
204
|
See [LICENSE][] for details.
|
|
43
205
|
|
|
44
206
|
[license]: LICENSE.md
|
data/lib/twitter/arguments.rb
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
module Twitter
|
|
2
|
+
# An Array subclass that extracts options from arguments
|
|
2
3
|
class Arguments < Array
|
|
4
|
+
# The options hash extracted from the arguments
|
|
5
|
+
#
|
|
6
|
+
# @api public
|
|
7
|
+
# @example
|
|
8
|
+
# args = Twitter::Arguments.new([:user1, :user2, {trim_user: true}])
|
|
9
|
+
# args.options # => {trim_user: true}
|
|
3
10
|
# @return [Hash]
|
|
4
11
|
attr_reader :options
|
|
5
12
|
|
|
6
13
|
# Initializes a new Arguments object
|
|
7
14
|
#
|
|
15
|
+
# @api public
|
|
16
|
+
# @example
|
|
17
|
+
# args = Twitter::Arguments.new([:user1, :user2, {trim_user: true}])
|
|
18
|
+
# args # => [:user1, :user2]
|
|
19
|
+
# args.options # => {trim_user: true}
|
|
20
|
+
# @param args [Array] An array of arguments, optionally ending with a Hash
|
|
8
21
|
# @return [Twitter::Arguments]
|
|
9
22
|
def initialize(args)
|
|
10
|
-
@options = args.last.is_a?(
|
|
23
|
+
@options = args.last.is_a?(Hash) ? args.pop : {} # : Hash[Symbol, untyped]
|
|
11
24
|
super(args.flatten)
|
|
12
25
|
end
|
|
13
26
|
end
|
data/lib/twitter/base.rb
CHANGED
|
@@ -1,23 +1,46 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "uri"
|
|
2
2
|
require "forwardable"
|
|
3
3
|
require "memoizable"
|
|
4
4
|
require "twitter/null_object"
|
|
5
5
|
require "twitter/utils"
|
|
6
6
|
|
|
7
7
|
module Twitter
|
|
8
|
+
# Base class for Twitter objects
|
|
8
9
|
class Base
|
|
9
10
|
extend Forwardable
|
|
10
11
|
include Memoizable
|
|
11
12
|
include Twitter::Utils
|
|
13
|
+
|
|
14
|
+
# The raw attributes hash
|
|
15
|
+
#
|
|
16
|
+
# @api public
|
|
17
|
+
# @example
|
|
18
|
+
# user.attrs # => {id: 123, name: "John"}
|
|
12
19
|
# @return [Hash]
|
|
13
20
|
attr_reader :attrs
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
|
|
22
|
+
# @!method to_h
|
|
23
|
+
# Converts the object to a hash
|
|
24
|
+
# @api public
|
|
25
|
+
# @example
|
|
26
|
+
# user.to_h # => {id: 123, name: "John"}
|
|
27
|
+
# @return [Hash]
|
|
28
|
+
alias_method :to_h, :attrs
|
|
29
|
+
|
|
30
|
+
# @!method to_hash
|
|
31
|
+
# Converts the object to a hash
|
|
32
|
+
# @api public
|
|
33
|
+
# @example
|
|
34
|
+
# user.to_hash # => {id: 123, name: "John"}
|
|
35
|
+
# @return [Hash]
|
|
36
|
+
alias_method :to_hash, :to_h
|
|
16
37
|
|
|
17
38
|
class << self
|
|
18
39
|
# Define methods that retrieve the value from attributes
|
|
19
40
|
#
|
|
41
|
+
# @api private
|
|
20
42
|
# @param attrs [Array, Symbol]
|
|
43
|
+
# @return [void]
|
|
21
44
|
def attr_reader(*attrs)
|
|
22
45
|
attrs.each do |attr|
|
|
23
46
|
define_attribute_method(attr)
|
|
@@ -25,6 +48,11 @@ module Twitter
|
|
|
25
48
|
end
|
|
26
49
|
end
|
|
27
50
|
|
|
51
|
+
# Define predicate methods for attributes
|
|
52
|
+
#
|
|
53
|
+
# @api private
|
|
54
|
+
# @param attrs [Array, Symbol]
|
|
55
|
+
# @return [void]
|
|
28
56
|
def predicate_attr_reader(*attrs)
|
|
29
57
|
attrs.each do |attr|
|
|
30
58
|
define_predicate_method(attr)
|
|
@@ -33,9 +61,11 @@ module Twitter
|
|
|
33
61
|
|
|
34
62
|
# Define object methods from attributes
|
|
35
63
|
#
|
|
64
|
+
# @api private
|
|
36
65
|
# @param klass [Symbol]
|
|
37
66
|
# @param key1 [Symbol]
|
|
38
67
|
# @param key2 [Symbol]
|
|
68
|
+
# @return [void]
|
|
39
69
|
def object_attr_reader(klass, key1, key2 = nil)
|
|
40
70
|
define_attribute_method(key1, klass, key2)
|
|
41
71
|
define_predicate_method(key1)
|
|
@@ -43,7 +73,9 @@ module Twitter
|
|
|
43
73
|
|
|
44
74
|
# Define URI methods from attributes
|
|
45
75
|
#
|
|
76
|
+
# @api private
|
|
46
77
|
# @param attrs [Array, Symbol]
|
|
78
|
+
# @return [void]
|
|
47
79
|
def uri_attr_reader(*attrs)
|
|
48
80
|
attrs.each do |uri_key|
|
|
49
81
|
array = uri_key.to_s.split("_")
|
|
@@ -58,6 +90,9 @@ module Twitter
|
|
|
58
90
|
end
|
|
59
91
|
|
|
60
92
|
# Define display_uri attribute methods
|
|
93
|
+
#
|
|
94
|
+
# @api private
|
|
95
|
+
# @return [void]
|
|
61
96
|
def display_uri_attr_reader
|
|
62
97
|
define_attribute_method(:display_url)
|
|
63
98
|
alias_method(:display_uri, :display_url)
|
|
@@ -67,26 +102,30 @@ module Twitter
|
|
|
67
102
|
|
|
68
103
|
# Dynamically define a method for a URI
|
|
69
104
|
#
|
|
105
|
+
# @api private
|
|
70
106
|
# @param key1 [Symbol]
|
|
71
107
|
# @param key2 [Symbol]
|
|
108
|
+
# @return [void]
|
|
72
109
|
def define_uri_method(key1, key2)
|
|
73
110
|
define_method(key1) do
|
|
74
|
-
|
|
111
|
+
URI.parse(@attrs[key2].chomp("#").gsub(/[^\x00-\x7F]/) { |c| c.bytes.map { |b| format("%%%02X", b) }.join }) unless @attrs[key2].nil? # steep:ignore FallbackAny,NoMethod
|
|
75
112
|
end
|
|
76
113
|
memoize(key1)
|
|
77
114
|
end
|
|
78
115
|
|
|
79
116
|
# Dynamically define a method for an attribute
|
|
80
117
|
#
|
|
118
|
+
# @api private
|
|
81
119
|
# @param key1 [Symbol]
|
|
82
120
|
# @param klass [Symbol]
|
|
83
121
|
# @param key2 [Symbol]
|
|
122
|
+
# @return [void]
|
|
84
123
|
def define_attribute_method(key1, klass = nil, key2 = nil)
|
|
85
124
|
define_method(key1) do
|
|
86
|
-
if attr_falsey_or_empty?(key1)
|
|
125
|
+
if attr_falsey_or_empty?(key1) # steep:ignore NoMethod
|
|
87
126
|
NullObject.new
|
|
88
127
|
else
|
|
89
|
-
klass.nil? ? @attrs[key1] : Twitter.const_get(klass).new(attrs_for_object(key1, key2))
|
|
128
|
+
klass.nil? ? @attrs[key1] : Twitter.const_get(klass).new(attrs_for_object(key1, key2)) # steep:ignore NoMethod,FallbackAny
|
|
90
129
|
end
|
|
91
130
|
end
|
|
92
131
|
memoize(key1)
|
|
@@ -94,11 +133,13 @@ module Twitter
|
|
|
94
133
|
|
|
95
134
|
# Dynamically define a predicate method for an attribute
|
|
96
135
|
#
|
|
136
|
+
# @api private
|
|
97
137
|
# @param key1 [Symbol]
|
|
98
138
|
# @param key2 [Symbol]
|
|
139
|
+
# @return [void]
|
|
99
140
|
def define_predicate_method(key1, key2 = key1)
|
|
100
141
|
define_method(:"#{key1}?") do
|
|
101
|
-
!attr_falsey_or_empty?(key2)
|
|
142
|
+
!attr_falsey_or_empty?(key2) # steep:ignore NoMethod
|
|
102
143
|
end
|
|
103
144
|
memoize(:"#{key1}?")
|
|
104
145
|
end
|
|
@@ -106,28 +147,48 @@ module Twitter
|
|
|
106
147
|
|
|
107
148
|
# Initializes a new object
|
|
108
149
|
#
|
|
150
|
+
# @api public
|
|
151
|
+
# @example
|
|
152
|
+
# Twitter::Base.new(id: 123, name: "John")
|
|
109
153
|
# @param attrs [Hash]
|
|
110
154
|
# @return [Twitter::Base]
|
|
111
|
-
def initialize(attrs =
|
|
155
|
+
def initialize(attrs = nil)
|
|
112
156
|
@attrs = attrs || {}
|
|
113
157
|
end
|
|
114
158
|
|
|
115
159
|
# Fetches an attribute of an object using hash notation
|
|
116
160
|
#
|
|
161
|
+
# @api public
|
|
162
|
+
# @deprecated Use attribute methods instead
|
|
163
|
+
# @example
|
|
164
|
+
# user[:id] # => 123
|
|
117
165
|
# @param method [String, Symbol] Message to send to the object
|
|
166
|
+
# @return [Object, nil]
|
|
118
167
|
def [](method)
|
|
119
|
-
|
|
120
|
-
|
|
168
|
+
location = caller_locations(1, 1)&.first
|
|
169
|
+
warn "#{location&.path}:#{location&.lineno}: [DEPRECATION] #[#{method.inspect}] is deprecated. Use ##{method} to fetch the value."
|
|
170
|
+
public_send(method.to_sym)
|
|
121
171
|
rescue NoMethodError
|
|
122
172
|
nil
|
|
123
173
|
end
|
|
124
174
|
|
|
125
|
-
|
|
175
|
+
private
|
|
126
176
|
|
|
177
|
+
# Check if an attribute is falsey or empty
|
|
178
|
+
#
|
|
179
|
+
# @api private
|
|
180
|
+
# @param key [Symbol]
|
|
181
|
+
# @return [Boolean]
|
|
127
182
|
def attr_falsey_or_empty?(key)
|
|
128
183
|
!@attrs[key] || (@attrs[key].respond_to?(:empty?) && @attrs[key].empty?)
|
|
129
184
|
end
|
|
130
185
|
|
|
186
|
+
# Get attributes for creating a nested object
|
|
187
|
+
#
|
|
188
|
+
# @api private
|
|
189
|
+
# @param key1 [Symbol]
|
|
190
|
+
# @param key2 [Symbol]
|
|
191
|
+
# @return [Hash]
|
|
131
192
|
def attrs_for_object(key1, key2 = nil)
|
|
132
193
|
if key2.nil?
|
|
133
194
|
@attrs[key1]
|
data/lib/twitter/basic_user.rb
CHANGED
|
@@ -2,7 +2,13 @@ require "twitter/identity"
|
|
|
2
2
|
require "twitter/utils"
|
|
3
3
|
|
|
4
4
|
module Twitter
|
|
5
|
-
|
|
5
|
+
# Represents a basic Twitter user with minimal attributes
|
|
6
|
+
class BasicUser < Identity
|
|
7
|
+
# The user's screen name (handle)
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
# @example
|
|
11
|
+
# user.screen_name # => "sferik"
|
|
6
12
|
# @return [String]
|
|
7
13
|
attr_reader :screen_name
|
|
8
14
|
|
data/lib/twitter/client.rb
CHANGED
|
@@ -3,13 +3,79 @@ require "twitter/utils"
|
|
|
3
3
|
require "twitter/version"
|
|
4
4
|
|
|
5
5
|
module Twitter
|
|
6
|
+
# Base client class for Twitter API authentication
|
|
6
7
|
class Client
|
|
7
8
|
include Twitter::Utils
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
# The OAuth access token
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
13
|
+
# @example
|
|
14
|
+
# client.access_token # => "token"
|
|
15
|
+
# @return [String]
|
|
16
|
+
attr_accessor :access_token
|
|
17
|
+
|
|
18
|
+
# The OAuth access token secret
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
# @example
|
|
22
|
+
# client.access_token_secret # => "secret"
|
|
23
|
+
# @return [String]
|
|
24
|
+
attr_accessor :access_token_secret
|
|
25
|
+
|
|
26
|
+
# The OAuth consumer key
|
|
27
|
+
#
|
|
28
|
+
# @api public
|
|
29
|
+
# @example
|
|
30
|
+
# client.consumer_key # => "key"
|
|
31
|
+
# @return [String]
|
|
32
|
+
attr_accessor :consumer_key
|
|
33
|
+
|
|
34
|
+
# The OAuth consumer secret
|
|
35
|
+
#
|
|
36
|
+
# @api public
|
|
37
|
+
# @example
|
|
38
|
+
# client.consumer_secret # => "secret"
|
|
39
|
+
# @return [String]
|
|
40
|
+
attr_accessor :consumer_secret
|
|
41
|
+
|
|
42
|
+
# The proxy server URI
|
|
43
|
+
#
|
|
44
|
+
# @api public
|
|
45
|
+
# @example
|
|
46
|
+
# client.proxy # => "http://proxy.example.com:8080"
|
|
47
|
+
# @return [String]
|
|
48
|
+
attr_accessor :proxy
|
|
49
|
+
|
|
50
|
+
# The HTTP request timeouts
|
|
51
|
+
#
|
|
52
|
+
# @api public
|
|
53
|
+
# @example
|
|
54
|
+
# client.timeouts # => {connect: 5, read: 10}
|
|
55
|
+
# @return [Hash]
|
|
56
|
+
attr_accessor :timeouts
|
|
57
|
+
|
|
58
|
+
# The development environment name for Premium API endpoints
|
|
59
|
+
#
|
|
60
|
+
# @api public
|
|
61
|
+
# @example
|
|
62
|
+
# client.dev_environment # => "dev"
|
|
63
|
+
# @return [String]
|
|
64
|
+
attr_accessor :dev_environment
|
|
65
|
+
|
|
66
|
+
# The user agent string sent with requests
|
|
67
|
+
#
|
|
68
|
+
# @api public
|
|
69
|
+
# @example
|
|
70
|
+
# client.user_agent = "MyApp/1.0"
|
|
71
|
+
# @return [String]
|
|
9
72
|
attr_writer :user_agent
|
|
10
73
|
|
|
11
74
|
# Initializes a new Client object
|
|
12
75
|
#
|
|
76
|
+
# @api public
|
|
77
|
+
# @example
|
|
78
|
+
# client = Twitter::Client.new(consumer_key: "key")
|
|
13
79
|
# @param options [Hash]
|
|
14
80
|
# @return [Twitter::Client]
|
|
15
81
|
def initialize(options = {})
|
|
@@ -19,33 +85,58 @@ module Twitter
|
|
|
19
85
|
yield(self) if block_given?
|
|
20
86
|
end
|
|
21
87
|
|
|
88
|
+
# Check if user token credentials are present
|
|
89
|
+
#
|
|
90
|
+
# @api public
|
|
91
|
+
# @example
|
|
92
|
+
# client.user_token? # => true
|
|
22
93
|
# @return [Boolean]
|
|
23
94
|
def user_token?
|
|
24
95
|
!(blank_string?(access_token) || blank_string?(access_token_secret))
|
|
25
96
|
end
|
|
26
97
|
|
|
98
|
+
# The user agent string sent with requests
|
|
99
|
+
#
|
|
100
|
+
# @api public
|
|
101
|
+
# @example
|
|
102
|
+
# client.user_agent # => "TwitterRubyGem/8.2.0"
|
|
27
103
|
# @return [String]
|
|
28
104
|
def user_agent
|
|
29
105
|
@user_agent ||= "TwitterRubyGem/#{Twitter::Version}"
|
|
30
106
|
end
|
|
31
107
|
|
|
108
|
+
# The OAuth credentials hash
|
|
109
|
+
#
|
|
110
|
+
# @api public
|
|
111
|
+
# @example
|
|
112
|
+
# client.credentials # => {consumer_key: "key", ...}
|
|
32
113
|
# @return [Hash]
|
|
33
114
|
def credentials
|
|
34
115
|
{
|
|
35
116
|
consumer_key:,
|
|
36
117
|
consumer_secret:,
|
|
37
118
|
token: access_token,
|
|
38
|
-
token_secret: access_token_secret
|
|
119
|
+
token_secret: access_token_secret
|
|
39
120
|
}
|
|
40
121
|
end
|
|
41
122
|
|
|
123
|
+
# Check if all credentials are present
|
|
124
|
+
#
|
|
125
|
+
# @api public
|
|
126
|
+
# @example
|
|
127
|
+
# client.credentials? # => true
|
|
42
128
|
# @return [Boolean]
|
|
43
129
|
def credentials?
|
|
44
130
|
credentials.values.none? { |v| blank_string?(v) }
|
|
45
131
|
end
|
|
46
132
|
|
|
47
|
-
|
|
133
|
+
private
|
|
48
134
|
|
|
135
|
+
# Check if string is blank or nil
|
|
136
|
+
#
|
|
137
|
+
# @api private
|
|
138
|
+
# @param string [String]
|
|
139
|
+
# @return [Boolean]
|
|
49
140
|
def blank_string?(string)
|
|
50
141
|
string.respond_to?(:empty?) ? string.empty? : !string
|
|
51
142
|
end
|
data/lib/twitter/creatable.rb
CHANGED
|
@@ -2,14 +2,18 @@ require "time"
|
|
|
2
2
|
require "memoizable"
|
|
3
3
|
|
|
4
4
|
module Twitter
|
|
5
|
+
# Provides created_at functionality for Twitter objects
|
|
5
6
|
module Creatable
|
|
6
7
|
include Memoizable
|
|
7
8
|
|
|
8
9
|
# Time when the object was created on Twitter
|
|
9
10
|
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# tweet.created_at # => 2025-01-15 12:00:00 UTC
|
|
10
14
|
# @return [Time]
|
|
11
15
|
def created_at
|
|
12
|
-
time = @attrs[:created_at]
|
|
16
|
+
time = @attrs[:created_at] # steep:ignore FallbackAny
|
|
13
17
|
return if time.nil?
|
|
14
18
|
|
|
15
19
|
time = Time.parse(time) unless time.is_a?(Time)
|
|
@@ -17,9 +21,14 @@ module Twitter
|
|
|
17
21
|
end
|
|
18
22
|
memoize :created_at
|
|
19
23
|
|
|
24
|
+
# Check if the created_at attribute is present
|
|
25
|
+
#
|
|
26
|
+
# @api public
|
|
27
|
+
# @example
|
|
28
|
+
# tweet.created? # => true
|
|
20
29
|
# @return [Boolean]
|
|
21
30
|
def created?
|
|
22
|
-
!!@attrs[:created_at]
|
|
31
|
+
!!@attrs[:created_at] # steep:ignore FallbackAny
|
|
23
32
|
end
|
|
24
33
|
memoize :created?
|
|
25
34
|
end
|