pampa_workers 0.0.38
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 +7 -0
- data/lib/basedivision.rb +5 -0
- data/lib/baseworker.rb +5 -0
- data/lib/client.rb +245 -0
- data/lib/division.rb +46 -0
- data/lib/login.rb +7 -0
- data/lib/mybotprocess.rb +348 -0
- data/lib/mychildprocess.rb +9 -0
- data/lib/mycrawlprocess.rb +49 -0
- data/lib/mylocalprocess.rb +164 -0
- data/lib/myparentprocess.rb +141 -0
- data/lib/myprocess.rb +264 -0
- data/lib/myremoteprocess.rb +128 -0
- data/lib/pampa-local.rb +41 -0
- data/lib/pampa.rb +261 -0
- data/lib/params.rb +50 -0
- data/lib/remotedivision.rb +8 -0
- data/lib/remoteworker.rb +8 -0
- data/lib/role.rb +8 -0
- data/lib/timezone.rb +151 -0
- data/lib/user.rb +25 -0
- data/lib/userdivision.rb +5 -0
- data/lib/userrole.rb +8 -0
- data/lib/worker.rb +234 -0
- metadata +229 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
module BlackStack
|
2
|
+
|
3
|
+
# no maneja conexion a la base de datos.
|
4
|
+
# ejecuta un loop mientras el metodo canRun? retorne true.
|
5
|
+
class MyRemoteProcess < BlackStack::MyChildProcess
|
6
|
+
#
|
7
|
+
attr_accessor :worker
|
8
|
+
|
9
|
+
# update worker configuration in the division
|
10
|
+
def updateWorker()
|
11
|
+
#
|
12
|
+
self.worker = BlackStack::RemoteWorker.new
|
13
|
+
# me notifico a la central. obtengo asignacion si ya la tenia
|
14
|
+
url = "#{BlackStack::Pampa::api_url}/api1.3/pampa/get.json"
|
15
|
+
res = BlackStack::Netting::call_post(url, {
|
16
|
+
'api_key' => BlackStack::Pampa::api_key,
|
17
|
+
'name' => self.fullWorkerName }.merge( BlackStack::RemoteHost.new.poll )
|
18
|
+
)
|
19
|
+
parsed = JSON.parse(res.body)
|
20
|
+
if (parsed['status'] != BlackStack::Netting::SUCCESS)
|
21
|
+
raise parsed['status'].to_s
|
22
|
+
else
|
23
|
+
self.worker.id = parsed['id']
|
24
|
+
self.worker.assigned_process = parsed['assigned_process']
|
25
|
+
self.worker.id_object = parsed['id_object']
|
26
|
+
self.worker.id_division = parsed['id_division']
|
27
|
+
self.worker.division_name = parsed['division_name']
|
28
|
+
self.worker.ws_url = parsed['ws_url']
|
29
|
+
self.worker.ws_port = parsed['ws_port']
|
30
|
+
self.worker.division = BlackStack::RemoteDivision.new
|
31
|
+
self.worker.division.name = parsed['division_name']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
def run()
|
37
|
+
super
|
38
|
+
|
39
|
+
# creo el objeto logger
|
40
|
+
self.logger = RemoteLogger.new(
|
41
|
+
"#{self.fullWorkerName}.log",
|
42
|
+
BlackStack::Pampa::api_protocol,
|
43
|
+
BlackStack::Pampa::api_domain,
|
44
|
+
BlackStack::Pampa::api_port,
|
45
|
+
BlackStack::Pampa::api_key
|
46
|
+
)
|
47
|
+
|
48
|
+
logger.log "Remote process is alive!"
|
49
|
+
|
50
|
+
# actualiza parametros de la central
|
51
|
+
logger.logs "Update from central (1)... "
|
52
|
+
self.get
|
53
|
+
logger.done
|
54
|
+
|
55
|
+
# actualizo los datos de este worker (parent process)
|
56
|
+
logger.logs "Update worker (1)... "
|
57
|
+
self.updateWorker
|
58
|
+
logger.done
|
59
|
+
|
60
|
+
while (self.canRun?)
|
61
|
+
|
62
|
+
# reseteo en contador nested del logger
|
63
|
+
self.logger.reset()
|
64
|
+
|
65
|
+
# announcing my in the log
|
66
|
+
logger.log "Going to Run Remote"
|
67
|
+
logger.log "Process: #{self.assigned_process.to_s}."
|
68
|
+
logger.log "Object: #{(self.id_object.to_s.size==0)? 'n/a' : self.id_object.to_s}."
|
69
|
+
|
70
|
+
# obtengo la hora de inicio
|
71
|
+
start_time = Time.now
|
72
|
+
|
73
|
+
begin
|
74
|
+
# libero recursos
|
75
|
+
logger.logs "Release resources... "
|
76
|
+
GC.start
|
77
|
+
#DB.disconnect
|
78
|
+
logger.done
|
79
|
+
|
80
|
+
# envia senial a la central.
|
81
|
+
# si tiene asignada una division, envia senial a la division.
|
82
|
+
logger.logs "Ping... "
|
83
|
+
self.ping()
|
84
|
+
logger.done
|
85
|
+
|
86
|
+
# envia senial a la central.
|
87
|
+
# si tiene asignada una division, envia senial a la division.
|
88
|
+
logger.logs "Notify to Division... "
|
89
|
+
self.notify()
|
90
|
+
logger.done
|
91
|
+
|
92
|
+
# corro el procesamiento
|
93
|
+
self.process(ARGV)
|
94
|
+
|
95
|
+
rescue => e
|
96
|
+
puts ""
|
97
|
+
logger.log "Remote Process Error: " + e.to_s + "\r\n" + e.backtrace.join("\r\n").to_s
|
98
|
+
end
|
99
|
+
|
100
|
+
# actualiza parametros de la central
|
101
|
+
logger.logs "Update from central (2)... "
|
102
|
+
self.get
|
103
|
+
logger.done
|
104
|
+
|
105
|
+
# actualizo los datos de este worker (parent process)
|
106
|
+
logger.logs "Update worker (2)... "
|
107
|
+
self.updateWorker
|
108
|
+
logger.done
|
109
|
+
|
110
|
+
# sleep
|
111
|
+
logger.logs "Sleep... "
|
112
|
+
self.doSleep(start_time)
|
113
|
+
logger.done
|
114
|
+
|
115
|
+
logger.log "-------------------------------------------"
|
116
|
+
|
117
|
+
GC.start
|
118
|
+
#DB.disconnect
|
119
|
+
|
120
|
+
end # main while
|
121
|
+
|
122
|
+
#
|
123
|
+
logger.log self.whyCantRun()
|
124
|
+
|
125
|
+
end # run
|
126
|
+
end # class MyRemoteProcess
|
127
|
+
|
128
|
+
end # module BlackStack
|
data/lib/pampa-local.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative './division'
|
2
|
+
require_relative './params'
|
3
|
+
require_relative './worker'
|
4
|
+
require_relative './client'
|
5
|
+
require_relative './timezone'
|
6
|
+
require_relative './user'
|
7
|
+
require_relative './login'
|
8
|
+
require_relative './role'
|
9
|
+
require_relative './userdivision'
|
10
|
+
require_relative './userrole'
|
11
|
+
|
12
|
+
# funciones auxiliares
|
13
|
+
def guid()
|
14
|
+
DB['SELECT NEWID() AS [id]'].map(:id)[0]
|
15
|
+
end
|
16
|
+
|
17
|
+
def now()
|
18
|
+
# La llamada a GETDATE() desde ODBC no retorna precision de milisegundos, que es necesaria para los registros de log.
|
19
|
+
# La llamada a SYSDATETIME() retorna un valor de alta precision que no es compatible para pegar en los campos del tipo DATATIME.
|
20
|
+
# La linea de abajo obtiene la hora en formato de SYSDATE y le trunca los ultimos digitos para hacer que el valor sea compatible con los campos DATETIME.
|
21
|
+
(DB['SELECT SYSDATETIME() AS [now]'].map(:now)[0]).to_s[0..22]
|
22
|
+
end
|
23
|
+
|
24
|
+
def diff(unit, t0, t1)
|
25
|
+
# La llamada a GETDATE() desde ODBC no retorna precision de milisegundos, que es necesaria para los registros de log.
|
26
|
+
# La llamada a SYSDATETIME() retorna un valor de alta precision que no es compatible para pegar en los campos del tipo DATATIME.
|
27
|
+
# La linea de abajo obtiene la hora en formato de SYSDATE y le trunca los ultimos digitos para hacer que el valor sea compatible con los campos DATETIME.
|
28
|
+
(DB["SELECT DATEDIFF(#{unit}, '#{t0.to_s}', '#{t1.to_s}') AS [diff]"].map(:diff)[0]).to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def before(n) # n minutes
|
32
|
+
DB["SELECT DATEADD(mi, -#{n.to_s}, GETDATE()) AS [now]"].map(:now).to_s[0]
|
33
|
+
end
|
34
|
+
|
35
|
+
def monthsFromNow(n) # n months
|
36
|
+
DB["SELECT DATEADD(mm, +#{n.to_s}, GETDATE()) AS [now]"].map(:now).to_s[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
def daysFromNow(n) # n days
|
40
|
+
DB["SELECT DATEADD(dd, +#{n.to_s}, GETDATE()) AS [now]"].map(:now).to_s[0]
|
41
|
+
end
|
data/lib/pampa.rb
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
require 'blackstack_commons'
|
2
|
+
require 'simple_command_line_parser'
|
3
|
+
require 'simple_cloud_logging'
|
4
|
+
require 'simple_host_monitoring'
|
5
|
+
require 'socket'
|
6
|
+
require 'time'
|
7
|
+
require 'uri'
|
8
|
+
require 'net/http'
|
9
|
+
require 'json'
|
10
|
+
require 'openssl'
|
11
|
+
require 'tiny_tds'
|
12
|
+
require 'sequel'
|
13
|
+
|
14
|
+
#require './lib/base'
|
15
|
+
#require './config.rb'
|
16
|
+
|
17
|
+
require_relative './baseworker'
|
18
|
+
require_relative './basedivision'
|
19
|
+
|
20
|
+
require_relative './remoteworker'
|
21
|
+
require_relative './remotedivision'
|
22
|
+
|
23
|
+
require_relative './myprocess'
|
24
|
+
require_relative './mychildprocess'
|
25
|
+
require_relative './mylocalprocess'
|
26
|
+
require_relative './myparentprocess'
|
27
|
+
require_relative './myremoteprocess'
|
28
|
+
require_relative './mybotprocess'
|
29
|
+
require_relative './mycrawlprocess'
|
30
|
+
require_relative './remoteworker'
|
31
|
+
require_relative './remotedivision'
|
32
|
+
|
33
|
+
module BlackStack
|
34
|
+
|
35
|
+
module Pampa
|
36
|
+
|
37
|
+
#
|
38
|
+
@@division_name = nil
|
39
|
+
|
40
|
+
def self.division_name()
|
41
|
+
@@division_name
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
def self.set_division_name(s)
|
46
|
+
@@division_name = s
|
47
|
+
end
|
48
|
+
|
49
|
+
# Api-key of the client who will be the owner of a process.
|
50
|
+
@@api_key = nil
|
51
|
+
|
52
|
+
def self.api_key()
|
53
|
+
@@api_key
|
54
|
+
end
|
55
|
+
|
56
|
+
# Protocol, HTTP or HTTPS, of the BlackStack server where this process will be registered.
|
57
|
+
@@api_protocol = nil
|
58
|
+
|
59
|
+
#
|
60
|
+
def self.api_protocol
|
61
|
+
@@api_protocol
|
62
|
+
end
|
63
|
+
|
64
|
+
# Domain of the BlackStack server where this process will be registered.
|
65
|
+
@@api_domain = nil
|
66
|
+
|
67
|
+
#
|
68
|
+
def self.api_domain
|
69
|
+
@@api_domain
|
70
|
+
end
|
71
|
+
|
72
|
+
# Port of the BlackStack server where this process will be registered.
|
73
|
+
@@api_port = nil
|
74
|
+
|
75
|
+
#
|
76
|
+
def self.api_port
|
77
|
+
@@api_port
|
78
|
+
end
|
79
|
+
|
80
|
+
# get the full URL of the worker api server
|
81
|
+
def self.api_url()
|
82
|
+
"#{BlackStack::Pampa::api_protocol}://#{BlackStack::Pampa::api_domain}:#{BlackStack::Pampa::api_port}"
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
def self.set_api_key(s)
|
87
|
+
@@api_key = s
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
def self.set_api_url(h)
|
92
|
+
@@api_key = h[:api_key]
|
93
|
+
@@api_protocol = h[:api_protocol]
|
94
|
+
@@api_domain = h[:api_domain]
|
95
|
+
@@api_port = h[:api_port]
|
96
|
+
end
|
97
|
+
|
98
|
+
# path where you will store the data of each client
|
99
|
+
@@storage_folder = nil
|
100
|
+
@@storage_sub_folders = []
|
101
|
+
|
102
|
+
#
|
103
|
+
def self.storage_folder()
|
104
|
+
@@storage_folder
|
105
|
+
end
|
106
|
+
def self.storage_sub_folders(a)
|
107
|
+
@@storage_sub_folder = a
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
def self.set_storage_folder(path)
|
112
|
+
@@storage_folder = path
|
113
|
+
end
|
114
|
+
def self.set_storage_sub_folders(a)
|
115
|
+
@@storage_sub_folders = a
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
#
|
120
|
+
# default timezome for any new user
|
121
|
+
#
|
122
|
+
#
|
123
|
+
@@id_timezone_default = nil
|
124
|
+
|
125
|
+
#
|
126
|
+
def self.id_timezone_default()
|
127
|
+
@@id_timezone_default
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
def self.set_id_timezone_default(id)
|
132
|
+
@@id_timezone_default = id
|
133
|
+
end
|
134
|
+
|
135
|
+
# Array of external IP addresses of the servers where farms are running.
|
136
|
+
# If you have many servers running behind a NAT server, only add the IP
|
137
|
+
# of the external gateway here. This array is used to know if a worker
|
138
|
+
# is running inside your farm datacenter, or it is running in the computer
|
139
|
+
# of someone else.
|
140
|
+
@@farm_external_ip_addresses = []
|
141
|
+
|
142
|
+
#
|
143
|
+
def self.farm_external_ip_addresses()
|
144
|
+
@@farm_external_ip_addresses
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
def self.set_farm_external_ip_addresses(a)
|
149
|
+
@@farm_external_ip_addresses = a
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
def self.get_guid
|
154
|
+
res = BlackStack::Netting::call_post(
|
155
|
+
"#{self.api_url}/api1.4/get_guid.json",
|
156
|
+
{'api_key' => @@api_key}
|
157
|
+
)
|
158
|
+
parsed = JSON.parse(res.body)
|
159
|
+
parsed['value']
|
160
|
+
end
|
161
|
+
|
162
|
+
# Central database connection parameters
|
163
|
+
@@db_url = nil
|
164
|
+
@@db_port = nil
|
165
|
+
@@db_name = nil
|
166
|
+
@@db_user = nil
|
167
|
+
@@db_password = nil
|
168
|
+
|
169
|
+
#
|
170
|
+
def self.db_url
|
171
|
+
@@db_url
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
def self.db_port
|
176
|
+
@@db_port
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
def self.db_name
|
181
|
+
@@db_name
|
182
|
+
end
|
183
|
+
|
184
|
+
#
|
185
|
+
def self.db_user
|
186
|
+
@@db_user
|
187
|
+
end
|
188
|
+
|
189
|
+
#
|
190
|
+
def self.db_password
|
191
|
+
@@db_password
|
192
|
+
end
|
193
|
+
|
194
|
+
# Set connection params to the central database
|
195
|
+
def self.set_db_params(h)
|
196
|
+
@@db_url = h[:db_url]
|
197
|
+
@@db_port = h[:db_port]
|
198
|
+
@@db_name = h[:db_name]
|
199
|
+
@@db_user = h[:db_user]
|
200
|
+
@@db_password = h[:db_password]
|
201
|
+
end
|
202
|
+
|
203
|
+
# TODO: doc me!
|
204
|
+
def self.connection_descriptor()
|
205
|
+
ret = nil
|
206
|
+
|
207
|
+
# validar que el formato no sea nulo
|
208
|
+
if (self.division_name.to_s.length == 0)
|
209
|
+
raise "Division name expected."
|
210
|
+
end
|
211
|
+
|
212
|
+
if (self.division_name == "local")
|
213
|
+
ret = {
|
214
|
+
:adapter => 'tinytds',
|
215
|
+
:dataserver => BlackStack::Pampa::db_url, # IP or hostname
|
216
|
+
:port => BlackStack::Pampa::db_port, # Required when using other that 1433 (default)
|
217
|
+
:database => BlackStack::Pampa::db_name,
|
218
|
+
:user => BlackStack::Pampa::db_user,
|
219
|
+
:password => BlackStack::Pampa::db_password
|
220
|
+
}
|
221
|
+
else
|
222
|
+
url = "#{BlackStack::Pampa::api_url}/api1.2/division/get.json"
|
223
|
+
res = BlackStack::Netting::call_post(url, {
|
224
|
+
'api_key' => BlackStack::Pampa::api_key,
|
225
|
+
'dname' => "#{self.division_name}",
|
226
|
+
})
|
227
|
+
parsed = JSON.parse(res.body)
|
228
|
+
|
229
|
+
if (parsed["status"] != BlackStack::Netting::SUCCESS)
|
230
|
+
raise "Error getting connection string: #{parsed["status"]}"
|
231
|
+
else
|
232
|
+
wid = parsed["value"]
|
233
|
+
|
234
|
+
ret = {
|
235
|
+
:adapter => 'tinytds',
|
236
|
+
:dataserver => parsed["db_url"], # IP or hostname
|
237
|
+
:port => parsed["db_port"], # only required if port is different than 1433
|
238
|
+
:database => parsed["db_name"],
|
239
|
+
:user => parsed["db_user"],
|
240
|
+
:password => parsed["db_password"]
|
241
|
+
}
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
ret
|
246
|
+
end # connectionDescriptor
|
247
|
+
|
248
|
+
#
|
249
|
+
def self.db_connection()
|
250
|
+
Sequel.connect(BlackStack::Pampa::connection_descriptor)
|
251
|
+
end
|
252
|
+
|
253
|
+
#
|
254
|
+
def self.require_db_classes()
|
255
|
+
# You have to load all the Sinatra classes after connect the database.
|
256
|
+
require_relative '../lib/pampa-local.rb'
|
257
|
+
end
|
258
|
+
|
259
|
+
end # module Pampa
|
260
|
+
|
261
|
+
end # module BlackStack
|
data/lib/params.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module BlackStack
|
2
|
+
|
3
|
+
class Params < Sequel::Model(:params)
|
4
|
+
Params.dataset = Params.dataset.disable_insert_output
|
5
|
+
|
6
|
+
def self.getValue(s)
|
7
|
+
param = Params.where(:name=>s).first
|
8
|
+
if (param == nil)
|
9
|
+
raise "Unknown parameter name (#{s.to_s})"
|
10
|
+
else
|
11
|
+
if param.type == PARAM_TYPE_VARCHAR
|
12
|
+
return param.value_varchar.to_s
|
13
|
+
elsif param.type == PARAM_TYPE_NUMERIC
|
14
|
+
return param.value_numeric.to_i
|
15
|
+
elsif param.type == PARAM_TYPE_DATETIME
|
16
|
+
return param.value_datetime
|
17
|
+
elsif param.type == PARAM_TYPE_BIT
|
18
|
+
return param.value_bit
|
19
|
+
else
|
20
|
+
raise "Unknown parameter type (#{param.type.to_s})."
|
21
|
+
end # if param.type
|
22
|
+
end # if (param == nil)
|
23
|
+
end # def self.getValue
|
24
|
+
|
25
|
+
def self.setValue(s, v) # TODO: Testear este metodo
|
26
|
+
param = Params.where(:name=>s).first
|
27
|
+
if (param == nil)
|
28
|
+
raise "Unknown parameter name (#{s.to_s})"
|
29
|
+
else
|
30
|
+
if param.type == PARAM_TYPE_VARCHAR
|
31
|
+
param.value_varchar = v
|
32
|
+
param.save()
|
33
|
+
elsif param.type == PARAM_TYPE_NUMERIC
|
34
|
+
param.value_numeric = v
|
35
|
+
param.save()
|
36
|
+
elsif param.type == PARAM_TYPE_DATETIME
|
37
|
+
param.value_datetime = v
|
38
|
+
param.save()
|
39
|
+
elsif param.type == PARAM_TYPE_BIT
|
40
|
+
param.value_bit = v
|
41
|
+
param.save()
|
42
|
+
else
|
43
|
+
raise "Unknown parameter type (#{param.type.to_s})."
|
44
|
+
end # if param.type
|
45
|
+
end # if (param == nil)
|
46
|
+
end # def self.getValue
|
47
|
+
|
48
|
+
end # class
|
49
|
+
|
50
|
+
end # module BlackStack
|
data/lib/remoteworker.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
module BlackStack
|
2
|
+
|
3
|
+
class RemoteWorker
|
4
|
+
attr_accessor :id, :process, :last_ping_time, :name, :active, :id_division, :assigned_process, :id_object, :division_name, :ws_url, :ws_port, :division
|
5
|
+
include BlackStack::BaseWorker
|
6
|
+
end # Remote Worker
|
7
|
+
|
8
|
+
end # module BlackStack
|
data/lib/role.rb
ADDED
data/lib/timezone.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
module BlackStack
|
2
|
+
class Timezone < Sequel::Model(:timezone)
|
3
|
+
BlackStack::Timezone.dataset = BlackStack::Timezone.dataset.disable_insert_output
|
4
|
+
|
5
|
+
# Recibe un string con formato "+HH:MM".
|
6
|
+
# Retorna la cantidad de horas como un numero real, con decimales.
|
7
|
+
def self.descToFloat(s)
|
8
|
+
sign = s[0]
|
9
|
+
if (sign=="+")
|
10
|
+
n = 1.0
|
11
|
+
else
|
12
|
+
n = -1.0
|
13
|
+
end
|
14
|
+
hours = s[1..2]
|
15
|
+
minutes = s[4..5]
|
16
|
+
int_part = hours.to_f
|
17
|
+
dec_part = minutes.to_f / 60.00
|
18
|
+
ret = n*(int_part + dec_part)
|
19
|
+
return ret.to_f
|
20
|
+
end
|
21
|
+
|
22
|
+
# Recibe la cantidad de horas como un numero real, con decimales.
|
23
|
+
# Retorna un string con formato "+HH:MM".
|
24
|
+
def self.floatToDesc(x)
|
25
|
+
int_part = x.to_i
|
26
|
+
dec_part = (x-int_part.to_f).round(2).abs
|
27
|
+
hours = int_part
|
28
|
+
minutes = (dec_part * 60.00).to_i
|
29
|
+
if (hours<0)
|
30
|
+
desc = "%03d" % hours
|
31
|
+
else
|
32
|
+
desc = "+" + "%02d" % hours
|
33
|
+
end
|
34
|
+
desc += ":" + "%02d" % minutes
|
35
|
+
return desc
|
36
|
+
end
|
37
|
+
|
38
|
+
# Example: '-03:00'
|
39
|
+
# Example: ' 08:00'
|
40
|
+
def self.getDatabaseOffset()
|
41
|
+
dbtime = DB["select SYSDATETIMEOFFSET() AS o"].first[:o].to_s
|
42
|
+
#puts ""
|
43
|
+
#puts ""
|
44
|
+
#puts "dbtime:#{dbtime.to_s}:."
|
45
|
+
#puts ""
|
46
|
+
#puts ""
|
47
|
+
ret = "#{dbtime[-5..-3]}:#{dbtime[-2..-1]}"
|
48
|
+
ret[0] = '+' if ret[0]!='-'
|
49
|
+
#puts ""
|
50
|
+
#puts ""
|
51
|
+
#puts "dbtime:#{ret.to_s}:."
|
52
|
+
#puts ""
|
53
|
+
#puts ""
|
54
|
+
return ret
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convierte el atributo offset en un string con formato de hora.
|
58
|
+
# Ejemplos: 5.0 => 05:00, 5.5 => 05:30, -5.75 => -05:45
|
59
|
+
def offsetDescription()
|
60
|
+
return BlackStack::Timezone.floatToDesc(self.offset.to_f)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Convierte una hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
|
64
|
+
# Recibe un string con formato "+HH:MM".
|
65
|
+
# Retorna un string con formato "+HH:MM".
|
66
|
+
def convertFromThisTimeZoneToDatabaseTime(s_time_in_client_timezone)
|
67
|
+
f_time_in_client_timezone = BlackStack::Timezone.descToFloat(s_time_in_client_timezone)
|
68
|
+
s = BlackStack::Timezone.getDatabaseOffset()
|
69
|
+
x = BlackStack::Timezone.descToFloat(s) # database offset
|
70
|
+
y = self.offset # client offset
|
71
|
+
z = y - x
|
72
|
+
return BlackStack::Timezone.floatToDesc((f_time_in_client_timezone.to_f + z.to_f).modulo(24))
|
73
|
+
end
|
74
|
+
|
75
|
+
# Convierte una hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
|
76
|
+
# Recibe un string con formato "+HH:MM".
|
77
|
+
# Retorna un string con formato "+HH:MM".
|
78
|
+
def convertFromDatabaseTimeToThisTimeZone(s_time_in_database)
|
79
|
+
f_time_in_database = BlackStack::Timezone.descToFloat(s_time_in_database)
|
80
|
+
s = BlackStack::Timezone.getDatabaseOffset()
|
81
|
+
x = BlackStack::Timezone.descToFloat(s) # database offset
|
82
|
+
y = self.offset # client offset
|
83
|
+
z = y - x
|
84
|
+
return BlackStack::Timezone.floatToDesc((f_time_in_database.to_f - z.to_f).modulo(24))
|
85
|
+
end
|
86
|
+
|
87
|
+
# Convierte una fecha-hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
|
88
|
+
# Recibe un string con formato "YYYY-MM-DD HH:MM:SS".
|
89
|
+
# Retorna un string con formato "YYYY-MM-DD HH:MM:SS".
|
90
|
+
def convertFromDatabaseDateTimeToThisTimeZone(s_datetime_in_database)
|
91
|
+
s = BlackStack::Timezone.getDatabaseOffset() # Example: '-03:00'
|
92
|
+
#puts ""
|
93
|
+
#puts ""
|
94
|
+
#puts "s:#{s.to_s}:."
|
95
|
+
#puts ""
|
96
|
+
#puts ""
|
97
|
+
x = BlackStack::Timezone.descToFloat(s) # database offset. Number of hours, with decimals
|
98
|
+
#puts ""
|
99
|
+
#puts ""
|
100
|
+
#puts "x:#{x.to_s}:."
|
101
|
+
#puts ""
|
102
|
+
#puts ""
|
103
|
+
y = self.offset # client offset
|
104
|
+
#puts ""
|
105
|
+
#puts ""
|
106
|
+
#puts "y:#{y.to_s}:."
|
107
|
+
#puts ""
|
108
|
+
#puts ""
|
109
|
+
z = y - x
|
110
|
+
#puts ""
|
111
|
+
#puts ""
|
112
|
+
#puts "z:#{z.to_s}:."
|
113
|
+
#puts ""
|
114
|
+
#puts ""
|
115
|
+
ret = DB["SELECT DATEADD(HH, #{z.to_s}, '#{s_datetime_in_database}') AS o"].first[:o].to_s[0..18]
|
116
|
+
#puts ""
|
117
|
+
#puts ""
|
118
|
+
#puts "convertFromDatabaseDateTimeToThisTimeZone:#{ret}:."
|
119
|
+
#puts ""
|
120
|
+
#puts ""
|
121
|
+
|
122
|
+
return ret
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
def get_now()
|
127
|
+
datetime1 = DB["SELECT GETDATE() AS o"].first[:o].to_s[0..18]
|
128
|
+
datetime2 = self.convertFromDatabaseDateTimeToThisTimeZone(datetime1)
|
129
|
+
#puts ""
|
130
|
+
#puts ""
|
131
|
+
#puts "timezone:#{self.large_description}:."
|
132
|
+
#puts "datetime1:#{datetime1}:."
|
133
|
+
#puts "datetime2:#{datetime2}:."
|
134
|
+
#puts ""
|
135
|
+
#puts ""
|
136
|
+
yy = datetime2[0..3] # yyyy-mm-dd hh:mi:ss
|
137
|
+
mm = datetime2[5..6]
|
138
|
+
dd = datetime2[8..9]
|
139
|
+
hh = datetime2[11..12]
|
140
|
+
mi = datetime2[14..15]
|
141
|
+
ss = datetime2[17..18]
|
142
|
+
#puts ""
|
143
|
+
#puts ""
|
144
|
+
#puts "get_now:#{yy}-#{mm}-#{dd} #{hh}:#{mi}:#{ss}:."
|
145
|
+
#puts ""
|
146
|
+
#puts ""
|
147
|
+
return Time.new(yy,mm,dd,hh,mi,ss)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end # module BlackStack
|
data/lib/user.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module BlackStack
|
2
|
+
class User < Sequel::Model(:user)
|
3
|
+
BlackStack::User.dataset = BlackStack::User.dataset.disable_insert_output
|
4
|
+
many_to_one :client, :class=>:'BlackStack::Client', :key=>:id_client
|
5
|
+
one_to_many :user_roles, :class=>:'BlackStack::UserRole', :key=>:id_user
|
6
|
+
|
7
|
+
# TODO: agregar todos los arrays de un usuario
|
8
|
+
# => one_to_many :searches, :class=>:Search, :key=>:id_user
|
9
|
+
# => one_to_many :emlist, :class=>:EmList, :key=>:id_user
|
10
|
+
# => one_to_many :emlist, :class=>:EmList, :key=>:id_user
|
11
|
+
# => etc.
|
12
|
+
|
13
|
+
# retorna la primera division habilitada a la que pertenezca este usuario
|
14
|
+
def division
|
15
|
+
row = DB[
|
16
|
+
"SELECT d.id " +
|
17
|
+
"FROM division d WITH (NOLOCK) " +
|
18
|
+
"JOIN user_division ud WITH (NOLOCK) ON (d.id=ud.id_division AND ud.id_user='#{self.id}') " +
|
19
|
+
"WHERE ISNULL(d.available,0) = 1 "
|
20
|
+
].first
|
21
|
+
return nil if row.nil?
|
22
|
+
return BlackStack::Division.where(:id=>row[:id]).first if !row.nil?
|
23
|
+
end
|
24
|
+
end # class User
|
25
|
+
end # module BlackStack
|
data/lib/userdivision.rb
ADDED
data/lib/userrole.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
module BlackStack
|
2
|
+
class UserRole < Sequel::Model(:user_role)
|
3
|
+
BlackStack::UserRole.dataset = BlackStack::UserRole.dataset.disable_insert_output
|
4
|
+
many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
|
5
|
+
many_to_one :role, :class=>:'BlackStack::Role', :key=>:id_role
|
6
|
+
|
7
|
+
end
|
8
|
+
end # module BlackStack
|