pampa_workers 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 782e133cec2c858b619c751b3bf51df20e29f771
4
+ data.tar.gz: 42f4cab18236d5c33be917894ddad9195a6047b4
5
+ SHA512:
6
+ metadata.gz: d4ce7738ae0bcc792a35fdd132d081bf94fa2da36dbfff2b20d5d6093b17847675aa9ae567d810bcecd94e20550c5931238e7c937db0fa5b0977cfa55e35eab1
7
+ data.tar.gz: 3eec7d8fed322007313031574e103442fd7585200ad364c5f333f20579270630cbf63e0c66f14fe0a488de20f2b21145c78d46cf2c0f932e85e78402a204a7bf
@@ -0,0 +1,5 @@
1
+ module BlackStack
2
+ module BaseDivision
3
+
4
+ end # BaseDivision
5
+ end # module BlackStack
@@ -0,0 +1,5 @@
1
+ module BlackStack
2
+ module BaseWorker
3
+ KEEP_ACTIVE_MINUTES = 5 # if the worker didnt send a ping during the last X minutes, it is considered as not-active
4
+ end # BaseWorker
5
+ end # module BlackStack
@@ -0,0 +1,189 @@
1
+ require 'simple_host_monitoring'
2
+ require_relative './user'
3
+ require_relative './role'
4
+ require_relative './timezone'
5
+
6
+ module BlackStack
7
+ class Client < Sequel::Model(:client)
8
+ BlackStack::Client.dataset = BlackStack::Client.dataset.disable_insert_output
9
+
10
+ one_to_many :users, :class=>:'BlackStack::User', :key=>:id_client
11
+ many_to_one :timezone, :class=>:'BlackStack::Timezone', :key=>:id_timezone
12
+ many_to_one :billingCountry, :class=>:'BlackStack::LnCountry', :key=>:billing_id_lncountry
13
+ many_to_one :user_to_contect, :class=>'BlackStack:::User', :key=>:id_user_to_contact
14
+
15
+
16
+ # -----------------------------------------------------------------------------------------
17
+ # Arrays
18
+ #
19
+ #
20
+ # -----------------------------------------------------------------------------------------
21
+
22
+ # returns the workers belong this clients, that have not been deleted
23
+ def not_deleted_workers()
24
+ BlackStack::Worker.where(:id_client=>self.id, :delete_time=>nil)
25
+ end
26
+
27
+ # returns the hosts where this client has not-deleted workers, even if the host is not belong this client
28
+ def hosts()
29
+ BlackStack::LocalHost.where(id: self.not_deleted_workers.select(:id_host).all.map(&:id_host))
30
+ end
31
+
32
+ # returns the hosts belong this client
33
+ def own_hosts()
34
+ BlackStack::LocalHost.where(:id_client=>self.id, :delete_time=>nil)
35
+ end
36
+
37
+ # -----------------------------------------------------------------------------------------
38
+ # Configuration
39
+ #
40
+ #
41
+ # -----------------------------------------------------------------------------------------
42
+
43
+ # retorna true si la 5 variables (billing_address, billing_city, billing_state, billing_zipcode, billing_id_lncountry) tienen un valor destinto a nil o a un string vacio.
44
+ def hasBillingAddress?
45
+ if (
46
+ self.billing_address.to_s.size == 0 ||
47
+ self.billing_city.to_s.size == 0 ||
48
+ self.billing_state.to_s.size == 0 ||
49
+ self.billing_zipcode.to_s.size == 0 ||
50
+ self.billing_id_lncountry.to_s.size == 0
51
+ )
52
+ return false
53
+ else
54
+ return true
55
+ end
56
+ end
57
+
58
+ # retorna un array de objectos UserRole, asignados a todos los usuarios de este cliente
59
+ def user_roles
60
+ a = []
61
+ self.users.each { |o|
62
+ a.concat o.user_roles
63
+ # libero recursos
64
+ GC.start
65
+ DB.disconnect
66
+ }
67
+ a
68
+ end
69
+
70
+ # si el cliente no tiene una zona horaria configurada, retorna la zona horaria por defecto
71
+ # excepciones:
72
+ # => "Default timezone not found."
73
+ def getTimezone()
74
+ ret = nil
75
+ if (self.timezone != nil)
76
+ ret = self.timezone
77
+ else
78
+ ret = BlackStack::Timezone.where(:id=>BlackStack::Pampa::id_timezone_default).first
79
+ if (ret == nil)
80
+ raise "Default timezone not found."
81
+ end
82
+ end
83
+ return ret
84
+ end
85
+
86
+ # llama a la api de postmark preguntando el reseller email configurado para este clietne fue ferificado
87
+ def checkDomainForSSMVerified()
88
+ return_message = {}
89
+ domain = self.domain_for_ssm
90
+ email = self.from_email_for_ssm
91
+ id = ''
92
+ client = ''
93
+
94
+ if domain != nil && email != nil
95
+ begin
96
+ client_postmark = Postmark::AccountApiClient.new(POSTMARK_API_TOKEN, secure: true)
97
+ client_list = client_postmark.get_signatures()
98
+
99
+ client_list.each do |sign|
100
+ if sign[:domain] == domain
101
+ if sign[:email_address] == email
102
+ id = sign[:id]
103
+ break
104
+ end
105
+ end
106
+ end
107
+
108
+ if id.to_s.size > 0
109
+ client = client_postmark.get_sender(id)
110
+ if !client[:confirmed]
111
+ self.domain_for_ssm_verified = false
112
+ self.save
113
+
114
+ return_message[:status] = "No Verified"
115
+ return_message[:value] = client[:id]
116
+
117
+ return return_message.to_json
118
+ else
119
+ self.domain_for_ssm_verified = true
120
+ self.save
121
+
122
+ # sincronizo con la central
123
+ return_message = {}
124
+
125
+ return_message[:status] = "success"
126
+ return_message[:value] = client[:id]
127
+
128
+ return return_message.to_json
129
+ end
130
+ end
131
+
132
+ rescue Postmark::ApiInputError => e
133
+ return_message[:status] = e.to_s
134
+ return return_message.to_json
135
+ #return e
136
+ rescue => e
137
+ return_message[:status] = e.to_s
138
+ return return_message.to_json
139
+ #return e
140
+ end
141
+ else
142
+ return_message[:status] = 'error'
143
+ return_message[:value] = ''
144
+ return return_message.to_json
145
+ end # checkDomainForSSMVerified
146
+ end
147
+
148
+ # retorna true si el cliente esta configurado para usar su propia nombre/email en el envio de notificaciones
149
+ def resellerSignature?
150
+ self.from_name_for_ssm.to_s.size>0 && self.from_email_for_ssm.to_s.size>0
151
+ end
152
+
153
+ # retorna true si el cliente esta configurado para usar su propia nombre/email en el envio de notificaciones, y si el email fue verificado en postmark
154
+ def resellerSignatureEnabled?
155
+ =begin # TODO: Mover esto a un proceso asincronico
156
+ # si el cliente esta configurado para usar su propia nombre/email
157
+ if self.resellerSignature?
158
+ # pero el email fue verificado en postmark
159
+ if self.domain_for_ssm_verified==nil || self.domain_for_ssm_verified!=true
160
+ # hago la verificacion contra postmark
161
+ self.checkDomainForSSMVerified
162
+ end
163
+ end
164
+ =end
165
+ # return
166
+ resellerSignature? == true && self.domain_for_ssm_verified==true
167
+ end
168
+
169
+ # retorna el email configurado y confirmado en PostMark para cuenta reseller, o retorna el email por defecto
170
+ def resellerSignatureEmail
171
+ # configuracion de cuenta reseller
172
+ if self.resellerSignatureEnabled?
173
+ return self.from_email_for_ssm.to_s
174
+ else
175
+ return BlackStack::Params.getValue("notifications.user.email_from")
176
+ end
177
+ end
178
+
179
+ # retorna el nombre configurado para cuenta reseller, solo si el email esta confirmado en PostMark; o retorna el email por defecto
180
+ def resellerSignatureName
181
+ # configuracion de cuenta reseller
182
+ if self.resellerSignatureEnabled?
183
+ return self.from_email_for_ssm.to_s
184
+ else
185
+ return BlackStack::Params.getValue("notifications.user.name_from")
186
+ end
187
+ end
188
+ end # class Client
189
+ end # module BlackStack
@@ -0,0 +1,46 @@
1
+ module BlackStack
2
+
3
+ class Division < Sequel::Model(:division)
4
+ include BlackStack::BaseDivision
5
+ Division.dataset = Division.dataset.disable_insert_output
6
+
7
+ def home()
8
+ Division.where(
9
+ :db_url=>self.db_url,
10
+ :db_port=>self.db_port,
11
+ :db_user=>self.db_user,
12
+ :db_password=>self.db_password,
13
+ :db_name=>self.db_name,
14
+ :home=>true,
15
+ :available=>true
16
+ ).first
17
+ end
18
+
19
+ def self.getDefault()
20
+ q =
21
+ "SELECT TOP 1 d.id AS did " +
22
+ "FROM division d " +
23
+ "WHERE d.name='#{SIGNUP_DIVISION}' "
24
+ row = DB[q].first
25
+ if (row==nil)
26
+ return nil
27
+ end
28
+ return Division.where(:id=>row[:did]).first
29
+ end
30
+
31
+ # Actualiza el campo stat_name de todas las divisiones que son "gemelas" as la division pasada por parametro.
32
+ # Ver issue #976.
33
+ def self.updateStat(division, stat_name, date_time)
34
+ Division.where(
35
+ :db_url=>division.db_url,
36
+ :db_port=>division.db_port,
37
+ :db_user=>division.db_user,
38
+ :db_password=>division.db_password,
39
+ ).each { |d|
40
+ q = "UPDATE division SET #{stat_name}='#{date_time.to_s}' WHERE id='#{d.id}'"
41
+ }
42
+ end
43
+
44
+ end # class
45
+
46
+ end # module BlackStack
@@ -0,0 +1,7 @@
1
+ module BlackStack
2
+ class Login < Sequel::Model(:login)
3
+ BlackStack::Login.dataset = BlackStack::Login.dataset.disable_insert_output
4
+
5
+ many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
6
+ end
7
+ end # module BlackStack
@@ -0,0 +1,346 @@
1
+ module BlackStack
2
+
3
+ # clase de base para todos los bots ejecuten acciones con una cuenta de LinkedIn, Facebook, Twitter, etc.
4
+ class MyBotProcess < BlackStack::MyRemoteProcess
5
+ attr_accessor :username, :login_verifications, :run_once
6
+
7
+ # constructor
8
+ def initialize(
9
+ the_worker_name,
10
+ the_division_name,
11
+ the_minimum_enlapsed_seconds=MyProcess::DEFAULT_MINIMUM_ENLAPSED_SECONDS,
12
+ the_verify_configuration=true,
13
+ the_email=nil,
14
+ the_password=nil
15
+ )
16
+ super(the_worker_name, the_division_name, the_minimum_enlapsed_seconds, the_verify_configuration, the_email, the_password)
17
+ self.assigned_process = File.expand_path($0)
18
+ self.worker_name = "#{the_worker_name}"
19
+ self.division_name = the_division_name
20
+ self.minimum_enlapsed_seconds = the_minimum_enlapsed_seconds
21
+
22
+ # algunas clases como CreateLnUserProcess o RepairLnUserProcess, trabajan unicamente con el username especificado en este atributo, llamando al access point get_lnuser_by_username.
23
+ # si este atributo es nil, entonces la clase pide un lnuser a la division, llamando al access point get_lnuser.
24
+ self.username = nil
25
+
26
+ # al correr un proceso sin supervision, el login require verificaciones automaticas que demoran tiempo (account blocingcaptcha, sms pin, bloqueo)
27
+ # las verificaciones consument tiempo.
28
+ # si este proceso se corre de forma supevisada, las verificaciones se pueden deshabilitar
29
+ self.login_verifications = true
30
+
31
+ # al correr sin supervision, el proceso de terminar un un paquete de procesamiento y comenzar con otro, funcionando en un loop infinito.
32
+ # si este proceso se corre de forma supevisada, se desa correr el procesamiento una unica vez.
33
+ # cuando se activa este flag, generalmente se setea el atributo self.username tambien.
34
+ self.run_once = false
35
+ end
36
+
37
+ # returns a hash with the parameters of a lnuser
38
+ # raises an exception if it could not get a lnuser, or if ocurrs any other problem
39
+ def getLnUserByUsername(username)
40
+ nTries = 0
41
+ parsed = nil
42
+ lnuser = nil # hash
43
+ bSuccess = false
44
+ sError = ""
45
+ while (nTries < 5 && bSuccess == false)
46
+ begin
47
+ nTries = nTries + 1
48
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/login.lnuser/get_lnuser.json"
49
+ res = BlackStack::Netting::call_post(url, {'api_key' => BlackStack::Pampa::api_key, 'username' => username.encode("UTF-8")})
50
+ parsed = JSON.parse(res.body)
51
+ if (parsed['status']=='success')
52
+ lnuser = parsed
53
+ bSuccess = true
54
+ else
55
+ sError = parsed['status']
56
+ end
57
+ rescue Errno::ECONNREFUSED => e
58
+ sError = "Errno::ECONNREFUSED:" + e.to_console
59
+ rescue => e2
60
+ sError = "Exception: " + e2.to_console
61
+ end
62
+ end # while
63
+
64
+ if (bSuccess==false)
65
+ raise BlackStack::Netting::ApiCallException.new(sError)
66
+ end
67
+
68
+ return lnuser
69
+ end # getLnUser()
70
+
71
+ # returns a hash with the parameters of a lnuser
72
+ # raises an exception if it could not get a lnuser, or if ocurrs any other problem
73
+ def getLnUser(workflow_name='incrawl.lnsearchvariation')
74
+ nTries = 0
75
+ parsed = nil
76
+ lnuser = nil # hash
77
+ bSuccess = false
78
+ sError = ""
79
+ while (nTries < 5 && bSuccess == false)
80
+ begin
81
+ nTries = nTries + 1
82
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/#{workflow_name}/get_lnuser.json"
83
+ res = BlackStack::Netting::call_post(url, {'api_key' => BlackStack::Pampa::api_key, 'name' => self.fullWorkerName})
84
+ parsed = JSON.parse(res.body)
85
+ if (parsed['status']=='success')
86
+ lnuser = parsed
87
+ bSuccess = true
88
+ else
89
+ sError = parsed['status']
90
+ end
91
+ rescue Errno::ECONNREFUSED => e
92
+ sError = "Errno::ECONNREFUSED:" + e.to_console
93
+ rescue => e2
94
+ sError = "Exception:" + e2.to_console
95
+ end
96
+ end # while
97
+
98
+ if (bSuccess==false)
99
+ raise BlackStack::Netting::ApiCallException.new(sError)
100
+ end
101
+
102
+ return lnuser
103
+ end # getLnUser()
104
+
105
+ #
106
+ def notifyLnUserUrl(id_lnuser, profile_url)
107
+ nTries = 0
108
+ parsed = nil
109
+ bSuccess = false
110
+ sError = ""
111
+ while (nTries < 5 && bSuccess == false)
112
+ begin
113
+ nTries = nTries + 1
114
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/login.lnuser/notify_url.json"
115
+ res = BlackStack::Netting::call_post(url,
116
+ {:api_key => BlackStack::Pampa::api_key,
117
+ 'id_lnuser' => id_lnuser,
118
+ 'url' => profile_url,}
119
+ )
120
+ parsed = JSON.parse(res.body)
121
+
122
+ if (parsed['status']=='success')
123
+ bSuccess = true
124
+ else
125
+ sError = parsed['status']
126
+ end
127
+ rescue Errno::ECONNREFUSED => e
128
+ sError = "Errno::ECONNREFUSED:" + e.to_console
129
+ rescue => e2
130
+ sError = "Exception:" + e2.to_console
131
+ end
132
+ end # while
133
+
134
+ if (bSuccess==false)
135
+ raise "#{sError}"
136
+ end
137
+ end # notifyLnUserStatus
138
+
139
+ #
140
+ def notifyLnUserStatus(id_lnuser, status, workflow_name='incrawl.lnsearchvariation')
141
+ nTries = 0
142
+ parsed = nil
143
+ bSuccess = false
144
+ sError = ""
145
+ while (nTries < 5 && bSuccess == false)
146
+ begin
147
+ nTries = nTries + 1
148
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/#{workflow_name}/notify_lnuser_status.json"
149
+ res = BlackStack::Netting::call_post(url,
150
+ {'api_key' => BlackStack::Pampa::api_key,
151
+ 'id_lnuser' => id_lnuser,
152
+ 'status' => status,}
153
+ )
154
+ parsed = JSON.parse(res.body)
155
+
156
+ if (parsed['status']=='success')
157
+ bSuccess = true
158
+ else
159
+ sError = parsed['status']
160
+ end
161
+ rescue Errno::ECONNREFUSED => e
162
+ sError = "Errno::ECONNREFUSED:" + e.to_console
163
+ rescue => e2
164
+ sError = "Exception:" + e2.to_console
165
+ end
166
+ end # while
167
+
168
+ if (bSuccess==false)
169
+ raise "#{sError}"
170
+ end
171
+
172
+ end # notifyLnUserStatus
173
+
174
+ #
175
+ def notifyLnUserActivity(id_lnuser, code, workflow_name='incrawl.lnsearchvariation')
176
+ nTries = 0
177
+ parsed = nil
178
+ bSuccess = false
179
+ sError = ""
180
+ while (nTries < 5 && bSuccess == false)
181
+ begin
182
+ nTries = nTries + 1
183
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/#{workflow_name}/notify_lnuser_activity.json"
184
+ res = BlackStack::Netting::call_post(url,
185
+ {'api_key' => BlackStack::Pampa::api_key,
186
+ 'id_lnuser' => id_lnuser,
187
+ 'code' => code,}
188
+ )
189
+ parsed = JSON.parse(res.body)
190
+
191
+ if (parsed['status']=='success')
192
+ bSuccess = true
193
+ else
194
+ sError = parsed['status']
195
+ end
196
+ rescue Errno::ECONNREFUSED => e
197
+ sError = "Errno::ECONNREFUSED:" + e.to_console
198
+ rescue => e2
199
+ sError = "Exception:" + e2.to_console
200
+ end
201
+ end # while
202
+
203
+ if (bSuccess==false)
204
+ raise "#{sError}"
205
+ end
206
+ end # notifyLnUserStatus
207
+
208
+ # Toma una captura del browser.
209
+ # Sube un registro a la tabla boterrorlog, con el id del worker, el proceso asinado, y el screenshot.
210
+ #
211
+ # uid: id de un registro en la tabla lnuser.
212
+ # description: backtrace de la excepcion.
213
+ #
214
+ def notifyError(uid, description, oid=nil)
215
+ # tomo captura de pantalla
216
+ file = nil
217
+ =begin # TODO: habilitar esto cuando se migre a RestClient en vez de CallPost
218
+ begin
219
+ screenshot_filename = "./error.png" # TODO: colocar un nombre unico formado por por el fullname del worker, y la fecha-hora.
220
+ BrowserFactory.screenshot screenshot_filename
221
+ file = File.new(screenshot_filename, "rb")
222
+ rescue => e
223
+ puts "Screenshot Error: #{e.to_s}"
224
+ file = nil
225
+ end
226
+ =end
227
+ #puts ""
228
+ #puts "id_worker:#{PROCESS.worker.id}"
229
+ #puts "worker_name:#{PROCESS.fullWorkerName}"
230
+ #puts "process:#{PROCESS.worker.assigned_process}"
231
+ #puts ""
232
+ # subo el error
233
+ nTries = 0
234
+ bSuccess = false
235
+ parsed = nil
236
+ sError = ""
237
+ while (nTries < 5 && bSuccess == false)
238
+ begin
239
+ nTries = nTries + 1
240
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/boterror.json"
241
+ res = BlackStack::Netting::call_post(url, # TODO: migrar a RestClient para poder hacer file upload
242
+ 'api_key' => BlackStack::Pampa::api_key,
243
+ 'id_lnuser' => uid,
244
+ 'id_object' => oid,
245
+ 'worker_name' => PROCESS.fullWorkerName,
246
+ 'process' => PROCESS.worker.assigned_process,
247
+ 'description' => description,
248
+ 'screenshot' => file,
249
+ )
250
+ parsed = JSON.parse(res.body)
251
+ if (parsed['status']=='success')
252
+ bSuccess = true
253
+ else
254
+ sError = parsed['status']
255
+ end
256
+ rescue Errno::ECONNREFUSED => e
257
+ sError = "Errno::ECONNREFUSED:" + e.to_console
258
+ rescue => e2
259
+ sError = "Exception:" + e2.to_console
260
+ end
261
+ end # while
262
+
263
+ if (bSuccess==false)
264
+ raise "#{sError}"
265
+ end
266
+ end
267
+
268
+ #
269
+ def isLnUserAvailable(id_lnuser, need_sales_navigator=false, workflow_name='incrawl.lnsearchvariation')
270
+ nTries = 0
271
+ parsed = nil
272
+ bSuccess = false
273
+ sError = ""
274
+ ret = false
275
+
276
+ while (nTries < 5 && bSuccess == false)
277
+ begin
278
+ nTries = nTries + 1
279
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/#{workflow_name}/is_lnuser_available.json"
280
+ res = BlackStack::Netting::call_post(url,
281
+ {'api_key' => BlackStack::Pampa::api_key,
282
+ 'id_lnuser' => id_lnuser,
283
+ 'need_sales_navigator' => need_sales_navigator,}
284
+ )
285
+ parsed = JSON.parse(res.body)
286
+
287
+ if (parsed['status']=='success')
288
+ bSuccess = true
289
+ ret = parsed['value']
290
+ else
291
+ sError = parsed['status']
292
+ end
293
+ rescue Errno::ECONNREFUSED => e
294
+ sError = "Errno::ECONNREFUSED:" + e.to_s
295
+ rescue => e2
296
+ sError = "Alghoritm Exception" + e2.to_s + '\r\n' + e2.backtrace.join("\r\n").to_s
297
+ end
298
+ end # while
299
+
300
+ if (bSuccess==false)
301
+ raise "#{sError}"
302
+ end
303
+
304
+ return ret
305
+ end # isLnUserAvailable
306
+
307
+ #
308
+ def releaseLnUser(id_lnuser, workflow_name='incrawl.lnsearchvariation')
309
+ nTries = 0
310
+ parsed = nil
311
+ bSuccess = false
312
+ sError = ""
313
+ ret = false
314
+
315
+ while (nTries < 5 && bSuccess == false)
316
+ begin
317
+ nTries = nTries + 1
318
+ url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/#{workflow_name}/release_lnuser.json"
319
+ res = BlackStack::Netting::call_post(url,
320
+ {'api_key' => BlackStack::Pampa::api_key, 'id_lnuser' => id_lnuser,}
321
+ )
322
+ parsed = JSON.parse(res.body)
323
+
324
+ if (parsed['status']=='success')
325
+ bSuccess = true
326
+ ret = parsed['value']
327
+ else
328
+ sError = parsed['status']
329
+ end
330
+ rescue Errno::ECONNREFUSED => e
331
+ sError = "Errno::ECONNREFUSED:" + e.to_console
332
+ rescue => e2
333
+ sError = "Exception:" + e2.to_console
334
+ end
335
+ end # while
336
+
337
+ if (bSuccess==false)
338
+ raise "#{sError}"
339
+ end
340
+
341
+ return ret
342
+ end # isLnUserAvailable
343
+
344
+ end # class MyBotProcess
345
+
346
+ end # module BlackStack