qabot 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/dbclasses.rb +499 -0
  3. data/lib/qabot.rb +249 -0
  4. metadata +126 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1a4a77bc1c0e5d1a1667b935df168d08e7d34e71
4
+ data.tar.gz: d892ff34caba0b887d45396ac3aa6f49c5e28e21
5
+ SHA512:
6
+ metadata.gz: 004704ab96d13f2ed72231a711d837be00bea93c7d341fbe5d2dc640d577620cd518e12f595636d7b9ecd55d199d95a297b2257e91062b9b5380d41d20c69579
7
+ data.tar.gz: dbdff29081158455c92ed69be4ab107869e8744463ee2094d9d14cd303cf0969514c096808bc87f3b71822b26ed4988c98eb836d64b6e918a3ed3101b3d21fbd
data/lib/dbclasses.rb ADDED
@@ -0,0 +1,499 @@
1
+ # sequel class fro the qacategory table
2
+ module BlackStack
3
+ class User < Sequel::Model(:user)
4
+ one_to_many :boolflags, :class=>:'BlackStack::QABot::BoolFlag', :key=>:id_user
5
+ one_to_many :intflags, :class=>:'BlackStack::QABot::IntFlag', :key=>:id_user
6
+ one_to_many :floatflags, :class=>:'BlackStack::QABot::FloatFlag', :key=>:id_user
7
+ one_to_many :categories, :class=>:'BlackStack::QABot::Category', :key=>:id_user
8
+
9
+ # return all flags of this user
10
+ def flags()
11
+ return self.boolflags + self.intflags + self.floatflags
12
+ end
13
+
14
+ end # class User
15
+
16
+ class Client < Sequel::Model(:client)
17
+ # return all flags of all the users of this client
18
+ def flags()
19
+ return self.users.map{|u| u.flags}.flatten
20
+ end
21
+
22
+ # return all categories of all the users of this client
23
+ def categories()
24
+ return self.users.map{|u| u.categories}.flatten
25
+ end
26
+
27
+ end # class Client
28
+
29
+ module QABot
30
+ #
31
+ class Category < Sequel::Model(:qacategory)
32
+ BlackStack::QABot::Category.dataset = BlackStack::QABot::Category.dataset.disable_insert_output
33
+ many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
34
+ one_to_many :boolflags, :class=>:'BlackStack::BoolFlag', :key=>:id_qacategory
35
+ one_to_many :intflags, :class=>:'BlackStack::IntFlag', :key=>:id_qacategory
36
+ one_to_many :floatflags, :class=>:'BlackStack::FloatFlag', :key=>:id_qacategory
37
+ end # class Category
38
+
39
+ #
40
+ class Alert < Sequel::Model(:qaalert)
41
+ many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
42
+ many_to_one :receiver, :class=>:'BlackStack::User', :key=>:id_receiver
43
+
44
+ end # class Alert
45
+
46
+ #
47
+ class BoolFlag < Sequel::Model(:qaboolflag)
48
+ BlackStack::QABot::BoolFlag.dataset = BlackStack::QABot::BoolFlag.dataset.disable_insert_output
49
+ include BlackStack::QABot::Flag
50
+ many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
51
+ many_to_one :category, :class=>:'BlackStack::QABot::Category', :key=>:id_category
52
+ one_to_many :alerts, :class=>:'BlackStack::QABot::Alert', :key=>:id_qaxflag
53
+
54
+ # map the attributes of this object to a hash.
55
+ # add custom elements to the hash: `:up_to_date`, `:last_update_description`
56
+ # return such a hash.
57
+ def to_hash()
58
+ {
59
+ :id => self.id,
60
+ :type => BlackStack::QABot::BOOL,
61
+ :id_qacategory => self.id_qacategory,
62
+ :create_time => self.create_time,
63
+ :delete_time => self.delete_time,
64
+ :id_user => self.id_user,
65
+ :name => self.name,
66
+ :html_description => self.html_description,
67
+ # how often run this qa check - what is the frequency to show the timeline -- ss, mi, hh, mm, dd, qq, yy
68
+ :trace_frequency_period => self.trace_frequency_period,
69
+ :trace_frequency_units => self.trace_frequency_units,
70
+ # show this flag public in the web
71
+ :public => self.public,
72
+ # what is the latest value reported
73
+ :value => self.value,
74
+ # what is the value to show red (true or false).
75
+ :trigger_red => self.trigger_red,
76
+ # each time the value is changed, you can show a comment about the last status.
77
+ :alert_comments => self.alert_comments,
78
+ # if it is currently red
79
+ :stat_red => self.stat_red,
80
+ # order to show it inside the category, in the dashboard
81
+ :order => self.order,
82
+ # sharing this with other people, so other people can add my alert on their dashboards.
83
+ :share => self.share,
84
+ # activate this flag to show in the flags column of the dashboard
85
+ :show_as_flag => self.show_as_flag,
86
+ # activate tis flag to show in the timelines column of the dashboard
87
+ :show_as_timeline => self.show_as_timeline,
88
+ # custom elements
89
+ :up_to_date => self.up_to_date?,
90
+ :last_update_description => self.last_update_description,
91
+ }
92
+ end # def to_hash()
93
+
94
+ # it is red if the `value` is the same than the value assigned to `trigger_red`
95
+ def is_red?
96
+ self.value == self.trigger_red
97
+ end
98
+
99
+ # map the attributes of the hash `h` to this object.
100
+ def parse(h)
101
+ self.value = h[:value] == true
102
+ self.value_red = h[:value_red] == true
103
+ q = "
104
+ UPDATE qaboolflag
105
+ SET
106
+ id_qacategory = '#{h[:id_qacategory]}',
107
+ --create_time = '#{h[:create_time]}',
108
+ --delete_time = '#{h[:delete_time]}',
109
+ id_user = '#{h[:id_user]}',
110
+ name = '#{h[:name].to_s.to_sql}',
111
+ html_description = '#{h[:html_description].to_s.to_sql}',
112
+ -- how often run this qa check - what is the frequency to show the timeline -- ss, mi, hh, mm, dd, qq, yy
113
+ trace_frequency_period = '#{h[:trace_frequency_period]}',
114
+ trace_frequency_units = #{h[:trace_frequency_units]},
115
+ -- show this flag public in the web
116
+ [public] = #{h[:public] == true ? 1 : 0},
117
+ -- what is the latest value reported
118
+ [value] = #{h[:value] == true ? 1 : 0},
119
+ -- what is the value to show red (true or false). Default value is `false`.
120
+ trigger_red = #{h[:trigger_red] == true ? 1 : 0},
121
+ -- each time the value is changed, you can show a comment about the last status.
122
+ alert_comments = '#{h[:alert_comments].to_s.to_sql}',
123
+ -- if it is currently red
124
+ stat_red = #{self.is_red? ? 1 : 0},
125
+ -- order to show it inside the category, in the dashboard
126
+ [order] = #{h[:order].to_i},
127
+ -- sharing this with other people, so other people can add my alert on their dashboards.
128
+ share = #{h[:share] == true ? 1 : 0},
129
+ -- activate this flag to show in the flags column of the dashboard
130
+ show_as_flag = #{h[:show_as_flag] == true ? 1 : 0},
131
+ -- activate tis flag to show in the timelines column of the dashboard
132
+ show_as_timeline = #{h[:show_as_timeline] == true ? 1 : 0}
133
+ WHERE
134
+ id = '#{h[:id]}'
135
+ "
136
+ #puts
137
+ #puts
138
+ #puts q
139
+ #puts
140
+ #puts
141
+ DB.execute(q)
142
+ end # def parse(h)
143
+
144
+ # create a new object.
145
+ # map the attributes of the hash `h` to this object.
146
+ # return such an object.
147
+ def self.create(client, h)
148
+ u = client.users.first # TODO: the email of the user should be included in the hash descriptor, and validate the user exists and is belonging this client.
149
+ g = client.categories.select { |g| g.name == h[:category] }.first
150
+ if g.nil?
151
+ g = BlackStack::QABot::Category.new
152
+ g.id = guid()
153
+ g.create_time = now()
154
+ g.id_user = u.id
155
+ g.name = h[:category]
156
+ g.save
157
+ end # g.nil?
158
+ o = BlackStack::QABot::BoolFlag.new
159
+ h[:id] = guid()
160
+ h[:id_qacategory] = g.id
161
+ h[:id_user] = u.id
162
+ h[:create_time] = now()
163
+ o.parse(h)
164
+ o
165
+ end # def create(h)
166
+
167
+ # return true if the flag has been updated after `dateadd(#{self.trace_frequency_period}, -#{self.trace_frequency_units}, getdate())`
168
+ def up_to_date?
169
+ !DB["
170
+ select top 1 id
171
+ from qaboolflagtrace with (nolock)
172
+ where trace_time > dateadd(#{self.trace_frequency_period}, -#{self.trace_frequency_units}, getdate())
173
+ and id_qaboolflag = '#{self.id}'
174
+ "].first.nil?
175
+ end
176
+
177
+ # return a label to describe when this flag has been updated the last time
178
+ def last_update_description
179
+ row = DB["
180
+ select top 1 dbo.fnTimeAgoDescription(trace_time, getdate()) as timeago
181
+ from qaboolflagtrace with (nolock)
182
+ where id_qaboolflag = '#{self.id}'
183
+ order by trace_time desc
184
+ "].first
185
+ return !row.nil? ? row[:timeago] : 'never'
186
+ end
187
+ end # class BoolFlag
188
+
189
+ #
190
+ class IntFlag < Sequel::Model(:qaintflag)
191
+ BlackStack::QABot::IntFlag.dataset = BlackStack::QABot::IntFlag.dataset.disable_insert_output
192
+ include BlackStack::QABot::Flag
193
+ many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
194
+ many_to_one :category, :class=>:'BlackStack::QABot::Category', :key=>:id_category
195
+ one_to_many :alerts, :class=>:'BlackStack::QABot::Alert', :key=>:id_qaxflag
196
+
197
+ # map the attributes of this object to a hash.
198
+ # add custom elements to the hash: `:up_to_date`, `:last_update_description`
199
+ # return such a hash.
200
+ def to_hash()
201
+ {
202
+ :id => self.id,
203
+ :type => BlackStack::QABot::INT,
204
+ :id_qacategory => self.id_qacategory,
205
+ :create_time => self.create_time,
206
+ :delete_time => self.delete_time,
207
+ :id_user => self.id_user,
208
+ :name => self.name,
209
+ :html_description => self.html_description,
210
+ # how often run this qa check - what is the frequency to show the timeline -- ss, mi, hh, mm, dd, qq, yy
211
+ :trace_frequency_period => self.trace_frequency_period,
212
+ :trace_frequency_units => self.trace_frequency_units,
213
+ # show this flag public in the web
214
+ :public => self.public,
215
+ # what is the latest value reported
216
+ :value => self.value,
217
+ # what is the value to decide to go green or red.
218
+ value_threshold => self.value_threshold,
219
+ # what is the value to show red (true or false).
220
+ :trigger_red => self.trigger_red,
221
+ # each time the value is changed, you can show a comment about the last status.
222
+ :alert_comments => self.alert_comments,
223
+ # if it is currently red
224
+ :stat_red => self.stat_red,
225
+ # order to show it inside the category, in the dashboard
226
+ :order => self.order,
227
+ # sharing this with other people, so other people can add my alert on their dashboards.
228
+ :share => self.share,
229
+ # activate this flag to show in the flags column of the dashboard
230
+ :show_as_flag => self.show_as_flag,
231
+ # activate tis flag to show in the timelines column of the dashboard
232
+ :show_as_timeline => self.show_as_timeline,
233
+ # custom elements
234
+ :up_to_date => self.up_to_date?,
235
+ :last_update_description => self.last_update_description,
236
+ }
237
+ end # def to_hash()
238
+
239
+ # it is red if the `value` is the same than the value assigned to `trigger_red`
240
+ def is_red?
241
+ if self.trigger_red == BlackStack::QABot::LOWER_OR_EQUAL
242
+ return self.value <= self.value_threshold
243
+ elsif self.trigger_red == BlackStack::QABot::LOWER
244
+ return self.value < self.value_threshold
245
+ elsif self.trigger_red == BlackStack::QABot::EQUAL
246
+ return self.value == self.value_threshold
247
+ elsif self.trigger_red == BlackStack::QABot::GREATER
248
+ return self.value > self.value_threshold
249
+ elsif self.trigger_red == BlackStack::QABot::GREATER_OR_EQUAL
250
+ return self.value >= self.value_threshold
251
+ else
252
+ return nil
253
+ end
254
+ end
255
+
256
+ # map the attributes of the hash `h` to this object.
257
+ def parse(h)
258
+ self.value = h[:value].to_i
259
+ self.value_threshold = h[:value_threshold].to_i
260
+ self.value_red = h[:value_red].to_i
261
+ q = "
262
+ UPDATE qaboolflag
263
+ SET
264
+ id_qacategory = '#{h[:id_qacategory]}',
265
+ --create_time = '#{h[:create_time]}',
266
+ --delete_time = '#{h[:delete_time]}',
267
+ id_user = '#{h[:id_user]}',
268
+ name = '#{h[:name].to_s.to_sql}',
269
+ html_description = '#{h[:html_description].to_s.to_sql}',
270
+ -- how often run this qa check - what is the frequency to show the timeline -- ss, mi, hh, mm, dd, qq, yy
271
+ trace_frequency_period = '#{h[:trace_frequency_period]}',
272
+ trace_frequency_units = #{h[:trace_frequency_units]},
273
+ -- show this flag public in the web
274
+ [public] = #{h[:public] == true ? 1 : 0},
275
+ -- what is the latest value reported
276
+ [value] = #{h[:value].to_i.to_s},
277
+ -- what is the value to decide to go green or red.
278
+ value_threshold = #{h[:value_threshold].to_i.to_s},
279
+ -- what is the value to show red (true or false). Default value is `false`.
280
+ trigger_red = #{h[:trigger_red].to_i.to_s},
281
+ -- each time the value is changed, you can show a comment about the last status.
282
+ alert_comments = '#{h[:alert_comments].to_s.to_sql}',
283
+ -- if it is currently red
284
+ stat_red = #{self.is_red? ? 1 : 0},
285
+ -- order to show it inside the category, in the dashboard
286
+ [order] = #{h[:order].to_i},
287
+ -- sharing this with other people, so other people can add my alert on their dashboards.
288
+ share = #{h[:share] == true ? 1 : 0},
289
+ -- activate this flag to show in the flags column of the dashboard
290
+ show_as_flag = #{h[:show_as_flag] == true ? 1 : 0},
291
+ -- activate tis flag to show in the timelines column of the dashboard
292
+ show_as_timeline = #{h[:show_as_timeline] == true ? 1 : 0}
293
+ WHERE
294
+ id = '#{h[:id]}'
295
+ "
296
+ DB.execute(q)
297
+ end # def parse(h)
298
+
299
+ # create a new object.
300
+ # map the attributes of the hash `h` to this object.
301
+ # return such an object.
302
+ def self.create(client, h)
303
+ u = client.users.first # TODO: the email of the user should be included in the hash descriptor, and validate the user exists and is belonging this client.
304
+ g = client.categories.select { |g| g.name == h[:category] }.first
305
+ if g.nil?
306
+ g = BlackStack::QABot::Category.new
307
+ g.id = guid()
308
+ g.create_time = now()
309
+ g.id_user = u.id
310
+ g.name = h[:category]
311
+ g.save
312
+ end # g.nil?
313
+ o = BlackStack::QABot::IntFlag.new
314
+ h[:id] = guid()
315
+ h[:id_qacategory] = g.id
316
+ h[:id_user] = u.id
317
+ h[:create_time] = now()
318
+ o.parse(h)
319
+ o
320
+ end # def parse(h)
321
+
322
+ # return true if the flag has been updated after `dateadd(#{self.trace_frequency_period}, -#{self.trace_frequency_units}, getdate())`
323
+ def up_to_date?
324
+ !DB["
325
+ select top 1 id
326
+ from qaintflagtrace with (nolock)
327
+ where trace_time > dateadd(#{self.trace_frequency_period}, -#{self.trace_frequency_units}, getdate())
328
+ and id_qaintflag = '#{self.id}'
329
+ "].first.nil?
330
+ end
331
+
332
+ # return a label to describe when this flag has been updated the last time
333
+ def last_update_description
334
+ row = DB["
335
+ select top 1 dbo.fnTimeAgoDescription(trace_time, getdate()) as timeago
336
+ from qaintflagtrace with (nolock)
337
+ where id_qaintflag = '#{self.id}'
338
+ order by trace_time desc
339
+ "].first
340
+ return !row.nil? ? row[:timeago] : 'never'
341
+ end
342
+ end # class IntFlag
343
+
344
+ #
345
+ class FloatFlag < Sequel::Model(:qafloatflag)
346
+ BlackStack::QABot::FloatFlag.dataset = BlackStack::QABot::FloatFlag.dataset.disable_insert_output
347
+ include BlackStack::QABot::Flag
348
+ many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
349
+ many_to_one :category, :class=>:'BlackStack::QABot::Category', :key=>:id_category
350
+ one_to_many :alerts, :class=>:'BlackStack::QABot::Alert', :key=>:id_qaxflag
351
+
352
+ # map the attributes of this object to a hash.
353
+ # add custom elements to the hash: `:up_to_date`, `:last_update_description`
354
+ # return such a hash.
355
+ def to_hash()
356
+ {
357
+ :id => self.id,
358
+ :type => BlackStack::QABot::FLOAT,
359
+ :id_qacategory => self.id_qacategory,
360
+ :create_time => self.create_time,
361
+ :delete_time => self.delete_time,
362
+ :id_user => self.id_user,
363
+ :name => self.name,
364
+ :html_description => self.html_description,
365
+ # how often run this qa check - what is the frequency to show the timeline -- ss, mi, hh, mm, dd, qq, yy
366
+ :trace_frequency_period => self.trace_frequency_period,
367
+ :trace_frequency_units => self.trace_frequency_units,
368
+ # show this flag public in the web
369
+ :public => self.public,
370
+ # what is the latest value reported
371
+ :value => self.value,
372
+ # what is the value to decide to go green or red.
373
+ value_threshold => self.value_threshold,
374
+ # what is the value to show red (true or false).
375
+ :trigger_red => self.trigger_red,
376
+ # each time the value is changed, you can show a comment about the last status.
377
+ :alert_comments => self.alert_comments,
378
+ # if it is currently red
379
+ :stat_red => self.stat_red,
380
+ # order to show it inside the category, in the dashboard
381
+ :order => self.order,
382
+ # sharing this with other people, so other people can add my alert on their dashboards.
383
+ :share => self.share,
384
+ # activate this flag to show in the flags column of the dashboard
385
+ :show_as_flag => self.show_as_flag,
386
+ # activate tis flag to show in the timelines column of the dashboard
387
+ :show_as_timeline => self.show_as_timeline,
388
+ # custom elements
389
+ :up_to_date => self.up_to_date?,
390
+ :last_update_description => self.last_update_description,
391
+ }
392
+ end # def to_hash()
393
+
394
+ # it is red if the `value` is the same than the value assigned to `trigger_red`
395
+ def is_red?
396
+ if self.trigger_red == BlackStack::QABot::LOWER_OR_EQUAL
397
+ return self.value <= self.value_threshold
398
+ elsif self.trigger_red == BlackStack::QABot::LOWER
399
+ return self.value < self.value_threshold
400
+ elsif self.trigger_red == BlackStack::QABot::EQUAL
401
+ return self.value == self.value_threshold
402
+ elsif self.trigger_red == BlackStack::QABot::GREATER
403
+ return self.value > self.value_threshold
404
+ elsif self.trigger_red == BlackStack::QABot::GREATER_OR_EQUAL
405
+ return self.value >= self.value_threshold
406
+ else
407
+ return nil
408
+ end
409
+ end
410
+
411
+ # map the attributes of the hash `h` to this object.
412
+ def parse(h)
413
+ self.value = h[:value].to_f
414
+ self.value_threshold = h[:value_threshold].to_f
415
+ self.value_red = h[:value_red].to_f
416
+ q = "
417
+ UPDATE qaboolflag
418
+ SET
419
+ id_qacategory = '#{h[:id_qacategory]}',
420
+ --create_time = '#{h[:create_time]}',
421
+ --delete_time = '#{h[:delete_time]}',
422
+ id_user = '#{h[:id_user]}',
423
+ name = '#{h[:name].to_s.to_sql}',
424
+ html_description = '#{h[:html_description].to_s.to_sql}',
425
+ -- how often run this qa check - what is the frequency to show the timeline -- ss, mi, hh, mm, dd, qq, yy
426
+ trace_frequency_period = '#{h[:trace_frequency_period]}',
427
+ trace_frequency_units = #{h[:trace_frequency_units]},
428
+ -- show this flag public in the web
429
+ [public] = #{h[:public] == true ? 1 : 0},
430
+ -- what is the latest value reported
431
+ [value] = #{h[:value].to_f.to_s},
432
+ -- what is the value to decide to go green or red.
433
+ value_threshold = #{h[:value_threshold].to_f.to_s},
434
+ -- what is the value to show red (true or false). Default value is `false`.
435
+ trigger_red = #{h[:trigger_red].to_f.to_s},
436
+ -- each time the value is changed, you can show a comment about the last status.
437
+ alert_comments = '#{h[:alert_comments].to_s.to_sql}',
438
+ -- if it is currently red
439
+ stat_red = #{self.is_red? ? 1 : 0},
440
+ -- order to show it inside the category, in the dashboard
441
+ [order] = #{h[:order].to_i},
442
+ -- sharing this with other people, so other people can add my alert on their dashboards.
443
+ share = #{h[:share] == true ? 1 : 0},
444
+ -- activate this flag to show in the flags column of the dashboard
445
+ show_as_flag = #{h[:show_as_flag] == true ? 1 : 0},
446
+ -- activate tis flag to show in the timelines column of the dashboard
447
+ show_as_timeline = #{h[:show_as_timeline] == true ? 1 : 0}
448
+ WHERE
449
+ id = '#{h[:id]}'
450
+ "
451
+ DB.execute(q)
452
+ end # def parse(h)
453
+
454
+ # create a new object.
455
+ # map the attributes of the hash `h` to this object.
456
+ # return such an object.
457
+ def self.create(h)
458
+ u = client.users.first # TODO: the email of the user should be included in the hash descriptor, and validate the user exists and is belonging this client.
459
+ g = client.categories.select { |g| g.name == h[:category] }.first
460
+ if g.nil?
461
+ g = BlackStack::QABot::Category.new
462
+ g.id = guid()
463
+ g.create_time = now()
464
+ g.id_user = u.id
465
+ g.name = h[:category]
466
+ g.save
467
+ end # g.nil?
468
+ o = BlackStack::QABot::FloatFlag.new
469
+ h[:id] = guid()
470
+ h[:id_qacategory] = g.id
471
+ h[:id_user] = u.id
472
+ h[:create_time] = now()
473
+ o.parse(h)
474
+ o
475
+ end # def parse(h)
476
+
477
+ # return true if the flag has been updated after `dateadd(#{self.trace_frequency_period}, -#{self.trace_frequency_units}, getdate())`
478
+ def up_to_date?
479
+ !DB["
480
+ select top 1 id
481
+ from qafloatflagtrace with (nolock)
482
+ where trace_time > dateadd(#{self.trace_frequency_period}, -#{self.trace_frequency_units}, getdate())
483
+ and id_qafloatflag = '#{self.id}'
484
+ "].first.nil?
485
+ end
486
+
487
+ # return a label to describe when this flag has been updated the last time
488
+ def last_update_description
489
+ row = DB["
490
+ select top 1 dbo.fnTimeAgoDescription(trace_time, getdate()) as timeago
491
+ from qafloatflagtrace with (nolock)
492
+ where id_qafloatflag = '#{self.id}'
493
+ order by trace_time desc
494
+ "].first
495
+ return !row.nil? ? row[:timeago] : 'never'
496
+ end
497
+ end # class FloatFlag
498
+ end # module QABot
499
+ end # module BlackStack
data/lib/qabot.rb ADDED
@@ -0,0 +1,249 @@
1
+
2
+ # sequel class fro the qacategory table
3
+ module BlackStack
4
+ module QABot
5
+ BOOL = 'bool'
6
+ INT = 'int'
7
+ FLOAT = 'float'
8
+
9
+ SS = 'ss'
10
+ MI = 'mi'
11
+ HH = 'hh'
12
+ DD = 'dd'
13
+ WW = 'ww'
14
+ MM = 'mm'
15
+ QQ = 'qq'
16
+ YY = 'yy'
17
+
18
+ LOWER_OR_EQUAL = -2
19
+ LOWER = -1
20
+ EQUAL = 0
21
+ GREATER = 1
22
+ GREATER_OR_EQUAL = 2
23
+
24
+ @@flags_descriptors = []
25
+
26
+ def self.require_db_classes()
27
+ # CRM classes
28
+ require_relative '../lib/dbclasses.rb'
29
+ end
30
+
31
+ def self.flag_descriptors()
32
+ @@flags_descriptors
33
+ end
34
+
35
+ def self.types()
36
+ [
37
+ BlackStack::QABot::BOOL,
38
+ BlackStack::QABot::INT,
39
+ BlackStack::QABot::FLOAT,
40
+ ]
41
+ end
42
+
43
+ def self.periods()
44
+ [
45
+ BlackStack::QABot::SS,
46
+ BlackStack::QABot::MI,
47
+ BlackStack::QABot::HH,
48
+ BlackStack::QABot::DD,
49
+ BlackStack::QABot::WW,
50
+ BlackStack::QABot::MM,
51
+ BlackStack::QABot::QQ,
52
+ BlackStack::QABot::YY,
53
+ ]
54
+ end
55
+
56
+ def self.trigger_red_values()
57
+ [
58
+ BlackStack::QABot::LOWER_OR_EQUAL,
59
+ BlackStack::QABot::LOWER,
60
+ BlackStack::QABot::EQUAL,
61
+ BlackStack::QABot::GREATER_OR_EQUAL,
62
+ BlackStack::QABot::GREATER,
63
+ ]
64
+ end
65
+
66
+ # Validate the values of the hash, after executing the `:value_function` procedure
67
+ def self.validate_descriptor_values(h)
68
+ errors = []
69
+ # VALIDATE: if `:type` is `BOOL`, `:value` must be boolean.
70
+ errors << "`:value` must be boolean" if h[:type] == BlackStack::QABot::BOOL && ![true, false].include?(h[:value])
71
+ # VALIDATE: if `:type` is `INT`, `:value` must be integer.
72
+ errors << "`:value` must be integer" if h[:type] == BlackStack::QABot::INT && !h[:value].is_a?(Integer)
73
+ # VALIDATE: if `:type` is `FLOAT`, `:value` must be float.
74
+ errors << "`:value` must be float" if h[:type] == BlackStack::QABot::FLOAT && !h[:value].is_a?(Float)
75
+ # return
76
+ errors
77
+ end
78
+
79
+ # Validate the values of the hash, prior executing the `:value_function` procedure
80
+ def self.validate_descriptor_parameters_except_functions(h)
81
+ errors = []
82
+ # VALIDATE: the `:type` is a valid value
83
+ errors << "Invalid type: #{h[:type]}" unless BlackStack::QABot.types().include?(h[:type])
84
+ # VALIDATE: the ':category' is a string no longer than 500 chars
85
+ errors << "Invalid category: #{h[:category]}. Must be string lower than 500 chars." unless h[:category].is_a?(String) && h[:category].length <= 500
86
+ # VALIDATE: the `:name` is a string no longer than 500 chars
87
+ errors << "Invalid name: #{h[:name]}. Must be string lower than 500 chars." unless h[:name].is_a?(String) && h[:name].length <= 500
88
+ # VALIDATE: the `:description` is a string no longer than 8000 chars
89
+ errors << "Invalid description: #{h[:description]}. Must be string lower than 8000 chars." unless h[:description].is_a?(String) && h[:description].length <= 8000
90
+ # VALIDATE: the ':trace_fraquency_period` is a valid value
91
+ errors << "Invalid trace_frequency_period: #{h[:trace_frequency_period]}" unless BlackStack::QABot.periods().include?(h[:trace_frequency_period])
92
+ # VALIDATE: the `:trace_frequency_units` is an integer higher than 0
93
+ errors << "Invalid trace_frequency_units: #{h[:trace_frequency_units]}. Must be integer higher than 0." unless h[:trace_frequency_units].is_a?(Integer) && h[:trace_frequency_units] > 0
94
+ # VALIDATE: the `:show_as_flag` is a boolean
95
+ errors << "Invalid show_as_flag: #{h[:show_as_flag]}. Must be boolean." unless h[:show_as_flag].is_a?(TrueClass) || h[:show_as_flag].is_a?(FalseClass)
96
+ # VALIDATE: the `:show_as_timeline` is a boolean
97
+ errors << "Invalid show_as_timeline: #{h[:show_as_timeline]}. Must be boolean." unless h[:show_as_timeline].is_a?(TrueClass) || h[:show_as_timeline].is_a?(FalseClass)
98
+ # VALIDATE: the `:public` is a boolean
99
+ errors << "Invalid public: #{h[:public]}. Must be boolean." unless h[:public].is_a?(TrueClass) || h[:public].is_a?(FalseClass)
100
+ # VALIDATE: the `:share` is a boolean
101
+ errors << "Invalid share: #{h[:share]}. Must be boolean." unless h[:share].is_a?(TrueClass) || h[:share].is_a?(FalseClass)
102
+ # VALIDATE: if `:type` is `BOOL`, then `:trigger_red` must be a boolean
103
+ errors << "Invalid trigger_red: #{h[:trigger_red]}. Must be boolean." if h[:type] == BlackStack::QABot::BOOL && !(h[:trigger_red].is_a?(TrueClass) || h[:trigger_red].is_a?(FalseClass))
104
+ # VALIDATE: if `:type` is `INT` OR `FLOAT`, then `:trigger_red` must be beloning `trigger_red_values`
105
+ errors << "Invalid trigger_red: #{h[:trigger_red]}. Must be one of #{trigger_red_values.to_s}" if (h[:type] == BlackStack::QABot::INT || h[:type] == BlackStack::QABot::FLOAT) && !trigger_red_values.include?(h[:trigger_red])
106
+ # VALIDATE: if `:type` is 'INT', then `:value_threshold` must ba an integer.
107
+ errors << "Invalid trigger_red: #{h[:value_threshold]}. Must be integer." if h[:type] == BlackStack::QABot::INT && !h[:value_threshold].is_a?(Integer)
108
+ # VALIDATE: if `:ty[e` is `FLOAT`, then `:trigger_red` must be a float.
109
+ errors << "Invalid trigger_red: #{h[:value_threshold]}. Must be float." if h[:type] == BlackStack::QABot::FLOAT && !h[:value_threshold].is_a?(Float)
110
+ # return errors
111
+ errors
112
+ end # def self.validate_descriptor_parameters_except_functions
113
+
114
+ # return a `flag` object belonging this client, with this name
115
+ def self.find(client, name)
116
+ return nil if client.nil? || name.nil?
117
+ return nil if client.flags.nil?
118
+ client.flags.each do |flag|
119
+ return flag if flag.name == name
120
+ end
121
+ nil
122
+ end
123
+
124
+ # return `true` if exists a flag belonging this client, with this name
125
+ def self.exists?(client, name)
126
+ !BlackStack::QABot::find(client, name).nil?
127
+ end
128
+
129
+ # create a new flag belonging this client, with this name
130
+ def self.create(client, h)
131
+ o = nil
132
+ o = BlackStack::QABot::BoolFlag.create(client, h) if h[:type] == BlackStack::QABot::BOOL
133
+ o = BlackStack::QABot::IntFlag.create(client, h) if h[:type] == BlackStack::QABot::INT
134
+ o = BlackStack::QABot::FloatFlag.create(client, h) if h[:type] == BlackStack::QABot::FLOAT
135
+ o
136
+ end # def self.create
137
+
138
+ # update the flag belonging this client, with this name, with the values in the hash descriptor
139
+ def self.parse(client, h)
140
+ o = BlackStack::QABot::find(client, h[:name])
141
+ return nil if o.nil?
142
+ h[:id] = o.id
143
+
144
+ g = client.categories.select { |g| g.name == h[:category] }.first
145
+ if g.nil?
146
+ g = BlackStack::QABot::Category.new
147
+ g.id = guid()
148
+ g.create_time = now()
149
+ g.id_user = u.id
150
+ g.name = h[:category]
151
+ g.save
152
+ end # g.nil?
153
+ h[:id_qacategory] = g.id
154
+ h[:id_user] = client.users.first.id # TODO: I should receive the email of the email in the hash descriptor, and validate the email is belonging the client.
155
+ h[:html_description] = h[:description]
156
+ o.parse(h)
157
+ o
158
+ end # def self.parse
159
+
160
+ # return `true` if exists a flag belonging this client, with this name
161
+ def self.exists_by_id?(client, id)
162
+ return false if client.nil? || id.nil?
163
+ return false if client.flags.nil?
164
+ client.flags.each do |flag|
165
+ return true if flag.id == id
166
+ end
167
+ false
168
+ end
169
+
170
+ # return `true` if exists a flag belonging this client, with this name
171
+ def self.exists_by_id_and_name?(client, id, name)
172
+ return false if client.nil? || id.nil? || name.nil?
173
+ return false if client.flags.nil?
174
+ client.flags.each do |flag|
175
+ return true if flag.id == id && flag.name == name
176
+ end
177
+ false
178
+ end
179
+
180
+ # return `true` if exists a flag belonging this client, with this name
181
+ def self.exists_by_name?(client, name)
182
+ return false if client.nil? || name.nil?
183
+ return false if client.flags.nil?
184
+ client.flags.each do |flag|
185
+ return true if flag.name == name
186
+ end
187
+ false
188
+ end
189
+
190
+ # return `true` if exists a flag belonging this client, with this name
191
+ def self.exists_by_name_and_id?(client, name, id)
192
+ return false if client.nil? || name.nil? || id.nil?
193
+ return false if client.flags.nil?
194
+ client.flags.each do |flag|
195
+ return true if flag.name == name && flag.id == id
196
+ end
197
+ false
198
+ end
199
+
200
+ #
201
+ def self.add_flag(h)
202
+ # get the errors on all parameters except functions
203
+ errors = BlackStack::QABot::validate_descriptor_parameters_except_functions(h)
204
+ # VALIDATE: the `:value_function` is a procedure
205
+ errors << "Invalid value_function. Must be procedure." unless h[:value_function].is_a?(Proc)
206
+ # VALIDATE: the `:alert_comments_function` is a procedure
207
+ errors << "Invalid alert_comments_function. Must be procedure." unless h[:alert_comments_function].is_a?(Proc)
208
+ # raise an exception if `errors` has any element
209
+ raise errors.join("\n") if errors.length > 0
210
+ # add `h` to `@@flags_descriptors`
211
+ @@flags_descriptors << h
212
+ # return the array
213
+ @@flags_descriptors
214
+ end # def self.add_flag
215
+
216
+ def self.run_all()
217
+ @@flags_descriptors.each do |h|
218
+ BlackStack::QABot.run(h)
219
+ end
220
+ end
221
+
222
+ def self.run(h)
223
+ h[:value] = h[:value_function].call()
224
+ h[:alert_comments] = h[:alert_comments_function].call()
225
+ BlackStack::QABot::Flag.push(h)
226
+ end
227
+
228
+ # this module contains methods that are commons to any kind flags
229
+ module Flag
230
+ # return true of the latest trace is `stat_red==true`, and the previous trace is `stat_red==false`.
231
+ def should_alert?
232
+ # TODO: Code Me!
233
+ false
234
+ end # def should_alert?
235
+
236
+ # send an email notification to all the receivers of this flag.
237
+ def alert()
238
+ # TODO: Code Me!
239
+ end # def alert()
240
+
241
+ # submit a flag descriptor to the server, via REST-API.
242
+ def self.push(h)
243
+ url = "#{BlackStack::Pampa::api_url}/api.1.1.0/qabot/push.json"
244
+ api_key = BlackStack::Pampa::api_key
245
+ BlackStack::Netting::api_call( url, {:api_key => api_key}.merge(h) )
246
+ end
247
+ end # module Flag
248
+ end # module QABot
249
+ end # module BlackStack
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qabot
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Leandro Daniel Sardi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-04-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.8.1
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.8.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 1.8.1
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.8.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: tiny_tds
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.0.5
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.0.5
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 1.0.5
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.0.5
53
+ - !ruby/object:Gem::Dependency
54
+ name: sequel
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 4.28.0
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 4.28.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 4.28.0
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 4.28.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: pampa_workers
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: 1.1.36
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.1.36
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.1.36
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.1.36
93
+ description: 'THIS GEM IS STILL IN DEVELOPMENT STAGE. Find documentation here: https://github.com/leandrosardi/pampa_dispatcher.'
94
+ email: leandro.sardi@expandedventure.com
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - lib/dbclasses.rb
100
+ - lib/qabot.rb
101
+ homepage: https://rubygems.org/gems/pampa_deployer
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.4.5.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: THIS GEM IS STILL IN DEVELOPMENT STAGE. Distribute work along a pool of Pampa
125
+ workers.
126
+ test_files: []