mass-client 1.0.23 → 1.0.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/base-line/profile.rb +154 -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: 5768caa40938991a8b3622882554c8cf6007b1eaa6a515a567239a37ac0ad69b
|
4
|
+
data.tar.gz: 1b583d8993f857ee75fc41c70988229d1a842457f512e1eaf5d78c6fa2d98ef6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6310d3567d96a961ed126ed2d83dffdf48c4d4fa30b9a5681e5d6d40f1b22cfd5266197ce46e0ca4cf7536d934771dc0cfc5a27546fe2e242191037e0f796829
|
7
|
+
data.tar.gz: d8bc9fa2b1888143c673b40c54924edd2b5eda70929f925215d6cc268d7bd0c5cdd784092dd5a87c9e469bd330cda887fd75dea907fe5f1833ca9a716959b82d
|
data/lib/base-line/profile.rb
CHANGED
@@ -2,6 +2,160 @@ 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 = 30 # 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
|
+
s = ''
|
31
|
+
acquire_lock
|
32
|
+
begin
|
33
|
+
# Upload the file to Dropbox
|
34
|
+
s = BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
|
35
|
+
json = JSON.parse(s)
|
36
|
+
if json['is_downloadable'].nil? || !json['is_downloadable']
|
37
|
+
raise "Dropbox file upload failed. Dropbox response: #{s}"
|
38
|
+
end
|
39
|
+
rescue => e
|
40
|
+
raise "Error during upload: #{e.message} - Dropbox response: #{s}"
|
41
|
+
ensure
|
42
|
+
# Always release the lock, even if an error occurs
|
43
|
+
release_lock
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
#
|
49
|
+
#
|
50
|
+
|
51
|
+
# download image from Selenium using JavaScript and upload to Dropbox
|
52
|
+
# return the URL of the screenshot
|
53
|
+
#
|
54
|
+
# Parameters:
|
55
|
+
# - url: Internet address of the image to download from the website and upload to dropbox.
|
56
|
+
# - dropbox_folder: Dropbox folder name to store the image.
|
57
|
+
#
|
58
|
+
def download_image_0(url, dropbox_folder = nil)
|
59
|
+
raise "Either dropbox_folder parameter or self.desc['id_account'] are required." if dropbox_folder.nil? && self.desc['id_account'].nil?
|
60
|
+
dropbox_folder = self.desc['id_account'] if dropbox_folder.nil?
|
61
|
+
|
62
|
+
# Parameters
|
63
|
+
id = SecureRandom.uuid
|
64
|
+
|
65
|
+
# JavaScript to get base64 image data
|
66
|
+
js0 = "
|
67
|
+
function getImageBase64(imageSrc) {
|
68
|
+
return new Promise(async (resolve, reject) => {
|
69
|
+
try {
|
70
|
+
const response = await fetch(imageSrc);
|
71
|
+
const blob = await response.blob();
|
72
|
+
const reader = new FileReader();
|
73
|
+
reader.onloadend = function() {
|
74
|
+
resolve(reader.result);
|
75
|
+
};
|
76
|
+
reader.onerror = function(error) {
|
77
|
+
reject(error);
|
78
|
+
};
|
79
|
+
reader.readAsDataURL(blob);
|
80
|
+
} catch (error) {
|
81
|
+
reject(error);
|
82
|
+
}
|
83
|
+
});
|
84
|
+
}
|
85
|
+
return getImageBase64('#{url}');
|
86
|
+
"
|
87
|
+
|
88
|
+
# Execute JavaScript and get base64 image data
|
89
|
+
base64_image = driver.execute_script(js0)
|
90
|
+
raise "Failed to retrieve image data from URL: #{url}" if base64_image.nil?
|
91
|
+
|
92
|
+
# Extract MIME type and base64 data
|
93
|
+
mime_type_match = base64_image.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,/)
|
94
|
+
if mime_type_match
|
95
|
+
mime_subtype = mime_type_match[1] # e.g., 'png', 'jpeg', 'gif'
|
96
|
+
# Map common MIME subtypes to file extensions
|
97
|
+
extension = case mime_subtype
|
98
|
+
when 'jpeg' then 'jpg'
|
99
|
+
else mime_subtype
|
100
|
+
end
|
101
|
+
# Remove the data URL prefix
|
102
|
+
image_data = base64_image.sub(/^data:image\/[a-zA-Z0-9.+-]+;base64,/, '')
|
103
|
+
else
|
104
|
+
raise "Unsupported or invalid image data format."
|
105
|
+
end
|
106
|
+
|
107
|
+
# Update filename and paths
|
108
|
+
filename = "#{id}.#{extension}"
|
109
|
+
tmp_paths = if Mass.download_path.is_a?(String)
|
110
|
+
["#{Mass.download_path}/#{filename}"]
|
111
|
+
elsif Mass.download_path.is_a?(Array)
|
112
|
+
Mass.download_path.map { |s| "#{s}/#{filename}" }
|
113
|
+
else
|
114
|
+
raise "Invalid Mass.download_path configuration."
|
115
|
+
end
|
116
|
+
|
117
|
+
# Save the image to the first available path
|
118
|
+
tmp_path = tmp_paths.find { |path| File.writable?(File.dirname(path)) }
|
119
|
+
raise "No writable path found in #{tmp_paths.join(', ')}." if tmp_path.nil?
|
120
|
+
|
121
|
+
File.open(tmp_path, 'wb') do |file|
|
122
|
+
file.write(Base64.decode64(image_data))
|
123
|
+
end
|
124
|
+
|
125
|
+
# Proceed with Dropbox operations
|
126
|
+
year = Time.now.year.to_s.rjust(4, '0')
|
127
|
+
month = Time.now.month.to_s.rjust(2, '0')
|
128
|
+
folder = "/massprospecting.rpa/#{dropbox_folder}.#{year}.#{month}"
|
129
|
+
path = "#{folder}/#{filename}"
|
130
|
+
BlackStack::DropBox.dropbox_create_folder(folder)
|
131
|
+
|
132
|
+
# Upload the file to Dropbox
|
133
|
+
upload_to_dropbox_with_lock(tmp_path, path)
|
134
|
+
|
135
|
+
# Delete the local file
|
136
|
+
File.delete(tmp_path)
|
137
|
+
|
138
|
+
# Return the URL of the file in Dropbox
|
139
|
+
#
|
140
|
+
# Add a timeout to wait the file is present in the cloud.
|
141
|
+
# Reference: https://github.com/MassProspecting/docs/issues/320
|
142
|
+
self.wait_for_dropbox_url(path).gsub('&dl=1', '&dl=0')
|
143
|
+
end
|
144
|
+
|
145
|
+
# download image from Selenium using JavaScript and upload to Dropbox
|
146
|
+
# return the URL of the screenshot
|
147
|
+
#
|
148
|
+
# Parameters:
|
149
|
+
# - img: Selenium image element to download from the website and upload to dropbox.
|
150
|
+
# - dropbox_folder: Dropbox folder name to store the image.
|
151
|
+
#
|
152
|
+
def download_image(img, dropbox_folder=nil)
|
153
|
+
download_image_0(img.attribute('src'), dropbox_folder)
|
154
|
+
end # def download_image
|
155
|
+
|
156
|
+
#
|
157
|
+
#
|
158
|
+
#
|
5
159
|
def self.object_name
|
6
160
|
'profile'
|
7
161
|
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
|