rails_local_analytics 0.2.0 → 0.2.2
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/README.md +3 -0
- data/app/assets/stylesheets/rails_local_analytics/application.css +4 -0
- data/app/controllers/rails_local_analytics/dashboard_controller.rb +54 -22
- data/app/views/rails_local_analytics/dashboard/index.html.erb +72 -26
- data/lib/rails_local_analytics/version.rb +1 -1
- metadata +16 -3
- data/app/lib/rails_local_analytics/histogram.rb +0 -47
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c1dffba4cbead6faa6192e3c1df830aa749f6f653bdc8f0eef6e9dbd3a2650b
|
|
4
|
+
data.tar.gz: b0b6a574e09786c7888c4e6194fff36616f9d0634d99773955e762417ee3c828
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 021fcb8b029ce1d842415eb5a4a3ed39a433726851988891455f2aa1ec510a1f56acc9563bad3003b799624384a8ff74ef40183e0a81746df82bb1d3b68d2e24
|
|
7
|
+
data.tar.gz: 6c9d8b537f1de5f9b28b1b6e6baac6135a389a1ba65bb5dbc19a4ebdd7b73e1efaf855e6daaaa81b8b06b0a2d1913e0d0cdc97fd31635c794d545238751820c6
|
data/README.md
CHANGED
|
@@ -138,6 +138,9 @@ Some examples of additional things you may want to track:
|
|
|
138
138
|
* You may not need to store this in a new column, one example pattern could be to store this data in the existing `platform` database field
|
|
139
139
|
- Country detection
|
|
140
140
|
* Country detection is difficult. As such we dont try to include it by default.
|
|
141
|
+
* Consider using language detection instead
|
|
142
|
+
- Language detection
|
|
143
|
+
* You can gather the language from the `request.env["HTTP_ACCEPT_LANGUAGE"]` or `browser.accept_language.first.full`
|
|
141
144
|
- Users or organizations
|
|
142
145
|
* You may want to track your users or another model which is a core tenant to your particular application
|
|
143
146
|
|
|
@@ -3,6 +3,7 @@ module RailsLocalAnalytics
|
|
|
3
3
|
PER_PAGE_LIMIT = 1000
|
|
4
4
|
|
|
5
5
|
helper_method :pagination_page_number
|
|
6
|
+
helper_method :display_columns
|
|
6
7
|
|
|
7
8
|
def index
|
|
8
9
|
params[:type] ||= "page"
|
|
@@ -17,17 +18,13 @@ module RailsLocalAnalytics
|
|
|
17
18
|
return
|
|
18
19
|
end
|
|
19
20
|
|
|
20
|
-
if params[:group_by].present? && !@klass.display_columns.include?(params[:group_by])
|
|
21
|
-
params[:group_by] = nil
|
|
22
|
-
end
|
|
23
|
-
|
|
24
21
|
if params[:start_date].present?
|
|
25
22
|
@start_date = Date.parse(params[:start_date])
|
|
26
23
|
else
|
|
27
24
|
@start_date = Date.today
|
|
28
25
|
end
|
|
29
26
|
|
|
30
|
-
if params[:end_date]
|
|
27
|
+
if params[:end_date].present?
|
|
31
28
|
@end_date = Date.parse(params[:end_date])
|
|
32
29
|
else
|
|
33
30
|
@end_date = Date.today
|
|
@@ -63,20 +60,18 @@ module RailsLocalAnalytics
|
|
|
63
60
|
|
|
64
61
|
prev_start_date, prev_end_date = get_prev_dates(start_date, end_date)
|
|
65
62
|
|
|
66
|
-
|
|
63
|
+
difference_where_conditions = params.require(:conditions).permit(*display_columns)
|
|
67
64
|
|
|
68
65
|
current_total = fetch_records(
|
|
69
66
|
start_date,
|
|
70
67
|
end_date,
|
|
71
|
-
|
|
72
|
-
pluck_columns: ["SUM(total)"],
|
|
68
|
+
difference_where_conditions: difference_where_conditions,
|
|
73
69
|
).first
|
|
74
70
|
|
|
75
71
|
prev_total = fetch_records(
|
|
76
72
|
prev_start_date,
|
|
77
73
|
prev_end_date,
|
|
78
|
-
|
|
79
|
-
pluck_columns: ["SUM(total)"],
|
|
74
|
+
difference_where_conditions: difference_where_conditions,
|
|
80
75
|
).first
|
|
81
76
|
|
|
82
77
|
if prev_total
|
|
@@ -90,36 +85,69 @@ module RailsLocalAnalytics
|
|
|
90
85
|
|
|
91
86
|
private
|
|
92
87
|
|
|
93
|
-
def fetch_records(start_date, end_date,
|
|
88
|
+
def fetch_records(start_date, end_date, difference_where_conditions: nil)
|
|
89
|
+
aggregate_sql_field = "SUM(total)"
|
|
90
|
+
|
|
94
91
|
tracked_requests = @klass
|
|
95
92
|
.where("day >= ?", start_date)
|
|
96
93
|
.where("day <= ?", end_date)
|
|
97
|
-
.order(
|
|
94
|
+
.order("#{aggregate_sql_field} DESC")
|
|
98
95
|
|
|
99
|
-
if
|
|
96
|
+
if difference_where_conditions
|
|
97
|
+
tracked_requests = tracked_requests.where(difference_where_conditions)
|
|
98
|
+
else
|
|
100
99
|
tracked_requests = tracked_requests
|
|
101
100
|
.limit(PER_PAGE_LIMIT)
|
|
102
101
|
.offset(PER_PAGE_LIMIT * (pagination_page_number-1))
|
|
103
|
-
end
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
if params[:filter].present?
|
|
104
|
+
col, val = params[:filter].split("==")
|
|
105
|
+
|
|
106
|
+
if display_columns.include?(col)
|
|
107
|
+
tracked_requests = tracked_requests.where(col => val)
|
|
108
|
+
else
|
|
109
|
+
raise ArgumentError
|
|
110
|
+
end
|
|
111
|
+
end
|
|
107
112
|
end
|
|
108
113
|
|
|
109
114
|
if params[:search].present?
|
|
110
115
|
tracked_requests = tracked_requests.multi_search(params[:search])
|
|
111
116
|
end
|
|
112
117
|
|
|
113
|
-
if params[:group_by].
|
|
114
|
-
|
|
115
|
-
pluck_columns = [params[:group_by], "SUM(total)"]
|
|
118
|
+
if params[:group_by].blank?
|
|
119
|
+
pluck_columns = display_columns.dup
|
|
116
120
|
else
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
case params[:group_by]
|
|
122
|
+
when "url_hostname_and_path"
|
|
123
|
+
if display_columns.include?("url_hostname") && display_columns.include?("url_path")
|
|
124
|
+
pluck_columns = [:url_hostname, :url_path]
|
|
125
|
+
else
|
|
126
|
+
raise ArgumentError
|
|
127
|
+
end
|
|
128
|
+
when "referrer_hostname_and_path"
|
|
129
|
+
if display_columns.include?("referrer_hostname") && display_columns.include?("referrer_path")
|
|
130
|
+
pluck_columns = [:referrer_hostname, :referrer_path]
|
|
131
|
+
else
|
|
132
|
+
raise ArgumentError
|
|
133
|
+
end
|
|
134
|
+
when *display_columns
|
|
135
|
+
pluck_columns = [params[:group_by]]
|
|
136
|
+
else
|
|
137
|
+
raise ArgumentError
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
group_by = pluck_columns.dup
|
|
142
|
+
|
|
143
|
+
if difference_where_conditions
|
|
144
|
+
pluck_columns = [aggregate_sql_field]
|
|
145
|
+
else
|
|
146
|
+
pluck_columns << aggregate_sql_field
|
|
119
147
|
end
|
|
120
148
|
|
|
121
149
|
tracked_requests
|
|
122
|
-
.group(*
|
|
150
|
+
.group(*group_by)
|
|
123
151
|
.pluck(*pluck_columns)
|
|
124
152
|
end
|
|
125
153
|
|
|
@@ -141,5 +169,9 @@ module RailsLocalAnalytics
|
|
|
141
169
|
return [prev_start_date, prev_end_date]
|
|
142
170
|
end
|
|
143
171
|
|
|
172
|
+
def display_columns
|
|
173
|
+
@display_columns ||= @klass.display_columns
|
|
174
|
+
end
|
|
175
|
+
|
|
144
176
|
end
|
|
145
177
|
end
|
|
@@ -1,31 +1,76 @@
|
|
|
1
|
-
<%
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
<%
|
|
2
|
+
data_columns = params[:group_by].present? ? [params[:group_by]] : display_columns
|
|
3
|
+
|
|
4
|
+
if data_columns.first == "url_hostname_and_path"
|
|
5
|
+
data_columns = ["URL Hostname", "URL Path"]
|
|
6
|
+
elsif data_columns.first == "referrer_hostname_and_path"
|
|
7
|
+
data_columns = ["Referrer Hostname", "Referrer Path"]
|
|
8
|
+
end
|
|
9
|
+
%>
|
|
10
|
+
|
|
11
|
+
<%
|
|
12
|
+
group_by_opts = [
|
|
13
|
+
["All", nil],
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
group_by_opts += display_columns.map{|x| [x.titleize.sub("Url ", "URL "), x] }
|
|
17
|
+
|
|
18
|
+
if display_columns.include?("url_hostname") && display_columns.include?("url_path")
|
|
19
|
+
index = group_by_opts.index(["URL Hostname", "url_hostname"])
|
|
20
|
+
group_by_opts.insert(
|
|
21
|
+
index,
|
|
22
|
+
["URL Hostname and Path", "url_hostname_and_path"],
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if display_columns.include?("referrer_hostname") && display_columns.include?("referrer_path")
|
|
27
|
+
index = group_by_opts.index(["Referrer Hostname", "referrer_hostname"])
|
|
28
|
+
group_by_opts.insert(
|
|
29
|
+
index,
|
|
30
|
+
["Referrer Hostname and Path", "referrer_hostname_and_path"],
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
%>
|
|
34
|
+
|
|
35
|
+
<div class="well well-sm">
|
|
36
|
+
<%= form_tag url_for(params.except(:start_date, :to).to_unsafe_hash), method: "get", id: "search-form" do %>
|
|
37
|
+
<div>
|
|
38
|
+
<label style="margin-right: 10px;">Group By: <%= select_tag :group_by, options_for_select(group_by_opts, params[:group_by]) %></label>
|
|
39
|
+
|
|
40
|
+
<label style="margin-right: 10px;">From: <%= date_field_tag :start_date, @start_date %></label>
|
|
41
|
+
<label style="margin-right: 10px;">To: <%= date_field_tag :end_date, @end_date %></label>
|
|
42
|
+
|
|
43
|
+
<label style="margin-right: 10px;">Search: <%= text_field_tag :search, params[:search] %></label>
|
|
44
|
+
<% end %>
|
|
9
45
|
|
|
10
|
-
|
|
11
|
-
|
|
46
|
+
<% if params[:filter] %>
|
|
47
|
+
<div>
|
|
48
|
+
<label>Active Filter:</label>
|
|
49
|
+
<div class="badge badge-primary" style="margin-top: 5px; margin-bottom: 10px;">
|
|
50
|
+
<% filter_col, filter_val = params[:filter].split("==") %>
|
|
51
|
+
<%= filter_col.titleize.sub("Url ", "URL ") %> = "<%= filter_val %>"
|
|
52
|
+
</div>
|
|
53
|
+
<%= link_to "Remove Filter", url_for(params.to_unsafe_h.merge(filter: nil)) %>
|
|
54
|
+
</div>
|
|
55
|
+
<% end %>
|
|
12
56
|
|
|
13
57
|
<div>
|
|
14
|
-
<%= link_to "Today", url_for(params.merge(start_date: Date.today, end_date: Date.today).to_unsafe_hash) %>
|
|
58
|
+
<%= link_to "Today", url_for(params.merge(start_date: Date.today, end_date: Date.today).to_unsafe_hash), style: ("font-weight: bold;" if @start_date == Date.today && @end_date == Date.today) %>
|
|
15
59
|
|
|
|
16
|
-
|
|
60
|
+
<% yesterday = Date.today - 1.day %>
|
|
61
|
+
<%= link_to "Yesterday", url_for(params.merge(start_date: yesterday, end_date: yesterday).to_unsafe_hash), style: ("font-weight: bold;" if @start_date == yesterday && @end_date == yesterday) %>
|
|
17
62
|
|
|
|
18
|
-
<%= link_to "Last 7 days", url_for(params.merge(start_date: 7.days.ago.to_date, end_date: Date.today).to_unsafe_hash) %>
|
|
63
|
+
<%= link_to "Last 7 days", url_for(params.merge(start_date: 7.days.ago.to_date, end_date: Date.today).to_unsafe_hash), style: ("font-weight: bold;" if @start_date == 7.days.ago.to_date && @end_date == Date.today) %>
|
|
19
64
|
|
|
|
20
|
-
<%= link_to "Last 30 days", url_for(params.merge(start_date: 30.days.ago.to_date, end_date: Date.today).to_unsafe_hash) %>
|
|
65
|
+
<%= link_to "Last 30 days", url_for(params.merge(start_date: 30.days.ago.to_date, end_date: Date.today).to_unsafe_hash), style: ("font-weight: bold;" if @start_date == 30.days.ago.to_date && @end_date == Date.today) %>
|
|
21
66
|
|
|
|
22
|
-
<%= link_to "Last 3 Months", url_for(params.merge(start_date: 3.months.ago.to_date, end_date: Date.today).to_unsafe_hash) %>
|
|
67
|
+
<%= link_to "Last 3 Months", url_for(params.merge(start_date: 3.months.ago.to_date, end_date: Date.today).to_unsafe_hash), style: ("font-weight: bold;" if @start_date == 3.months.ago.to_date && @end_date == Date.today) %>
|
|
23
68
|
|
|
|
24
|
-
<%= link_to "Last 6 Months", url_for(params.merge(start_date: 6.months.ago.to_date, end_date: Date.today).to_unsafe_hash) %>
|
|
69
|
+
<%= link_to "Last 6 Months", url_for(params.merge(start_date: 6.months.ago.to_date, end_date: Date.today).to_unsafe_hash), style: ("font-weight: bold;" if @start_date == 6.months.ago.to_date && @end_date == Date.today) %>
|
|
25
70
|
|
|
|
26
|
-
<%= link_to "Last Year", url_for(params.merge(start_date: 1.year.ago.to_date, end_date: Date.today).to_unsafe_hash) %>
|
|
71
|
+
<%= link_to "Last Year", url_for(params.merge(start_date: 1.year.ago.to_date, end_date: Date.today).to_unsafe_hash), style: ("font-weight: bold;" if @start_date == 1.year.ago.to_date && @end_date == Date.today) %>
|
|
27
72
|
</div>
|
|
28
|
-
|
|
73
|
+
</div>
|
|
29
74
|
|
|
30
75
|
<h2>Requests by <%= params[:type].titleize %></h2>
|
|
31
76
|
|
|
@@ -33,7 +78,7 @@
|
|
|
33
78
|
<thead>
|
|
34
79
|
<% data_columns.each do |header| %>
|
|
35
80
|
<th>
|
|
36
|
-
<%= header.sub("Url ", "URL ") %>
|
|
81
|
+
<%= header.titleize.sub("Url ", "URL ") %>
|
|
37
82
|
</th>
|
|
38
83
|
<% end %>
|
|
39
84
|
|
|
@@ -42,22 +87,23 @@
|
|
|
42
87
|
</th>
|
|
43
88
|
|
|
44
89
|
<th>
|
|
45
|
-
|
|
90
|
+
Prev Period Difference
|
|
46
91
|
</th>
|
|
47
92
|
</thead>
|
|
48
93
|
|
|
49
94
|
<tbody>
|
|
50
95
|
<% @results.each_with_index do |row, row_index| %>
|
|
51
96
|
<tr>
|
|
52
|
-
<% row[0..-2].
|
|
97
|
+
<% row[0..-2].each_with_index do |value, col_index| %>
|
|
53
98
|
<td>
|
|
54
|
-
|
|
99
|
+
<% filter_param = "#{data_columns[col_index]}==#{value}" %>
|
|
100
|
+
<%= link_to (value || ""), url_for(params.to_unsafe_h.merge(filter: filter_param)), title: "Filter" %>
|
|
55
101
|
</td>
|
|
56
102
|
<% end %>
|
|
57
103
|
|
|
58
104
|
<td>
|
|
59
105
|
<% total = row.last %>
|
|
60
|
-
<%= total
|
|
106
|
+
<%= number_with_delimiter(total) %>
|
|
61
107
|
</td>
|
|
62
108
|
|
|
63
109
|
<td>
|
|
@@ -85,7 +131,7 @@
|
|
|
85
131
|
<% prev_period_row_index = @prev_period_results.index{|prev_period_row| row[0..-2] == prev_period_row[0..-2] } %>
|
|
86
132
|
|
|
87
133
|
<% if prev_period_row_index.nil? %>
|
|
88
|
-
+<%= total
|
|
134
|
+
+<%= number_with_delimiter(total) %>
|
|
89
135
|
<% else %>
|
|
90
136
|
<% prev_period_row = @prev_period_results.delete_at(prev_period_row_index) %>
|
|
91
137
|
|
|
@@ -93,9 +139,9 @@
|
|
|
93
139
|
<% diff = total - prev_period_total %>
|
|
94
140
|
|
|
95
141
|
<% if diff >= 0 %>
|
|
96
|
-
+<%= diff
|
|
142
|
+
+<%= number_with_delimiter(diff) %>
|
|
97
143
|
<% else %>
|
|
98
|
-
<%= diff
|
|
144
|
+
<%= number_with_delimiter(diff) %>
|
|
99
145
|
<% end %>
|
|
100
146
|
<% end %>
|
|
101
147
|
<% end %>
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_local_analytics
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Weston Ganger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-12-
|
|
11
|
+
date: 2024-12-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rspec-html-matchers
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: database_cleaner
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -97,7 +111,6 @@ files:
|
|
|
97
111
|
- app/controllers/rails_local_analytics/dashboard_controller.rb
|
|
98
112
|
- app/jobs/rails_local_analytics/application_job.rb
|
|
99
113
|
- app/jobs/rails_local_analytics/record_request_job.rb
|
|
100
|
-
- app/lib/rails_local_analytics/histogram.rb
|
|
101
114
|
- app/models/rails_local_analytics/application_record.rb
|
|
102
115
|
- app/models/tracked_requests_by_day_page.rb
|
|
103
116
|
- app/models/tracked_requests_by_day_site.rb
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
module RailsLocalAnalytics
|
|
2
|
-
class Histogram
|
|
3
|
-
attr_reader :bars, :from_date, :to_date
|
|
4
|
-
|
|
5
|
-
def initialize(scope, from_date, to_date)
|
|
6
|
-
@scope = scope
|
|
7
|
-
@from_date, @to_date = from_date, to_date
|
|
8
|
-
@bars = scope.map { |record| Bar.new(record.date, record.total, self) }
|
|
9
|
-
fill_missing_days(@bars, @from_date, @to_date)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def fill_missing_days(bars, from, to)
|
|
13
|
-
i = 0
|
|
14
|
-
while (day = from + i) <= to
|
|
15
|
-
if !@bars[i] || @bars[i].label != day
|
|
16
|
-
@bars.insert(i, Bar.new(day, 0, self))
|
|
17
|
-
end
|
|
18
|
-
i += 1
|
|
19
|
-
end
|
|
20
|
-
@bars
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def max_value
|
|
24
|
-
@max_total ||= bars.map(&:value).max
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def total
|
|
28
|
-
@bars.reduce(0) { |sum, bar| sum += bar.value }
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
class Bar
|
|
32
|
-
attr_reader :label, :value, :histogram
|
|
33
|
-
|
|
34
|
-
def initialize(label, value, histogram)
|
|
35
|
-
@label, @value, @histogram = label, value, histogram
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def height
|
|
39
|
-
if histogram.max_value > 0
|
|
40
|
-
(value.to_f / histogram.max_value).round(2)
|
|
41
|
-
else
|
|
42
|
-
0
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|