mass-client 1.0.22 → 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: 89942512c664d6c1e10f0511db2f17c914a22d4b5b80d6b50fa4151c17997304
4
- data.tar.gz: c7dc604ffa10a35ed2f1e74377d73a7402a2714b3c554c086c91216f867fccb7
3
+ metadata.gz: 960021fea3e8dc9a0735b20a24730083231b8109ec74dd738a3d8508ff5ced3a
4
+ data.tar.gz: 126df561fa20424d26c71d3b6b32000b7ae1ae72b6beda64bc37e9bfef56894b
5
5
  SHA512:
6
- metadata.gz: b1480e0a4e9f4b414a7bec3148ee96c8611e2f44fd3b7dde949e296be04a4b3ab0354f485dfa964546ec40e1e15876612cfca54781073d8dcc104ad932205e1a
7
- data.tar.gz: 6abc1702733af395df62d3c8ff01b1d2c701f337d32427bfb77b59ea4ebff591f87ab39690fb3943d87a77f2e7560a96f4aedbfb045ac69d08156734d6fd2bfd
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
@@ -218,14 +220,14 @@ module Mass
218
220
  #
219
221
  # @return [String] The URL of the file in Dropbox, with the `&dl=1` parameter
220
222
  # replaced by `&dl=0`.
221
- # @raise [RuntimeError] If the file is not available within the specified
223
+ # @return nil If the file is not available within the specified
222
224
  # maximum wait time, raises an error with a timeout message.
223
225
  #
224
226
  # @example
225
227
  # wait_for_dropbox_url('/path/to/file', max_wait: 60, interval: 3)
226
228
  # # => "https://www.dropbox.com/s/yourfile?dl=0"
227
229
  #
228
- def wait_for_dropbox_url(path, max_wait: 30, interval: 2)
230
+ def wait_for_dropbox_url(path, max_wait: 5, interval: 2)
229
231
  start_time = Time.now
230
232
 
231
233
  loop do
@@ -235,7 +237,8 @@ module Mass
235
237
  rescue => e
236
238
  # Check if the timeout has been exceeded
237
239
  if Time.now - start_time > max_wait
238
- raise "Timeout exceeded while waiting for Dropbox file (#{path}): #{e.message}"
240
+ #raise "Timeout exceeded while waiting for Dropbox file (#{path}): #{e.message}"
241
+ return nil
239
242
  end
240
243
 
241
244
  # Wait for a short interval before retrying
@@ -244,110 +247,6 @@ module Mass
244
247
  end
245
248
  end
246
249
 
247
- # download image from Selenium using JavaScript and upload to Dropbox
248
- # return the URL of the screenshot
249
- #
250
- # Parameters:
251
- # - url: Internet address of the image to download from the website and upload to dropbox.
252
- # - dropbox_folder: Dropbox folder name to store the image.
253
- #
254
- def download_image_0(url, dropbox_folder = nil)
255
- raise "Either dropbox_folder parameter or self.desc['id_account'] are required." if dropbox_folder.nil? && self.desc['id_account'].nil?
256
- dropbox_folder = self.desc['id_account'] if dropbox_folder.nil?
257
-
258
- # Parameters
259
- id = SecureRandom.uuid
260
-
261
- # JavaScript to get base64 image data
262
- js0 = "
263
- function getImageBase64(imageSrc) {
264
- return new Promise(async (resolve, reject) => {
265
- try {
266
- const response = await fetch(imageSrc);
267
- const blob = await response.blob();
268
- const reader = new FileReader();
269
- reader.onloadend = function() {
270
- resolve(reader.result);
271
- };
272
- reader.onerror = function(error) {
273
- reject(error);
274
- };
275
- reader.readAsDataURL(blob);
276
- } catch (error) {
277
- reject(error);
278
- }
279
- });
280
- }
281
- return getImageBase64('#{url}');
282
- "
283
-
284
- # Execute JavaScript and get base64 image data
285
- base64_image = driver.execute_script(js0)
286
- raise "Failed to retrieve image data from URL: #{url}" if base64_image.nil?
287
-
288
- # Extract MIME type and base64 data
289
- mime_type_match = base64_image.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,/)
290
- if mime_type_match
291
- mime_subtype = mime_type_match[1] # e.g., 'png', 'jpeg', 'gif'
292
- # Map common MIME subtypes to file extensions
293
- extension = case mime_subtype
294
- when 'jpeg' then 'jpg'
295
- else mime_subtype
296
- end
297
- # Remove the data URL prefix
298
- image_data = base64_image.sub(/^data:image\/[a-zA-Z0-9.+-]+;base64,/, '')
299
- else
300
- raise "Unsupported or invalid image data format."
301
- end
302
-
303
- # Update filename and paths
304
- filename = "#{id}.#{extension}"
305
- tmp_paths = if Mass.download_path.is_a?(String)
306
- ["#{Mass.download_path}/#{filename}"]
307
- elsif Mass.download_path.is_a?(Array)
308
- Mass.download_path.map { |s| "#{s}/#{filename}" }
309
- else
310
- raise "Invalid Mass.download_path configuration."
311
- end
312
-
313
- # Save the image to the first available path
314
- tmp_path = tmp_paths.find { |path| File.writable?(File.dirname(path)) }
315
- raise "No writable path found in #{tmp_paths.join(', ')}." if tmp_path.nil?
316
-
317
- File.open(tmp_path, 'wb') do |file|
318
- file.write(Base64.decode64(image_data))
319
- end
320
-
321
- # Proceed with Dropbox operations
322
- year = Time.now.year.to_s.rjust(4, '0')
323
- month = Time.now.month.to_s.rjust(2, '0')
324
- folder = "/massprospecting.rpa/#{dropbox_folder}.#{year}.#{month}"
325
- path = "#{folder}/#{filename}"
326
- BlackStack::DropBox.dropbox_create_folder(folder)
327
-
328
- # Upload the file to Dropbox
329
- BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
330
- # Delete the local file
331
- File.delete(tmp_path)
332
-
333
- # Return the URL of the file in Dropbox
334
- #
335
- # Add a timeout to wait the file is present in the cloud.
336
- # Reference: https://github.com/MassProspecting/docs/issues/320
337
- self.wait_for_dropbox_url(path).gsub('&dl=1', '&dl=0')
338
- end
339
-
340
- # download image from Selenium using JavaScript and upload to Dropbox
341
- # return the URL of the screenshot
342
- #
343
- # Parameters:
344
- # - img: Selenium image element to download from the website and upload to dropbox.
345
- # - dropbox_folder: Dropbox folder name to store the image.
346
- #
347
- def download_image(img, dropbox_folder=nil)
348
- download_image_0(img.attribute('src'), dropbox_folder)
349
- end # def download_image
350
-
351
250
  # take screenshot and upload it to dropbox
352
251
  # return the URL of the screenshot
353
252
  def screenshot(dropbox_folder=nil)
@@ -365,7 +264,7 @@ module Mass
365
264
  folder = "/massprospecting.rpa/#{dropbox_folder}.#{year}.#{month}"
366
265
  path = "#{folder}/#{filename}"
367
266
  BlackStack::DropBox.dropbox_create_folder(folder)
368
- BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
267
+ upload_to_dropbox_with_lock(tmp_path, path)
369
268
  File.delete(tmp_path)
370
269
  BlackStack::DropBox.get_file_url(path).gsub('&dl=1', '&dl=0')
371
270
  end # def screenshot
@@ -387,7 +286,7 @@ module Mass
387
286
  folder = "/massprospecting.bots/#{dropbox_folder}.#{year}.#{month}"
388
287
  path = "#{folder}/#{filename}"
389
288
  BlackStack::DropBox.dropbox_create_folder(folder)
390
- BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
289
+ upload_to_dropbox_with_lock(tmp_path, path)
391
290
  File.delete(tmp_path)
392
291
  BlackStack::DropBox.get_file_url(path).gsub('&dl=1', '&dl=0')
393
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.22
4
+ version: 1.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Daniel Sardi