mass-client 1.0.23 → 1.0.25

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: 8a5ae6cc2ac6143f4c2a98af32576c2cf85c2fe27faa8d7e1746df88d4192fe0
4
- data.tar.gz: 9e3a2043d09803dc5a668fc5a03409819f296be6bd3ce5d35e6338dabfb991eb
3
+ metadata.gz: 5768caa40938991a8b3622882554c8cf6007b1eaa6a515a567239a37ac0ad69b
4
+ data.tar.gz: 1b583d8993f857ee75fc41c70988229d1a842457f512e1eaf5d78c6fa2d98ef6
5
5
  SHA512:
6
- metadata.gz: 96e85dce902b72f67f6ff88c546591a639f126fb814b561fb1c1845036dcd159e04cafd7c7aa6921878fbbb5e991ca1eaf7ed320d1588c09217770e91a3c2ae8
7
- data.tar.gz: 02edbb6c8c90ba3fbbdc4f2202cd67ce5bc079f70cc7bc3a54c17e318fdb8c4715cbec556a5593ac74c0db394a17d78f5f3ccac204a91ca463367786883869d3
6
+ metadata.gz: 6310d3567d96a961ed126ed2d83dffdf48c4d4fa30b9a5681e5d6d40f1b22cfd5266197ce46e0ca4cf7536d934771dc0cfc5a27546fe2e242191037e0f796829
7
+ data.tar.gz: d8bc9fa2b1888143c673b40c54924edd2b5eda70929f925215d6cc268d7bd0c5cdd784092dd5a87c9e469bd330cda887fd75dea907fe5f1833ca9a716959b82d
@@ -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
- BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
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
- BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mass-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.23
4
+ version: 1.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Daniel Sardi