trueandco_analytics 0.3.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 (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