active_analytics 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +53 -0
  4. data/Rakefile +18 -0
  5. data/app/assets/config/active_analytics_manifest.js +1 -0
  6. data/app/assets/javascripts/active_analytics/application.js +3 -0
  7. data/app/assets/javascripts/active_analytics/ariato.js +746 -0
  8. data/app/assets/stylesheets/active_analytics/application.css +33 -0
  9. data/app/assets/stylesheets/active_analytics/ariato.css +3548 -0
  10. data/app/assets/stylesheets/active_analytics/charts.css +2606 -0
  11. data/app/controllers/active_analytics/application_controller.rb +4 -0
  12. data/app/controllers/active_analytics/pages_controller.rb +22 -0
  13. data/app/controllers/active_analytics/referrers_controller.rb +18 -0
  14. data/app/controllers/active_analytics/sites_controller.rb +16 -0
  15. data/app/helpers/active_analytics/application_helper.rb +4 -0
  16. data/app/helpers/active_analytics/pages_helper.rb +15 -0
  17. data/app/helpers/active_analytics/referrers_helper.rb +4 -0
  18. data/app/helpers/active_analytics/sites_helper.rb +4 -0
  19. data/app/jobs/active_analytics/application_job.rb +4 -0
  20. data/app/mailers/active_analytics/application_mailer.rb +6 -0
  21. data/app/models/active_analytics/application_record.rb +5 -0
  22. data/app/models/active_analytics/views_per_day.rb +100 -0
  23. data/app/views/active_analytics/pages/_table.html.erb +21 -0
  24. data/app/views/active_analytics/pages/index.html.erb +12 -0
  25. data/app/views/active_analytics/pages/show.html.erb +23 -0
  26. data/app/views/active_analytics/referrers/_table.html.erb +14 -0
  27. data/app/views/active_analytics/referrers/index.html.erb +8 -0
  28. data/app/views/active_analytics/referrers/show.html.erb +14 -0
  29. data/app/views/active_analytics/sites/_histogram.html.erb +19 -0
  30. data/app/views/active_analytics/sites/index.html.erb +7 -0
  31. data/app/views/active_analytics/sites/show.html.erb +16 -0
  32. data/app/views/layouts/active_analytics/_footer.html.erb +6 -0
  33. data/app/views/layouts/active_analytics/_header.html.erb +25 -0
  34. data/app/views/layouts/active_analytics/application.html.erb +19 -0
  35. data/config/routes.rb +13 -0
  36. data/db/migrate/20210303094108_create_active_analytics_views_per_days.rb +20 -0
  37. data/lib/active_analytics.rb +22 -0
  38. data/lib/active_analytics/engine.rb +5 -0
  39. data/lib/active_analytics/version.rb +3 -0
  40. data/lib/tasks/active_analytics_tasks.rake +4 -0
  41. metadata +100 -0
@@ -0,0 +1,4 @@
1
+ module ActiveAnalytics
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,22 @@
1
+ require_dependency "active_analytics/application_controller"
2
+
3
+ module ActiveAnalytics
4
+ class PagesController < ApplicationController
5
+ include PagesHelper
6
+
7
+ def index
8
+ scope = ViewsPerDay.where(site: params[:site]).after(30.days.ago)
9
+ @histogram = ViewsPerDay::Histogram.new(scope.order_by_date.group_by_date)
10
+ @pages = scope.top(100).group_by_page
11
+ end
12
+
13
+ def show
14
+ scope = ViewsPerDay.where(site: params[:site], page: page_from_params).after(30.days.ago)
15
+ @histogram = ViewsPerDay::Histogram.new(scope.order_by_date.group_by_date)
16
+ @referrers = scope.top.group_by_referrer_site
17
+
18
+ @next_pages = ViewsPerDay.where(referrer_host: params[:site], referrer_path: page_from_params).top.group_by_page
19
+ @previous_pages = ViewsPerDay.where(site: params[:site], page: page_from_params).top.group_by_referrer_page
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require_dependency "active_analytics/application_controller"
2
+
3
+ module ActiveAnalytics
4
+ class ReferrersController < ApplicationController
5
+ def index
6
+ scope = ViewsPerDay.where(site: params[:site])
7
+ @referrers = scope.top(100).group_by_referrer_site
8
+ @histogram = ViewsPerDay::Histogram.new(scope.order_by_date.group_by_date)
9
+ end
10
+
11
+ def show
12
+ scope = ViewsPerDay.where(site: params[:site], referrer_host: params[:referrer])
13
+ @histogram = ViewsPerDay::Histogram.new(scope.order_by_date.group_by_date)
14
+ @previous_pages = scope.top(100).group_by_referrer_page
15
+ @next_pages = scope.top(100).group_by_page
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ require_dependency "active_analytics/application_controller"
2
+
3
+ module ActiveAnalytics
4
+ class SitesController < ApplicationController
5
+ def index
6
+ @sites = ViewsPerDay.after(30.days.ago).order_by_totals.group_by_site
7
+ end
8
+
9
+ def show
10
+ scope = ViewsPerDay.where(site: params[:site]).after(30.days.ago)
11
+ @histogram = ViewsPerDay::Histogram.new(scope.order_by_date.group_by_date)
12
+ @referrers = scope.top.group_by_referrer_site
13
+ @pages = scope.top.group_by_page
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveAnalytics
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ module ActiveAnalytics
2
+ module PagesHelper
3
+ def page_to_params(name)
4
+ name == "/" ? "index" : name[1..-1]
5
+ end
6
+
7
+ def page_from_params
8
+ if params[:page] == "index"
9
+ "/"
10
+ elsif params[:page].present?
11
+ "/#{params[:page]}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveAnalytics
2
+ module ReferrersHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveAnalytics
2
+ module SitesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveAnalytics
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module ActiveAnalytics
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveAnalytics
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,100 @@
1
+ module ActiveAnalytics
2
+ class ViewsPerDay < ApplicationRecord
3
+ validates_presence_of :site, :page, :date
4
+
5
+ scope :after, -> (date) { where("date > ?", date) }
6
+ scope :order_by_totals, -> { order(Arel.sql("SUM(total) DESC")) }
7
+ scope :order_by_date, -> { order(:date) }
8
+ scope :top, -> (n = 10) { order_by_totals.limit(n) }
9
+
10
+ class Site
11
+ attr_reader :host, :total
12
+ def initialize(host, total)
13
+ @host, @total = host, total
14
+ end
15
+ end
16
+
17
+ class Page
18
+ attr_reader :host, :path, :total
19
+ def initialize(host, path, total)
20
+ @host, @path, @total = host, path, total
21
+ end
22
+
23
+ def url
24
+ host + path
25
+ end
26
+ end
27
+
28
+ class Day
29
+ attr_reader :day, :total
30
+ def initialize(day, total)
31
+ @day, @total = day, total
32
+ end
33
+ end
34
+
35
+ class Histogram
36
+ attr_reader :bars
37
+
38
+ def initialize(scope)
39
+ @bars = scope.map { |day| Bar.new(day.day, day.total, self) }
40
+ end
41
+
42
+ def max_value
43
+ @max_total ||= bars.map(&:value).max
44
+ end
45
+
46
+ class Bar
47
+ attr_reader :label, :value, :histogram
48
+
49
+ def initialize(label, value, histogram)
50
+ @label, @value,@histogram = label, value, histogram
51
+ end
52
+
53
+ def height
54
+ (value.to_f / histogram.max_value).round(2)
55
+ end
56
+ end
57
+ end
58
+
59
+ def self.group_by_site
60
+ group(:site).pluck("site, SUM(total)").map do |row|
61
+ Site.new(row[0], row[1])
62
+ end
63
+ end
64
+
65
+ def self.group_by_page
66
+ group(:site, :page).pluck("site, page, SUM(total)").map do |row|
67
+ Page.new(row[0], row[1], row[2])
68
+ end
69
+ end
70
+
71
+ def self.group_by_referrer_site
72
+ group(:referrer_host).pluck("referrer_host, SUM(total)").map do |row|
73
+ Site.new(row[0], row[1])
74
+ end
75
+ end
76
+
77
+ def self.group_by_referrer_page
78
+ group(:referrer_host, :referrer_path).pluck("referrer_host, referrer_path, SUM(total)").map do |row|
79
+ Page.new(row[0], row[1], row[2])
80
+ end
81
+ end
82
+
83
+ def self.group_by_date
84
+ group(:date).pluck("date, SUM(total)").map do |row|
85
+ Day.new(row[0], row[1])
86
+ end
87
+ end
88
+
89
+ def self.to_histogram
90
+ ViewsPerDay::Histogram.new(self)
91
+ end
92
+
93
+ def self.append(params)
94
+ vpd = find_or_initialize_by(params)
95
+ vpd.referrer_path = nil if vpd.referrer_path?
96
+ vpd.total += 1 if vpd.persisted?
97
+ vpd.save!
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,21 @@
1
+ <table>
2
+ <% for page in pages %>
3
+ <tr>
4
+ <td>
5
+ <% if page.host == params[:site] %>
6
+ <% if page.path.present? %>
7
+ <%= link_to page.path, page_path(site: page.host, page: page_to_params(page.path)) %>
8
+ <% else %>
9
+ <%= link_to page.host, site_path(site: page.host) %>
10
+ <small>(page not provided <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#strict-origin-when-cross-origin">?</a>)</small>
11
+ <% end %>
12
+ <% elsif page.host.present? && page.path.present? %>
13
+ <%= page.url %>
14
+ <% else %>
15
+ (None or direct)
16
+ <% end %>
17
+ </td>
18
+ <td><%= page.total %></td>
19
+ </tr>
20
+ <% end %>
21
+ </table>
@@ -0,0 +1,12 @@
1
+ <section>
2
+ <h2>Pages</h2>
3
+ </section>
4
+
5
+ <section>
6
+ <%= render "/active_analytics/sites/histogram", histogram: @histogram %>
7
+ </section>
8
+
9
+ <section>
10
+ <h3>Pages</h3>
11
+ <%= render "/active_analytics/pages/table", pages: @pages %>
12
+ </section>
@@ -0,0 +1,23 @@
1
+ <section>
2
+ <h2><%= page_from_params %></h2>
3
+ </section>
4
+
5
+ <section>
6
+ <h3>Views per day</h3>
7
+ <%= render "/active_analytics/sites/histogram", histogram: @histogram %>
8
+ </section>
9
+
10
+ <section>
11
+ <h3>Top referrers</h3>
12
+ <%= render "/active_analytics/referrers/table", referrers: @referrers %>
13
+ </section>
14
+
15
+ <section>
16
+ <h3>Previous Pages</h3>
17
+ <%= render "table", pages: @previous_pages %>
18
+ </section>
19
+
20
+ <section>
21
+ <h3>Next Pages</h3>
22
+ <%= render "table", pages: @next_pages %>
23
+ </section>
@@ -0,0 +1,14 @@
1
+ <table>
2
+ <% for referrer in referrers %>
3
+ <tr>
4
+ <td>
5
+ <% if referrer.host %>
6
+ <%= link_to referrer.host, referrer_path(site: params[:site], referrer: referrer.host) %>
7
+ <% else %>
8
+ <%= referrer.host %>
9
+ <% end %>
10
+ </td>
11
+ <td><%= referrer.total %></td>
12
+ </tr>
13
+ <% end %>
14
+ </table>
@@ -0,0 +1,8 @@
1
+ <section>
2
+ <h2>Referrers</h2>
3
+ <%= render "/active_analytics/sites/histogram", histogram: @histogram %>
4
+ </section>
5
+
6
+ <section>
7
+ <%= render "table", referrers: @referrers %>
8
+ </section>
@@ -0,0 +1,14 @@
1
+ <section>
2
+ <h2>Referrer <%= params[:referrer] %></h2>
3
+ <%= render "/active_analytics/sites/histogram", histogram: @histogram %>
4
+ </section>
5
+
6
+ <section>
7
+ <h3>Sources</h3>
8
+ <%= render "/active_analytics/pages/table", pages: @previous_pages %>
9
+ </section>
10
+
11
+ <section>
12
+ <h3>Destinations</h3>
13
+ <%= render "/active_analytics/pages/table", pages: @next_pages %>
14
+ </section>
@@ -0,0 +1,19 @@
1
+ <table class="charts-css column show-5-secondary-axes show-data-on-hover show-labels" style="height: calc(var(--space-2x) * 10);">
2
+ <thead>
3
+ <tr>
4
+ <th scope="col">Day</th>
5
+ <th scope="col">Views</th>
6
+ </tr>
7
+ </thead>
8
+
9
+ <tbody>
10
+ <% for bar in histogram.bars %>
11
+ <tr>
12
+ <th scope="row"><%= l bar.label, format: :short %></td>
13
+ <td style="--size: <%= bar.height %>; --color: rgb(240,241,243);">
14
+ <span class="data"><%= bar.value.to_i %></span>
15
+ </td>
16
+ </tr>
17
+ <% end %>
18
+ </tbody>
19
+ </table>
@@ -0,0 +1,7 @@
1
+ <h1>Sites</h1>
2
+
3
+ <ul>
4
+ <% for site in @sites %>
5
+ <li><%= link_to site.host, site_path(site: site.host) %> <%= site.total %></li>
6
+ <% end %>
7
+ </ul>
@@ -0,0 +1,16 @@
1
+ <section>
2
+ <h3>Views per day</h3>
3
+ <%= render "/active_analytics/sites/histogram", histogram: @histogram %>
4
+ </section>
5
+
6
+ <section>
7
+ <h3>Top Pages</h3>
8
+ <%= render "/active_analytics/pages/table", pages: @pages %>
9
+ <p style="text-align: center;"><br/><%= link_to "More pages", pages_path, role: "button"%></p>
10
+ </section>
11
+
12
+ <section>
13
+ <h3>Top referrers</h3>
14
+ <%= render "/active_analytics/referrers/table", referrers: @referrers %>
15
+ <p style="text-align: center;"><br/><%= link_to "More referrers", referrers_path, role: "button" %></p>
16
+ </section>
@@ -0,0 +1,6 @@
1
+ <footer>
2
+ <p>
3
+ Made in <a href="https://www.basesecrete.com">Base Secrète</a> |
4
+ <%= link_to "Source code", "https://github.com/BaseSecrete/active_analytics" %>
5
+ </p>
6
+ </footer>
@@ -0,0 +1,25 @@
1
+ <header>
2
+ <nav aria-label="site"> <!-- implicit role="navigation", aria label "site" is announced = "site navigation" -->
3
+ <div role="toolbar" data-ariato="Application.Toolbar">
4
+ <div role="group">
5
+ <%= link_to "Analytics", active_analytics_path, role: "button" %>
6
+ <% if params[:site] %>
7
+ <div class="menubutton">
8
+ <button type="button" id="site-menu-button" aria-haspopup="true" aria-controls="site-menu"><%= params[:site] %></button>
9
+ <ul id="site-menu" role="menu" aria-labelledby="site-menu-button">
10
+ <li role="none">
11
+ <%= link_to "Site", site_path(params[:site]), role: "menuitem", tabindex: -1 %>
12
+ </li>
13
+ <li role="none">
14
+ <%= link_to "Pages", pages_path, role: "menuitem", tabindex: -1 %>
15
+ </li>
16
+ <li role="none">
17
+ <%= link_to "Referrers", referrers_path, role: "menuitem", tabindex: -1 %>
18
+ </li>
19
+ </ul>
20
+ </div>
21
+ <% end %>
22
+ </div>
23
+ </div>
24
+ </nav>
25
+ </header>
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Active analytics</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "active_analytics/application", media: "all" %>
9
+ <%= javascript_include_tag "active_analytics/application" %>
10
+ </head>
11
+
12
+ <body>
13
+ <%= render "/layouts/active_analytics/header" %>
14
+ <main aria-label="Content">
15
+ <%= yield %>
16
+ </main>
17
+ <%= render "/layouts/active_analytics/footer" %>
18
+ </body>
19
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,13 @@
1
+ ActiveAnalytics::Engine.routes.draw do
2
+ get "/:site", to: "sites#show", as: :site, constraints: {site: /[^\/]+/}
3
+
4
+ # Referrers
5
+ get "/:site/referrers", to: "referrers#index", constraints: {site: /[^\/]+/}, as: :referrers
6
+ get "/:site/referrers/:referrer", to: "referrers#show", constraints: {site: /[^\/]+/, referrer: /[^\/]+/}, as: :referrer
7
+
8
+ # Pages
9
+ get "/:site/pages", to: "pages#index", constraints: {site: /[^\/]+/}, as: :pages
10
+ get "/:site/*page", to: "pages#show", as: :page, constraints: {site: /[^\/]+/}
11
+
12
+ root to: "sites#index", as: :active_analytics
13
+ end