adspower-client 1.0.18 → 1.0.19
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/adspower-client.gemspec +2 -2
- data/lib/adspower-client.rb +90 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c91e849c43700d337b826208f705deef1bb3ec6e493ac872cd7d838afc67859
|
|
4
|
+
data.tar.gz: 176aefa58b9bd965fcbab16b7714dec6ac5cf3a8e0cad23b759248ae82b6fbd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 564d87a5328385d750e0734363a7dae2a20e56469801b4042818deb6c6f81468cdf0172d80bc47b09a432fb03b0834147771f11c6b939e10544b3d73952b450c
|
|
7
|
+
data.tar.gz: 4aa7af6322c6489d26733ff50117e3341d50fe68ecdba7846642149cbccb2874619483aa4a5bf0debacbb4d2ed93d2b5ca9eaf5507ca57afa755190c6dda2724
|
data/adspower-client.gemspec
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'adspower-client'
|
|
3
|
-
s.version = '1.0.
|
|
4
|
-
s.date = '2025-
|
|
3
|
+
s.version = '1.0.19'
|
|
4
|
+
s.date = '2025-11-03'
|
|
5
5
|
s.summary = "Ruby library for operating AdsPower API."
|
|
6
6
|
s.description = "Ruby library for operating AdsPower API."
|
|
7
7
|
s.authors = ["Leandro Daniel Sardi"]
|
data/lib/adspower-client.rb
CHANGED
|
@@ -49,9 +49,23 @@ class AdsPowerClient
|
|
|
49
49
|
|
|
50
50
|
# Release the lock
|
|
51
51
|
def release_lock
|
|
52
|
-
|
|
52
|
+
if @lockfile
|
|
53
|
+
@lockfile.flock(File::LOCK_UN)
|
|
54
|
+
# don't close while you expect further operations; close only on object shutdown
|
|
55
|
+
# @lockfile.close
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
|
-
|
|
58
|
+
=begin
|
|
59
|
+
# add a destructor to close file when object is GC'd / program shuts down
|
|
60
|
+
# Call client.close when you're done with the client instance (e.g., at program exit).
|
|
61
|
+
def close
|
|
62
|
+
if @lockfile && !@lockfile.closed?
|
|
63
|
+
@lockfile.flock(File::LOCK_UN) rescue nil
|
|
64
|
+
@lockfile.close rescue nil
|
|
65
|
+
@lockfile = nil
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
=end
|
|
55
69
|
# Wrapper method for critical sections
|
|
56
70
|
def with_lock
|
|
57
71
|
acquire_lock
|
|
@@ -81,12 +95,67 @@ class AdsPowerClient
|
|
|
81
95
|
return
|
|
82
96
|
end
|
|
83
97
|
|
|
98
|
+
def self.drivers
|
|
99
|
+
@@drivers
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Quit and remove all drivers (safe)
|
|
103
|
+
def self.cleanup_all
|
|
104
|
+
@@drivers.keys.each do |id|
|
|
105
|
+
drv = @@drivers[id]
|
|
106
|
+
begin
|
|
107
|
+
drv.quit if drv
|
|
108
|
+
rescue => e
|
|
109
|
+
# best-effort: ignore but log if desired
|
|
110
|
+
ensure
|
|
111
|
+
@@drivers.delete(id)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Quit and remove a specific driver (safe)
|
|
117
|
+
def self.cleanup(id)
|
|
118
|
+
drv = @@drivers[id]
|
|
119
|
+
begin
|
|
120
|
+
drv.quit if drv
|
|
121
|
+
rescue => e
|
|
122
|
+
# best-effort: ignore but log if desired
|
|
123
|
+
ensure
|
|
124
|
+
@@drivers.delete(id)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
=begin
|
|
128
|
+
# Try to kill processes matching a pattern (last resort)
|
|
129
|
+
# Call it only if quit and client.stop both failed.
|
|
130
|
+
def self.force_kill_by_ws(ws_endpoint)
|
|
131
|
+
# example ws_endpoint: "127.0.0.1:12345" -> 12345
|
|
132
|
+
port = ws_endpoint.split(':').last rescue nil
|
|
133
|
+
return unless port
|
|
134
|
+
# find and kill processes that hold that port
|
|
135
|
+
begin
|
|
136
|
+
pids = `lsof -ti tcp:#{port}`.split.map(&:to_i)
|
|
137
|
+
pids.each { |pid| Process.kill('KILL', pid) rescue nil }
|
|
138
|
+
rescue => e
|
|
139
|
+
# ignore/ log
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
=end
|
|
84
143
|
# Kill all the adspower_global processes running on the local computer.
|
|
85
144
|
def server_stop
|
|
86
145
|
with_lock do
|
|
87
146
|
self.server_pids.each { |pid|
|
|
88
147
|
`kill -9 #{pid}`
|
|
89
148
|
}
|
|
149
|
+
# clean up @@driver
|
|
150
|
+
@@drivers.each do |id, driver|
|
|
151
|
+
begin
|
|
152
|
+
driver.quit if driver
|
|
153
|
+
rescue => e
|
|
154
|
+
# Log or handle the exception if needed
|
|
155
|
+
ensure
|
|
156
|
+
@@drivers[id] = nil
|
|
157
|
+
end
|
|
158
|
+
end
|
|
90
159
|
end
|
|
91
160
|
return
|
|
92
161
|
end
|
|
@@ -478,8 +547,25 @@ class AdsPowerClient
|
|
|
478
547
|
end
|
|
479
548
|
|
|
480
549
|
def driver2(id, headless: false, read_timeout: 180)
|
|
481
|
-
return @@drivers[id] if @@drivers[id]
|
|
482
|
-
|
|
550
|
+
#return @@drivers[id] if @@drivers[id]
|
|
551
|
+
# If we have a cached driver, verify it's still valid
|
|
552
|
+
if @@drivers[id]
|
|
553
|
+
begin
|
|
554
|
+
# quick, non-destructive sanity check: ask for window_handles
|
|
555
|
+
@@drivers[id].window_handles
|
|
556
|
+
return @@drivers[id]
|
|
557
|
+
rescue Selenium::WebDriver::Error::InvalidSessionIdError,
|
|
558
|
+
Selenium::WebDriver::Error::NoSuchWindowError,
|
|
559
|
+
Errno::ECONNREFUSED => e
|
|
560
|
+
# stale/broken driver: best-effort cleanup and continue to create a new one
|
|
561
|
+
#warn "detected stale driver for #{id}: #{e.class}: #{e.message}"
|
|
562
|
+
self.class.cleanup(id)
|
|
563
|
+
rescue => e
|
|
564
|
+
#warn "unexpected error checking cached driver: #{e.class}: #{e.message}"
|
|
565
|
+
self.class.cleanup(id)
|
|
566
|
+
end
|
|
567
|
+
end
|
|
568
|
+
|
|
483
569
|
# 1) start the AdsPower profile / grab its WebSocket URL
|
|
484
570
|
data = start(id, headless)['data']
|
|
485
571
|
ws = data['ws']['selenium'] # e.g. "127.0.0.1:XXXXX"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: adspower-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leandro Daniel Sardi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: uri
|