blackstack-core 1.2.15 → 1.2.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/functions.rb +267 -69
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7ad16f1534d386b0e4e441f136672f53b225bf32ae2a65e628d115c563a6997
4
- data.tar.gz: e5787c25c7d410e2112acef2478aac40cc36c4ba1c65513d751f6b2935ac7c7e
3
+ metadata.gz: 21f1505a48eddf72b71e67994ad8c4ee978b9ebefa6c21e13a98dab640436fa4
4
+ data.tar.gz: 267f3225f76f481b534cdca45223e119421038a20bdc61fb0917dc442c4882c7
5
5
  SHA512:
6
- metadata.gz: d5b003446c612b655777d61fbd7ffbc3e03a08f782455690890c6abaef10d00fe550c967ddfb150b661c30eaab7e92ab0016123c08a7fe1c531c3349d3a19706
7
- data.tar.gz: 00df2249b2c3081c796ddac04738abdfa22d5d7c52b7a9cfdd21b071ec856ce46fa4d494bebd4b23c8e1ae268384c5529dc74d778d6d8048bc36bb6561db2429
6
+ metadata.gz: 982ff25a2a8419a8e7c8ae5d323c603ee733ec66443a318c0c64206ef18be75248b11507fe268d017b4be38a710b702abea4e5a89449f042cbba1cebb4cb219b
7
+ data.tar.gz: f8c0607bbf9420e2093d9d98d8f99b265f05b420cfc3af3f0491e1ac2f1529d7c07de1fe1338e45bfad7c4ebd6e1f604e3f39ef1ee94355ad05a273836acf9a2
data/lib/functions.rb CHANGED
@@ -6,88 +6,286 @@ module BlackStack
6
6
  File.exists?('./.sandbox')
7
7
  end
8
8
 
9
- module API
10
- # API connection parameters
11
- @@api_key = nil # Api-key of the client who will be the owner of a process.
12
- @@api_protocol = nil # Protocol, HTTP or HTTPS, of the BlackStack server where this process will be registered.
13
- @@api_domain = nil # Domain of the BlackStack server where this process will be registered.
14
- @@api_port = nil # Port of the BlackStack server where this process will be registered.
15
- @@api_less_secure_port = nil # Port of the BlackStack server where this process will be registered.
16
-
17
- # API connection getters and setters
18
- def self.api_key()
19
- @@api_key
20
- end
21
- def self.api_protocol
22
- @@api_protocol
23
- end
24
- def self.api_domain
25
- @@api_domain
26
- end
27
- def self.api_port
28
- @@api_port
29
- end
30
- def self.api_less_secure_port
31
- @@api_less_secure_port
32
- end
33
- def self.api_url()
34
- "#{BlackStack::API.api_protocol}://#{BlackStack::API.api_domain}:#{BlackStack::API.api_port}"
35
- end
36
- def self.api_less_secure_url()
37
- "http://#{BlackStack::API.api_domain}:#{BlackStack::API.api_less_secure_port}"
38
- end
39
- def self.set_api_key(s)
40
- # validate: the parameter s is required
41
- raise 'The parameter s is required' unless s
9
+ module API
10
+ @@api_key = nil
11
+ @@api_url = nil
12
+ @@api_port = nil
13
+ @@api_version = '1.0'
14
+ @@classes = {}
42
15
 
43
- # validate: the parameter s must be a string
44
- raise 'The parameter s must be a string' unless s.is_a?(String)
16
+ def self.api_key
17
+ @@api_key
18
+ end # def self.api_key
45
19
 
46
- # map values
47
- @@api_key = s
48
- end
49
- def self.set_api_url(h)
50
- # validate: the parameter h is requred
51
- raise "The parameter h is required." if h.nil?
20
+ def self.api_url
21
+ @@api_url
22
+ end
52
23
 
53
- # validate: the parameter h must be a hash
54
- raise "The parameter h must be a hash" unless h.is_a?(Hash)
24
+ def self.api_version
25
+ @@api_version
26
+ end # def self.api_version
55
27
 
56
- # validate: the :api_key key is required
57
- raise 'The key :api_key is required' unless h.has_key?(:api_key)
28
+ def self.api_port
29
+ @@api_port
30
+ end # def self.api_port
58
31
 
59
- # validate: the :api_protocol key is required
60
- raise 'The key :api_protocol is required' unless h.has_key?(:api_domain)
32
+ def self.api_url()
33
+ "#{BlackStack::API.api_protocol}://#{BlackStack::API.api_domain}:#{BlackStack::API.api_port}"
34
+ end
61
35
 
62
- # validate: the :api_domain key is required
63
- raise 'The key :api_domain is required' unless h.has_key?(:api_domain)
36
+ def self.classes
37
+ @@classes
38
+ end # def self.classes
39
+
40
+ def self.set_client(
41
+ api_key: ,
42
+ api_url: ,
43
+ api_version: '1.0',
44
+ api_port: nil
45
+ )
46
+ @@api_key = api_key
47
+ @@api_url = api_url
48
+ @@api_version = api_version
49
+ @@api_port = api_port
50
+ end # def self.set_client
64
51
 
65
- # validate: the :api_port key is required
66
- raise 'The key :api_port is required' unless h.has_key?(:api_port)
52
+ def self.set_server(
53
+ classes: {}
54
+ )
55
+ @@classes = classes
56
+ end # def self.set_server
67
57
 
68
- # validate: the :api_key key is a string
69
- raise 'The key :api_key must be a string' unless h[:api_key].is_a?(String)
58
+ def self.post(
59
+ endpoint: ,
60
+ params: {}
61
+ )
62
+ begin
63
+ url = "#{@@api_url}:#{@@api_port}/api#{@@api_version}/#{endpoint}.json"
64
+ params['api_key'] = @@api_key
65
+ res = BlackStack::Netting.call_post(url, params)
66
+ parsed = JSON.parse(res.body)
67
+ return JSON.parse(res.body)
70
68
 
71
- # validate: the :api_protocol key is a string
72
- raise 'The key :api_protocol must be a string' unless h[:api_protocol].is_a?(String)
69
+ ## write response.body into a file
70
+ # File.open('response.body.html', 'w') { |file| file.write(res.body) }
71
+ rescue => e
72
+ return {
73
+ 'status' => e.message,
74
+ 'value' => e.to_console
75
+ }
76
+ end
77
+ end # def self.post
73
78
 
74
- # validate: the :api_domain key is a string
75
- raise 'The key :api_domain must be a string' unless h[:api_domain].is_a?(String)
79
+ end # module API
76
80
 
77
- # validate: the :api_port key is an integer, or a string that can be converted to an integer
78
- raise 'The key :api_port must be an integer' unless h[:api_port].is_a?(Integer) || (h[:api_port].is_a?(String) && h[:api_port].to_i.to_s == h[:api_port])
81
+ # Base class.
82
+ # List of methods you have to overload if you develop a profile type.
83
+ #
84
+ class Base
85
+ # object json descriptor
86
+ attr_accessor :desc
79
87
 
80
- # validate: the :api_less_secure_port key is an integer, or a string that can be converted to an integer
81
- raise 'The key :api_less_secure_port must be an integer' unless h[:api_less_secure_port].is_a?(Integer) || (h[:api_less_secure_port].is_a?(String) && h[:api_less_secure_port].to_i.to_s == h[:api_less_secure_port])
88
+ def self.object_name
89
+ raise 'You have to overload this method in your class.'
90
+ end
82
91
 
83
- # map the values
84
- @@api_key = h[:api_key]
85
- @@api_protocol = h[:api_protocol]
86
- @@api_domain = h[:api_domain]
87
- @@api_port = h[:api_port].to_i
88
- @@api_less_secure_port = h[:api_less_secure_port].to_i
89
- end
90
- end # module API
92
+ def initialize(h)
93
+ self.desc = h
94
+ end
95
+
96
+ # Crate an instance of a child class using speicfications in the `desc['name']` attribute.
97
+ # By default, returns the same instance.
98
+ def child_class_instance
99
+ return self
100
+ end
101
+
102
+ def self.account_value(field:)
103
+ params = {}
104
+ params['field'] = field
105
+ # call the API
106
+ ret = BlackStack::API.post(
107
+ endpoint: "account_value",
108
+ params: params
109
+ )
110
+ raise "Error calling account_value endpoint: #{ret['status']}" if ret['status'] != 'success'
111
+ return ret['result']
112
+ end # def self.base
113
+
114
+
115
+ # Get array of hash descriptor of profile.
116
+ #
117
+ # Parameters:
118
+ # - page: integer. Page number.
119
+ # - limit: integer. Number of profiles per page.
120
+ # - params: hash. Additional filter parameters used by the specific child class.
121
+ #
122
+ def self.page(page:, limit:, filters: {})
123
+ # add page and limit to the params
124
+ params = {}
125
+ params['page'] = page
126
+ params['limit'] = limit
127
+ params['filters'] = filters
128
+ params['backtrace'] = Mass.backtrace
129
+ # call the API
130
+ ret = BlackStack::API.post(
131
+ endpoint: "#{self.object_name}/page",
132
+ params: params
133
+ )
134
+ raise "Error calling page endpoint: #{ret['status']}" if ret['status'] != 'success'
135
+ return ret['results'].map { |h| self.new(h).child_class_instance }
136
+ end # def self.base
137
+
138
+ # Get array of hash descriptors of profiles.
139
+ #
140
+ # Parameters:
141
+ # - id: guid. Id of the profile to bring.
142
+ #
143
+ def self.count
144
+ params = {}
145
+ params['backtrace'] = Mass.backtrace
146
+ ret = BlackStack::API.post(
147
+ endpoint: "#{self.object_name}/count",
148
+ params: params
149
+ )
150
+ raise "Error calling count endpoint: #{ret['status']}" if ret['status'] != 'success'
151
+ return ret['result'].to_i
152
+ end # def self.count
153
+
154
+ # Get array of hash descriptors of profiles.
155
+ #
156
+ # Parameters:
157
+ # - id: guid. Id of the profile to bring.
158
+ #
159
+ def self.get(id)
160
+ params = {}
161
+ params['id'] = id
162
+ params['backtrace'] = Mass.backtrace
163
+ ret = BlackStack::API.post(
164
+ endpoint: "#{self.object_name}/get",
165
+ params: params
166
+ )
167
+ raise "Error calling get endpoint: #{ret['status']}" if ret['status'] != 'success'
168
+ return self.new(ret['result']).child_class_instance
169
+ end # def self.get
170
+
171
+ # Submit a hash descriptor to the server for an update
172
+ #
173
+ def self.update(desc)
174
+ params = {}
175
+ params['desc'] = desc
176
+ params['backtrace'] = Mass.backtrace
177
+ ret = BlackStack::API.post(
178
+ endpoint: "#{self.object_name}/update",
179
+ params: params
180
+ )
181
+ raise "Error calling update endpoint: #{ret['status']}" if ret['status'] != 'success'
182
+ return self.new(ret['result']).child_class_instance
183
+ end # def self.update
184
+
185
+ # Submit a hash descriptor to the server for an update
186
+ #
187
+ def update
188
+ self.class.update(self.desc)
189
+ end
190
+
191
+ # Submit a hash descriptor to the server for an insert
192
+ #
193
+ def self.insert(desc)
194
+ params = {}
195
+ params['desc'] = desc
196
+ params['backtrace'] = Mass.backtrace
197
+ ret = BlackStack::API.post(
198
+ endpoint: "#{self.object_name}/insert",
199
+ params: params
200
+ )
201
+ raise "Error calling insert endpoint: #{ret['status']}" if ret['status'] != 'success'
202
+ return self.new(ret['result']).child_class_instance
203
+ end # def self.insert
204
+
205
+
206
+ # Submit a hash descriptor to the server for an upsert
207
+ #
208
+ def self.upsert(desc)
209
+ params = {}
210
+ params['desc'] = desc
211
+ params['backtrace'] = Mass.backtrace
212
+ ret = BlackStack::API.post(
213
+ endpoint: "#{self.object_name}/upsert",
214
+ params: params
215
+ )
216
+ raise "Error calling upsert endpoint: #{ret['status']}" if ret['status'] != 'success'
217
+ return self.new(ret['result']).child_class_instance
218
+ end # def self.upsert
219
+
220
+ # Submit a hash descriptor to the server for an upsert
221
+ #
222
+ def upsert
223
+ self.class.upsert(self.desc)
224
+ end
225
+
226
+
227
+ # return the HTML of a page downloaded by Zyte.
228
+ #
229
+ # Parameters:
230
+ # - url: the URL of the page to download.
231
+ # - api_key: the Zyte API key.
232
+ # - options: the options to pass to Zyte.
233
+ #
234
+ def zyte_html(url, api_key:, options:, data_filename:)
235
+ ret = nil
236
+ # getting the HTML
237
+ zyte = ZyteClient.new(key: api_key)
238
+ html = zyte.extract(url: url, options: options, data_filename: data_filename)
239
+ # return the URL of the file in the cloud
240
+ return html
241
+ end # def zyte_html
242
+
243
+ # create a file in the cloud with the HTML of a page downloaded by Zyte.
244
+ # return the URL of the file.
245
+ #
246
+ # Parameters:
247
+ # - url: the URL of the page to download.
248
+ # - api_key: the Zyte API key.
249
+ # - options: the options to pass to Zyte.
250
+ # - dropbox_folder: the folder in the cloud where to store the file. If nil, it will use the self.desc['id_account'] value.
251
+ # - retry_times: the number of times to retry the download until the HTML is valid.
252
+ #
253
+ def zyte_snapshot(url, api_key:, options:, data_filename:, dropbox_folder:nil, retry_times: 3)
254
+ # "The garbage character must be due to the 520 error code which was caused on the second request."
255
+ garbage = "\x9E\xE9e"
256
+
257
+ ret = nil
258
+ raise "Either dropbox_folder parameter or self.desc['id_account'] are required." if dropbox_folder.nil? && self.desc['id_account'].nil?
259
+ dropbox_folder = self.desc['id_account'] if dropbox_folder.nil?
260
+ # build path to the local file in /tmp
261
+ id = SecureRandom.uuid
262
+ filename = "#{id}.html"
263
+ tmp_path = "/tmp/#{filename}"
264
+ # build path to the file in the cloud
265
+ year = Time.now.year.to_s.rjust(4,'0')
266
+ month = Time.now.month.to_s.rjust(2,'0')
267
+ dropbox_folder = "/massprospecting.bots/#{dropbox_folder}.#{year}.#{month}"
268
+ dropbox_path = "#{dropbox_folder}/#{filename}"
269
+ # getting the HTML - Retry mechanism
270
+ zyte = ZyteClient.new(key: api_key)
271
+ try = 0
272
+ html = garbage
273
+ while try < retry_times && html == garbage
274
+ html = zyte.extract(url: url, options: options, data_filename: data_filename)
275
+ try += 1
276
+ end
277
+ # save the HTML in the local file in /tmp
278
+ File.open(tmp_path, 'w') { |file| file.write(html) }
279
+ # create the folder in the cloud and upload the file
280
+ BlackStack::DropBox.dropbox_create_folder(dropbox_folder)
281
+ BlackStack::DropBox.dropbox_upload_file(tmp_path, dropbox_path)
282
+ # delete the local file
283
+ File.delete(tmp_path)
284
+ # return the URL of the file in the cloud
285
+ return BlackStack::DropBox.get_file_url(dropbox_path)
286
+ end # def zyte_snapshot
287
+
288
+ end # class Base
91
289
 
92
290
  # -----------------------------------------------------------------------------------------
93
291
  # PRY Supporting Functions
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blackstack-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.15
4
+ version: 1.2.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Daniel Sardi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-06 00:00:00.000000000 Z
11
+ date: 2024-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: content_spinning