sql-jarvis 2.1.4 → 2.1.6
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 +4 -4
- data/app/controllers/blazer/checks_controller.rb +17 -1
- data/app/controllers/blazer/queries_controller.rb +26 -5
- data/app/mailers/blazer/slack_notifier.rb +27 -9
- data/app/models/blazer/check.rb +22 -0
- data/app/views/blazer/checks/_form.html.haml +10 -0
- data/app/views/blazer/queries/show.html.haml +4 -2
- data/lib/blazer/engine.rb +1 -0
- data/lib/blazer/excel_parser.rb +1 -5
- data/lib/blazer/version.rb +1 -1
- data/lib/blazer.rb +2 -0
- data/lib/generators/blazer/templates/config.yml.tt +3 -0
- data/lib/generators/blazer/templates/install.rb.tt +1 -0
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 91f27080fce44b6ea0ee444d2b790dddcaa7a9ee8b600f85e020622d2c83e455
|
|
4
|
+
data.tar.gz: 6dd4fcbd656d5d3e8c664173d788c5e79f61087079682560578f13a95eaa0c6f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57be82558a33daf54f8b2c869d287fb6ef77c3a6260723a585321dc66b9b1e1681704186d257b5143a7b6e91e255821bd35a851dac8518d1205c73837a5389d9
|
|
7
|
+
data.tar.gz: 24fbb87c6b50ee64309e0e4b02db2dcdb01c64df7ddfa71855116289265732bf07c02c04df3a50ca586c8523718cdc97e44c5b1bf885fb31d95456c90eabb5d6
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module Blazer
|
|
2
2
|
class ChecksController < BaseController
|
|
3
3
|
before_action :set_check, only: [:edit, :update, :destroy, :run]
|
|
4
|
+
before_action :set_accessible, only: [:new, :edit]
|
|
4
5
|
|
|
5
6
|
def index
|
|
6
7
|
state_order = [nil, "disabled", "error", "timed out", "failing", "passing"]
|
|
@@ -46,11 +47,26 @@ module Blazer
|
|
|
46
47
|
private
|
|
47
48
|
|
|
48
49
|
def check_params
|
|
49
|
-
params.require(:check).permit(:query_id, :emails, :slack_channels, :invert, :check_type, :schedule)
|
|
50
|
+
params.require(:check).permit(:query_id, :emails, :slack_channels, :invert, :check_type, :schedule, slack_members: [])
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
def set_check
|
|
53
54
|
@check = Blazer::Check.find(params[:id])
|
|
54
55
|
end
|
|
56
|
+
|
|
57
|
+
def set_accessible
|
|
58
|
+
@slack_mentions ||= get_slack_mentions + @check.slack_members.each_with_object([]) { |m, list| list << [m, m] if m.present? }
|
|
59
|
+
ensure
|
|
60
|
+
@slack_mentions ||= []
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def get_slack_mentions
|
|
64
|
+
return [] unless Blazer.settings.key?('slack_mentions')
|
|
65
|
+
Blazer::RunStatement.new.perform(Blazer.data_sources[@check.query.data_source], Blazer.settings['slack_mentions'], {}).rows.map do |row|
|
|
66
|
+
[row.last, "[#{row.first}] #{row.second} - ##{row.last}"]
|
|
67
|
+
end
|
|
68
|
+
rescue
|
|
69
|
+
[]
|
|
70
|
+
end
|
|
55
71
|
end
|
|
56
72
|
end
|
|
@@ -61,6 +61,15 @@ module Blazer
|
|
|
61
61
|
@statement = @query.statement.dup
|
|
62
62
|
process_vars(@statement, @query.data_source)
|
|
63
63
|
|
|
64
|
+
filename = []
|
|
65
|
+
filename << @query.name.parameterize if @query
|
|
66
|
+
filename << params[:start_time].to_s.to_date
|
|
67
|
+
if params[:end_time]
|
|
68
|
+
filename << 'to'
|
|
69
|
+
filename << params[:end_time].to_s.to_date
|
|
70
|
+
end
|
|
71
|
+
@filename = filename.compact.join('-')
|
|
72
|
+
|
|
64
73
|
@smart_vars = {}
|
|
65
74
|
@sql_errors = []
|
|
66
75
|
data_source = Blazer.data_sources[@query.data_source]
|
|
@@ -253,7 +262,8 @@ module Blazer
|
|
|
253
262
|
end
|
|
254
263
|
end
|
|
255
264
|
|
|
256
|
-
@filename = @query
|
|
265
|
+
@filename = params[:filename] || @query&.name&.parameterize
|
|
266
|
+
|
|
257
267
|
@min_width_types = @columns.each_with_index.select { |c, i| @first_row[i].is_a?(Time) || @first_row[i].is_a?(String) || @data_source.smart_columns[c] }.map(&:last)
|
|
258
268
|
|
|
259
269
|
@boom = @result.boom if @result
|
|
@@ -278,7 +288,6 @@ module Blazer
|
|
|
278
288
|
end
|
|
279
289
|
end
|
|
280
290
|
|
|
281
|
-
filename = @query.try(:name).try(:parameterize).presence || 'query'
|
|
282
291
|
respond_to do |format|
|
|
283
292
|
format.html do
|
|
284
293
|
render layout: false
|
|
@@ -286,10 +295,14 @@ module Blazer
|
|
|
286
295
|
format.xlsx do
|
|
287
296
|
parser = ::Blazer::ExcelParser.new(@query, @columns, @rows)
|
|
288
297
|
tmp_file = parser.export
|
|
289
|
-
send_file tmp_file,
|
|
298
|
+
send_file tmp_file,
|
|
299
|
+
type: 'application/xlsx; charset=utf-8; header=present',
|
|
300
|
+
disposition: "attachment; filename=\"#{@filename}.xlsx\""
|
|
290
301
|
end
|
|
291
302
|
format.csv do
|
|
292
|
-
send_data csv_data(@columns, @rows, @data_source),
|
|
303
|
+
send_data csv_data(@columns, @rows, @data_source),
|
|
304
|
+
type: 'text/csv; charset=utf-8; header=present',
|
|
305
|
+
disposition: "attachment; filename=\"#{@filename}.csv\""
|
|
293
306
|
end
|
|
294
307
|
end
|
|
295
308
|
end
|
|
@@ -349,8 +362,16 @@ module Blazer
|
|
|
349
362
|
|
|
350
363
|
def get_assignees
|
|
351
364
|
return [] unless Blazer.settings.key?('assignees')
|
|
365
|
+
|
|
352
366
|
Blazer::RunStatement.new.perform(@data_source, Blazer.settings['assignees'], {}).rows.map do |row|
|
|
353
|
-
|
|
367
|
+
case row.size
|
|
368
|
+
when 2
|
|
369
|
+
[row.first, row.last.to_s.titleize]
|
|
370
|
+
when 3
|
|
371
|
+
[row.first, "#{row.second.to_s.titleize} - #{row.last}"]
|
|
372
|
+
else
|
|
373
|
+
[row.first, row.first]
|
|
374
|
+
end
|
|
354
375
|
end
|
|
355
376
|
rescue
|
|
356
377
|
[]
|
|
@@ -28,20 +28,38 @@ module Blazer
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def self.failing_checks(channel, checks)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
all_mentions = []
|
|
32
|
+
attachments = checks.map do |check|
|
|
33
|
+
mentions = check.slack_mention_tags
|
|
34
|
+
all_mentions << mentions
|
|
35
|
+
result = Blazer.data_sources[check.query.data_source].run_statement(check.query.statement)
|
|
36
|
+
{
|
|
37
|
+
mrkdwn_in: %w[title text],
|
|
38
|
+
title: "<#{query_url(check.query_id)}|#{escape(check.query.name)}> #{escape(check.state)} #{mentions.join(' ')}",
|
|
39
|
+
text: "#{Blazer.slack_preview_items_number} first rows `#{result.columns.first}: #{result.rows.first(Blazer.slack_preview_items_number).map(&:first).join(', ')}`",
|
|
40
|
+
color: 'warning'
|
|
41
|
+
}
|
|
42
|
+
end
|
|
35
43
|
|
|
36
44
|
payload = {
|
|
37
45
|
channel: channel,
|
|
38
|
-
|
|
46
|
+
blocks: [
|
|
39
47
|
{
|
|
40
|
-
|
|
41
|
-
text:
|
|
42
|
-
|
|
48
|
+
type: 'header',
|
|
49
|
+
text: {
|
|
50
|
+
type: 'plain_text',
|
|
51
|
+
text: escape("#{pluralize(checks.size, 'Check')} Failing")
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'section',
|
|
56
|
+
text: {
|
|
57
|
+
type: 'mrkdwn',
|
|
58
|
+
text: "Hey #{all_mentions.uniq.join(' ')}, there are some failing checks:"
|
|
59
|
+
}
|
|
43
60
|
}
|
|
44
|
-
]
|
|
61
|
+
],
|
|
62
|
+
attachments: attachments
|
|
45
63
|
}
|
|
46
64
|
|
|
47
65
|
post(Blazer.slack_webhook_url, payload)
|
data/app/models/blazer/check.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module Blazer
|
|
2
2
|
class Check < Record
|
|
3
|
+
serialize :slack_members, Array
|
|
4
|
+
|
|
3
5
|
belongs_to :creator, Blazer::BELONGS_TO_OPTIONAL.merge(class_name: Blazer.user_class.to_s) if Blazer.user_class
|
|
4
6
|
belongs_to :query
|
|
5
7
|
|
|
@@ -22,6 +24,26 @@ module Blazer
|
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
27
|
+
def slack_mention_tags
|
|
28
|
+
tags = []
|
|
29
|
+
slack_members.each do |code|
|
|
30
|
+
case code
|
|
31
|
+
when /^U/
|
|
32
|
+
tags << "<@#{code.strip}>"
|
|
33
|
+
when /^S/
|
|
34
|
+
tags << "<!subteam^#{code.strip}>"
|
|
35
|
+
when 'here'
|
|
36
|
+
tags << '<!here|here>'
|
|
37
|
+
when 'channel'
|
|
38
|
+
tags << '<!channel>'
|
|
39
|
+
when 'everyone'
|
|
40
|
+
tags << '<!everyone>'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
tags.uniq
|
|
45
|
+
end
|
|
46
|
+
|
|
25
47
|
def update_state(result)
|
|
26
48
|
check_type =
|
|
27
49
|
if respond_to?(:check_type)
|
|
@@ -42,6 +42,10 @@
|
|
|
42
42
|
.form-group
|
|
43
43
|
= f.label :slack_channels
|
|
44
44
|
= f.text_field :slack_channels, placeholder: "Optional, comma separated", class: "form-control"
|
|
45
|
+
.form-group
|
|
46
|
+
= f.label :slack_members
|
|
47
|
+
= f.collection_select :slack_members, @slack_mentions, :first, :last, {}, { placeholder: "User, Users group Slack ID", class: "form-control", multiple: true }
|
|
48
|
+
%p.text-muted Slack members: can select or enter new user/user_group Slack ID. It also supports special mentions: channel, everyone, here.
|
|
45
49
|
%p.text-muted
|
|
46
50
|
Emails #{Blazer.slack? ? "and Slack notifications " : nil}are sent when a check starts failing, and when it starts passing again.
|
|
47
51
|
%p
|
|
@@ -49,3 +53,9 @@
|
|
|
49
53
|
= link_to "Delete", check_path(@check), method: :delete, "data-confirm" => "Are you sure?", class: "btn btn-danger"
|
|
50
54
|
= f.submit "Save", class: "btn btn-success"
|
|
51
55
|
= link_to "Back", :back, class: "btn btn-link"
|
|
56
|
+
:javascript
|
|
57
|
+
$(document).ready(function() {
|
|
58
|
+
$('#check_slack_members').select2({
|
|
59
|
+
tags: true,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
- blazer_title @query.name
|
|
2
|
+
|
|
2
3
|
.topbar
|
|
3
4
|
.container
|
|
4
5
|
.row{:style => "padding-top: 13px;"}
|
|
@@ -10,8 +11,9 @@
|
|
|
10
11
|
= link_to "Edit", edit_query_path(@query, variable_params), class: "btn btn-default", disabled: !@query.editable?(blazer_user)
|
|
11
12
|
= link_to "Fork", new_query_path(variable_params.merge(fork_query_id: @query.id, data_source: @query.data_source, name: @query.name)), class: "btn btn-info"
|
|
12
13
|
- if !@error && @success
|
|
13
|
-
= button_to "⤓ .csv", run_queries_path(query_id: @query.id, format: "csv", forecast: params[:forecast]), params: {statement: @statement}, class: "btn btn-primary"
|
|
14
|
-
= button_to "⤓ .xlsx", run_queries_path(query_id: @query.id, format: "xlsx"), params: {statement: @statement}, class: "btn btn-primary"
|
|
14
|
+
= button_to "⤓ .csv", run_queries_path(query_id: @query.id, format: "csv", forecast: params[:forecast]), params: { statement: @statement, filename: @filename }, class: "btn btn-primary"
|
|
15
|
+
= button_to "⤓ .xlsx", run_queries_path(query_id: @query.id, format: "xlsx"), params: { statement: @statement, filename: @filename }, class: "btn btn-primary"
|
|
16
|
+
|
|
15
17
|
%div{:style => "margin-bottom: 60px;"}
|
|
16
18
|
- if @sql_errors.any?
|
|
17
19
|
.alert.alert-danger
|
data/lib/blazer/engine.rb
CHANGED
|
@@ -41,6 +41,7 @@ module Blazer
|
|
|
41
41
|
Blazer.images = Blazer.settings["images"] || false
|
|
42
42
|
Blazer.override_csp = Blazer.settings["override_csp"] || false
|
|
43
43
|
Blazer.slack_webhook_url = Blazer.settings["slack_webhook_url"] || ENV["BLAZER_SLACK_WEBHOOK_URL"]
|
|
44
|
+
Blazer.slack_preview_items_number = Blazer.settings["slack_preview_items_number"] || 25
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
end
|
data/lib/blazer/excel_parser.rb
CHANGED
|
@@ -13,10 +13,6 @@ module Blazer
|
|
|
13
13
|
save_file!
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def filename
|
|
17
|
-
"#{query.name.to_s.parameterize}-#{Time.current.strftime('%y-%m-%d')}.xlsx"
|
|
18
|
-
end
|
|
19
|
-
|
|
20
16
|
private
|
|
21
17
|
|
|
22
18
|
attr_reader :query, :excel
|
|
@@ -31,7 +27,7 @@ module Blazer
|
|
|
31
27
|
end
|
|
32
28
|
|
|
33
29
|
def save_file!
|
|
34
|
-
tmp_file = Tempfile.new
|
|
30
|
+
tmp_file = Tempfile.new.path
|
|
35
31
|
excel.serialize(tmp_file)
|
|
36
32
|
return tmp_file
|
|
37
33
|
end
|
data/lib/blazer/version.rb
CHANGED
data/lib/blazer.rb
CHANGED
|
@@ -61,8 +61,11 @@ audit: true
|
|
|
61
61
|
# mapbox_access_token: <%= ENV["MAPBOX_ACCESS_TOKEN"] %>
|
|
62
62
|
|
|
63
63
|
# assignees: 'SELECT id, name FROM users ORDER BY id ASC'
|
|
64
|
+
# slack_mentions: 'SELECT 'User' as type, name as title, ext_code as code FROM users ORDER BY id ASC'
|
|
64
65
|
# teams: 'SELECT id, name FROM teams'
|
|
65
66
|
|
|
67
|
+
slack_preview_items_number: 25
|
|
68
|
+
|
|
66
69
|
check_schedules:
|
|
67
70
|
- "1 day"
|
|
68
71
|
- "1 hour"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sql-jarvis
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.
|
|
4
|
+
version: 2.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-06-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: railties
|
|
@@ -150,7 +150,7 @@ dependencies:
|
|
|
150
150
|
- - ">="
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
152
|
version: '0'
|
|
153
|
-
description:
|
|
153
|
+
description:
|
|
154
154
|
email: andrew@chartkick.com
|
|
155
155
|
executables: []
|
|
156
156
|
extensions: []
|
|
@@ -270,7 +270,7 @@ homepage: https://github.com/ThanhKhoaIT/blazer
|
|
|
270
270
|
licenses:
|
|
271
271
|
- MIT
|
|
272
272
|
metadata: {}
|
|
273
|
-
post_install_message:
|
|
273
|
+
post_install_message:
|
|
274
274
|
rdoc_options: []
|
|
275
275
|
require_paths:
|
|
276
276
|
- lib
|
|
@@ -285,8 +285,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
285
285
|
- !ruby/object:Gem::Version
|
|
286
286
|
version: '0'
|
|
287
287
|
requirements: []
|
|
288
|
-
rubygems_version: 3.
|
|
289
|
-
signing_key:
|
|
288
|
+
rubygems_version: 3.2.3
|
|
289
|
+
signing_key:
|
|
290
290
|
specification_version: 4
|
|
291
291
|
summary: Fork from ankane! Explore your data with SQL. Easily create charts and dashboards,
|
|
292
292
|
and share them with your team.
|