mass-client 1.0.17 → 1.0.18

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: 15fc20e0e46b85a66c45cbabbf3862fd1db6bff5fc254ec8b94414a0c5f086da
4
- data.tar.gz: 6cd0e9274b472a4e64a07d3f9f0d846b5499b2bbb3384e3e45a322d3a1210202
3
+ metadata.gz: 226f48f9298fc4e264e311c3544c19935e985a9d5bab26b11740ceba9770fec7
4
+ data.tar.gz: 0a5943bb27e3a9b58e212ab4929dec83462712fb9614edb2019458065d53b22c
5
5
  SHA512:
6
- metadata.gz: 663c292587112ca68d8a29643d7348d4510cf7028d1564d7f24c9259c518e1e25de0dfffc8bfef889f90f2f8e7a9d4625e80e4d95e8344ce81db83387c84cb66
7
- data.tar.gz: 176098ed2b937fc66af21da5e0d2d585a1960c209ab0eaa2be6579aa2a05fe866f532b36011c2bcb01043e51af202e1026235e870116f519191ecc04cd954e9b
6
+ metadata.gz: a91705cfe04215ec98a8d2418dc87fad48fb724fc0e60a6a80d52de28f2b6631a3e88d5047673fa583d0eba9630c2fe5e917ee0f382d748f1182f79f8020d85c
7
+ data.tar.gz: cf042ef9442239c66aecf000392b315d804c662d0f240e79125ef90109471f28da072da178ff0069cc9ee1602f5d3d2b0c6e97b63f1eca3be4e3b644d2205abe
@@ -175,96 +175,109 @@ module Mass
175
175
  automaticDownloads.find_element(:id => status.to_s).click()
176
176
  end # def automatic_downloads
177
177
 
178
+
179
+ def wait_for_file(file_paths, timeout = 30)
180
+ Timeout.timeout(timeout) do
181
+ loop do
182
+ file_paths.each do |path|
183
+ return path if File.exist?(path)
184
+ end
185
+ sleep(1)
186
+ end
187
+ end
188
+ rescue Timeout::Error
189
+ raise "Downloaded file not found in paths #{file_paths.join(',')} after #{timeout} seconds."
190
+ end
191
+
178
192
  # download image from Selenium using JavaScript and upload to Dropbox
179
193
  # return the URL of the screenshot
180
194
  #
181
195
  # Parameters:
182
196
  # - url: Internet address of the image to download from the website and upload to dropbox.
183
197
  # - dropbox_folder: Dropbox folder name to store the image.
184
- #
185
- def download_image_0(url, dropbox_folder=nil)
198
+ #
199
+ def download_image_0(url, dropbox_folder = nil)
186
200
  raise "Either dropbox_folder parameter or self.desc['id_account'] are required." if dropbox_folder.nil? && self.desc['id_account'].nil?
187
201
  dropbox_folder = self.desc['id_account'] if dropbox_folder.nil?
188
- # parameters
202
+
203
+ # Parameters
189
204
  id = SecureRandom.uuid
190
- filename = "#{id}.png"
191
- tmp_path = ["#{Mass.download_path}/#{filename}"] if Mass.download_path.is_a?(String)
192
- tmp_paths = Mass.download_path.map { |s| "#{s}/#{filename}" } if Mass.download_path.is_a?(Array)
193
-
194
- # excute JavaScript function downloadImage with the parameter src
195
- #binding.pry
196
- # this function is to download images from the same browser, using the proxy of the browser.
197
- # never download images from the server, because sites can track the IP.
198
- =begin
199
- js0 = "
200
- async function downloadImage(imageSrc, filename) {
201
- const image = await fetch(imageSrc)
202
- const imageBlog = await image.blob()
203
- const imageURL = URL.createObjectURL(imageBlog)
204
-
205
- const link = document.createElement('a')
206
- link.href = imageURL
207
- link.download = filename
208
- document.body.appendChild(link)
209
- link.click()
210
- document.body.removeChild(link)
211
- }
212
- downloadImage('#{url}', '#{filename}')
213
- "
214
- =end
215
- # Promise Handling: By returning a Promise in the JavaScript code, Selenium will wait for the asynchronous operation to complete.
216
- # Reference: https://github.com/MassProspecting/docs/issues/253
205
+
206
+ # JavaScript to get base64 image data
217
207
  js0 = "
218
- function downloadImage(imageSrc, filename) {
208
+ function getImageBase64(imageSrc) {
219
209
  return new Promise(async (resolve, reject) => {
220
210
  try {
221
- const image = await fetch(imageSrc);
222
- const imageBlob = await image.blob();
223
- const imageURL = URL.createObjectURL(imageBlob);
224
-
225
- const link = document.createElement('a');
226
- link.href = imageURL;
227
- link.download = filename;
228
- document.body.appendChild(link);
229
- link.click();
230
- document.body.removeChild(link);
231
-
232
- resolve('Download initiated');
233
- } catch (error) {
211
+ const response = await fetch(imageSrc);
212
+ const blob = await response.blob();
213
+ const reader = new FileReader();
214
+ reader.onloadend = function() {
215
+ resolve(reader.result);
216
+ };
217
+ reader.onerror = function(error) {
234
218
  reject(error);
219
+ };
220
+ reader.readAsDataURL(blob);
221
+ } catch (error) {
222
+ reject(error);
235
223
  }
236
224
  });
237
- }
238
- return downloadImage('#{url}', '#{filename}');
225
+ }
226
+ return getImageBase64('#{url}');
239
227
  "
240
- #binding.pry
241
- driver.execute_script(js0)
242
- sleep(10)
243
- # code
244
- year = Time.now.year.to_s.rjust(4,'0')
245
- month = Time.now.month.to_s.rjust(2,'0')
228
+
229
+ # Execute JavaScript and get base64 image data
230
+ base64_image = driver.execute_script(js0)
231
+ raise "Failed to retrieve image data from URL: #{url}" if base64_image.nil?
232
+
233
+ # Extract MIME type and base64 data
234
+ mime_type_match = base64_image.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,/)
235
+ if mime_type_match
236
+ mime_subtype = mime_type_match[1] # e.g., 'png', 'jpeg', 'gif'
237
+ # Map common MIME subtypes to file extensions
238
+ extension = case mime_subtype
239
+ when 'jpeg' then 'jpg'
240
+ else mime_subtype
241
+ end
242
+ # Remove the data URL prefix
243
+ image_data = base64_image.sub(/^data:image\/[a-zA-Z0-9.+-]+;base64,/, '')
244
+ else
245
+ raise "Unsupported or invalid image data format."
246
+ end
247
+
248
+ # Update filename and paths
249
+ filename = "#{id}.#{extension}"
250
+ tmp_paths = if Mass.download_path.is_a?(String)
251
+ ["#{Mass.download_path}/#{filename}"]
252
+ elsif Mass.download_path.is_a?(Array)
253
+ Mass.download_path.map { |s| "#{s}/#{filename}" }
254
+ else
255
+ raise "Invalid Mass.download_path configuration."
256
+ end
257
+
258
+ # Save the image to the first available path
259
+ tmp_path = tmp_paths.find { |path| File.writable?(File.dirname(path)) }
260
+ raise "No writable path found in #{tmp_paths.join(', ')}." if tmp_path.nil?
261
+
262
+ File.open(tmp_path, 'wb') do |file|
263
+ file.write(Base64.decode64(image_data))
264
+ end
265
+
266
+ # Proceed with Dropbox operations
267
+ year = Time.now.year.to_s.rjust(4, '0')
268
+ month = Time.now.month.to_s.rjust(2, '0')
246
269
  folder = "/massprospecting.rpa/#{dropbox_folder}.#{year}.#{month}"
247
270
  path = "#{folder}/#{filename}"
248
271
  BlackStack::DropBox.dropbox_create_folder(folder)
249
-
250
- # find the tmp_path that exists
251
- tmp_path = nil
252
- tmp_paths.each { |s|
253
- if File.exist?(s)
254
- tmp_path = s
255
- break
256
- end
257
- }
258
- raise "Downloaded file #{filename} not found in paths #{tmp_paths.join(',')}." if tmp_path.nil?
259
-
260
- # upload the file to dropbox
272
+
273
+ # Upload the file to Dropbox
261
274
  BlackStack::DropBox.dropbox_upload_file(tmp_path, path)
262
- # delete the file
275
+ # Delete the local file
263
276
  File.delete(tmp_path)
264
- # return the URL of the file in dropbox
277
+ # Return the URL of the file in Dropbox
265
278
  BlackStack::DropBox.get_file_url(path).gsub('&dl=1', '&dl=0')
266
- end # def download_image_0
267
-
279
+ end
280
+
268
281
  # download image from Selenium using JavaScript and upload to Dropbox
269
282
  # return the URL of the screenshot
270
283
  #
data/lib/mass-client.rb CHANGED
@@ -5,6 +5,8 @@ require 'blackstack-core'
5
5
  require 'simple_cloud_logging'
6
6
  require 'simple_command_line_parser'
7
7
  require 'colorize'
8
+ require 'timeout'
9
+ require 'base64'
8
10
 
9
11
  # mass client configuration
10
12
  module Mass
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.17
4
+ version: 1.0.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Daniel Sardi
@@ -11,23 +11,45 @@ cert_chain: []
11
11
  date: 2024-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: uri
14
+ name: timeout
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.11.2
20
- - - ">="
19
+ version: 0.4.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
21
25
  - !ruby/object:Gem::Version
22
- version: 0.11.2
26
+ version: 0.4.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.1
23
34
  type: :runtime
24
35
  prerelease: false
25
36
  version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: uri
43
+ requirement: !ruby/object:Gem::Requirement
26
44
  requirements:
27
45
  - - "~>"
28
46
  - !ruby/object:Gem::Version
29
47
  version: 0.11.2
30
- - - ">="
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
31
53
  - !ruby/object:Gem::Version
32
54
  version: 0.11.2
33
55
  - !ruby/object:Gem::Dependency
@@ -37,9 +59,6 @@ dependencies:
37
59
  - - "~>"
38
60
  - !ruby/object:Gem::Version
39
61
  version: 0.2.0
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: 0.2.0
43
62
  type: :runtime
44
63
  prerelease: false
45
64
  version_requirements: !ruby/object:Gem::Requirement
@@ -47,9 +66,6 @@ dependencies:
47
66
  - - "~>"
48
67
  - !ruby/object:Gem::Version
49
68
  version: 0.2.0
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- version: 0.2.0
53
69
  - !ruby/object:Gem::Dependency
54
70
  name: json
55
71
  requirement: !ruby/object:Gem::Requirement
@@ -57,9 +73,6 @@ dependencies:
57
73
  - - "~>"
58
74
  - !ruby/object:Gem::Version
59
75
  version: 2.6.3
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: 2.6.3
63
76
  type: :runtime
64
77
  prerelease: false
65
78
  version_requirements: !ruby/object:Gem::Requirement
@@ -67,9 +80,6 @@ dependencies:
67
80
  - - "~>"
68
81
  - !ruby/object:Gem::Version
69
82
  version: 2.6.3
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: 2.6.3
73
83
  - !ruby/object:Gem::Dependency
74
84
  name: blackstack-core
75
85
  requirement: !ruby/object:Gem::Requirement
@@ -77,9 +87,6 @@ dependencies:
77
87
  - - "~>"
78
88
  - !ruby/object:Gem::Version
79
89
  version: 1.2.20
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: 1.2.20
83
90
  type: :runtime
84
91
  prerelease: false
85
92
  version_requirements: !ruby/object:Gem::Requirement
@@ -87,9 +94,6 @@ dependencies:
87
94
  - - "~>"
88
95
  - !ruby/object:Gem::Version
89
96
  version: 1.2.20
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- version: 1.2.20
93
97
  - !ruby/object:Gem::Dependency
94
98
  name: colorize
95
99
  requirement: !ruby/object:Gem::Requirement
@@ -97,9 +101,6 @@ dependencies:
97
101
  - - "~>"
98
102
  - !ruby/object:Gem::Version
99
103
  version: 0.8.1
100
- - - ">="
101
- - !ruby/object:Gem::Version
102
- version: 0.8.1
103
104
  type: :runtime
104
105
  prerelease: false
105
106
  version_requirements: !ruby/object:Gem::Requirement
@@ -107,9 +108,6 @@ dependencies:
107
108
  - - "~>"
108
109
  - !ruby/object:Gem::Version
109
110
  version: 0.8.1
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- version: 0.8.1
113
111
  - !ruby/object:Gem::Dependency
114
112
  name: simple_cloud_logging
115
113
  requirement: !ruby/object:Gem::Requirement
@@ -117,9 +115,6 @@ dependencies:
117
115
  - - "~>"
118
116
  - !ruby/object:Gem::Version
119
117
  version: 1.2.6
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- version: 1.2.6
123
118
  type: :runtime
124
119
  prerelease: false
125
120
  version_requirements: !ruby/object:Gem::Requirement
@@ -127,9 +122,6 @@ dependencies:
127
122
  - - "~>"
128
123
  - !ruby/object:Gem::Version
129
124
  version: 1.2.6
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: 1.2.6
133
125
  - !ruby/object:Gem::Dependency
134
126
  name: simple_command_line_parser
135
127
  requirement: !ruby/object:Gem::Requirement
@@ -137,9 +129,6 @@ dependencies:
137
129
  - - "~>"
138
130
  - !ruby/object:Gem::Version
139
131
  version: 1.1.2
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- version: 1.1.2
143
132
  type: :runtime
144
133
  prerelease: false
145
134
  version_requirements: !ruby/object:Gem::Requirement
@@ -147,9 +136,6 @@ dependencies:
147
136
  - - "~>"
148
137
  - !ruby/object:Gem::Version
149
138
  version: 1.1.2
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: 1.1.2
153
139
  description: Ruby library for MassProspecting API.
154
140
  email: leandro@massprospecting.com
155
141
  executables: []