mitamirri 0.13.8 → 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (236) hide show
  1. data/Capfile +4 -0
  2. data/Gemfile +29 -0
  3. data/README.rdoc +6 -55
  4. data/Rakefile +34 -21
  5. data/VERSION +1 -1
  6. data/app/controllers/admin/tracking/reports_controller.rb +78 -0
  7. data/app/controllers/admin/tracking/trackable_sessions_controller.rb +7 -0
  8. data/app/controllers/application_controller.rb +1 -8
  9. data/app/controllers/trackable_actions_controller.rb +0 -2
  10. data/app/helpers/application_helper.rb +21 -0
  11. data/app/helpers/layout_helper.rb +18 -0
  12. data/app/models/content_report.rb +35 -0
  13. data/app/models/content_stat.rb +4 -0
  14. data/app/models/destination.rb +4 -0
  15. data/app/models/intersite_traffic_report.rb +47 -0
  16. data/app/models/keyword_stat.rb +4 -0
  17. data/app/models/lead.rb +3 -0
  18. data/app/models/lead_stat.rb +5 -0
  19. data/app/models/leads_report.rb +32 -0
  20. data/app/models/location_stat.rb +37 -0
  21. data/app/models/referrer_stat.rb +4 -0
  22. data/app/models/report.rb +83 -0
  23. data/app/models/stat_base.rb +11 -0
  24. data/app/models/trackable_action.rb +114 -91
  25. data/app/models/trackable_base.rb +12 -0
  26. data/app/models/trackable_location.rb +7 -13
  27. data/app/models/trackable_session.rb +255 -171
  28. data/app/models/trackable_stat.rb +45 -27
  29. data/app/models/traffic_explorer_report.rb +92 -0
  30. data/app/models/traffic_summary_report.rb +142 -0
  31. data/app/models/user_agent_stat.rb +4 -0
  32. data/app/models/visit.rb +6 -0
  33. data/app/models/visit_stat.rb +5 -0
  34. data/app/models/visitor.rb +4 -0
  35. data/app/models/visitor_profile_report.rb +23 -0
  36. data/app/views/admin/tracking/reports/_content.html.erb +28 -0
  37. data/app/views/admin/tracking/reports/_conversion_rate.html.erb +30 -0
  38. data/app/views/admin/tracking/reports/_criteria.html.erb +33 -0
  39. data/app/views/admin/tracking/reports/_entrance_pages.html.erb +29 -0
  40. data/app/views/admin/tracking/reports/_exit_pages.html.erb +28 -0
  41. data/app/views/admin/tracking/reports/_explorer_criteria.html.erb +22 -0
  42. data/app/views/admin/tracking/reports/_explorer_summary.html.erb +22 -0
  43. data/app/views/admin/tracking/reports/_intersite_destinations.html.erb +28 -0
  44. data/app/views/admin/tracking/reports/_intersite_referrals.html.erb +30 -0
  45. data/app/views/admin/tracking/reports/_leads.html.erb +30 -0
  46. data/app/views/admin/tracking/reports/_locations.html.erb +47 -0
  47. data/app/views/admin/tracking/reports/_recent_visits.html.erb +33 -0
  48. data/app/views/admin/tracking/reports/_referring_keywords.html.erb +28 -0
  49. data/app/views/admin/tracking/reports/_referring_sites.html.erb +28 -0
  50. data/app/views/admin/tracking/reports/_traffic_summary.html.erb +26 -0
  51. data/app/views/admin/tracking/reports/_user_agents.html.erb +28 -0
  52. data/app/views/{trackable_sessions/_visits_graph.html.erb → admin/tracking/reports/_visits_by_kind.html.erb} +3 -3
  53. data/app/views/admin/tracking/reports/content.html.erb +12 -0
  54. data/app/views/admin/tracking/reports/explorer.html.erb +13 -0
  55. data/app/views/admin/tracking/reports/index.html.erb +16 -0
  56. data/app/views/admin/tracking/reports/intersite.html.erb +11 -0
  57. data/app/views/admin/tracking/reports/leads.html.erb +11 -0
  58. data/app/views/admin/tracking/reports/summary.html.erb +16 -0
  59. data/app/views/admin/tracking/reports/visitor_profile.html.erb +11 -0
  60. data/app/views/{trackable_sessions → admin/tracking/trackable_sessions}/show.html.erb +5 -4
  61. data/app/views/layouts/application.html.erb +51 -18
  62. data/config.ru +4 -0
  63. data/config/application.rb +13 -0
  64. data/config/boot.rb +13 -110
  65. data/config/cucumber.yml +10 -0
  66. data/config/deploy.rb +40 -0
  67. data/config/environment.rb +4 -23
  68. data/config/environments/development.rb +24 -13
  69. data/config/environments/production.rb +41 -20
  70. data/config/environments/test.rb +28 -24
  71. data/config/initializers/formats.rb +19 -0
  72. data/config/initializers/metric_fu.rb +9 -0
  73. data/config/initializers/secret_token.rb +7 -0
  74. data/config/initializers/session_store.rb +3 -10
  75. data/config/locales/en.yml +1 -1
  76. data/config/mongoid.yml +19 -0
  77. data/config/routes.rb +16 -10
  78. data/features/access_reports.feature +26 -0
  79. data/features/step_definitions/reports_steps.rb +9 -0
  80. data/features/step_definitions/web_steps.rb +219 -0
  81. data/features/support/env.rb +32 -0
  82. data/features/support/hooks.rb +1 -0
  83. data/features/support/paths.rb +33 -0
  84. data/features/traffic_summary_report.feature +43 -0
  85. data/init.rb +0 -7
  86. data/lib/mitamirri.rb +9 -12
  87. data/lib/mitamirri/engine.rb +7 -0
  88. data/lib/mitamirri/helper.rb +13 -29
  89. data/lib/mitamirri/railtie.rb +10 -0
  90. data/lib/tasks/cucumber.rake +60 -0
  91. data/lib/tasks/rcov.rake +44 -0
  92. data/mitamirri.gemspec +228 -100
  93. data/public/404.html +26 -0
  94. data/public/422.html +26 -0
  95. data/public/500.html +26 -0
  96. data/{config/database.yml → public/favicon.ico} +0 -0
  97. data/public/images/icons/add.png +0 -0
  98. data/public/images/icons/collapsed.gif +0 -0
  99. data/public/images/icons/delete.png +0 -0
  100. data/public/images/icons/drag.png +0 -0
  101. data/public/images/icons/edit.png +0 -0
  102. data/public/images/icons/expanded.gif +0 -0
  103. data/public/images/icons/help_icon.png +0 -0
  104. data/public/images/icons/link_icon.png +0 -0
  105. data/public/images/icons/move.png +0 -0
  106. data/public/images/icons/move_white.png +0 -0
  107. data/public/images/icons/note.png +0 -0
  108. data/public/images/icons/note_white.png +0 -0
  109. data/public/images/icons/notification_icon_sprite.png +0 -0
  110. data/public/images/icons/spinner.gif +0 -0
  111. data/public/images/icons/view.png +0 -0
  112. data/public/images/icons/warning.png +0 -0
  113. data/public/images/icons/warning_2.png +0 -0
  114. data/public/images/icons/warning_box.png +0 -0
  115. data/public/images/icons/warning_icon.png +0 -0
  116. data/public/images/icons/warning_white.png +0 -0
  117. data/public/images/layout/arrow_asc.png +0 -0
  118. data/public/images/layout/arrow_desc.png +0 -0
  119. data/public/images/layout/back.png +0 -0
  120. data/public/images/layout/black_bar.png +0 -0
  121. data/public/images/layout/branding.png +0 -0
  122. data/public/images/layout/breadcrumb_bg.png +0 -0
  123. data/public/images/layout/button_bg.png +0 -0
  124. data/public/images/layout/content_left_bg.png +0 -0
  125. data/public/images/layout/content_right_bg.png +0 -0
  126. data/public/images/layout/footer_bg.png +0 -0
  127. data/public/images/layout/h1_bg.png +0 -0
  128. data/public/images/layout/h2_bg.png +0 -0
  129. data/public/images/layout/h2_bg_for_table.png +0 -0
  130. data/public/images/layout/header_bg_grey.png +0 -0
  131. data/public/images/layout/header_bg_purple.png +0 -0
  132. data/public/images/layout/legend_bg.png +0 -0
  133. data/public/images/layout/menu_box_bg.png +0 -0
  134. data/public/images/layout/shadow_border.png +0 -0
  135. data/public/images/layout/shadow_border_2.png +0 -0
  136. data/public/images/layout/shadow_border_3.png +0 -0
  137. data/public/images/layout/shadow_border_4.png +0 -0
  138. data/public/images/layout/tab.png +0 -0
  139. data/public/images/layout/tab_active.png +0 -0
  140. data/public/images/layout/table_header.png +0 -0
  141. data/public/images/layout/text_field_bg.jpg +0 -0
  142. data/public/images/layout/text_field_error_bg.png +0 -0
  143. data/public/images/layout/th_bg.png +0 -0
  144. data/public/images/layout/th_bg_selected.png +0 -0
  145. data/public/images/menu_icons/content_report.png +0 -0
  146. data/public/images/menu_icons/content_report_on.png +0 -0
  147. data/public/images/menu_icons/funnel.png +0 -0
  148. data/public/images/menu_icons/funnel_on.png +0 -0
  149. data/public/images/menu_icons/intersite_traffic.png +0 -0
  150. data/public/images/menu_icons/intersite_traffic_on.png +0 -0
  151. data/public/images/menu_icons/leads.png +0 -0
  152. data/public/images/menu_icons/leads_on.png +0 -0
  153. data/public/images/menu_icons/traffic_explorer.png +0 -0
  154. data/public/images/menu_icons/traffic_explorer_on.png +0 -0
  155. data/public/images/menu_icons/traffic_summary.png +0 -0
  156. data/public/images/menu_icons/traffic_summary_on.png +0 -0
  157. data/public/images/menu_icons/visitor_profile.png +0 -0
  158. data/public/images/menu_icons/visitor_profile_on.png +0 -0
  159. data/public/index.html +8 -0
  160. data/public/javascripts/application.js +2 -0
  161. data/public/javascripts/controls.js +965 -0
  162. data/public/javascripts/dragdrop.js +974 -0
  163. data/public/javascripts/effects.js +1123 -0
  164. data/public/javascripts/prototype.js +6001 -0
  165. data/public/javascripts/rails.js +175 -0
  166. data/public/robots.txt +5 -0
  167. data/public/stylesheets/.gitkeep +0 -0
  168. data/public/stylesheets/application.css +876 -0
  169. data/public/stylesheets/core.css +1146 -0
  170. data/public/stylesheets/core_ie.css +52 -0
  171. data/public/stylesheets/csshover3.htc +14 -0
  172. data/public/stylesheets/mitamirri.css +37 -724
  173. data/public/stylesheets/mitamirri_print.css +3 -0
  174. data/script/cucumber +10 -0
  175. data/script/rails +6 -0
  176. data/spec/blueprints.rb +13 -0
  177. data/spec/helpers/application_helper_spec.rb +23 -35
  178. data/spec/{lib → models}/content_report_spec.rb +12 -8
  179. data/spec/{lib → models}/intersite_traffic_report_spec.rb +6 -9
  180. data/spec/{lib → models}/leads_report_spec.rb +11 -12
  181. data/spec/models/location_stat_spec.rb +18 -0
  182. data/spec/models/trackable_action_spec.rb +46 -14
  183. data/spec/models/trackable_base_spec.rb +27 -0
  184. data/spec/models/trackable_session_spec.rb +181 -57
  185. data/spec/{lib/session_report_spec.rb → models/traffic_explorer_report_spec.rb} +8 -25
  186. data/spec/spec_helper.rb +8 -28
  187. data/{lib/mitamirri/tasks.rb → tasks/mitamirri.rake} +6 -7
  188. data/vendor/plugins/.gitkeep +0 -0
  189. metadata +316 -77
  190. data/.gitignore +0 -26
  191. data/app/controllers/trackable_sessions_controller.rb +0 -100
  192. data/app/views/trackable_sessions/_keywords_graph.html.erb +0 -24
  193. data/app/views/trackable_sessions/_print_buttons.html.erb +0 -3
  194. data/app/views/trackable_sessions/_sessions.html.erb +0 -26
  195. data/app/views/trackable_sessions/_top_referrers.html.erb +0 -24
  196. data/app/views/trackable_sessions/_traffic_summary_all.html.erb +0 -64
  197. data/app/views/trackable_sessions/_traffic_summary_by_kind.html.erb +0 -48
  198. data/app/views/trackable_sessions/content.html.erb +0 -119
  199. data/app/views/trackable_sessions/explorer.html.erb +0 -67
  200. data/app/views/trackable_sessions/export.xls.erb +0 -5
  201. data/app/views/trackable_sessions/index.html.erb +0 -47
  202. data/app/views/trackable_sessions/intersite.html.erb +0 -97
  203. data/app/views/trackable_sessions/leads.html.erb +0 -98
  204. data/app/views/trackable_sessions/visitor_profile.html.erb +0 -114
  205. data/config/initializers/backtrace_silencers.rb +0 -7
  206. data/config/initializers/database.rb +0 -1
  207. data/config/initializers/inflections.rb +0 -10
  208. data/config/initializers/mime_types.rb +0 -5
  209. data/config/initializers/new_rails_defaults.rb +0 -21
  210. data/db/development.sqlite3 +0 -0
  211. data/db/migrate/20100810173533_create_trackable_sessions.rb +0 -23
  212. data/db/migrate/20100810173605_create_trackable_actions.rb +0 -20
  213. data/db/test.sqlite3 +0 -1
  214. data/lib/mitamirri/content_report.rb +0 -75
  215. data/lib/mitamirri/intersite_traffic_report.rb +0 -122
  216. data/lib/mitamirri/leads_report.rb +0 -90
  217. data/lib/mitamirri/session_report.rb +0 -219
  218. data/lib/mitamirri/stat_report.rb +0 -216
  219. data/lib/mitamirri/visitor_profile_report.rb +0 -127
  220. data/script/about +0 -4
  221. data/script/console +0 -3
  222. data/script/dbconsole +0 -3
  223. data/script/destroy +0 -3
  224. data/script/generate +0 -3
  225. data/script/performance/benchmarker +0 -3
  226. data/script/performance/profiler +0 -3
  227. data/script/plugin +0 -3
  228. data/script/runner +0 -3
  229. data/script/server +0 -3
  230. data/spec/controllers/trackable_actions_controller_spec.rb +0 -5
  231. data/spec/controllers/trackable_sessions_controller_spec.rb +0 -5
  232. data/spec/custom_matchers.rb +0 -23
  233. data/spec/lib/stat_report_spec.rb +0 -106
  234. data/spec/rcov.opts +0 -4
  235. data/spec/schema.rb +0 -34
  236. data/spec/spec.opts +0 -4
@@ -1,46 +1,64 @@
1
+ # Summarizes all stats for all tracked sessions and their actions for a given site in a given month.
1
2
  class TrackableStat
2
3
 
3
- include MongoMapper::Document
4
+ # Mongoid Config =============================================================================
4
5
 
5
- # MongoMapper Setup ==============================================================================
6
+ include Mongoid::Document
7
+ include Mongoid::Timestamps
6
8
 
7
- many :trackable_sessions, :order => :created_at
9
+ references_many :trackable_sessions
8
10
 
9
- key :site, String, :index => true
10
- key :bounces, :default => 0
11
- key :clickthroughs, :default => 0
12
- key :conversions, :default => 0
13
- key :duration, :default => 0
14
- key :new_visits, :default => 0
15
- key :organic_visits, :default => 0
16
- key :pageviews, :default => 0
17
- key :ppc_visits, :default => 0
18
- key :direct_visits, :default => 0
19
- key :return_visits, :default => 0
20
- key :search_visits, :default => 0
21
- key :visits, :default => 0
22
- timestamps!
11
+ field :site
12
+ field :bounces, :type => Integer, :default => 0
13
+ field :clickthroughs, :type => Integer, :default => 0
14
+ field :conversions, :type => Integer, :default => 0
15
+ field :duration, :type => Integer, :default => 0
16
+ field :new_visits, :type => Integer, :default => 0
17
+ field :organic_visits, :type => Integer, :default => 0
18
+ field :pageviews, :type => Integer, :default => 0
19
+ field :ppc_visits, :type => Integer, :default => 0
20
+ field :direct_visits, :type => Integer, :default => 0
21
+ field :return_visits, :type => Integer, :default => 0
22
+ field :search_visits, :type => Integer, :default => 0
23
+ field :visits, :type => Integer, :default => 0
24
+
25
+ index :site, :unique => false
23
26
 
24
27
  # Scopes =========================================================================================
25
-
26
- scope :by_site, lambda { |site| { :conditions => { :site => site } } }
27
- scope :by_date, lambda { |date| { :conditions => { :created_at => { '$gte' => date.beginning_of_month, '$lte' => date.end_of_month } } } }
28
- scope :for_date_range, lambda { |start_date,end_date| { :conditions => { :created_at => { '$gte' => start_date.beginning_of_month, '$lte' => end_date.end_of_month } } } }
28
+
29
+ scope :by_site, lambda { |site| { :where => { :site => site } } }
30
+ scope :by_date, lambda { |date| { :where => { :created_at => { '$gte' => date.beginning_of_month, '$lte' => date.end_of_month } } } }
31
+ scope :for_date_range, lambda { |start_date,end_date| { :where => { :created_at => { '$gte' => start_date.beginning_of_month, '$lte' => end_date.end_of_month } } } }
32
+ scope :for_site, lambda { |site| { :where => { :site => site } } }
29
33
 
30
34
  # Class Methods ==================================================================================
31
35
 
36
+ # Returns the names of all sites that have been tracked, used in report filters.
32
37
  def self.sites
33
- TrackableStat.all(:fields => :site).map{|s| s.site.downcase}.uniq
38
+ TrackableStat.only(:site).map{|s| s.site.to_s.downcase}.uniq
34
39
  end
35
-
40
+
36
41
  # Instance Methods ===============================================================================
37
-
42
+
43
+ # Increments the running tallies of the session- and action-attributes for a given site in a given
44
+ # month. For example, an action's clickthroughs or conversions, or the kind of session (direct,
45
+ # natural, paid, search).
46
+ #
47
+ # ==== Attributes
48
+ #
49
+ # * +:session+ - action as a string: 'click', 'clickthrough', 'conversion', 'mouseover', 'scroll', 'view'
50
+ # * +:last_action+ - clickthrough destination
51
+ # * +:previous_action+ - the referring URL
52
+ #
53
+ # ==== Examples
54
+ #
55
+ # trackable_stat.touch( 'click', 'cnn.com', 'foo.com/cnn' )
38
56
  def touch(session, last_action, previous_action = nil)
39
57
  if previous_action.nil?
40
58
  # New session
41
59
  self.trackable_sessions << session
42
- self.clickthroughs += 1 if last_action.clickthrough?
43
- self.conversions += 1 if last_action.conversion?
60
+ self.clickthroughs += 1 if last_action && last_action.clickthrough?
61
+ self.conversions += 1 if last_action && last_action.conversion?
44
62
  self.direct_visits += 1 if session.kind == 'direct'
45
63
  self.new_visits += 1 if session.new_visit
46
64
  self.organic_visits += 1 if session.kind == 'natural'
@@ -60,5 +78,5 @@ class TrackableStat
60
78
  end
61
79
  self.save
62
80
  end
63
-
81
+
64
82
  end
@@ -0,0 +1,92 @@
1
+ class TrafficExplorerReport < Report
2
+
3
+ # Initialization =================================================================================
4
+
5
+ def ready?
6
+ self.site && self.time_period
7
+ end
8
+
9
+ def stats
10
+ sessions
11
+ end
12
+
13
+ # Graph data =====================================================================================
14
+
15
+ def visits(args)
16
+ [Visit.new(:kind => args[:visit_kind].titleize, :stats => visit_stats(args))]
17
+ end
18
+
19
+ def visit_stats(args)
20
+ _visit_stats = []
21
+ dates.each do |date|
22
+ _visit_stats << VisitStat.new(:date => date, :visits => TrackableSession.search_without_date(args).for_month(date).count)
23
+ end
24
+ _visit_stats
25
+ end
26
+
27
+ # Stat Methods ===================================================================================
28
+
29
+ def average_pages_per_visit
30
+ sprintf("%.1f", total_pageviews / total_visits.to_f).gsub('nan','0')
31
+ end
32
+
33
+ def average_time_on_site
34
+ average = total_duration / total_visits.to_f
35
+ average > 60 ? sprintf("%.1f minutes", average / 60.0) : sprintf("%.1f seconds", average).gsub('nan','0')
36
+ end
37
+
38
+ def bounce_rate
39
+ bounce_rate = total_bounces / total_visits.to_f
40
+ sprintf("%.1f%", bounce_rate * 100).gsub('nan','0')
41
+ end
42
+
43
+ def conversion_rate
44
+ conversion_rate = total_conversions / total_visits.to_f
45
+ sprintf("%.1f%", conversion_rate * 100).gsub('nan','0')
46
+ end
47
+
48
+ def total_bounces
49
+ @total_bounces ||= stats.select{|s| s.bounce}.count
50
+ end
51
+
52
+ def total_clickthroughs
53
+ @total_clickthroughs ||= stats.select{|s| s.has_clickthroughs}.count
54
+ end
55
+
56
+ def total_clickthroughs_percentage
57
+ sprintf("%.1f%", (total_clickthroughs / total_visits.to_f) * 100).gsub('nan','0')
58
+ end
59
+
60
+ def total_conversions
61
+ @total_conversions ||= stats.select{|s| s.has_conversions}.count
62
+ end
63
+
64
+ def total_duration
65
+ @total_duration ||= stats.only(:duration).map{|s| s.duration}.sum
66
+ end
67
+
68
+ def total_new_visits
69
+ @total_new_visits ||= stats.select{|s| s.new_visit}.count
70
+ end
71
+
72
+ def total_new_visits_percentage
73
+ sprintf("%.1f%", (total_new_visits / total_visits.to_f) * 100).gsub('nan','0')
74
+ end
75
+
76
+ def total_pageviews
77
+ @total_pageviews ||= stats.only(:pageviews).map{|s| s.pageviews}.sum
78
+ end
79
+
80
+ def total_return_visits
81
+ @total_return_visits ||= stats.reject{|s| s.new_visit}.count
82
+ end
83
+
84
+ def total_return_visits_percentage
85
+ sprintf("%.1f%", (total_return_visits / total_visits.to_f) * 100).gsub('nan','0')
86
+ end
87
+
88
+ def total_visits
89
+ @total_visits ||= sessions.count
90
+ end
91
+
92
+ end
@@ -0,0 +1,142 @@
1
+ class TrafficSummaryReport < Report
2
+
3
+ # Initialization =================================================================================
4
+
5
+ def ready?
6
+ self.site && self.time_period
7
+ end
8
+
9
+ def stats
10
+ if multiple_sites?
11
+ @stats ||= TrackableStat.for_date_range(start_date, end_date)
12
+ else
13
+ @stats ||= TrackableStat.for_site(site).for_date_range(start_date, end_date)
14
+ end
15
+ end
16
+
17
+ # Graph data =====================================================================================
18
+
19
+ def keywords_by_frequency(args)
20
+ TrackableSession.keywords_histogram(args).inject([]){|a,v| a << KeywordStat.new(:keyword => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24]
21
+ end
22
+
23
+ def top_referrers(args)
24
+ TrackableSession.referrers_histogram(args).inject([]){|a,v| a << ReferrerStat.new(:referrer => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24]
25
+ end
26
+
27
+ def visits(args)
28
+ _visits = []
29
+ _visits << Visit.new(:kind => 'All', :stats => visit_stats(args))
30
+ _visits << Visit.new(:kind => 'Direct Traffic', :stats => visit_stats(args.merge(:visit_kind => 'direct')))
31
+ _visits << Visit.new(:kind => 'Referring Sites', :stats => visit_stats(args.merge(:visit_kind => 'natural')))
32
+ _visits << Visit.new(:kind => 'Organic Search', :stats => visit_stats(args.merge(:visit_kind => 'search')))
33
+ _visits << Visit.new(:kind => 'Paid Search', :stats => visit_stats(args.merge(:visit_kind => 'paid')))
34
+ _visits
35
+ end
36
+
37
+ def visit_stats(args)
38
+ _visit_stats = []
39
+ dates.each do |date|
40
+ _visit_stats << VisitStat.new(:date => date, :visits => TrackableSession.search_without_date(args).for_month(date).count)
41
+ end
42
+ _visit_stats
43
+ end
44
+
45
+ # Stat Methods ===================================================================================
46
+
47
+ def average_pages_per_visit
48
+ sprintf("%.1f", total_pageviews / total_visits.to_f).gsub('nan','0')
49
+ end
50
+
51
+ def average_time_on_site
52
+ average = total_duration / total_visits.to_f
53
+ average > 60 ? sprintf("%.1f minutes", average / 60.0) : sprintf("%.1f seconds", average).gsub('nan','0')
54
+ end
55
+
56
+ def bounce_rate
57
+ bounce_rate = total_bounces / total_visits.to_f
58
+ sprintf("%.1f%", bounce_rate * 100).gsub('nan','0')
59
+ end
60
+
61
+ def conversion_rate
62
+ conversion_rate = total_conversions / total_visits.to_f
63
+ sprintf("%.1f%", conversion_rate * 100).gsub('nan','0')
64
+ end
65
+
66
+ def total_bounces
67
+ @total_bounces ||= stats.only(:bounces).map{|s| s.bounces}.sum
68
+ end
69
+
70
+ def total_clickthroughs
71
+ @total_clickthroughs ||= stats.only(:clickthroughs).map{|s| s.clickthroughs}.sum
72
+ end
73
+
74
+ def total_clickthroughs_percentage
75
+ sprintf("%.1f%", (total_clickthroughs / total_visits.to_f) * 100).gsub('nan','0')
76
+ end
77
+
78
+ def total_conversions
79
+ @total_conversions ||= stats.only(:conversions).map{|s| s.conversions}.sum
80
+ end
81
+
82
+ def total_direct_visits
83
+ @total_direct_visits ||= stats.only(:direct_visits).map{|s| s.direct_visits}.sum
84
+ end
85
+
86
+ def total_direct_visits_percentage
87
+ sprintf("%.1f%", (total_direct_visits / total_visits.to_f) * 100).gsub('nan','0')
88
+ end
89
+
90
+ def total_duration
91
+ @total_duration ||= stats.only(:duration).map{|s| s.duration}.sum
92
+ end
93
+
94
+ def total_new_visits
95
+ @total_new_visits ||= stats.only(:new_visits).map{|s| s.new_visits}.sum
96
+ end
97
+
98
+ def total_new_visits_percentage
99
+ sprintf("%.1f%", (total_new_visits / total_visits.to_f) * 100).gsub('nan','0')
100
+ end
101
+
102
+ def total_organic_visits
103
+ @total_organic_visits ||= stats.only(:organic_visits).map{|s| s.organic_visits}.sum
104
+ end
105
+
106
+ def total_organic_visits_percentage
107
+ sprintf("%.1f%", (total_organic_visits / total_visits.to_f) * 100).gsub('nan','0')
108
+ end
109
+
110
+ def total_pageviews
111
+ @total_pageviews ||= stats.only(:pageviews).map{|s| s.pageviews}.sum
112
+ end
113
+
114
+ def total_ppc_visits
115
+ @total_ppc_visits ||= stats.only(:ppc_visits).map{|s| s.ppc_visits}.sum
116
+ end
117
+
118
+ def total_ppc_visits_percentage
119
+ sprintf("%.1f%", (total_ppc_visits / total_visits.to_f) * 100).gsub('nan','0')
120
+ end
121
+
122
+ def total_return_visits
123
+ @total_return_visits ||= stats.only(:return_visits).map{|s| s.return_visits}.sum
124
+ end
125
+
126
+ def total_return_visits_percentage
127
+ sprintf("%.1f%", (total_return_visits / total_visits.to_f) * 100).gsub('nan','0')
128
+ end
129
+
130
+ def total_search_visits
131
+ @total_search_visits ||= stats.only(:search_visits).map{|s| s.search_visits}.sum
132
+ end
133
+
134
+ def total_search_visits_percentage
135
+ sprintf("%.1f%", (total_search_visits / total_visits.to_f) * 100).gsub('nan','0')
136
+ end
137
+
138
+ def total_visits
139
+ @total_visits ||= stats.only(:visits).map{|s| s.visits}.sum
140
+ end
141
+
142
+ end
@@ -0,0 +1,4 @@
1
+ class UserAgentStat < StatBase
2
+ attr_accessor :user_agent
3
+ attr_accessor :count
4
+ end
@@ -0,0 +1,6 @@
1
+ class Visit < StatBase
2
+ attr_accessor :kind
3
+ attr_accessor :date
4
+ attr_accessor :stats
5
+ attr_accessor :site
6
+ end
@@ -0,0 +1,5 @@
1
+ class VisitStat < StatBase
2
+ attr_accessor :date
3
+ attr_accessor :visits
4
+ attr_accessor :clickthroughs
5
+ end
@@ -0,0 +1,4 @@
1
+ class Visitor < StatBase
2
+ attr_accessor :user_agent_stats
3
+ attr_accessor :location_stats
4
+ end
@@ -0,0 +1,23 @@
1
+ class VisitorProfileReport < Report
2
+
3
+ # Initialization =================================================================================
4
+
5
+ def ready?
6
+ self.site && self.time_period && self.visit_kind
7
+ end
8
+
9
+ def wants_traffic_kind?
10
+ true
11
+ end
12
+
13
+ # Stats for Visualization ========================================================================
14
+
15
+ def locations_by_frequency(args)
16
+ TrackableSession.locations_histogram(args).inject([]){|a,v| a << LocationStat.new(:name => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24]
17
+ end
18
+
19
+ def user_agents_by_frequency(args)
20
+ TrackableSession.user_agents_histogram(args).inject([]){|a,v| a << UserAgentStat.new(:user_agent => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24]
21
+ end
22
+
23
+ end
@@ -0,0 +1,28 @@
1
+ <div class="form_container">
2
+ <%= legend_tag "Top Content", :help => 'This chart shows the top 25 most-requested pages across the selected site(s). Click on any bar in the graph for a count of visits to the corresponding page.' -%>
3
+ <br />
4
+ <%- if @pages_series.empty? -%>
5
+ <p><em>No data matched your criteria.</em></p>
6
+ <%- else -%>
7
+ <div id="pages_chart" class="chart" style="width: 100%; border: 1px solid #999999; background-color: #ffffff; text-align: center;"></div>
8
+
9
+ <%= Seer::visualize(
10
+ @pages_series,
11
+ :as => :bar_chart,
12
+ :in_element => 'pages_chart',
13
+ :series => {:series_label => 'url', :data_method => 'views'},
14
+ :chart_options => {
15
+ :height => @pages_series.size * 20,
16
+ :width => 900,
17
+ :is_3_d => false,
18
+ :legend => 'none',
19
+ :colors => ["#7e7587"],
20
+ :title => "# of Page Views",
21
+ :title_font_size => 9,
22
+ :title_x => '',
23
+ :axis_font_size => 10
24
+ }
25
+ ).html_safe
26
+ -%>
27
+ <%- end -%>
28
+ </div>
@@ -0,0 +1,30 @@
1
+ <div class="form_container">
2
+ <%= legend_tag "Visit-to-Lead Conversion Rate (#{params[:time_period].titleize})", :help => 'This graph shows the overall conversion rate week-over-week, which is the percentage of visits that resulted in a lead being submitted. Click on a data point for the conversion rate for the corresponding week.' -%>
3
+ <br />
4
+ <%- if @leads.empty? -%>
5
+ <p><em>No lead data matches your criteria.</em></p>
6
+ <%- else -%>
7
+ <div id="conversions_chart" class="chart" style="width: 100%; border: 1px solid #999999; background-color: #ffffff; text-align: center;"></div>
8
+ <%= Seer::visualize(
9
+ @leads,
10
+ :as => :line_chart,
11
+ :in_element => 'conversions_chart',
12
+ :series => {
13
+ :series_label => 'Conversion Rate',
14
+ :data_label => 'short_date',
15
+ :data_method => 'conversion_rate',
16
+ :data_series => @leads_series
17
+ },
18
+ :chart_options => {
19
+ :height => 300,
20
+ :width => 900,
21
+ :axis_font_size => 11,
22
+ :colors => ['#7e7587','#7e7e00','#007e7e','#7e0000', '#007e00'],
23
+ :title => "",
24
+ :point_size => 5,
25
+ :legend => 'none'
26
+ }
27
+ ).html_safe
28
+ -%>
29
+ <%- end -%>
30
+ </div>
@@ -0,0 +1,33 @@
1
+ <form>
2
+ <fieldset class="form_container">
3
+ <%= legend_tag "Report Criteria" -%>
4
+ <%- if @sites.count > 2 -%>
5
+ <div class="three_column">
6
+ <fieldset>
7
+ <label for="site">Site:</label><br />
8
+ <%= select_tag "site", options_for_select(@sites, params[:site] || "All Sites") -%>
9
+ </fieldset>
10
+ </div>
11
+ <%- else -%>
12
+ <%= hidden_field_tag :site, @sites.first -%>
13
+ <%- end -%>
14
+ <div class="three_column">
15
+ <fieldset>
16
+ <label for="time_period">Time Period:</label><br />
17
+ <%= select_tag "time_period", options_for_select(@time_periods, params[:time_period].titleize) -%>
18
+ </fieldset>
19
+ </div>
20
+ <%- if @report.wants_traffic_kind? -%>
21
+ <div class="three_column">
22
+ <fieldset>
23
+ <label for="visit_kind">Traffic Type:</label><br />
24
+ <%= select_tag "visit_kind", options_for_select(TrackableSession.kinds_for_select, params[:visit_kind]) -%>
25
+ </fieldset>
26
+ </div>
27
+ <%- end -%>
28
+ <div class="link_block">
29
+ <input type="submit" class="link_button" value="Generate Report" />
30
+ <%= link_to 'Back', admin_tracking_root_path, :class => 'link_button' -%>
31
+ </div>
32
+ </fieldset>
33
+ </form>