blackstack-core 1.2.15 → 1.2.17

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.
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