birdsong 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +107 -87
- data/birdsong.gemspec +1 -0
- data/lib/birdsong/scrapers/scraper.rb +56 -42
- data/lib/birdsong/scrapers/tweet_scraper.rb +19 -3
- data/lib/birdsong/version.rb +1 -1
- metadata +17 -4
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dda08c757d1c68ec0444b27d413dd2f19691c08c4a2bfed33b99e4029e00ec81
|
4
|
+
data.tar.gz: 6f67bc01f6bd34abac6db6fc2b182d1f063890e44e127a8e9ecbeffc45b5db4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 579e935b51eb486d037c5ea7a9bc75c23cd7ee3365483aa69dbe4fa2ba56f763ea0566e00eea7402635e483553028e03553a7d44d2117f7f28c4721e308bd54b
|
7
|
+
data.tar.gz: 81466c8e53b847b3044b1c517ba72647ceedff0857bc291830dce42c914b8261cf143cef5b00629cf80008a5af12ceef7345c88576e4345a0826339677eb9541
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
birdsong (0.2.
|
4
|
+
birdsong (0.2.8)
|
5
5
|
capybara (~> 3.40)
|
6
6
|
curb (~> 1.0, >= 1.0.5)
|
7
7
|
oauth (~> 0.5.6)
|
@@ -13,30 +13,23 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
rack (~> 2.0, >= 2.2.0)
|
20
|
-
rack-test (>= 0.6.3)
|
21
|
-
rails-dom-testing (~> 2.0)
|
22
|
-
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
23
|
-
actionview (7.0.1)
|
24
|
-
activesupport (= 7.0.1)
|
25
|
-
builder (~> 3.1)
|
26
|
-
erubi (~> 1.4)
|
27
|
-
rails-dom-testing (~> 2.0)
|
28
|
-
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
29
|
-
activesupport (7.0.1)
|
16
|
+
activesupport (7.1.4)
|
17
|
+
base64
|
18
|
+
bigdecimal
|
30
19
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
20
|
+
connection_pool (>= 2.2.5)
|
21
|
+
drb
|
31
22
|
i18n (>= 1.6, < 2)
|
32
23
|
minitest (>= 5.1)
|
24
|
+
mutex_m
|
33
25
|
tzinfo (~> 2.0)
|
34
|
-
addressable (2.8.
|
35
|
-
public_suffix (>= 2.0.2, <
|
26
|
+
addressable (2.8.7)
|
27
|
+
public_suffix (>= 2.0.2, < 7.0)
|
36
28
|
ast (2.4.2)
|
29
|
+
backport (1.2.0)
|
37
30
|
base64 (0.2.0)
|
38
|
-
|
39
|
-
|
31
|
+
benchmark (0.3.0)
|
32
|
+
bigdecimal (3.1.8)
|
40
33
|
byebug (11.1.3)
|
41
34
|
capybara (3.40.0)
|
42
35
|
addressable
|
@@ -47,105 +40,131 @@ GEM
|
|
47
40
|
rack-test (>= 0.6.3)
|
48
41
|
regexp_parser (>= 1.5, < 3.0)
|
49
42
|
xpath (~> 3.2)
|
50
|
-
concurrent-ruby (1.
|
51
|
-
|
52
|
-
curb (1.0.
|
53
|
-
|
54
|
-
|
43
|
+
concurrent-ruby (1.3.4)
|
44
|
+
connection_pool (2.4.1)
|
45
|
+
curb (1.0.6)
|
46
|
+
diff-lcs (1.5.1)
|
47
|
+
dotenv (3.1.2)
|
48
|
+
drb (2.2.1)
|
49
|
+
e2mmap (0.1.0)
|
55
50
|
ethon (0.16.0)
|
56
51
|
ffi (>= 1.15.0)
|
57
|
-
ffi (1.
|
58
|
-
|
52
|
+
ffi (1.17.0-arm64-darwin)
|
53
|
+
ffi (1.17.0-x86_64-darwin)
|
54
|
+
ffi (1.17.0-x86_64-linux-gnu)
|
55
|
+
i18n (1.14.6)
|
59
56
|
concurrent-ruby (~> 1.0)
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
jaro_winkler (1.6.0)
|
58
|
+
json (2.7.2)
|
59
|
+
kramdown (2.4.0)
|
60
|
+
rexml
|
61
|
+
kramdown-parser-gfm (1.1.0)
|
62
|
+
kramdown (~> 2.0)
|
63
|
+
language_server-protocol (3.17.0.3)
|
64
|
+
logger (1.6.1)
|
63
65
|
matrix (0.4.2)
|
64
|
-
method_source (1.0.0)
|
65
66
|
mini_mime (1.1.5)
|
66
|
-
minitest (5.
|
67
|
-
|
67
|
+
minitest (5.25.1)
|
68
|
+
mutex_m (0.2.0)
|
69
|
+
nokogiri (1.16.7-arm64-darwin)
|
68
70
|
racc (~> 1.4)
|
69
|
-
nokogiri (1.
|
71
|
+
nokogiri (1.16.7-x86_64-darwin)
|
70
72
|
racc (~> 1.4)
|
71
|
-
nokogiri (1.
|
73
|
+
nokogiri (1.16.7-x86_64-linux)
|
72
74
|
racc (~> 1.4)
|
73
75
|
oauth (0.5.14)
|
74
|
-
oj (3.16.
|
76
|
+
oj (3.16.6)
|
75
77
|
bigdecimal (>= 3.0)
|
76
|
-
|
77
|
-
|
78
|
+
ostruct (>= 0.2)
|
79
|
+
ostruct (0.6.0)
|
80
|
+
parallel (1.26.3)
|
81
|
+
parser (3.3.5.0)
|
78
82
|
ast (~> 2.4.1)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
rack
|
83
|
-
|
84
|
-
|
85
|
-
activesupport (>= 4.2.0)
|
86
|
-
nokogiri (>= 1.6)
|
87
|
-
rails-html-sanitizer (1.4.2)
|
88
|
-
loofah (~> 2.3)
|
89
|
-
railties (7.0.1)
|
90
|
-
actionpack (= 7.0.1)
|
91
|
-
activesupport (= 7.0.1)
|
92
|
-
method_source
|
93
|
-
rake (>= 12.2)
|
94
|
-
thor (~> 1.0)
|
95
|
-
zeitwerk (~> 2.5)
|
83
|
+
racc
|
84
|
+
public_suffix (6.0.1)
|
85
|
+
racc (1.8.1)
|
86
|
+
rack (3.1.7)
|
87
|
+
rack-test (2.1.0)
|
88
|
+
rack (>= 1.3)
|
96
89
|
rainbow (3.1.1)
|
97
|
-
rake (13.
|
98
|
-
|
99
|
-
|
100
|
-
|
90
|
+
rake (13.2.1)
|
91
|
+
rbs (2.8.4)
|
92
|
+
regexp_parser (2.9.2)
|
93
|
+
reverse_markdown (2.1.1)
|
94
|
+
nokogiri
|
95
|
+
rexml (3.3.8)
|
96
|
+
rubocop (1.66.1)
|
97
|
+
json (~> 2.3)
|
98
|
+
language_server-protocol (>= 3.17.0)
|
101
99
|
parallel (~> 1.10)
|
102
|
-
parser (>= 3.
|
100
|
+
parser (>= 3.3.0.2)
|
103
101
|
rainbow (>= 2.2.2, < 4.0)
|
104
|
-
regexp_parser (>=
|
105
|
-
|
106
|
-
rubocop-ast (>= 1.15.1, < 2.0)
|
102
|
+
regexp_parser (>= 2.4, < 3.0)
|
103
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
107
104
|
ruby-progressbar (~> 1.7)
|
108
|
-
unicode-display_width (>=
|
109
|
-
rubocop-ast (1.
|
110
|
-
parser (>= 3.
|
111
|
-
rubocop-
|
112
|
-
rubocop (>=
|
113
|
-
rubocop-
|
114
|
-
rubocop (>=
|
115
|
-
|
116
|
-
|
117
|
-
rubocop
|
118
|
-
rubocop-
|
105
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
106
|
+
rubocop-ast (1.32.3)
|
107
|
+
parser (>= 3.3.1.0)
|
108
|
+
rubocop-md (1.2.3)
|
109
|
+
rubocop (>= 1.45)
|
110
|
+
rubocop-minitest (0.36.0)
|
111
|
+
rubocop (>= 1.61, < 2.0)
|
112
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
113
|
+
rubocop-packaging (0.5.2)
|
114
|
+
rubocop (>= 1.33, < 2.0)
|
115
|
+
rubocop-performance (1.22.1)
|
116
|
+
rubocop (>= 1.48.1, < 2.0)
|
117
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
118
|
+
rubocop-rails (2.26.1)
|
119
119
|
activesupport (>= 4.2.0)
|
120
120
|
rack (>= 1.1)
|
121
|
-
rubocop (>=
|
122
|
-
|
123
|
-
|
124
|
-
rubocop (>= 1.
|
125
|
-
rubocop-ast (>= 1.0
|
126
|
-
rubocop-
|
121
|
+
rubocop (>= 1.52.0, < 2.0)
|
122
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
123
|
+
rubocop-rails_config (1.16.0)
|
124
|
+
rubocop (>= 1.57.0)
|
125
|
+
rubocop-ast (>= 1.26.0)
|
126
|
+
rubocop-md
|
127
|
+
rubocop-minitest (~> 0.22)
|
127
128
|
rubocop-packaging (~> 0.5)
|
128
129
|
rubocop-performance (~> 1.11)
|
129
130
|
rubocop-rails (~> 2.0)
|
130
|
-
ruby-progressbar (1.
|
131
|
+
ruby-progressbar (1.13.0)
|
131
132
|
rubyzip (2.3.2)
|
132
|
-
selenium-devtools (0.
|
133
|
+
selenium-devtools (0.129.0)
|
133
134
|
selenium-webdriver (~> 4.2)
|
134
|
-
selenium-webdriver (4.
|
135
|
+
selenium-webdriver (4.25.0)
|
135
136
|
base64 (~> 0.2)
|
137
|
+
logger (~> 1.4)
|
136
138
|
rexml (~> 3.2, >= 3.2.5)
|
137
139
|
rubyzip (>= 1.2.2, < 3.0)
|
138
140
|
websocket (~> 1.0)
|
139
|
-
|
141
|
+
solargraph (0.50.0)
|
142
|
+
backport (~> 1.2)
|
143
|
+
benchmark
|
144
|
+
bundler (~> 2.0)
|
145
|
+
diff-lcs (~> 1.4)
|
146
|
+
e2mmap
|
147
|
+
jaro_winkler (~> 1.5)
|
148
|
+
kramdown (~> 2.3)
|
149
|
+
kramdown-parser-gfm (~> 1.1)
|
150
|
+
parser (~> 3.0)
|
151
|
+
rbs (~> 2.0)
|
152
|
+
reverse_markdown (~> 2.0)
|
153
|
+
rubocop (~> 1.38)
|
154
|
+
thor (~> 1.0)
|
155
|
+
tilt (~> 2.0)
|
156
|
+
yard (~> 0.9, >= 0.9.24)
|
157
|
+
thor (1.3.2)
|
158
|
+
tilt (2.4.0)
|
140
159
|
typhoeus (1.4.1)
|
141
160
|
ethon (>= 0.9.0)
|
142
|
-
tzinfo (2.0.
|
161
|
+
tzinfo (2.0.6)
|
143
162
|
concurrent-ruby (~> 1.0)
|
144
|
-
unicode-display_width (2.
|
145
|
-
websocket (1.2.
|
163
|
+
unicode-display_width (2.6.0)
|
164
|
+
websocket (1.2.11)
|
146
165
|
xpath (3.2.0)
|
147
166
|
nokogiri (~> 1.8)
|
148
|
-
|
167
|
+
yard (0.9.37)
|
149
168
|
|
150
169
|
PLATFORMS
|
151
170
|
arm64-darwin-21
|
@@ -164,6 +183,7 @@ DEPENDENCIES
|
|
164
183
|
rubocop-performance
|
165
184
|
rubocop-rails
|
166
185
|
rubocop-rails_config
|
186
|
+
solargraph
|
167
187
|
|
168
188
|
BUNDLED WITH
|
169
189
|
2.3.26
|
data/birdsong.gemspec
CHANGED
@@ -47,6 +47,7 @@ Gem::Specification.new do |spec|
|
|
47
47
|
spec.add_development_dependency "rubocop-rails_config"
|
48
48
|
spec.add_development_dependency "rubocop-performance"
|
49
49
|
spec.add_development_dependency "dotenv"
|
50
|
+
spec.add_development_dependency "solargraph"
|
50
51
|
|
51
52
|
# For more information and examples about making a new gem, checkout our
|
52
53
|
# guide at: https://bundler.io/guides/creating_gem.html
|
@@ -67,14 +67,11 @@ module Birdsong
|
|
67
67
|
|
68
68
|
page.driver.browser.intercept do |request, &continue|
|
69
69
|
# This passes the request forward unmodified, since we only care about the response
|
70
|
-
# puts "checking request: #{request.url}"
|
71
|
-
|
72
70
|
continue.call(request) && next unless request.url.include?(subpage_search)
|
73
71
|
|
74
|
-
|
75
72
|
continue.call(request) do |response|
|
76
|
-
|
77
73
|
# Check if not a CORS prefetch and finish up if not
|
74
|
+
# puts "checking request: #{request.url}"
|
78
75
|
if !response.body.empty? && response.body
|
79
76
|
check_passed = true
|
80
77
|
unless additional_search_parameters.nil?
|
@@ -110,6 +107,7 @@ module Birdsong
|
|
110
107
|
|
111
108
|
page.driver.execute_script("window.stop();")
|
112
109
|
|
110
|
+
# debugger if response_body.nil?
|
113
111
|
raise Birdsong::NoTweetFoundError if response_body.nil?
|
114
112
|
Oj.load(response_body)
|
115
113
|
rescue Birdsong::WebDriverError
|
@@ -143,49 +141,65 @@ module Birdsong
|
|
143
141
|
Capybara.current_driver = :selenium
|
144
142
|
end
|
145
143
|
|
146
|
-
|
147
|
-
|
148
|
-
|
144
|
+
def login
|
145
|
+
# Reset the sessions so that there's nothing laying around
|
146
|
+
page.quit
|
149
147
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
148
|
+
# Check if we're on a Twitter page already, if not visit it.
|
149
|
+
unless page.driver.browser.current_url.include?("twitter.com") || page.driver.browser.current_url.include?("x.com")
|
150
|
+
# There seems to be a bug in the Linux ARM64 version of chromedriver where this will properly
|
151
|
+
# navigate but then timeout, crashing it all up. So instead we check and raise the error when
|
152
|
+
# that then fails again.
|
153
|
+
page.driver.browser.navigate.to("https://x.com")
|
154
|
+
end
|
157
155
|
|
158
|
-
#
|
159
|
-
|
160
|
-
|
161
|
-
|
156
|
+
# We don't have to login if we already are
|
157
|
+
begin
|
158
|
+
return if find_field("Search", wait: 10).present?
|
159
|
+
rescue Capybara::ElementNotFound; end
|
160
|
+
|
161
|
+
page.driver.browser.find_element(link_text: "Sign in").click # Check if we're redirected to a login page, if we aren't we're already logged in
|
162
162
|
|
163
|
-
# # Check if we're redirected to a login page, if we aren't we're already logged in
|
164
163
|
# return unless page.has_xpath?('//*[@id="loginForm"]/div/div[3]/button')
|
165
164
|
|
166
|
-
#
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
165
|
+
# Try to log in
|
166
|
+
loop_count = 0
|
167
|
+
while loop_count < 5 do
|
168
|
+
3.times do
|
169
|
+
sleep(rand * 8.8)
|
170
|
+
element = page.driver.browser.find_element(tag_name: "input", name: "text")
|
171
|
+
next if element.nil?
|
172
|
+
element.click
|
173
|
+
break
|
174
|
+
rescue StandardError => e
|
175
|
+
puts e
|
176
|
+
next
|
177
|
+
end
|
178
|
+
|
179
|
+
sleep(rand * 2.8)
|
180
|
+
fill_in("text", with: ENV["TWITTER_USER_NAME"])
|
181
|
+
sleep(rand * 2.8)
|
182
|
+
find_button("Next").click
|
183
|
+
sleep(rand * 2.1)
|
184
|
+
fill_in("password", with: ENV["TWITTER_PASSWORD"])
|
185
|
+
|
186
|
+
begin
|
187
|
+
click_button("Log in", exact_text: true) # Note: "Log in" (lowercase `in`) instead redirects to Facebook's login page
|
188
|
+
rescue Capybara::ElementNotFound; end # If we can't find it don't break horribly, just keep waiting
|
189
|
+
|
190
|
+
break unless has_css?('p[data-testid="login-error-message"', wait: 10)
|
191
|
+
loop_count += 1
|
192
|
+
sleep(rand * 10.3)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Sometimes Twitter just... doesn't let you log in
|
196
|
+
raise "Twitter not accessible" if loop_count == 5
|
197
|
+
|
198
|
+
# No we don't want to save our login credentials
|
199
|
+
begin
|
200
|
+
click_on("Save Info")
|
201
|
+
rescue Capybara::ElementNotFound; end
|
202
|
+
end
|
189
203
|
|
190
204
|
def fetch_image(url)
|
191
205
|
request = Typhoeus::Request.new(url, followlocation: true)
|
@@ -20,15 +20,29 @@ module Birdsong
|
|
20
20
|
# login
|
21
21
|
graphql_object = get_content_of_subpage_from_url(
|
22
22
|
"https://x.com/jack/status/#{id}",
|
23
|
-
"/
|
23
|
+
"/TweetResultByRestId",
|
24
24
|
"data,tweetResult,result"
|
25
25
|
)
|
26
26
|
|
27
27
|
graphql_object = graphql_object.first if graphql_object.kind_of?(Array)
|
28
28
|
graphql_object = graphql_object["data"]["tweetResult"]["result"]
|
29
29
|
|
30
|
+
raise Birdsong::NoTweetFoundError if graphql_object.nil?
|
31
|
+
|
30
32
|
if graphql_object.key?("__typename") && graphql_object["__typename"] == "TweetUnavailable"
|
31
|
-
raise Birdsong::NoTweetFoundError
|
33
|
+
raise Birdsong::NoTweetFoundError if graphql_object["reason"] != "NsfwLoggedOut"
|
34
|
+
@@logger.info "Post is tagged NSFW, logging in to access..."
|
35
|
+
# Let's login and start this over?
|
36
|
+
login
|
37
|
+
@@logger.info "Logged in, retrying post..."
|
38
|
+
|
39
|
+
graphql_object = get_content_of_subpage_from_url(
|
40
|
+
"https://x.com/jack/status/#{id}",
|
41
|
+
"/TweetDetail"
|
42
|
+
)
|
43
|
+
|
44
|
+
# The format gets weird for this request
|
45
|
+
graphql_object = graphql_object["data"]["threaded_conversation_with_injections_v2"]["instructions"][0]["entries"][0]["content"]["itemContent"]["tweet_results"]["result"]["tweet"]
|
32
46
|
end
|
33
47
|
|
34
48
|
text = graphql_object["legacy"]["full_text"]
|
@@ -51,7 +65,7 @@ module Birdsong
|
|
51
65
|
video_preview_image = Birdsong.retrieve_media(media["media_url_https"])
|
52
66
|
video_variants = media["video_info"]["variants"]
|
53
67
|
largest_bitrate_variant = video_variants.sort_by do |variant|
|
54
|
-
variant
|
68
|
+
variant.has_key?("bitrate") ? variant["bitrate"] : 0
|
55
69
|
end.last
|
56
70
|
|
57
71
|
videos << Birdsong.retrieve_media(largest_bitrate_variant["url"])
|
@@ -106,7 +120,9 @@ module Birdsong
|
|
106
120
|
# First check if a post has a fact check overlay, if so, clear it.
|
107
121
|
# The only issue is that this can take *awhile* to search. Not sure what to do about that
|
108
122
|
# since it's Instagram's fault for having such a fucked up obfuscated hierarchy # Take the screenshot and return it
|
123
|
+
# rubocop:disable Lint/Debugger
|
109
124
|
save_screenshot("#{Birdsong.temp_storage_location}/instagram_screenshot_#{SecureRandom.uuid}.png")
|
125
|
+
# rubocop:enable Lint/Debugger
|
110
126
|
end
|
111
127
|
end
|
112
128
|
end
|
data/lib/birdsong/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: birdsong
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Guess
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: typhoeus
|
@@ -238,6 +238,20 @@ dependencies:
|
|
238
238
|
- - ">="
|
239
239
|
- !ruby/object:Gem::Version
|
240
240
|
version: '0'
|
241
|
+
- !ruby/object:Gem::Dependency
|
242
|
+
name: solargraph
|
243
|
+
requirement: !ruby/object:Gem::Requirement
|
244
|
+
requirements:
|
245
|
+
- - ">="
|
246
|
+
- !ruby/object:Gem::Version
|
247
|
+
version: '0'
|
248
|
+
type: :development
|
249
|
+
prerelease: false
|
250
|
+
version_requirements: !ruby/object:Gem::Requirement
|
251
|
+
requirements:
|
252
|
+
- - ">="
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: '0'
|
241
255
|
description:
|
242
256
|
email:
|
243
257
|
- cguess@gmail.com
|
@@ -248,7 +262,6 @@ files:
|
|
248
262
|
- ".github/workflows/main.yml"
|
249
263
|
- ".gitignore"
|
250
264
|
- ".rubocop.yml"
|
251
|
-
- ".ruby-version"
|
252
265
|
- CHANGELOG.md
|
253
266
|
- CODE_OF_CONDUCT.md
|
254
267
|
- Gemfile
|
@@ -288,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
301
|
- !ruby/object:Gem::Version
|
289
302
|
version: '0'
|
290
303
|
requirements: []
|
291
|
-
rubygems_version: 3.
|
304
|
+
rubygems_version: 3.5.22
|
292
305
|
signing_key:
|
293
306
|
specification_version: 4
|
294
307
|
summary: A gem to interface with Twitter's API V2
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
3.0.5
|