[Git][noosfero/noosfero][master] analytics: measure time on page
Bráulio Bhavamitra
gitlab at gitlab.com
Fri Aug 28 20:47:20 BRT 2015
Bráulio Bhavamitra pushed to branch master at Noosfero / noosfero
Commits:
492c3d63 by Braulio Bhavamitra at 2015-08-28T20:17:16Z
analytics: measure time on page
- - - - -
12 changed files:
- + plugins/analytics/controllers/myprofile/analytics_plugin/stats_controller.rb
- plugins/analytics/lib/analytics_plugin.rb
- plugins/analytics/lib/analytics_plugin/base.rb
- plugins/analytics/lib/ext/profile.rb
- plugins/analytics/locales/en.yml
- plugins/analytics/locales/pt.yml
- plugins/analytics/models/analytics_plugin/page_view.rb
- plugins/analytics/models/analytics_plugin/visit.rb
- plugins/analytics/test/functional/content_viewer_controller_test.rb
- plugins/analytics/views/analytics_plugin/_body_ending.html.slim
- + plugins/analytics/views/analytics_plugin/stats/_table.html.slim
- + plugins/analytics/views/analytics_plugin/stats/index.html.slim
Changes:
=====================================
plugins/analytics/controllers/myprofile/analytics_plugin/stats_controller.rb
=====================================
--- /dev/null
+++ b/plugins/analytics/controllers/myprofile/analytics_plugin/stats_controller.rb
@@ -0,0 +1,21 @@
+class AnalyticsPlugin::StatsController < MyProfileController
+
+ no_design_blocks
+
+ before_filter :skip_page_view
+
+ def index
+ end
+
+ protected
+
+ def default_url_options
+ # avoid rails' use_relative_controller!
+ {use_route: '/'}
+ end
+
+ def skip_page_view
+ @analytics_skip_page_view = true
+ end
+
+end
=====================================
plugins/analytics/lib/analytics_plugin.rb
=====================================
--- a/plugins/analytics/lib/analytics_plugin.rb
+++ b/plugins/analytics/lib/analytics_plugin.rb
@@ -1,6 +1,7 @@
module AnalyticsPlugin
- TimeOnPageUpdateInterval = 2.minutes * 1000
+ TimeOnPageUpdateInterval = 2.minutes
+ TimeOnPageUpdateIntervalMs = TimeOnPageUpdateInterval * 1000
extend Noosfero::Plugin::ParentMethods
=====================================
plugins/analytics/lib/analytics_plugin/base.rb
=====================================
--- a/plugins/analytics/lib/analytics_plugin/base.rb
+++ b/plugins/analytics/lib/analytics_plugin/base.rb
@@ -28,8 +28,7 @@ class AnalyticsPlugin::Base < Noosfero::Plugin
unless profile.analytics_anonymous?
# FIXME: use session.id in Rails 4
- session_id = Marshal.load(Base64.decode64 request['_session_id'])['session_id'] rescue nil
- #session_id = request.session_options[:id]
+ session_id = request.session_options[:id]
page_view.user = user
page_view.session_id = session_id
end
@@ -40,4 +39,12 @@ class AnalyticsPlugin::Base < Noosfero::Plugin
}]
end
+ def control_panel_buttons
+ {
+ title: I18n.t('analytics_plugin.lib.plugin.panel_button'),
+ icon: 'analytics-access',
+ url: {controller: 'analytics_plugin/stats', action: :index}
+ }
+ end
+
end
=====================================
plugins/analytics/lib/ext/profile.rb
=====================================
--- a/plugins/analytics/lib/ext/profile.rb
+++ b/plugins/analytics/lib/ext/profile.rb
@@ -13,7 +13,7 @@ end
class Profile
def analytics_settings attrs = {}
- @analytics_settings ||= Noosfero::Plugin::Settings.new self, AnalyticsPlugin, attrs
+ @analytics_settings ||= Noosfero::Plugin::Settings.new self, ::AnalyticsPlugin, attrs
attrs.each{ |a, v| @analytics_settings.send "#{a}=", v }
@analytics_settings
end
=====================================
plugins/analytics/locales/en.yml
=====================================
--- a/plugins/analytics/locales/en.yml
+++ b/plugins/analytics/locales/en.yml
@@ -5,6 +5,13 @@ en: &en
plugin:
name: 'Access tracking'
description: 'Register the access of selected profiles'
+ panel_button: 'Access tracking'
+
+ views:
+ stats:
+ user: 'User'
+ initial_time: 'Time'
+ pages: 'Pages'
en-US:
<<: *en
=====================================
plugins/analytics/locales/pt.yml
=====================================
--- a/plugins/analytics/locales/pt.yml
+++ b/plugins/analytics/locales/pt.yml
@@ -5,6 +5,13 @@ pt: &pt
plugin:
name: 'Rastreio de accesso'
description: 'Registra o acesso de perfis selecionados'
+ panel_button: 'Rastreio de accesso'
+
+ views:
+ stats:
+ user: 'Usuário'
+ initial_time: 'Horário'
+ pages: 'Páginas'
pt-BR:
<<: *pt
=====================================
plugins/analytics/models/analytics_plugin/page_view.rb
=====================================
--- a/plugins/analytics/models/analytics_plugin/page_view.rb
+++ b/plugins/analytics/models/analytics_plugin/page_view.rb
@@ -25,10 +25,24 @@ class AnalyticsPlugin::PageView < ActiveRecord::Base
before_validation :fill_referer_page_view, on: :create
before_validation :fill_visit, on: :create
+ scope :latest, -> { order 'request_started_at DESC' }
+
def request_duration
self.request_finished_at - self.request_started_at
end
+ def initial_time
+ self.page_loaded_at || self.request_finished_at
+ end
+
+ def user_last_time_seen
+ self.initial_time + self.time_on_page
+ end
+
+ def user_on_page?
+ Time.now < self.user_last_time_seen + AnalyticsPlugin::TimeOnPageUpdateInterval
+ end
+
def page_load!
self.page_loaded_at = Time.now
self.update_column :page_loaded_at, self.page_loaded_at
@@ -36,10 +50,9 @@ class AnalyticsPlugin::PageView < ActiveRecord::Base
def increase_time_on_page!
now = Time.now
- initial_time = self.page_loaded_at || self.request_finished_at
- return unless now > initial_time
+ return unless now > self.initial_time
- self.time_on_page = now - initial_time
+ self.time_on_page = now - self.initial_time
self.update_column :time_on_page, self.time_on_page
end
@@ -59,7 +72,7 @@ class AnalyticsPlugin::PageView < ActiveRecord::Base
end
def fill_visit
- self.visit = self.referer_page_view.visit if self.referer_page_view
+ self.visit = self.referer_page_view.visit if self.referer_page_view and self.referer_page_view.user_on_page?
self.visit ||= AnalyticsPlugin::Visit.new profile: profile
end
=====================================
plugins/analytics/models/analytics_plugin/visit.rb
=====================================
--- a/plugins/analytics/models/analytics_plugin/visit.rb
+++ b/plugins/analytics/models/analytics_plugin/visit.rb
@@ -3,9 +3,17 @@ class AnalyticsPlugin::Visit < ActiveRecord::Base
attr_accessible *self.column_names
attr_accessible :profile
- default_scope -> { includes :page_views }
-
belongs_to :profile
has_many :page_views, class_name: 'AnalyticsPlugin::PageView', dependent: :destroy
+ default_scope -> { joins(:page_views).includes :page_views }
+
+ scope :latest, -> { order 'analytics_plugin_page_views.request_started_at DESC' }
+
+ def first_page_view
+ self.page_views.first
+ end
+
+ delegate :user, :initial_time, to: :first_page_view
+
end
=====================================
plugins/analytics/test/functional/content_viewer_controller_test.rb
=====================================
--- a/plugins/analytics/test/functional/content_viewer_controller_test.rb
+++ b/plugins/analytics/test/functional/content_viewer_controller_test.rb
@@ -31,6 +31,8 @@ class ContentViewerControllerTest < ActionController::TestCase
first_page_view = @community.page_views.order(:id).first
assert_equal @request.referer, first_page_view.referer_url
+ assert_equal @user, first_page_view.user
+ assert first_page_view.request_duration > 0 and first_page_view.request_duration < 1
@request.env['HTTP_REFERER'] = first_url
get :view_page, profile: @community.identifier, page: @community.articles.last.path.split('/')
@@ -40,9 +42,13 @@ class ContentViewerControllerTest < ActionController::TestCase
second_page_view = @community.page_views.order(:id).last
assert_equal first_page_view, second_page_view.referer_page_view
- assert_equal @user, second_page_view.user
-
- assert second_page_view.request_duration > 0 and second_page_view.request_duration < 1
+ # another visit, the referer is set but should be ignored because
+ # the user didn't report to be on the page until now
+ @request.env['HTTP_REFERER'] = first_url
+ future = Time.now + 2*AnalyticsPlugin::TimeOnPageUpdateInterval
+ Time.stubs(:now).returns(future)
+ get :view_page, profile: @community.identifier, page: @community.articles.last.path.split('/')
+ assert_equal 2, @community.visits.count
end
end
=====================================
plugins/analytics/views/analytics_plugin/_body_ending.html.slim
=====================================
--- a/plugins/analytics/views/analytics_plugin/_body_ending.html.slim
+++ b/plugins/analytics/views/analytics_plugin/_body_ending.html.slim
@@ -1,6 +1,6 @@
javascript:
analytics.timeOnPage.baseUrl = #{url_for(controller: 'analytics_plugin/time_on_page').to_json}
- analytics.timeOnPage.updateInterval = #{AnalyticsPlugin::TimeOnPageUpdateInterval.to_json}
+ analytics.timeOnPage.updateInterval = #{AnalyticsPlugin::TimeOnPageUpdateIntervalMs.to_json}
analytics.requestId = #{request.env['action_dispatch.request_id'].to_json}
analytics.init()
=====================================
plugins/analytics/views/analytics_plugin/stats/_table.html.slim
=====================================
--- /dev/null
+++ b/plugins/analytics/views/analytics_plugin/stats/_table.html.slim
@@ -0,0 +1,38 @@
+
+table#analytics-stats.table data-toggle='table' data-striped='true' data-sortable='true' data-icons-prefix='fa'
+ thead
+ - unless profile.analytics_anonymous?
+ th= t'analytics_plugin.views.stats.user'
+ th= t'analytics_plugin.views.stats.initial_time'
+ th= t'analytics_plugin.views.stats.pages'
+
+ tbody
+ - profile.visits.each do |visit|
+ tr
+ td= link_to visit.user.name, visit.user.url
+ td
+ div data-toggle="tooltip" data-title='#{l visit.initial_time}'
+ = time_ago_in_words(visit.initial_time)
+ | 
+ = _'ago'
+ td
+ - visit.page_views.each do |page_view|
+ = link_to page_view.url, page_view.url
+ |
+ = "(#{distance_of_time_in_words page_view.time_on_page})"
+ | ->
+
+javascript:
+ $('#analytics-stats').bootstrapTable({
+ striped: true,
+ columns: [
+ {sortable: true},
+ {sortable: true},
+ {sortable: true},
+ ],
+ })
+
+ $(document).ready(function() {
+ $('[data-toggle="tooltip"]').tooltip()
+ })
+
=====================================
plugins/analytics/views/analytics_plugin/stats/index.html.slim
=====================================
--- /dev/null
+++ b/plugins/analytics/views/analytics_plugin/stats/index.html.slim
@@ -0,0 +1,5 @@
+- content_for :head
+ = javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.8.1/bootstrap-table-all.min.js'
+ = stylesheet_link_tag 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.8.1/bootstrap-table.css'
+
+= render 'table'
View it on GitLab: https://gitlab.com/noosfero/noosfero/commit/492c3d63597701e331a22aad279e182c569f03a4
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listas.softwarelivre.org/pipermail/noosfero-dev/attachments/20150828/a4774378/attachment-0001.html>
More information about the Noosfero-dev
mailing list