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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1808eed99ef9e1885a1935f212651f7da9d5a60dcf2d74d5988eca88fd962122
4
- data.tar.gz: c7fc73864f0f71cbd4dfd7f038e02bdbfa11ff1091d8d1f2fd13f07ad71abefd
3
+ metadata.gz: dda08c757d1c68ec0444b27d413dd2f19691c08c4a2bfed33b99e4029e00ec81
4
+ data.tar.gz: 6f67bc01f6bd34abac6db6fc2b182d1f063890e44e127a8e9ecbeffc45b5db4a
5
5
  SHA512:
6
- metadata.gz: 97a72857edf2f49da68729ac86f4cc1aa992e76d0f58bcaafc1b7595e9becb5859dcb17819929920833e477586c58cdc957a8c480a8036862f5df5e9fa7c57da
7
- data.tar.gz: 874c0218358e28d827a67da10a0ef0dad45623deb0897c5dbf7939266fb2eaa23d40146d624acbb6a68cbd9bc02f36890be96bfe18affaa810e49bc919d3ff52
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.5)
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
- actionpack (7.0.1)
17
- actionview (= 7.0.1)
18
- activesupport (= 7.0.1)
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.6)
35
- public_suffix (>= 2.0.2, < 6.0)
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
- bigdecimal (3.1.7)
39
- builder (3.2.4)
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.1.9)
51
- crass (1.0.6)
52
- curb (1.0.5)
53
- dotenv (2.7.6)
54
- erubi (1.10.0)
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.16.3)
58
- i18n (1.9.1)
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
- loofah (2.13.0)
61
- crass (~> 1.0.2)
62
- nokogiri (>= 1.5.9)
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.15.0)
67
- nokogiri (1.13.1-arm64-darwin)
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.13.1-x86_64-darwin)
71
+ nokogiri (1.16.7-x86_64-darwin)
70
72
  racc (~> 1.4)
71
- nokogiri (1.13.1-x86_64-linux)
73
+ nokogiri (1.16.7-x86_64-linux)
72
74
  racc (~> 1.4)
73
75
  oauth (0.5.14)
74
- oj (3.16.3)
76
+ oj (3.16.6)
75
77
  bigdecimal (>= 3.0)
76
- parallel (1.21.0)
77
- parser (3.1.0.0)
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
- public_suffix (5.0.5)
80
- racc (1.6.0)
81
- rack (2.2.3)
82
- rack-test (1.1.0)
83
- rack (>= 1.0, < 3)
84
- rails-dom-testing (2.0.3)
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.0.6)
98
- regexp_parser (2.2.0)
99
- rexml (3.2.5)
100
- rubocop (1.25.1)
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.1.0.0)
100
+ parser (>= 3.3.0.2)
103
101
  rainbow (>= 2.2.2, < 4.0)
104
- regexp_parser (>= 1.8, < 3.0)
105
- rexml
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 (>= 1.4.0, < 3.0)
109
- rubocop-ast (1.15.1)
110
- parser (>= 3.0.1.1)
111
- rubocop-minitest (0.17.1)
112
- rubocop (>= 0.90, < 2.0)
113
- rubocop-packaging (0.5.1)
114
- rubocop (>= 0.89, < 2.0)
115
- rubocop-performance (1.13.2)
116
- rubocop (>= 1.7.0, < 2.0)
117
- rubocop-ast (>= 0.4.0)
118
- rubocop-rails (2.9.1)
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 (>= 0.90.0, < 2.0)
122
- rubocop-rails_config (1.8.1)
123
- railties (>= 5.0)
124
- rubocop (>= 1.19)
125
- rubocop-ast (>= 1.0.1)
126
- rubocop-minitest (~> 0.15)
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.11.0)
131
+ ruby-progressbar (1.13.0)
131
132
  rubyzip (2.3.2)
132
- selenium-devtools (0.125.0)
133
+ selenium-devtools (0.129.0)
133
134
  selenium-webdriver (~> 4.2)
134
- selenium-webdriver (4.21.1)
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
- thor (1.2.1)
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.4)
161
+ tzinfo (2.0.6)
143
162
  concurrent-ruby (~> 1.0)
144
- unicode-display_width (2.1.0)
145
- websocket (1.2.10)
163
+ unicode-display_width (2.6.0)
164
+ websocket (1.2.11)
146
165
  xpath (3.2.0)
147
166
  nokogiri (~> 1.8)
148
- zeitwerk (2.5.4)
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
- # def login
147
- # # Reset the sessions so that there's nothing laying around
148
- # page.quit
144
+ def login
145
+ # Reset the sessions so that there's nothing laying around
146
+ page.quit
149
147
 
150
- # # Check if we're on a Instagram page already, if not visit it.
151
- # unless page.driver.browser.current_url.include? "twitter.com" || page.driver.browser.current_url.include? "x.com"
152
- # # There seems to be a bug in the Linux ARM64 version of chromedriver where this will properly
153
- # # navigate but then timeout, crashing it all up. So instead we check and raise the error when
154
- # # that then fails again.
155
- # page.driver.browser.navigate.to("https://x.com")
156
- # end
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
- # # We don't have to login if we already are
159
- # begin
160
- # return if find_field("Search", wait: 10).present?
161
- # rescue Capybara::ElementNotFound; end
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
- # # Try to log in
167
- # loop_count = 0
168
- # while loop_count < 5 do
169
- # fill_in("username", with: ENV["TWITTER_USER_NAME"])
170
- # fill_in("password", with: ENV["TWITTER_PASSWORD"])
171
-
172
- # begin
173
- # click_button("Log in", exact_text: true) # Note: "Log in" (lowercase `in`) instead redirects to Facebook's login page
174
- # rescue Capybara::ElementNotFound; end # If we can't find it don't break horribly, just keep waiting
175
-
176
- # break unless has_css?('p[data-testid="login-error-message"', wait: 10)
177
- # loop_count += 1
178
- # sleep(rand * 10.3)
179
- # end
180
-
181
- # # Sometimes Instagram just... doesn't let you log in
182
- # raise "Instagram not accessible" if loop_count == 5
183
-
184
- # # No we don't want to save our login credentials
185
- # begin
186
- # click_on("Save Info")
187
- # rescue Capybara::ElementNotFound; end
188
- # end
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
- "/graphql",
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["bitrate"].nil? ? 0 : variant["bitrate"]
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Birdsong
4
- VERSION = "0.2.7"
4
+ VERSION = "0.2.8"
5
5
  end
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.7
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-06-19 00:00:00.000000000 Z
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.2.33
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