qabot 1.1.1

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 (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: []