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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a5ae6cc2ac6143f4c2a98af32576c2cf85c2fe27faa8d7e1746df88d4192fe0
4
- data.tar.gz: 9e3a2043d09803dc5a668fc5a03409819f296be6bd3ce5d35e6338dabfb991eb
3
+ metadata.gz: 960021fea3e8dc9a0735b20a24730083231b8109ec74dd738a3d8508ff5ced3a
4
+ data.tar.gz: 126df561fa20424d26c71d3b6b32000b7ae1ae72b6beda64bc37e9bfef56894b
5
5
  SHA512:
6
- metadata.gz: 96e85dce902b72f67f6ff88c546591a639f126fb814b561fb1c1845036dcd159e04cafd7c7aa6921878fbbb5e991ca1eaf7ed320d1588c09217770e91a3c2ae8
7
- data.tar.gz: 02edbb6c8c90ba3fbbdc4f2202cd67ce5bc079f70cc7bc3a54c17e318fdb8c4715cbec556a5593ac74c0db394a17d78f5f3ccac204a91ca463367786883869d3
6
+ metadata.gz: 92bb76f6c2cd71c2b9d5cbcc84fce102c7c5ab2de8949e6dedf5a09d8f928e221563133049ff212d4d601ea317b714a77e0767016d9e671c3df365b6120fc06f
7
+ data.tar.gz: 402f6999e082f2bc4e90168915a165c2f336bd3547bbd360e909d07ddc879af3add9c3d1363a39198d7a5d4e443505d7adc1936840b93a58d2b6131d8144e149
@@ -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
- 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.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Daniel Sardi