adspower-client 1.0.14 → 1.0.15
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 +114 -3
- 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: 78c1201b2d2e5a524b67b7cac64506ba9afc2538e9890a387a02252387dd1259
|
4
|
+
data.tar.gz: c82ad9106e87929604fc7242e13680cdeddef6e0ede4e1bfe8181eb7e5c042d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a9ef2494df3d2c2adbd7d9d16286ff2b5e5b05f0f1872c32cb3d0439db1d915df5c4de9b2ff1a2321e09f96dccd4122da266f749c4c7f9fd89d45490144e2f4
|
7
|
+
data.tar.gz: a1d62383908125640ea807fcd96e38577c821ee7f4785b37936666aa892fa2462d6897c06861f084f265a431391dcf523424cff2a4799244e0b5fdd24cb59266
|
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 = '
|
3
|
+
s.version = '1.0.15'
|
4
|
+
s.date = '2025-07-17'
|
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
@@ -6,10 +6,12 @@ require 'selenium-webdriver'
|
|
6
6
|
require 'watir'
|
7
7
|
require 'fileutils'
|
8
8
|
|
9
|
-
class AdsPowerClient
|
9
|
+
class AdsPowerClient
|
10
|
+
CLOUD_API_BASE = 'https://api.adspower.com/v1'
|
11
|
+
|
10
12
|
# reference: https://localapi-doc-en.adspower.com/
|
11
13
|
# reference: https://localapi-doc-en.adspower.com/docs/Rdw7Iu
|
12
|
-
attr_accessor :key, :port, :server_log, :adspower_listener, :adspower_default_browser_version
|
14
|
+
attr_accessor :key, :port, :server_log, :adspower_listener, :adspower_default_browser_version, :cloud_token
|
13
15
|
|
14
16
|
# control over the drivers created, in order to not create the same driver twice and not generate memory leaks.
|
15
17
|
# reference: https://github.com/leandrosardi/adspower-client/issues/4
|
@@ -22,7 +24,12 @@ class AdsPowerClient
|
|
22
24
|
self.port = h[:port] || '50325'
|
23
25
|
self.server_log = h[:server_log] || '~/adspower-client.log'
|
24
26
|
self.adspower_listener = h[:adspower_listener] || 'http://127.0.0.1'
|
27
|
+
|
28
|
+
# DEPRECATED
|
25
29
|
self.adspower_default_browser_version = h[:adspower_default_browser_version] || '116'
|
30
|
+
|
31
|
+
# PENDING
|
32
|
+
self.cloud_token = h[:cloud_token]
|
26
33
|
end
|
27
34
|
|
28
35
|
# Acquire the lock
|
@@ -89,6 +96,54 @@ class AdsPowerClient
|
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
99
|
+
# Count current profiles (optionally filtered by group)
|
100
|
+
def profile_count(group_id: nil)
|
101
|
+
count = 0
|
102
|
+
page = 1
|
103
|
+
|
104
|
+
loop do
|
105
|
+
params = { page: page, limit: 100 }
|
106
|
+
params[:group_id] = group_id if group_id
|
107
|
+
url = "#{adspower_listener}:#{port}/api/v2/browser-profile/list"
|
108
|
+
res = BlackStack::Netting.call_post(url, params)
|
109
|
+
data = JSON.parse(res.body)
|
110
|
+
raise "Error listing profiles: #{data['msg']}" unless data['code'] == 0
|
111
|
+
|
112
|
+
list = data['data']['list']
|
113
|
+
count += list.size
|
114
|
+
break if list.size < 100
|
115
|
+
|
116
|
+
page += 1
|
117
|
+
end
|
118
|
+
|
119
|
+
count
|
120
|
+
end
|
121
|
+
|
122
|
+
# Return a hash with:
|
123
|
+
# • :limit ⇒ total profile slots allowed (-1 = unlimited)
|
124
|
+
# • :used ⇒ number of profiles currently created
|
125
|
+
# • :remaining ⇒ slots left (nil if unlimited)
|
126
|
+
# Fetch your real profile quota from the Cloud API
|
127
|
+
def cloud_profile_quota
|
128
|
+
uri = URI("#{CLOUD_API_BASE}/account/get_info")
|
129
|
+
req = Net::HTTP::Get.new(uri)
|
130
|
+
req['Authorization'] = "Bearer #{self.cloud_token}"
|
131
|
+
|
132
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
133
|
+
http.request(req)
|
134
|
+
end
|
135
|
+
data = JSON.parse(res.body)
|
136
|
+
raise "Cloud API error: #{data['msg']}" unless data['code'] == 0
|
137
|
+
|
138
|
+
allowed = data['data']['total_profiles_allowed'].to_i
|
139
|
+
used = data['data']['profiles_used'].to_i
|
140
|
+
remaining = allowed < 0 ? nil : (allowed - used)
|
141
|
+
|
142
|
+
{ limit: allowed,
|
143
|
+
used: used,
|
144
|
+
remaining: remaining }
|
145
|
+
end # cloud_profile_quota
|
146
|
+
|
92
147
|
# Create a new user profile via API call and return the ID of the created user.
|
93
148
|
def create
|
94
149
|
with_lock do
|
@@ -106,8 +161,62 @@ class AdsPowerClient
|
|
106
161
|
raise "Error: #{ret.to_s}" if ret['msg'].to_s.downcase != 'success'
|
107
162
|
ret['data']['id']
|
108
163
|
end
|
109
|
-
end
|
164
|
+
end # def create
|
165
|
+
|
166
|
+
# Create a new desktop profile with custom name, proxy, and fingerprint settings
|
167
|
+
#
|
168
|
+
# @param name [String] the profile’s display name
|
169
|
+
# @param proxy_config [Hash] keys: :ip, :port, :user, :password, :proxy_soft (default 'other'), :proxy_type (default 'http')
|
170
|
+
# @param group_id [String] which AdsPower group to assign (default '0')
|
171
|
+
# @param browser_version [String] Chrome version to use (must match Chromedriver), defaults to adspower_default_browser_version
|
172
|
+
# @return String the new profile’s ID
|
173
|
+
def create2(name:, proxy_config:, group_id: '0', browser_version: nil)
|
174
|
+
browser_version ||= adspower_default_browser_version
|
175
|
+
|
176
|
+
with_lock do
|
177
|
+
url = "#{adspower_listener}:#{port}/api/v2/browser-profile/create"
|
178
|
+
body = {
|
179
|
+
'name' => name,
|
180
|
+
'group_id' => group_id,
|
181
|
+
'user_proxy_config' => {
|
182
|
+
'proxy_soft' => proxy_config[:proxy_soft] || 'other',
|
183
|
+
'proxy_type' => proxy_config[:proxy_type] || 'http',
|
184
|
+
'proxy_host' => proxy_config[:ip],
|
185
|
+
'proxy_port' => proxy_config[:port].to_s,
|
186
|
+
'proxy_user' => proxy_config[:user],
|
187
|
+
'proxy_password' => proxy_config[:password]
|
188
|
+
},
|
189
|
+
'fingerprint_config' => {
|
190
|
+
# 1) Chrome kernel version → must match your Chromedriver
|
191
|
+
'browser_kernel_config' => {
|
192
|
+
'version' => browser_version,
|
193
|
+
'type' => 'chrome'
|
194
|
+
},
|
195
|
+
# 2) Auto‐detect timezone (and locale) from proxy IP
|
196
|
+
'automatic_timezone' => '1',
|
197
|
+
'timezone' => '',
|
198
|
+
'language' => [],
|
199
|
+
# 3) Force desktop UA (no mobile): empty random_ua & default UA settings
|
200
|
+
'ua' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "\
|
201
|
+
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{browser_version}.0.0.0 Safari/537.36",
|
202
|
+
'ua_category' => 'desktop',
|
203
|
+
#'screen_resolution' => '1920*1080',
|
204
|
+
'is_mobile' => false,
|
205
|
+
# standard desktop fingerprints
|
206
|
+
'webrtc' => 'disabled', # hide real IP via WebRTC
|
207
|
+
'flash' => 'allow',
|
208
|
+
'fonts' => [], # default fonts
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
res = BlackStack::Netting.call_post(url, body)
|
213
|
+
ret = JSON.parse(res.body)
|
214
|
+
raise "Error creating profile: #{ret['msg']}" unless ret['code'] == 0
|
110
215
|
|
216
|
+
ret['data']['profile_id']
|
217
|
+
end
|
218
|
+
end # def create2
|
219
|
+
|
111
220
|
# Delete a user profile via API call.
|
112
221
|
def delete(id)
|
113
222
|
with_lock do
|
@@ -214,6 +323,8 @@ class AdsPowerClient
|
|
214
323
|
driver
|
215
324
|
end
|
216
325
|
|
326
|
+
# DEPRECATED - Use Zyte instead of this method.
|
327
|
+
#
|
217
328
|
# Create a new profile, start the browser, visit a page, grab the HTML, and clean up.
|
218
329
|
def html(url)
|
219
330
|
ret = {
|
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.15
|
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:
|
11
|
+
date: 2025-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uri
|