active_analytics 0.1.0

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 (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