mass-client 1.0.23 → 1.0.24
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/lib/base-line/profile.rb +153 -0
- data/lib/first-line/profile_rpa.rb +4 -110
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 960021fea3e8dc9a0735b20a24730083231b8109ec74dd738a3d8508ff5ced3a
|
|
4
|
+
data.tar.gz: 126df561fa20424d26c71d3b6b32000b7ae1ae72b6beda64bc37e9bfef56894b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 92bb76f6c2cd71c2b9d5cbcc84fce102c7c5ab2de8949e6dedf5a09d8f928e221563133049ff212d4d601ea317b714a77e0767016d9e671c3df365b6120fc06f
|
|
7
|
+
data.tar.gz: 402f6999e082f2bc4e90168915a165c2f336bd3547bbd360e909d07ddc879af3add9c3d1363a39198d7a5d4e443505d7adc1936840b93a58d2b6131d8144e149
|
data/lib/base-line/profile.rb
CHANGED
|
@@ -2,6 +2,159 @@ module Mass
|
|
|
2
2
|
class Profile < BlackStack::Base
|
|
3
3
|
attr_accessor :type
|
|
4
4
|
|
|
5
|
+
# DROPBOX LOCKFILE PARAMETERS
|
|
6
|
+
LOCKFILE_PATH = '/tmp/dropbox_upload.lock' # Path to your lockfile
|
|
7
|
+
LOCK_TIMEOUT = 5 # Maximum time in seconds to wait for the lock
|
|
8
|
+
|
|
9
|
+
# DROPBOX LOCKFILE FUNCTIONS
|
|
10
|
+
def acquire_lock
|
|
11
|
+
begin
|
|
12
|
+
Timeout.timeout(LOCK_TIMEOUT) do
|
|
13
|
+
# Wait until the lockfile can be created (i.e., it's not already taken)
|
|
14
|
+
while File.exist?(LOCKFILE_PATH)
|
|
15
|
+
sleep 0.1
|
|
16
|
+
end
|
|
17
|
+
# Create the lockfile
|
|
18
|
+
File.open(LOCKFILE_PATH, 'w') {}
|
|
19
|
+
end
|
|
20
|
+
rescue Timeout::Error
|
|
21
|
+
raise "Timeout while waiting for lockfile."
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def release_lock
|
|
26
|
+
File.delete(LOCKFILE_PATH) if File.exist?(LOCKFILE_PATH)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def upload_to_dropbox_with_lock(tmp_path, path)
|
|
30
|
+
acquire_lock
|
|
31
|
+
begin
|
|
32
|
+
# Upload the file to Dropbox
|
|
33
|
+
s = BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
|
|
34
|
+
json = JSON.parse(s)
|
|
35
|
+
if json['is_downloadable'].nil? || !json['is_downloadable']
|
|
36
|
+
raise "Dropbox file upload failed. Dropbox response: #{s}"
|
|
37
|
+
end
|
|
38
|
+
rescue => e
|
|
39
|
+
raise "Error during upload: #{e.message}"
|
|
40
|
+
ensure
|
|
41
|
+
# Always release the lock, even if an error occurs
|
|
42
|
+
release_lock
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
#
|
|
48
|
+
#
|
|
49
|
+
|
|
50
|
+
# download image from Selenium using JavaScript and upload to Dropbox
|
|
51
|
+
# return the URL of the screenshot
|
|
52
|
+
#
|
|
53
|
+
# Parameters:
|
|
54
|
+
# - url: Internet address of the image to download from the website and upload to dropbox.
|
|
55
|
+
# - dropbox_folder: Dropbox folder name to store the image.
|
|
56
|
+
#
|
|
57
|
+
def download_image_0(url, dropbox_folder = nil)
|
|
58
|
+
raise "Either dropbox_folder parameter or self.desc['id_account'] are required." if dropbox_folder.nil? && self.desc['id_account'].nil?
|
|
59
|
+
dropbox_folder = self.desc['id_account'] if dropbox_folder.nil?
|
|
60
|
+
|
|
61
|
+
# Parameters
|
|
62
|
+
id = SecureRandom.uuid
|
|
63
|
+
|
|
64
|
+
# JavaScript to get base64 image data
|
|
65
|
+
js0 = "
|
|
66
|
+
function getImageBase64(imageSrc) {
|
|
67
|
+
return new Promise(async (resolve, reject) => {
|
|
68
|
+
try {
|
|
69
|
+
const response = await fetch(imageSrc);
|
|
70
|
+
const blob = await response.blob();
|
|
71
|
+
const reader = new FileReader();
|
|
72
|
+
reader.onloadend = function() {
|
|
73
|
+
resolve(reader.result);
|
|
74
|
+
};
|
|
75
|
+
reader.onerror = function(error) {
|
|
76
|
+
reject(error);
|
|
77
|
+
};
|
|
78
|
+
reader.readAsDataURL(blob);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
reject(error);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return getImageBase64('#{url}');
|
|
85
|
+
"
|
|
86
|
+
|
|
87
|
+
# Execute JavaScript and get base64 image data
|
|
88
|
+
base64_image = driver.execute_script(js0)
|
|
89
|
+
raise "Failed to retrieve image data from URL: #{url}" if base64_image.nil?
|
|
90
|
+
|
|
91
|
+
# Extract MIME type and base64 data
|
|
92
|
+
mime_type_match = base64_image.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,/)
|
|
93
|
+
if mime_type_match
|
|
94
|
+
mime_subtype = mime_type_match[1] # e.g., 'png', 'jpeg', 'gif'
|
|
95
|
+
# Map common MIME subtypes to file extensions
|
|
96
|
+
extension = case mime_subtype
|
|
97
|
+
when 'jpeg' then 'jpg'
|
|
98
|
+
else mime_subtype
|
|
99
|
+
end
|
|
100
|
+
# Remove the data URL prefix
|
|
101
|
+
image_data = base64_image.sub(/^data:image\/[a-zA-Z0-9.+-]+;base64,/, '')
|
|
102
|
+
else
|
|
103
|
+
raise "Unsupported or invalid image data format."
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Update filename and paths
|
|
107
|
+
filename = "#{id}.#{extension}"
|
|
108
|
+
tmp_paths = if Mass.download_path.is_a?(String)
|
|
109
|
+
["#{Mass.download_path}/#{filename}"]
|
|
110
|
+
elsif Mass.download_path.is_a?(Array)
|
|
111
|
+
Mass.download_path.map { |s| "#{s}/#{filename}" }
|
|
112
|
+
else
|
|
113
|
+
raise "Invalid Mass.download_path configuration."
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Save the image to the first available path
|
|
117
|
+
tmp_path = tmp_paths.find { |path| File.writable?(File.dirname(path)) }
|
|
118
|
+
raise "No writable path found in #{tmp_paths.join(', ')}." if tmp_path.nil?
|
|
119
|
+
|
|
120
|
+
File.open(tmp_path, 'wb') do |file|
|
|
121
|
+
file.write(Base64.decode64(image_data))
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Proceed with Dropbox operations
|
|
125
|
+
year = Time.now.year.to_s.rjust(4, '0')
|
|
126
|
+
month = Time.now.month.to_s.rjust(2, '0')
|
|
127
|
+
folder = "/massprospecting.rpa/#{dropbox_folder}.#{year}.#{month}"
|
|
128
|
+
path = "#{folder}/#{filename}"
|
|
129
|
+
BlackStack::DropBox.dropbox_create_folder(folder)
|
|
130
|
+
|
|
131
|
+
# Upload the file to Dropbox
|
|
132
|
+
upload_to_dropbox_with_lock(tmp_path, path)
|
|
133
|
+
|
|
134
|
+
# Delete the local file
|
|
135
|
+
File.delete(tmp_path)
|
|
136
|
+
|
|
137
|
+
# Return the URL of the file in Dropbox
|
|
138
|
+
#
|
|
139
|
+
# Add a timeout to wait the file is present in the cloud.
|
|
140
|
+
# Reference: https://github.com/MassProspecting/docs/issues/320
|
|
141
|
+
self.wait_for_dropbox_url(path).gsub('&dl=1', '&dl=0')
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# download image from Selenium using JavaScript and upload to Dropbox
|
|
145
|
+
# return the URL of the screenshot
|
|
146
|
+
#
|
|
147
|
+
# Parameters:
|
|
148
|
+
# - img: Selenium image element to download from the website and upload to dropbox.
|
|
149
|
+
# - dropbox_folder: Dropbox folder name to store the image.
|
|
150
|
+
#
|
|
151
|
+
def download_image(img, dropbox_folder=nil)
|
|
152
|
+
download_image_0(img.attribute('src'), dropbox_folder)
|
|
153
|
+
end # def download_image
|
|
154
|
+
|
|
155
|
+
#
|
|
156
|
+
#
|
|
157
|
+
#
|
|
5
158
|
def self.object_name
|
|
6
159
|
'profile'
|
|
7
160
|
end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
module Mass
|
|
2
2
|
class ProfileRPA < Mass::Profile
|
|
3
|
+
|
|
3
4
|
@@buffer_driver = nil
|
|
4
5
|
attr_accessor :headless
|
|
5
6
|
|
|
7
|
+
# SELENIUM FUNCTIONS
|
|
6
8
|
def self.buffer_driver
|
|
7
9
|
@@buffer_driver
|
|
8
10
|
end
|
|
@@ -245,114 +247,6 @@ module Mass
|
|
|
245
247
|
end
|
|
246
248
|
end
|
|
247
249
|
|
|
248
|
-
# download image from Selenium using JavaScript and upload to Dropbox
|
|
249
|
-
# return the URL of the screenshot
|
|
250
|
-
#
|
|
251
|
-
# Parameters:
|
|
252
|
-
# - url: Internet address of the image to download from the website and upload to dropbox.
|
|
253
|
-
# - dropbox_folder: Dropbox folder name to store the image.
|
|
254
|
-
#
|
|
255
|
-
def download_image_0(url, dropbox_folder = nil)
|
|
256
|
-
raise "Either dropbox_folder parameter or self.desc['id_account'] are required." if dropbox_folder.nil? && self.desc['id_account'].nil?
|
|
257
|
-
dropbox_folder = self.desc['id_account'] if dropbox_folder.nil?
|
|
258
|
-
|
|
259
|
-
# Parameters
|
|
260
|
-
id = SecureRandom.uuid
|
|
261
|
-
|
|
262
|
-
# JavaScript to get base64 image data
|
|
263
|
-
js0 = "
|
|
264
|
-
function getImageBase64(imageSrc) {
|
|
265
|
-
return new Promise(async (resolve, reject) => {
|
|
266
|
-
try {
|
|
267
|
-
const response = await fetch(imageSrc);
|
|
268
|
-
const blob = await response.blob();
|
|
269
|
-
const reader = new FileReader();
|
|
270
|
-
reader.onloadend = function() {
|
|
271
|
-
resolve(reader.result);
|
|
272
|
-
};
|
|
273
|
-
reader.onerror = function(error) {
|
|
274
|
-
reject(error);
|
|
275
|
-
};
|
|
276
|
-
reader.readAsDataURL(blob);
|
|
277
|
-
} catch (error) {
|
|
278
|
-
reject(error);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
return getImageBase64('#{url}');
|
|
283
|
-
"
|
|
284
|
-
|
|
285
|
-
# Execute JavaScript and get base64 image data
|
|
286
|
-
base64_image = driver.execute_script(js0)
|
|
287
|
-
raise "Failed to retrieve image data from URL: #{url}" if base64_image.nil?
|
|
288
|
-
|
|
289
|
-
# Extract MIME type and base64 data
|
|
290
|
-
mime_type_match = base64_image.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,/)
|
|
291
|
-
if mime_type_match
|
|
292
|
-
mime_subtype = mime_type_match[1] # e.g., 'png', 'jpeg', 'gif'
|
|
293
|
-
# Map common MIME subtypes to file extensions
|
|
294
|
-
extension = case mime_subtype
|
|
295
|
-
when 'jpeg' then 'jpg'
|
|
296
|
-
else mime_subtype
|
|
297
|
-
end
|
|
298
|
-
# Remove the data URL prefix
|
|
299
|
-
image_data = base64_image.sub(/^data:image\/[a-zA-Z0-9.+-]+;base64,/, '')
|
|
300
|
-
else
|
|
301
|
-
raise "Unsupported or invalid image data format."
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
# Update filename and paths
|
|
305
|
-
filename = "#{id}.#{extension}"
|
|
306
|
-
tmp_paths = if Mass.download_path.is_a?(String)
|
|
307
|
-
["#{Mass.download_path}/#{filename}"]
|
|
308
|
-
elsif Mass.download_path.is_a?(Array)
|
|
309
|
-
Mass.download_path.map { |s| "#{s}/#{filename}" }
|
|
310
|
-
else
|
|
311
|
-
raise "Invalid Mass.download_path configuration."
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
# Save the image to the first available path
|
|
315
|
-
tmp_path = tmp_paths.find { |path| File.writable?(File.dirname(path)) }
|
|
316
|
-
raise "No writable path found in #{tmp_paths.join(', ')}." if tmp_path.nil?
|
|
317
|
-
|
|
318
|
-
File.open(tmp_path, 'wb') do |file|
|
|
319
|
-
file.write(Base64.decode64(image_data))
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
# Proceed with Dropbox operations
|
|
323
|
-
year = Time.now.year.to_s.rjust(4, '0')
|
|
324
|
-
month = Time.now.month.to_s.rjust(2, '0')
|
|
325
|
-
folder = "/massprospecting.rpa/#{dropbox_folder}.#{year}.#{month}"
|
|
326
|
-
path = "#{folder}/#{filename}"
|
|
327
|
-
BlackStack::DropBox.dropbox_create_folder(folder)
|
|
328
|
-
|
|
329
|
-
# Upload the file to Dropbox
|
|
330
|
-
s = BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
|
|
331
|
-
json = JSON.parse(s)
|
|
332
|
-
if json['is_downloadable'].nil? || !json['is_downloadable']
|
|
333
|
-
raise "Dropbox file upload failed. Dropbox response: #{s}"
|
|
334
|
-
end
|
|
335
|
-
# Delete the local file
|
|
336
|
-
File.delete(tmp_path)
|
|
337
|
-
|
|
338
|
-
# Return the URL of the file in Dropbox
|
|
339
|
-
#
|
|
340
|
-
# Add a timeout to wait the file is present in the cloud.
|
|
341
|
-
# Reference: https://github.com/MassProspecting/docs/issues/320
|
|
342
|
-
self.wait_for_dropbox_url(path).gsub('&dl=1', '&dl=0')
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
# download image from Selenium using JavaScript and upload to Dropbox
|
|
346
|
-
# return the URL of the screenshot
|
|
347
|
-
#
|
|
348
|
-
# Parameters:
|
|
349
|
-
# - img: Selenium image element to download from the website and upload to dropbox.
|
|
350
|
-
# - dropbox_folder: Dropbox folder name to store the image.
|
|
351
|
-
#
|
|
352
|
-
def download_image(img, dropbox_folder=nil)
|
|
353
|
-
download_image_0(img.attribute('src'), dropbox_folder)
|
|
354
|
-
end # def download_image
|
|
355
|
-
|
|
356
250
|
# take screenshot and upload it to dropbox
|
|
357
251
|
# return the URL of the screenshot
|
|
358
252
|
def screenshot(dropbox_folder=nil)
|
|
@@ -370,7 +264,7 @@ module Mass
|
|
|
370
264
|
folder = "/massprospecting.rpa/#{dropbox_folder}.#{year}.#{month}"
|
|
371
265
|
path = "#{folder}/#{filename}"
|
|
372
266
|
BlackStack::DropBox.dropbox_create_folder(folder)
|
|
373
|
-
|
|
267
|
+
upload_to_dropbox_with_lock(tmp_path, path)
|
|
374
268
|
File.delete(tmp_path)
|
|
375
269
|
BlackStack::DropBox.get_file_url(path).gsub('&dl=1', '&dl=0')
|
|
376
270
|
end # def screenshot
|
|
@@ -392,7 +286,7 @@ module Mass
|
|
|
392
286
|
folder = "/massprospecting.bots/#{dropbox_folder}.#{year}.#{month}"
|
|
393
287
|
path = "#{folder}/#{filename}"
|
|
394
288
|
BlackStack::DropBox.dropbox_create_folder(folder)
|
|
395
|
-
|
|
289
|
+
upload_to_dropbox_with_lock(tmp_path, path)
|
|
396
290
|
File.delete(tmp_path)
|
|
397
291
|
BlackStack::DropBox.get_file_url(path).gsub('&dl=1', '&dl=0')
|
|
398
292
|
end # def snapshot
|