trueandco_analytics 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +152 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/javascripts/trueandco_analytics.js +170 -0
  6. data/app/commands/trueandco_analytics/arr_jsons_to_arr_hash.rb +20 -0
  7. data/app/commands/trueandco_analytics/metric_c/add_list.rb +65 -0
  8. data/app/commands/trueandco_analytics/report_c/generate.rb +31 -0
  9. data/app/commands/trueandco_analytics/session_c/create.rb +65 -0
  10. data/app/commands/trueandco_analytics/session_c/put_data.rb +46 -0
  11. data/app/commands/trueandco_analytics/user_c/create_or_update_user_if_exist.rb +41 -0
  12. data/app/controllers/trueandco_analytics/application_controller.rb +5 -0
  13. data/app/controllers/trueandco_analytics/reciver_controller.rb +19 -0
  14. data/app/models/trueandco_analytics/application_record.rb +5 -0
  15. data/app/models/trueandco_analytics/metric_user.rb +8 -0
  16. data/app/models/trueandco_analytics/metric_user_session.rb +8 -0
  17. data/app/models/trueandco_analytics/metric_user_visit.rb +8 -0
  18. data/app/views/trueandco_analytics/receiver/pull_user_statistic.erb +0 -0
  19. data/app/workers/trueandco_analytics/user_session_metric_worker.rb +21 -0
  20. data/config/routes.rb +3 -0
  21. data/config/secrets.yml +2 -0
  22. data/db/migrate/20170802133950_create_metric_users.rb +19 -0
  23. data/db/migrate/20170802134044_create_metric_user_visits.rb +20 -0
  24. data/db/migrate/20170802134059_create_metric_user_sessions.rb +27 -0
  25. data/exe/trueandco_analytics +28 -0
  26. data/lib/extension_string.rb +20 -0
  27. data/lib/generators/trueandco_analytics/install_generator.rb +14 -0
  28. data/lib/generators/trueandco_analytics/templates/trueandco_analytics.rb +37 -0
  29. data/lib/trueandco_analytics/cli/common.rb +49 -0
  30. data/lib/trueandco_analytics/cli/report.rb +51 -0
  31. data/lib/trueandco_analytics/config/params.rb +81 -0
  32. data/lib/trueandco_analytics/engine.rb +31 -0
  33. data/lib/trueandco_analytics/helpers/trueandco_analytics_helper.rb +35 -0
  34. data/lib/trueandco_analytics/locales/en.yml +16 -0
  35. data/lib/trueandco_analytics/modules/info.rb +21 -0
  36. data/lib/trueandco_analytics/reports/application_report.rb +61 -0
  37. data/lib/trueandco_analytics/reports/details_report.rb +24 -0
  38. data/lib/trueandco_analytics/reports/page_buy_in_date_range_report.rb +29 -0
  39. data/lib/trueandco_analytics/services/logger.rb +24 -0
  40. data/lib/trueandco_analytics/services/redis_connect.rb +12 -0
  41. data/lib/trueandco_analytics/services/reports.rb +30 -0
  42. data/lib/trueandco_analytics/services/workers.rb +14 -0
  43. data/lib/trueandco_analytics/version.rb +3 -0
  44. data/lib/trueandco_analytics.rb +37 -0
  45. metadata +242 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2eddcffa3c6a13247a6f2ea46e5cde544fd73fbc
4
+ data.tar.gz: ef377598828ff1be656935568fab8d2c1d2a0311
5
+ SHA512:
6
+ metadata.gz: 1654ffbb2a22a87e2e5930cd0978284971e9ebbaf8b6bf69f45c151fdf0a12bd2a8d94f46fa87adefad7c4587deefabb249482d2b920559d0ae99bfd94888c97
7
+ data.tar.gz: 3e0a6bb73989e4f76d6e9bf02ebbda08e1372b537d71a72df9ac6bced523e8d81ba3313fb54c1b7a38003dc5ca7c3784b8881beaf142c02ebfbd82503bfabb5c
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2017
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # Trueandco_analytics
2
+ **Trueandco_analytics** Gems for authentication and authorization
3
+
4
+ ## About
5
+ Many systems analysts do not provide data about the specific user. This gem allows administrators to obtain reports on a particular user and common page statistics
6
+
7
+
8
+ ## Installation
9
+
10
+ 1. You shall have (redis, sidekiq, mysql) on your server.
11
+ 2. You have to include gems in your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'trueandco_analytics'
15
+ ```
16
+
17
+ 3. And then to start
18
+
19
+ ```ruby
20
+ bundle
21
+ ```
22
+
23
+ 4. To start the initialiser, for detailed configured gem
24
+
25
+ ```ruby
26
+ rails g trueandco_analytics:install
27
+ ```
28
+
29
+ After
30
+
31
+ ```ruby
32
+ rake db:migrate
33
+ ```
34
+ or
35
+ ```ruby
36
+ rails db:migrate
37
+ ```
38
+ That create 3 tables:
39
+
40
+ `metric_users`, `metric_user_sessions`, `metric_user_visits`
41
+
42
+ `metric_users` Info about users
43
+ `metric_user_sessions` Info about user sesssions
44
+ `metric_user_visits` Pages which were visited by the user within the session
45
+
46
+ Add assetcs
47
+ ```js
48
+ //= require trueandco_analytics
49
+ ```
50
+ Add helper ` track_user_behavior` to head for tracking
51
+ ```html
52
+ <!DOCTYPE html>
53
+ <html>
54
+ <head>
55
+ <title>Example</title>
56
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
57
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
58
+ <%= csrf_meta_tags %>
59
+ <%= track_user_behavior %>
60
+ </head>
61
+ ```
62
+
63
+ Add the mointing address
64
+ ```ruby
65
+ mount TrueandcoAnalytics::Engine, at: "/metric"
66
+ ```
67
+ And you need to listen queue `user_metric`
68
+ ```ruby
69
+ bundle exec sidekiq --queue=user_metric
70
+ ```
71
+ Need set in app
72
+ ```ruby
73
+ config.eager_load = true
74
+ ```
75
+ The application must have a route `root`
76
+
77
+ For use of the console mode. it is necessary to specify the current database.
78
+ ```ruby
79
+ config.db_connect = {
80
+ database: 'development_db_name',
81
+ username: 'ivan',
82
+ password: '3443555',
83
+ host: '127.0.0.1',
84
+ port: 3306
85
+ }
86
+ ```
87
+ It is possible to include the logging mode, having specified the name
88
+ ```ruby
89
+ config.log = 'name of log'
90
+ ```
91
+
92
+
93
+ ## Usage
94
+
95
+ Now we can take data in a convenient format.
96
+ It is necessary to specify the report and a format of data
97
+ So far only arr, csv is available
98
+
99
+ For this we use the service object `::TrueandcoAnalytics::Reports`
100
+
101
+ Available formats
102
+ ```ruby
103
+ ::TrueandcoAnalytics::Reports.available_formats
104
+ ```
105
+ List of reports
106
+ ```ruby
107
+ ::TrueandcoAnalytics::Reports.available_reports
108
+ ```
109
+ Get report obj with method report_name and data
110
+ ```ruby
111
+ ::TrueandcoAnalytics::Reports.get_report_obj('page_buy_in_date_range_report', 'csv')
112
+ ::TrueandcoAnalytics::Reports.get_report_obj('page_buy_in_date_range_report', 'csv', datetme_start, datetime_end)
113
+ ```
114
+
115
+ ### Usage console mod
116
+
117
+ bundle exec trueandco_analytics -h
118
+
119
+ ## Settings
120
+
121
+ * Time survey Analytics seconds
122
+ `config.time_survey = 15`
123
+
124
+ * Specify the method available in the ApplicationController to the receiving user object. Containing id, email.
125
+ `config.user_method = 'current_user'`
126
+
127
+ * Specify css the selector class for the button purchase
128
+ `config.buy_selector_class = 'buy'`
129
+
130
+ * Specify the database where redis will store the statistics for the session user
131
+ ```ruby
132
+ config.connect_redis = {
133
+ #url: "redis://your_host:6379",
134
+ #redis_password: '',
135
+ redis_db: 1
136
+ }
137
+ ```
138
+
139
+ * Specify Sidekiq config
140
+ `config.sidekiq_configure_client_url = 'redis://localhost:6379/1'`
141
+ `config.sidekiq_configure_server_url = 'redis://localhost:6379/1'`
142
+ `config.sidekiq_configure_namespace = 'metric'`
143
+
144
+
145
+ ## Ruby version tested
146
+
147
+ **2.2.4**
148
+
149
+ ## Contributing
150
+
151
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Rattt/trueandco_analytics. This project is intended to be a safe,
152
+ welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'TrueandcoAnalytics'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ require 'bundler/gem_tasks'
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'test'
31
+ t.pattern = 'test/**/*_test.rb'
32
+ t.verbose = false
33
+ end
34
+
35
+
36
+ task default: :test
@@ -0,0 +1,170 @@
1
+ var userLog = (function(){
2
+ //
3
+ // Private variables
4
+ //
5
+ var defaults = {
6
+
7
+ // Available functionality
8
+ clickCount: true,
9
+ clickDetails: true,
10
+
11
+ // Action Item
12
+ actionItem: {
13
+ processOnAction: false,
14
+ selector: '',
15
+ event: ''
16
+ },
17
+ processTime: 15,
18
+ processData: function(results, statistics_url){
19
+ console.log(results);
20
+ },
21
+ },
22
+ // End results, what is shown to the user
23
+ results = {
24
+ userReferrer: '',
25
+ time: {
26
+ totalTime: 0,
27
+ timeOnPage: 0,
28
+ timestamp: 0
29
+ },
30
+ clicks: {
31
+ clickCount:0,
32
+ clickDetails: []
33
+ },
34
+
35
+ },
36
+ support = !!document.querySelector && !!document.addEventListener,
37
+ data_receiver = '',
38
+ app_token = '',
39
+ settings;
40
+
41
+ // Helper Functions
42
+ var helperActions = {
43
+
44
+ userReferrer: function (){
45
+ result = document.referrer;
46
+ results.userReferrer = 10;
47
+ },
48
+
49
+ /**
50
+ * Detect the X,Y coordinates of the mouse movement
51
+ * @private
52
+ */
53
+ mouseMovement: function(){
54
+ document.addEventListener('mousemove', function(){
55
+ results.mouseMovements.push({
56
+ timestamp: Date.now(),
57
+ x: event.pageX,
58
+ y: event.pageY
59
+ });
60
+ });
61
+ },
62
+ }
63
+
64
+ /**
65
+ * Merge defaults with options
66
+ * @private
67
+ * @param {Object} default settings
68
+ * @param {Object} user options
69
+ * @returns {Object} merged object
70
+ */
71
+ function getSettings(defaults, options){
72
+ var option;
73
+ for(option in options){
74
+ if(options.hasOwnProperty(option)){
75
+ defaults[option] = options[option];
76
+ }
77
+ }
78
+ return defaults;
79
+ }
80
+
81
+ /**
82
+ * Initialize the event listeners
83
+ * @public
84
+ * @param {Object} user options
85
+ */
86
+ function init(statistics_url, token, options){
87
+ if(!support) return;
88
+ data_receiver = statistics_url;
89
+ app_token = token;
90
+
91
+ // Extend default options
92
+ if (options && typeof options === "object") {
93
+ settings = getSettings(defaults, options);
94
+ }
95
+
96
+ document.addEventListener('DOMContentLoaded', function() {
97
+
98
+ // Countdown Timer
99
+ window.setInterval(function(){
100
+ if(document['visibilityState'] === 'visible'){
101
+ results.time.timeOnPage++;
102
+ }
103
+ results.time.totalTime++;
104
+ // Check if we need to process results
105
+ if(settings.processTime > 0 && results.time.totalTime % settings.processTime === 0){
106
+ processResults();
107
+ }
108
+ },1000);
109
+ results.time.timestamp = (function() {
110
+ return Math.round((+new Date())/1000);
111
+ })();
112
+
113
+ // Click registration, increment click counter and save click time+position
114
+ if(settings.clickCount || settings.clickDetails){
115
+ document.addEventListener('mouseup', function(){
116
+ if(settings.clickCount){
117
+ results.clicks.clickCount++;
118
+ }
119
+ if(settings.clickDetails){
120
+ results.clicks.clickDetails.push({
121
+ timestamp: Date.now(),
122
+ node: event.target.outerHTML,
123
+ x: event.pageX,
124
+ y: event.pageY
125
+ });
126
+ }
127
+ });
128
+ }
129
+
130
+ // Mouse movements
131
+ if(settings.mouseMovement){
132
+ helperActions.mouseMovement();
133
+ }
134
+
135
+ // referral
136
+ if(settings.userReferrer){
137
+ helperActions.userReferrer();
138
+ }
139
+
140
+ // Event Listener to porcess
141
+ if(settings.actionItem.processOnAction){
142
+ var node = document.querySelector(settings.actionItem.selector);
143
+ if(!!!node) throw new Error('Selector was not found.');
144
+ node.addEventListener(settings.actionItem.event, function(){
145
+ return processResults();
146
+ })
147
+ }
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Calls provided function with results as parameter
153
+ * @public
154
+ */
155
+ function processResults(){
156
+ if(settings.hasOwnProperty('processData')){
157
+ var result = settings.processData.call(undefined, results, data_receiver, app_token);
158
+ results.clicks.clickDetails = []
159
+ return result;
160
+ }
161
+ return false;
162
+ }
163
+
164
+
165
+ // Module pattern, only expose necessary methods
166
+ return {
167
+ init: init,
168
+ processResults: processResults,
169
+ };
170
+ })();
@@ -0,0 +1,20 @@
1
+ module TrueandcoAnalytics
2
+ class ArrJsonsToArrHash
3
+
4
+ def initialize(arr_json)
5
+ @arr_json = arr_json
6
+ end
7
+
8
+ def execute
9
+ result = []
10
+ @arr_json.each do |json|
11
+ result << JSON.parse(json)
12
+ end
13
+ result
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :arr_json
19
+ end
20
+ end
@@ -0,0 +1,65 @@
1
+ module TrueandcoAnalytics
2
+ module MetricC
3
+ class AddList
4
+
5
+ def initialize(metric_user, session, user_session_data)
6
+ if metric_user.nil? || session.nil? || user_session_data.nil?
7
+ raise ArgumentError.new("#{self.to_s} metric_user=#{metric_user}
8
+ session=#{session} user_session_data=#{user_session_data}")
9
+ end
10
+ @metric_user = metric_user
11
+ @session = session
12
+ @user_session_data = user_session_data
13
+ end
14
+
15
+ def execute
16
+ uniq_pages = info_uniq_page
17
+ return if uniq_pages.nil?
18
+ uniq_pages.each do |page|
19
+ data = {
20
+ metric_user: metric_user,
21
+ metric_user_session: session,
22
+ page_path: page['page_path'],
23
+ user_action: page['clicks']['clickDetails'].to_json,
24
+ time_s: page['time']['timeOnPage'],
25
+ is_buy: page['clicks']['clickDetails'].length > 0
26
+ }
27
+ MetricUserVisit.create(data)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :metric_user, :session, :user_session_data
34
+
35
+ def info_uniq_page
36
+ length = user_session_data.length
37
+ return user_session_data if length < 2
38
+ results = []
39
+ page = user_session_data[0]['page_path']
40
+ clickDetails = []
41
+ index = 0
42
+ while index < length - 1
43
+ unless user_session_data[index]['clicks']['clickDetails'].empty?
44
+ clickDetails = user_session_data[index]['clicks']['clickDetails']
45
+ end
46
+ index += 1
47
+ unless page == user_session_data[index]['page_path']
48
+ data = user_session_data[index - 1]
49
+ data['clicks']['clickDetails'] = clickDetails
50
+ results << data
51
+ page = user_session_data[index]['page_path']
52
+ clickDetails = []
53
+ end
54
+ end
55
+ data = user_session_data[index]
56
+ unless data['clicks']['clickDetails'].empty?
57
+ clickDetails = data['clicks']['clickDetails']
58
+ end
59
+ data['clicks']['clickDetails'] = clickDetails
60
+ results << data
61
+ results
62
+ end
63
+ end
64
+ end
65
+ end