blazer 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of blazer might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 63faea5b7fa9ad8d4365931c80851e33d80553e8
4
- data.tar.gz: 30b6a8d2dd631512a5cd82a6fabe119e7e9d5963
3
+ metadata.gz: af24e4d2d3a7574a1b6e03186ea77d54dcb4f4b5
4
+ data.tar.gz: 3d9b34fd4cb0c26cb7516d75cfe2eab85a2d3b8f
5
5
  SHA512:
6
- metadata.gz: 69a08a57180385ed46ae3bd776fa3e67bf885ed9845dc7508f70d1d7d883d940120c4b03167800726fe6d0dcb728518e4cfbdc32b6fc2647813d381eea0d1670
7
- data.tar.gz: 681fdbe806cfc7675335802166199ed11124e6c443c4d8da31e279c47b48ed847a5d2061d24d657d5c343c47a284b929dc93f4188ca7fa7fcae4d47bcd225d67
6
+ metadata.gz: 5c9590d8f9798d5cef1ca335ba38f990ae51d021d2a04d4fa01929b43a032a823988ddc39b697e36888d62a84fe663d9a974fdbd9c6339fa00d50b15688aa899
7
+ data.tar.gz: 55fe87e6539b8f9b776c68bb18dd9b20564151f3b5dbb47ad3a0380e811914f4c4b5e6f8202dd891406e6c790c4f17ddfc21abd1f97ff05b65fd160950231cef
@@ -1,3 +1,9 @@
1
+ ## 1.5.1
2
+
3
+ - Added anomaly detection for data less than 2 weeks
4
+ - Added autolinking urls
5
+ - Added support for images
6
+
1
7
  ## 1.5.0
2
8
 
3
9
  - Added new bar chart format
data/README.md CHANGED
@@ -154,7 +154,7 @@ Create queries with variables.
154
154
  SELECT * FROM users WHERE gender = {gender}
155
155
  ```
156
156
 
157
- Use `{start_time}` and `{end_time}` for time ranges. [Example](https://blazerme.herokuapp.com/queries/8-ratings-by-time-range?start_time=1997-10-03T05%3A00%3A00%2B00%3A00&end_time=1997-10-04T04%3A59%3A59%2B00%3A00)
157
+ Use `{start_time}` and `{end_time}` for time ranges. [Example](https://blazerme.herokuapp.com/queries/9-time-range-selector?start_time=1997-10-03T05%3A00%3A00%2B00%3A00&end_time=1997-10-04T04%3A59%3A59%2B00%3A00)
158
158
 
159
159
  ```sql
160
160
  SELECT * FROM ratings WHERE rated_at >= {start_time} AND rated_at <= {end_time}
@@ -162,7 +162,7 @@ SELECT * FROM ratings WHERE rated_at >= {start_time} AND rated_at <= {end_time}
162
162
 
163
163
  ### Smart Variables
164
164
 
165
- [Example](https://blazerme.herokuapp.com/queries/3-users-by-occupation)
165
+ [Example](https://blazerme.herokuapp.com/queries/1-smart-variable)
166
166
 
167
167
  Suppose you have the query:
168
168
 
@@ -183,7 +183,7 @@ The first column is the value of the variable, and the second column is the labe
183
183
 
184
184
  ### Linked Columns
185
185
 
186
- [Example](https://blazerme.herokuapp.com/queries/4-highest-rated-movies) - title column
186
+ [Example](https://blazerme.herokuapp.com/queries/3-linked-column) - title column
187
187
 
188
188
  Link results to other pages in your apps or around the web. Specify a column name and where it should link to. You can use the value of the result with `{value}`.
189
189
 
@@ -195,7 +195,7 @@ linked_columns:
195
195
 
196
196
  ### Smart Columns
197
197
 
198
- [Example](https://blazerme.herokuapp.com/queries/10-users) - occupation_id column
198
+ [Example](https://blazerme.herokuapp.com/queries/2-smart-column) - occupation_id column
199
199
 
200
200
  Suppose you have the query:
201
201
 
@@ -239,13 +239,13 @@ Blazer will automatically generate charts based on the types of the columns retu
239
239
 
240
240
  There are two ways to generate line charts.
241
241
 
242
- 2+ columns - timestamp, numeric(s) - [Example](https://blazerme.herokuapp.com/queries/1-new-ratings-per-week)
242
+ 2+ columns - timestamp, numeric(s) - [Example](https://blazerme.herokuapp.com/queries/4-line-chart-format-1)
243
243
 
244
244
  ```sql
245
245
  SELECT date_trunc('week', created_at), COUNT(*) FROM users GROUP BY 1
246
246
  ```
247
247
 
248
- 3 columns - timestamp, string, numeric - [Example](https://blazerme.herokuapp.com/queries/7-new-ratings-by-gender-per-month)
248
+ 3 columns - timestamp, string, numeric - [Example](https://blazerme.herokuapp.com/queries/5-line-chart-format-2)
249
249
 
250
250
 
251
251
  ```sql
@@ -256,13 +256,13 @@ SELECT date_trunc('week', created_at), gender, COUNT(*) FROM users GROUP BY 1, 2
256
256
 
257
257
  There are also two ways to generate column charts.
258
258
 
259
- 2+ columns - string, numeric(s) - [Example](https://blazerme.herokuapp.com/queries/2-top-genres)
259
+ 2+ columns - string, numeric(s) - [Example](https://blazerme.herokuapp.com/queries/6-column-chart-format-1)
260
260
 
261
261
  ```sql
262
262
  SELECT gender, COUNT(*) FROM users GROUP BY 1
263
263
  ```
264
264
 
265
- 3 columns - string, string, numeric
265
+ 3 columns - string, string, numeric - [Example](https://blazerme.herokuapp.com/queries/7-column-chart-format-2)
266
266
 
267
267
  ```sql
268
268
  SELECT gender, zip_code, COUNT(*) FROM users GROUP BY 1, 2
@@ -270,7 +270,7 @@ SELECT gender, zip_code, COUNT(*) FROM users GROUP BY 1, 2
270
270
 
271
271
  ### Maps
272
272
 
273
- Columns named `latitude` and `longitude` or `lat` and `lon` - [Example](https://blazerme.herokuapp.com/queries/11-airports-in-pacific-time-zone)
273
+ Columns named `latitude` and `longitude` or `lat` and `lon` - [Example](https://blazerme.herokuapp.com/queries/15-map)
274
274
 
275
275
  ```sql
276
276
  SELECT name, latitude, longitude FROM cities
@@ -280,7 +280,7 @@ To enable, get an access token from [Mapbox](https://www.mapbox.com/) and set `E
280
280
 
281
281
  ### Targets
282
282
 
283
- Use the column name `target` to draw a line for goals.
283
+ Use the column name `target` to draw a line for goals. [Example](https://blazerme.herokuapp.com/queries/8-target-line)
284
284
 
285
285
  ```sql
286
286
  SELECT date_trunc('week', created_at), COUNT(*) AS new_users, 100000 AS target FROM users GROUP BY 1
@@ -288,7 +288,7 @@ SELECT date_trunc('week', created_at), COUNT(*) AS new_users, 100000 AS target F
288
288
 
289
289
  ## Dashboards
290
290
 
291
- Create a dashboard with multiple queries. [Example](https://blazerme.herokuapp.com/dashboards/1-movielens)
291
+ Create a dashboard with multiple queries. [Example](https://blazerme.herokuapp.com/dashboards/1-dashboard-demo)
292
292
 
293
293
  If the query has a chart, the chart is shown. Otherwise, you’ll see a table.
294
294
 
@@ -325,6 +325,8 @@ anomaly_checks: true
325
325
 
326
326
  If upgrading from version 1.4 or below, also follow the [upgrade instructions](#15).
327
327
 
328
+ If you’re on Heroku, follow [these additional instructions](#anomaly-detection-on-heroku).
329
+
328
330
  ## Data Sources
329
331
 
330
332
  Blazer supports multiple data sources :tada:
@@ -363,6 +365,25 @@ Have team members who want to learn SQL? Here are a few great, free resources.
363
365
 
364
366
  For an easy way to group by day, week, month, and more with correct time zones, check out [Groupdate](https://github.com/ankane/groupdate.sql).
365
367
 
368
+ ## Anomaly Detection on Heroku
369
+
370
+ Add the [R buildpack](https://github.com/virtualstaticvoid/heroku-buildpack-r) to your app.
371
+
372
+ ```sh
373
+ heroku buildpacks:add --index 1 https://github.com/ankane/heroku-buildpack-r.git\#cedar-14
374
+ ```
375
+
376
+ And create an `init.r` with:
377
+
378
+ ```sh
379
+ if (!"AnomalyDetection" %in% installed.packages()) {
380
+ install.packages("devtools")
381
+ devtools::install_github("twitter/AnomalyDetection")
382
+ }
383
+ ```
384
+
385
+ Commit and deploy away. The first deploy may take a few minutes.
386
+
366
387
  ## Upgrading
367
388
 
368
389
  ### 1.5
@@ -24,6 +24,11 @@ body {
24
24
  background-color: #fff;
25
25
  }
26
26
 
27
+ .results-table img {
28
+ max-width: 200px;
29
+ max-height: 200px;
30
+ }
31
+
27
32
  input.search {
28
33
  border: none;
29
34
  box-shadow: none;
@@ -199,7 +199,7 @@ module Blazer
199
199
  @filename = @query.name.parameterize if @query
200
200
  @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)
201
201
 
202
- @boom = @result.boom
202
+ @boom = @result.boom if @result
203
203
 
204
204
  @linked_columns = @data_source.linked_columns
205
205
 
@@ -8,9 +8,21 @@ module Blazer
8
8
  end
9
9
  end
10
10
 
11
+ BLAZER_URL_REGEX = /\Ahttps?:\/\/[\S]+\z/
12
+ BLAZER_IMAGE_EXT = %w[png jpg jpeg gif]
13
+
11
14
  def blazer_format_value(key, value)
12
15
  if value.is_a?(Integer) && !key.to_s.end_with?("id")
13
16
  number_with_delimiter(value)
17
+ elsif value =~ BLAZER_URL_REGEX
18
+ # see if image or link
19
+ if Blazer.images && (key.include?("image") || BLAZER_IMAGE_EXT.include?(value.split(".").last.split("?").first.try(:downcase)))
20
+ link_to value, target: "_blank" do
21
+ image_tag value, referrerpolicy: "no-referrer"
22
+ end
23
+ else
24
+ link_to value, value, target: "_blank"
25
+ end
14
26
  else
15
27
  value
16
28
  end
@@ -60,7 +60,7 @@ module Blazer
60
60
  end
61
61
 
62
62
  # do not notify on creation, except when not passing
63
- if (state_was || state != "passing") && state != state_was && emails.present?
63
+ if (state_was != "new" || state != "passing") && state != state_was && emails.present?
64
64
  Blazer::CheckMailer.state_change(self, state, state_was, result.rows.size, message).deliver_later
65
65
  end
66
66
  save! if changed?
@@ -16,7 +16,7 @@
16
16
  <tbody>
17
17
  <% @checks.each do |check| %>
18
18
  <tr>
19
- <td><%= link_to check.query.name, check.query %></td>
19
+ <td><%= link_to check.query.name, check.query %> <span class="text-muted"><%= check.try(:check_type).to_s.gsub("_", " ") %></span></td>
20
20
  <td>
21
21
  <% if check.state %>
22
22
  <small class="check-state <%= check.state.parameterize("_") %>"><%= check.state.upcase %></small>
@@ -102,10 +102,22 @@
102
102
 
103
103
  function getSQL() {
104
104
  var selectedText = editor.getSelectedText();
105
- var text = selectedText.length == 0 ? editor.getValue() : selectedText;
105
+ var text = selectedText.length < 10 ? editor.getValue() : selectedText;
106
106
  return text.replace(/\n/g, "\r\n");
107
107
  }
108
108
 
109
+ function getErrorLine() {
110
+ var error_line = /LINE (\d+)/g.exec($("#results").find('.alert-danger').text());
111
+
112
+ if (error_line) {
113
+ error_line = parseInt(error_line[1], 10);
114
+ if (editor.getSelectedText().length >= 10) {
115
+ error_line += editor.getSelectionRange().start.row;
116
+ }
117
+ return error_line;
118
+ }
119
+ }
120
+
109
121
  editor.getSession().on("change", adjustHeight);
110
122
  adjustHeight();
111
123
  $("#editor").show();
@@ -133,10 +145,8 @@
133
145
  xhr = runQuery(data, function (data) {
134
146
  $("#results").html(data);
135
147
 
136
- error_line = /LINE (\d+)/g.exec($("#results").find('.alert-danger').text());
137
-
148
+ error_line = getErrorLine();
138
149
  if (error_line) {
139
- error_line = parseInt(error_line[1], 10);
140
150
  editor.getSession().addGutterDecoration(error_line - 1, "error");
141
151
  editor.scrollToLine(error_line, true, true, function () {});
142
152
  editor.gotoLine(error_line, 0, true);
@@ -24,12 +24,14 @@ module Blazer
24
24
  attr_accessor :check_schedules
25
25
  attr_accessor :anomaly_checks
26
26
  attr_accessor :async
27
+ attr_accessor :images
27
28
  end
28
29
  self.audit = true
29
30
  self.user_name = :name
30
31
  self.check_schedules = ["5 minutes", "1 hour", "1 day"]
31
32
  self.anomaly_checks = false
32
33
  self.async = false
34
+ self.images = false
33
35
 
34
36
  TIMEOUT_MESSAGE = "Query timed out :("
35
37
  TIMEOUT_ERRORS = [
@@ -3,11 +3,16 @@ tryCatch({
3
3
 
4
4
  args <- commandArgs(trailingOnly = TRUE)
5
5
 
6
- con <- textConnection(args[1])
6
+ con <- textConnection(args[2])
7
7
  data <- read.csv(con, stringsAsFactors = FALSE)
8
8
  data$timestamp <- as.POSIXct(data$timestamp)
9
9
 
10
- res = AnomalyDetectionTs(data, direction = "both", alpha = 0.05)
10
+ if (identical(args[1], "ts")) {
11
+ res = AnomalyDetectionTs(data, direction = "both", alpha = 0.05)
12
+ } else {
13
+ res = AnomalyDetectionVec(data$count, direction = "both", alpha = 0.05, period = length(data$count) / 2 - 1)
14
+ }
15
+
11
16
  write.csv(res$anoms)
12
17
  }, error = function (e) {
13
18
  write.csv(geterrmessage())
@@ -35,6 +35,8 @@ module Blazer
35
35
  if Blazer.async
36
36
  require "blazer/run_statement_job"
37
37
  end
38
+
39
+ Blazer.images = Blazer.settings["images"] || false
38
40
  end
39
41
  end
40
42
  end
@@ -106,6 +106,7 @@ module Blazer
106
106
  end
107
107
  rescue => e
108
108
  message = "#{current_series}: #{e.message}"
109
+ raise e if Rails.env.development?
109
110
  end
110
111
  else
111
112
  message = "Bad format"
@@ -126,10 +127,12 @@ module Blazer
126
127
  end
127
128
  end
128
129
 
129
- timestamps = []
130
130
  r_script = %x[which Rscript].chomp
131
+ type = series.any? && series.last.first.to_time - series.first.first.to_time >= 2.weeks ? "ts" : "vec"
132
+ args = [type, csv_str]
131
133
  raise "R not found" if r_script.empty?
132
- output = %x[#{r_script} --vanilla #{File.expand_path("../detect_anomalies.R", __FILE__)} #{Shellwords.escape(csv_str)}]
134
+ command = "#{r_script} --vanilla #{File.expand_path("../detect_anomalies.R", __FILE__)} #{args.map { |a| Shellwords.escape(a) }.join(" ")}"
135
+ output = %x[#{command}]
133
136
  if output.empty?
134
137
  raise "Unknown R error"
135
138
  end
@@ -138,10 +141,18 @@ module Blazer
138
141
  error = rows.first && rows.first["x"]
139
142
  raise error if error
140
143
 
141
- rows.each do |row|
142
- timestamps << Time.parse(row["timestamp"])
144
+ timestamps = []
145
+ if type == "ts"
146
+ rows.each do |row|
147
+ timestamps << Time.parse(row["timestamp"])
148
+ end
149
+ timestamps.include?(series.last[0].to_time)
150
+ else
151
+ rows.each do |row|
152
+ timestamps << row["index"].to_i
153
+ end
154
+ timestamps.include?(series.length)
143
155
  end
144
- timestamps.include?(series.last[0].to_time)
145
156
  end
146
157
  end
147
158
  end
@@ -1,3 +1,3 @@
1
1
  module Blazer
2
- VERSION = "1.5.0"
2
+ VERSION = "1.5.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-29 00:00:00.000000000 Z
11
+ date: 2016-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -189,8 +189,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  version: '0'
190
190
  requirements: []
191
191
  rubyforge_project:
192
- rubygems_version: 2.4.5.1
192
+ rubygems_version: 2.6.1
193
193
  signing_key:
194
194
  specification_version: 4
195
195
  summary: Share data effortlessly with your team
196
196
  test_files: []
197
+ has_rdoc: