birdsong 0.2.6 → 0.2.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82bf946c745782199f6ec1dc9e1dd21bcf2b15584e69152ffebd1b5b8b452873
4
- data.tar.gz: 82dc7534653c03bd75b7f24ac588fa6c9d0fa689552f4b67e4739c296df90692
3
+ metadata.gz: dda08c757d1c68ec0444b27d413dd2f19691c08c4a2bfed33b99e4029e00ec81
4
+ data.tar.gz: 6f67bc01f6bd34abac6db6fc2b182d1f063890e44e127a8e9ecbeffc45b5db4a
5
5
  SHA512:
6
- metadata.gz: 0207ae04fb995778f6fe447f55c78f962aac6c0d7418912d9dc4bf5fd575742915ba9912360811e7921655b824a3bf9ef6739a67981ec209698e112e57c9aee4
7
- data.tar.gz: a8c301f6805c88ac99ef3b5306ef0c3df9ea6f710498a3d4b970c813519606e7c7cbc70b4250c8cde148f3ff50e912c7b0fad0b2dccecd0006f313bd04e299df
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"
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://twitter.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)
@@ -14,21 +14,35 @@ module Birdsong
14
14
  # - Number of likes *
15
15
  # - Hashtags
16
16
 
17
- Capybara.app_host = "https://twitter.com"
17
+ Capybara.app_host = "https://x.com"
18
18
 
19
19
  # video slideshows https://www.instagram.com/p/CY7KxwYOFBS/?utm_source=ig_embed&utm_campaign=loading
20
20
  # login
21
21
  graphql_object = get_content_of_subpage_from_url(
22
- "https://twitter.com/jack/status/#{id}",
23
- "/graphql",
22
+ "https://x.com/jack/status/#{id}",
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
data/lib/birdsong/user.rb CHANGED
@@ -39,7 +39,7 @@ module Birdsong
39
39
 
40
40
  @description = user_object[:description]
41
41
  @url = user_object[:url]
42
- @url = "https://www.twitter.com/#{@username}" if @url.nil?
42
+ @url = "https://www.x.com/#{@username}" if @url.nil?
43
43
 
44
44
  @followers_count = user_object[:followers_count]
45
45
  @following_count = user_object[:following_count]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Birdsong
4
- VERSION = "0.2.6"
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.6
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-14 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