referer_tracking 4.0.1 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +87 -23
- data/app/models/referer_tracking/tracking.rb +53 -0
- data/db/migrate/20150424090312_log_and_status.rb +6 -0
- data/lib/referer_tracking.rb +51 -22
- data/lib/referer_tracking/active_record_extensions.rb +11 -0
- data/lib/referer_tracking/controller_addons.rb +57 -0
- data/lib/referer_tracking/sweeper.rb +4 -66
- data/lib/referer_tracking/version.rb +1 -1
- data/test/dummy/app/controllers/users_controller.rb +12 -0
- data/test/dummy/app/models/user.rb +4 -0
- data/test/dummy/config/environments/test.rb +6 -1
- data/test/dummy/config/initializers/referer_tracking.rb +0 -2
- data/test/dummy/config/routes.rb +4 -1
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +17 -15
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +8 -0
- data/test/dummy/log/test.log +28156 -281
- data/test/dummy/tmp/cache/assets/test/sprockets/2cd8dbafa2066abde725994dae1058c3 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/669c55c2bc3e16bcc6e4ca54b102fda6 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e067a273d5fdb6cc978465b152e662b5 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/fd2dc9334cabdf1812653883c577dfaf +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/0G3oFbqJ7eFUY0UdwEjScsfwwbPpWiWBNw09qdd1ohI.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/0Z6bW0B1kuGtkIeYr4ThAL4uqYBz_KTiRnIbWojB7Aw.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/1H1i5_RyMh4B7slWyR-5HmOLlYMLqwBoIHac9sf2UGU.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/2i17CO5DMhuAQ23V2NrBSC1m1qGbVEcfTQPOZvRGs8E.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/46JXON6AslwNbbvz__9ddRiVifnFuk8ifD2rSIS85-M.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/4JY-SwetEJ9O6ZGcQcZ26z5Lwa71xMfRmfgrUMivfFY.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/523-OCQbCRB1j_tlqIjEssUe6m7reS6feGOWn7hrV4c.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/8SS1Jdp7AgUHgLl0L-2n3KE2-WflAeaChclAGEW_SFM.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/8yLF7Pm-8w-1cv3HnmHv6MSOWaTEPh6hBWRdTY7eCrI.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/9rTAa3n4m_1tnYuo_PQBUe9AHWAx8DmbK07tjEDBJYk.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Awt8aE1L6iJxPHDB19XLUcrdBHzK7yH-x57kv_NKojU.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Bee-ZlOeMpd0qyQPbZ3i8ZoH7Yhw2coD8YL3-9GViAw.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/DQ-VfoAVjHpu1y8DR1HQVmz_IAVzAgEOv2UGjbvlMLM.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/EQ5-Zi3kqng0IGc-dOuC3Nb6AJ7itxt2EhoMRjAZM78.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/HBa9hNZdUCrVlnn4DcWwu8ujBPsPhHj-SzAxTHx3gyM.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/JoQJIRS5fitTPBwEToHFffx8wzQh1OGFAu5xDSz11I8.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/MTXn13WRB7BfO1V3dblDHLOM3_n2bwr2PxtPNg0eo9A.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/MVvZCkjLbPbkR9gt8wskucEPJHuRZbsq0WzftgYgBrs.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/NGMpC_EFlJjbA20OjGoJtJfynmG55lVXqEBQElL0J8c.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/NW6MHRYmTMyI512aPcOJ4s6tgW0o_sXXmgrqQfKzkSs.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/O2agJjKw-HXlfsSATA2_aeqgAYO4bWrWRd1bcTN5_C0.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/OVj6tY43u7jqUGurvVYkWx3HFRru4oH1hxmXKnz_itc.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/PWG7LBu6STtK0n1rFJDQjW5x3J7tQd_Ij06lNYAzym0.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/PghEL7Jal_M5xfjdzxnW-Jiq-6kt7W49FaF44yRK3Yk.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/RYnKHL96X2OWT7cQwEm1CEbN-kP9jamPCD8Viq5WOJs.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/RvE2VrcnvR4vet1dyPKMSOu-qTSXJUVbsONOudiUiqo.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/YhdJORPRV4WeWGbpN4lF7qM1JemsU0sSBBFSeCjK5Zk.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/_zleWcY3FPsUHamwtaWVGPFC2ZrfVEdPcPxtZ0ncAKQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/aOYT6AMsiiCTko9bck34eQ_cpji7JFJkcO6Gih7XwY0.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/e6QsN5AJT0NQ1szDvc8kkfCz6XVVjVWDNHKP6f0YoSo.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/esK4x1b0AOlLi9q6KDmOPKMPG6uS7tF2XVFfrQpIgwU.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/fUBHMp2rRJ2R0D76_G51M7lBmOZpVQzuaSjbitW7IFc.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/gBSV6LbejlEAByktpuqDpXQOiHSTl-EHI5c0MW6-8rw.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/guTw1gpaRgyeuxZQ3eQFePUZcp9d-v1IWXG5qm_PTGY.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/hM0aSE9SRyMgQSqQY_G3js1_4dSng4Q9vnWpgMqFWTc.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/hg6DQjmNFxgP1ABwg213wrPGMurhGbyC2SJWF_eR3EM.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/i0po6m1De10_m-wY5hbOaMN1dZbKIitPo3bn9EcqeA4.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/igBCEQJL_hNTNkZQWbXcg0FX23pPTcv61SiuP8sww4Q.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/im21DLPpH4nyd4LX8cmORbNfg7jUx_PEXXMwJA87Qsw.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/joYQeCzbCCq4TvDcSpRWsiaR0i4HVRDhLBrQOenKw_U.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/jpA0RKjvuqt6qEaIASWc8qU1VB0Aydp6JgbzLhpGUOQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/k__HZRe6MJEx_es4mae2UKNJ7S-xQjjtNvuWfURI2L8.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kl1-ITbGxlNpIH_bdRiAd4APIX9fZOYgmo0XXZcrvgo.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/mUqHquf2Zmd8u6uiyK61Ezlu1TcpGRVaTOWUxxGEi1Q.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/n8Aje18PD8oQE5TPpOTUD3BGZ7_TmvPPZ5eXDXoq8Gg.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ngUc-SbI6D2rZ8MAICdvGgIewOpQ-2Pl0CILWKGcq3U.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/pwDXjciqVi1_CS4MlD2TH1ZqbzXchkMonNpsttR96Vk.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/qkq4_FDzkYw-Jgf-PQ1QvZRMOcpJieAhpakErII07uI.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/qmTv4Or54pJag3e-RuC8J8YBw5WvkzqP36yA1qF7brA.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/r6gN_QsTAf7c1o4Cst-frjvGHokmbxsEOdSr4mkMEJI.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/reN5Eb8r7-aFzpa3gnf0d-hIULaqBhZbU3j6bHL8c54.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ss0roaA9M5TQHC9lcaT0WzZ401TWw-pTCBcrTYorKrU.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/tZ-5zRkNGhZpjLydDPN14TgvqrG-sRsmhjHmD16K9w4.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/uAeR8lWRY18fsV62fVeVlDfQL-0svUgCWxUntrKiscM.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ut0rmLnfJ-Ischq127ylQ8-6EKVPTiko_mqVVAuMli8.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/vXSDU5apajRzjlgKITJW6ww-R5nViNgTca-WgN2rQjA.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/v_Ilb0G5vj-RNZGvNkGntio2WXLwx0dLgXj22KrEF1A.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/xE2R25fLVYnFI2W6I4LvT03gascYQsI-YR4dr_274d8.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/xyZgV6TicjUr8zQ2arynATHycCL5HEg4v44PTplSlCE.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/y9ZtIMFclPh-m6WSjAOTLR1Oz8oUv8IF4DdJDKgCgDE.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/zhLZKiMTXH3IgicVp2uI18ziLOLaV51MjYysWkjSLrw.cache +0 -0
- data/test/integration/referer_tracking/has_tracking_test.rb +31 -0
- data/test/integration/referer_tracking/referer_session_test.rb +42 -27
- data/test/test_helper.rb +1 -0
- data/test/tracking_test.rb +70 -0
- metadata +143 -9
- data/app/models/referer_tracking/referer_tracking.rb +0 -16
- data/test/referer_tracking_test.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f76b2d97ed6189bcd59080ee488692d971725a6d
|
4
|
+
data.tar.gz: f61ed77ebefe501cbe68f5d914dc99c1fcc4623e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b72c2026389dd1ea8fa9d1e982cf5a32860c88984331dc4e9f59eddb6f94541a009f78f5801542bf02fa44f450b1b92c49e0f68cafd8d700af0e4c3d22365be2
|
7
|
+
data.tar.gz: 5ba921e4ddf08d95dddd2d2bc3f7f17bc47ac9c9fb41132cd4036a375942ee7e0bdf5cc80b41a8e70f04329b75ba6ecd90d025ab34176875829ea5b226643607
|
data/README.md
CHANGED
@@ -1,22 +1,61 @@
|
|
1
1
|
# RefererTracking
|
2
2
|
|
3
3
|
Referer tracking automates better tracking in your Rails app. It tells you who creates
|
4
|
-
activerecord objects / models, where did they originally come from, what url did they use etc.
|
4
|
+
activerecord objects / models, where did they originally come from (http referrer), what url did they use etc.
|
5
5
|
It does it by saving referrer url to session and saving information about the request when creating new item.
|
6
|
-
It enables you to optimize your web-app user interface and flow.
|
7
6
|
|
8
|
-
|
9
|
-
saved to referer_trackings table. Also current request url and current request referer are saved.
|
7
|
+
Also you have tools to add log lines to tracking to get better information about flow of the users or how ab-tests affect later usage.
|
10
8
|
|
11
|
-
|
9
|
+
[<img src="https://secure.travis-ci.org/holli/referer_tracking.png" />](http://travis-ci.org/holli/referer_tracking)
|
10
|
+
|
11
|
+
## Example use cases
|
12
12
|
|
13
13
|
```
|
14
|
-
|
14
|
+
- Example configuration
|
15
|
+
- In UsersController.create
|
16
|
+
- referer_tracking_after_create(@user) # saves all referrer etc information
|
17
|
+
- @user.tracking_add_log_line('signup_ab_testing_b_variation') # having ab testing? Mark where user is going
|
18
|
+
- In SessionsController.create
|
19
|
+
- @user.tracking_add_log_line('10:th login')
|
20
|
+
- In some scheduled script
|
21
|
+
- @user.tracking_update_status('active') if @user.login_count > 10 && @user.blog_posts.count > 1
|
15
22
|
```
|
16
23
|
|
17
|
-
|
24
|
+
Later you can query how specific objects were made. It will let you know how did the user end up in your page and where did he create the object. This gem helps you to save data. But you still have to do the queries scripts yourself.
|
25
|
+
|
26
|
+
**How about last 100 objects with information about first pages (landing pages) and their flow**
|
27
|
+
|
28
|
+
```
|
29
|
+
RefererTracking::Tracking.where(:trackable_type => 'User').last(100).collect{|tracking| [tracking.first_url, tracking.referer_url, tracking.current_request_referer_url]}
|
30
|
+
# [['http://mysite.com/landing_page_01', 'http://google.com/...', 'http://mysite.com/signup_v01/hello'] ... ]
|
31
|
+
```
|
32
|
+
|
33
|
+
**How does specific landing page work**
|
34
|
+
|
35
|
+
```
|
36
|
+
landing_a = RefererTracking::Tracking.where(:trackable_type => 'User').find_all{|tracking| tracking.first_url.match(/yourdomain.com\/landing_page_b/)}
|
37
|
+
puts landing_a.collect{|tracking| tracking.trackable.name}
|
38
|
+
- instead of just looking creation numbers you can also see who came from there and how fast did they do their 10:th login
|
39
|
+
```
|
40
|
+
|
41
|
+
**Checking if some flow results in better conversion than other**
|
42
|
+
|
43
|
+
```
|
44
|
+
variation_a = RefererTracking::Tracking.where(:trackable_type => 'User').find_all{|tracking| tracking.get_log_lines('signup_ab_testing_a_variation')}
|
45
|
+
variation_b = RefererTracking::Tracking.where(:trackable_type => 'User').find_all{|tracking| tracking.get_log_lines('signup_ab_testing_b_variation')}
|
46
|
+
puts "var_a: #{variation_a.size}, active count #{variation_a.count{|tracking| tracking.status == 'active'}"
|
47
|
+
puts "var_b: #{variation_b.size}, active count #{variation_b.count{|tracking| tracking.status == 'active'}"
|
48
|
+
```
|
18
49
|
|
19
|
-
|
50
|
+
**Or maybe checking how user_agent affects conversion**
|
51
|
+
|
52
|
+
```
|
53
|
+
RefererTracking::Tracking.where(:trackable_type => 'User').find_all{|tracking| tracking.user_agent.to_s.include?('Android')}
|
54
|
+
```
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
## Automatically monitored items
|
20
59
|
|
21
60
|
```
|
22
61
|
- session_referer_url - where did the user originally come from - saved in session
|
@@ -30,6 +69,8 @@ You can query how specific objects were made by querying following. It will let
|
|
30
69
|
- user_agent, ip, session_id
|
31
70
|
- cookies_yaml - saves cookies if enabled in initializers with RefererTracking.save_cookies = true
|
32
71
|
- handy for parsing information related to google analytics, e.g. number of visits
|
72
|
+
- status - use by model.tracking_update_status('active') etc to add information
|
73
|
+
- log - so you can add lines later
|
33
74
|
```
|
34
75
|
|
35
76
|
|
@@ -46,24 +87,42 @@ in /gemfile
|
|
46
87
|
|
47
88
|
```
|
48
89
|
|
49
|
-
## Configure
|
90
|
+
## Configure / Usage
|
50
91
|
|
51
92
|
```
|
52
93
|
|
53
|
-
ApplicationController
|
54
|
-
include RefererTracking::ControllerAddons
|
94
|
+
class ApplicationController ... # in application_controller.rb
|
95
|
+
include RefererTracking::ControllerAddons # saves first visit infos to session and cookie
|
96
|
+
end
|
97
|
+
|
98
|
+
class User < Activerecord::Base
|
99
|
+
has_tracking
|
55
100
|
end
|
56
101
|
|
57
|
-
|
102
|
+
# By using sweepers
|
103
|
+
# also add to Gemfile "gem 'rails-observers'"
|
104
|
+
class UsersController
|
58
105
|
# This monitors saved items and creates RefererTracking items in db, enable in controllers you want it to be used
|
59
106
|
cache_sweeper RefererTracking::Sweeper
|
60
107
|
end
|
61
108
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
109
|
+
# Or by using custom methods
|
110
|
+
class UsersController
|
111
|
+
def create
|
112
|
+
@user = User.create
|
113
|
+
referer_tracking_after_create(@user)
|
114
|
+
end
|
115
|
+
|
116
|
+
def login
|
117
|
+
if @user.login_count == 10
|
118
|
+
@user.tracking_add_log_line("10_logins")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
66
124
|
|
125
|
+
/config/initializers/referer_tracking.rb # if you want to modify defaults, see https://github.com/holli/referer_tracking/blob/master/lib/referer_tracking.rb#L5
|
67
126
|
RefererTracking.save_cookies = true # saves all cookies to db
|
68
127
|
RefererTracking.set_referer_cookies = true # saves referer and first url data to cookie
|
69
128
|
# You should use it unless you are very performance minded : http://yuiblog.com/blog/2007/03/01/performance-research-part-3/
|
@@ -91,12 +150,17 @@ end
|
|
91
150
|
|
92
151
|
**Helpers include**
|
93
152
|
|
94
|
-
-
|
95
|
-
-
|
96
|
-
-
|
97
|
-
-
|
98
|
-
-
|
99
|
-
-
|
153
|
+
- **In Controllers**
|
154
|
+
- referer_tracking_first_request?
|
155
|
+
- referer_tracking_add_info(key, value) # only set in the first time called - saved in session
|
156
|
+
- referer_tracking_set_info(key, value) # change value always - saved in session
|
157
|
+
- referer_tracking_get_key(key)
|
158
|
+
- referer_tracking_request_set_info
|
159
|
+
- referer_tracking_request_add_infos # hash of current request infos
|
160
|
+
- **In Models** (E.g. when including in user-model)
|
161
|
+
- user.tracking_update_status('active')
|
162
|
+
- user.tracking_add_log_line('10:th login') # e.g. to track users flow
|
163
|
+
- user.tracking.get_log_lines(/login/) # results all log lines matching regexp
|
100
164
|
|
101
165
|
## Inside
|
102
166
|
|
@@ -105,7 +169,7 @@ is not recommended but possible with session[:referer_tracking]. Information is
|
|
105
169
|
|
106
170
|
## Requirements
|
107
171
|
|
108
|
-
Gem has been tested with
|
172
|
+
Gem has been tested with latest Ruby and Rails combinations, see https://github.com/holli/referer_tracking/blob/master/.travis.yml for more info.
|
109
173
|
|
110
174
|
[<img src="https://secure.travis-ci.org/holli/referer_tracking.png" />](http://travis-ci.org/holli/referer_tracking)
|
111
175
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module RefererTracking
|
2
|
+
class Tracking < ActiveRecord::Base
|
3
|
+
self.table_name = "referer_trackings"
|
4
|
+
belongs_to :trackable, :polymorphic => true
|
5
|
+
serialize :infos_session, Hash
|
6
|
+
serialize :infos_request, Hash
|
7
|
+
attr_accessible :trackable_id, :trackable_type, :cookie_referer_url, :cookie_first_url, :user_agent, :cookies_yaml, :current_request_referer_url
|
8
|
+
|
9
|
+
def first_url_combined
|
10
|
+
cookie_first_url || session_first_url
|
11
|
+
end
|
12
|
+
def referer_url_combined
|
13
|
+
cookie_referer_url || session_referer_url
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
def status=(new_status)
|
19
|
+
if status != new_status
|
20
|
+
write_attribute(:status, new_status)
|
21
|
+
add_log_line("status #{new_status}", save_model: false)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
def update_status(new_status, save_model: true)
|
25
|
+
if status != new_status
|
26
|
+
write_attribute(:status, new_status)
|
27
|
+
add_log_line("status #{new_status}", save_model: save_model)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_log_line(log_line, save_model: true)
|
32
|
+
Rails.logger.info("RefererTracking add_log_line to #{trackable_type}.#{trackable_id}: #{log_line}")
|
33
|
+
|
34
|
+
log_line = log_line.to_s.gsub("\n", ' ')
|
35
|
+
str = "#{Time.now.utc.to_s(:db)}: #{log_line}\n"
|
36
|
+
self.log = log.to_s + str
|
37
|
+
|
38
|
+
save if save_model
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_log_lines(regexp)
|
42
|
+
lines = log.to_s.lines.find_all{|str| str.match(regexp)}
|
43
|
+
lines.collect{|str| [ActiveSupport::TimeZone["UTC"].parse(str), str.split(": ", 2).last.to_s.strip]}
|
44
|
+
end
|
45
|
+
|
46
|
+
def log=(val)
|
47
|
+
write_attribute :log, val
|
48
|
+
end
|
49
|
+
private :'log='
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/lib/referer_tracking.rb
CHANGED
@@ -1,42 +1,71 @@
|
|
1
|
-
# Since ActionController::Caching::Sweeper was removed from rails core in 4
|
2
|
-
# and moved to gem rails-observers, we have trouble loading stuff in the right order
|
3
|
-
# (see lib/referer_tracking/sweeper.rb).
|
4
|
-
# Manually loading these here fixes the problem for now:
|
5
|
-
require "rails/observers/activerecord/active_record"
|
6
|
-
require "rails/observers/action_controller/caching"
|
7
|
-
|
8
1
|
require "referer_tracking/engine"
|
9
|
-
require "referer_tracking/controller_addons"
|
10
|
-
require "referer_tracking/sweeper"
|
11
2
|
|
12
3
|
module RefererTracking
|
13
4
|
|
14
|
-
mattr_accessor :save_cookies, :set_referer_cookies, :set_referer_cookies_name, :set_referer_cookies_first_url_max_length, :set_referer_cookies_ref_url_max_length
|
5
|
+
mattr_accessor :save_cookies, :set_referer_cookies, :set_referer_cookies_name, :set_referer_cookies_first_url_max_length, :set_referer_cookies_ref_url_max_length, :use_observer_sweeper_if_found
|
15
6
|
|
16
7
|
self.save_cookies = true
|
17
8
|
self.set_referer_cookies = true
|
18
9
|
self.set_referer_cookies_name = 'ref_track'
|
19
10
|
self.set_referer_cookies_first_url_max_length = 400
|
20
11
|
self.set_referer_cookies_ref_url_max_length = 200
|
12
|
+
self.use_observer_sweeper_if_found = true # if you have gem 'rails-observers' included we will use sweepers to save infos
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
|
15
|
+
|
16
|
+
mattr_accessor :add_observe_to_classes
|
17
|
+
self.add_observe_to_classes = []
|
18
|
+
def self.add_sweeper_model(model)
|
19
|
+
unless RefererTracking.add_observe_to_classes.include?(model)
|
20
|
+
RefererTracking.add_observe_to_classes.push(model)
|
21
|
+
RefererTracking.copy_sweeper_models_to_sweeper
|
27
22
|
end
|
23
|
+
end
|
28
24
|
|
29
|
-
|
30
|
-
|
25
|
+
def self.copy_sweeper_models_to_sweeper
|
26
|
+
if defined?(RefererTracking::Sweeper) && RefererTracking.use_observer_sweeper_if_found
|
27
|
+
RefererTracking::Sweeper.class_eval do
|
28
|
+
observe RefererTracking.add_observe_to_classes
|
29
|
+
end
|
30
|
+
Rails.logger.info("RefererTracking sweeper observing classes #{RefererTracking::Sweeper.observed_classes}")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
|
35
|
+
|
36
|
+
class Railtie < Rails::Railtie
|
37
|
+
initializer 'referer_tracking.insert_into_active_record' do
|
38
|
+
ActiveSupport.on_load :active_record do
|
39
|
+
require 'referer_tracking/active_record_extensions'
|
40
|
+
ActiveRecord::Base.send(:extend, RefererTracking::ActiveRecordExtension)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
initializer 'referer_tracking.sweeper', :after => 'action_controller.caching.sweepers' do
|
45
|
+
ActiveSupport.on_load(:action_controller) do
|
46
|
+
if defined?(ActionController::Caching::Sweeper)
|
47
|
+
require "referer_tracking/sweeper"
|
48
|
+
RefererTracking.copy_sweeper_models_to_sweeper
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
initializer 'referer_tracking.sweeper', :after => 'action_controller.caching.sweepers' do
|
54
|
+
ActiveSupport.on_load(:action_controller) do
|
55
|
+
if defined?(ActionController::Caching::Sweeper) && RefererTracking.use_observer_sweeper_if_found
|
56
|
+
require "referer_tracking/sweeper"
|
57
|
+
RefererTracking.copy_sweeper_models_to_sweeper
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
initializer 'referer_tracking.controller_addons', :after => 'action_controller' do
|
63
|
+
ActiveSupport.on_load(:action_controller) do
|
64
|
+
require "referer_tracking/controller_addons"
|
38
65
|
end
|
39
66
|
end
|
67
|
+
|
40
68
|
end
|
41
|
-
|
69
|
+
|
42
70
|
end
|
71
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module RefererTracking::ActiveRecordExtension
|
2
|
+
def has_referer_tracking
|
3
|
+
has_one :tracking, :class_name => "RefererTracking::Tracking", :as => :trackable
|
4
|
+
class_eval do
|
5
|
+
delegate :add_log_line, to: :tracking, prefix: true, allow_nil: true
|
6
|
+
delegate :'update_status', to: :tracking, prefix: true, allow_nil: true
|
7
|
+
end
|
8
|
+
|
9
|
+
RefererTracking.add_sweeper_model(self)
|
10
|
+
end
|
11
|
+
end
|
@@ -28,6 +28,61 @@ module RefererTracking::ControllerAddons
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
def referer_tracking_after_create(record)
|
32
|
+
@referer_tracking_saved_records = [] if @referer_tracking_saved_records.nil?
|
33
|
+
if session && session["referer_tracking"]
|
34
|
+
ses = session["referer_tracking"]
|
35
|
+
|
36
|
+
ref_mod = @referer_tracking_saved_records.find { |ref_mod| ref_mod.trackable == record || (record.id && ref_mod.trackable_id == record.id && ref_mod.trackable_type == record.class.to_s) }
|
37
|
+
if ref_mod.nil?
|
38
|
+
#ref_mod = RefererTracking::Tracking.new(:trackable_id => record.id, :trackable_type => record.class.to_s)
|
39
|
+
ref_mod = record.build_tracking
|
40
|
+
@referer_tracking_saved_records.push(ref_mod)
|
41
|
+
end
|
42
|
+
|
43
|
+
ses.each_pair do |key, value|
|
44
|
+
ref_mod[key] = value if ref_mod.has_attribute?(key)
|
45
|
+
ref_mod.infos_session[key] = value unless [:session_referer_url, :session_first_url].include?(key)
|
46
|
+
end
|
47
|
+
|
48
|
+
req = @referer_tracking_request_add_infos
|
49
|
+
if req && req.is_a?(Hash)
|
50
|
+
req.each_pair do |key, value|
|
51
|
+
ref_mod[key] = value if ref_mod.has_attribute?(key)
|
52
|
+
ref_mod.infos_request[key] = value
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
ref_mod[:ip] = request.ip
|
57
|
+
ref_mod[:user_agent] = request.env['HTTP_USER_AGENT']
|
58
|
+
ref_mod[:current_request_url] = request.url
|
59
|
+
ref_mod[:current_request_referer_url] = request.env["HTTP_REFERER"] # or request.headers["HTTP_REFERER"]
|
60
|
+
ref_mod[:session_id] = request.session["session_id"]
|
61
|
+
|
62
|
+
unless cookies[RefererTracking.set_referer_cookies_name].blank?
|
63
|
+
cookie_ver, cookie_time_org, cookie_first_url, cookie_referer_url = cookies[RefererTracking.set_referer_cookies_name].to_s.split("|||")
|
64
|
+
ref_mod[:cookie_first_url] = cookie_first_url
|
65
|
+
ref_mod[:cookie_referer_url] = cookie_referer_url
|
66
|
+
ref_mod[:cookie_time] = Time.at(cookie_time_org.to_i)
|
67
|
+
end
|
68
|
+
|
69
|
+
if RefererTracking.save_cookies
|
70
|
+
begin
|
71
|
+
ref_mod[:cookies_yaml] = cookies.instance_variable_get('@cookies').to_yaml
|
72
|
+
rescue
|
73
|
+
str = "referer_tracking after create problem encoding cookie yml, probably non utf8 chars #{e}"
|
74
|
+
logger.error(str)
|
75
|
+
ref_mod[:cookies_yaml] = "error: #{str}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
ref_mod.save unless ref_mod.trackable.new_record?
|
80
|
+
end
|
81
|
+
|
82
|
+
rescue Exception => e
|
83
|
+
Rails.logger.info "RefererTracking::Sweeper.after_create problem with creating record: #{e}"
|
84
|
+
end
|
85
|
+
|
31
86
|
###############################################
|
32
87
|
# Session add methods
|
33
88
|
|
@@ -77,6 +132,7 @@ module RefererTracking::ControllerAddons
|
|
77
132
|
request.user_agent =~ /bot/i
|
78
133
|
end
|
79
134
|
|
135
|
+
###############################################
|
80
136
|
|
81
137
|
def self.included(base)
|
82
138
|
base.class_eval do
|
@@ -88,5 +144,6 @@ module RefererTracking::ControllerAddons
|
|
88
144
|
end
|
89
145
|
end
|
90
146
|
|
147
|
+
|
91
148
|
end
|
92
149
|
|
@@ -1,73 +1,11 @@
|
|
1
1
|
class RefererTracking::Sweeper < ActionController::Caching::Sweeper
|
2
|
-
|
3
|
-
if session && session["referer_tracking"]
|
4
|
-
ses = session["referer_tracking"]
|
5
|
-
|
6
|
-
ref_mod = RefererTracking::RefererTracking.new(
|
7
|
-
:trackable_id => record.id, :trackable_type => record.class.to_s)
|
8
|
-
|
9
|
-
ses.each_pair do |key, value|
|
10
|
-
ref_mod[key] = value if ref_mod.has_attribute?(key)
|
11
|
-
ref_mod.infos_session[key] = value unless [:session_referer_url, :session_first_url].include?(key)
|
12
|
-
end
|
13
|
-
|
14
|
-
req = assigns(:referer_tracking_request_add_infos)
|
15
|
-
if req && req.is_a?(Hash)
|
16
|
-
req.each_pair do |key, value|
|
17
|
-
ref_mod[key] = value if ref_mod.has_attribute?(key)
|
18
|
-
ref_mod.infos_request[key] = value
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
ref_mod[:ip] = request.ip
|
23
|
-
ref_mod[:user_agent] = request.env['HTTP_USER_AGENT']
|
24
|
-
ref_mod[:current_request_url] = request.url
|
25
|
-
ref_mod[:current_request_referer_url] = request.env["HTTP_REFERER"] # or request.headers["HTTP_REFERER"]
|
26
|
-
ref_mod[:session_id] = request.session["session_id"]
|
27
|
-
|
28
|
-
unless cookies[RefererTracking.set_referer_cookies_name].blank?
|
29
|
-
cookie_ver, cookie_time_org, cookie_first_url, cookie_referer_url = cookies[RefererTracking.set_referer_cookies_name].to_s.split("|||")
|
30
|
-
ref_mod[:cookie_first_url] = RefererTracking::Sweeper.try_to_parse(cookie_first_url)
|
31
|
-
ref_mod[:cookie_referer_url] = RefererTracking::Sweeper.try_to_parse(cookie_referer_url)
|
32
|
-
ref_mod[:cookie_time] = Time.at(cookie_time_org.to_i)
|
33
|
-
end
|
2
|
+
# https://github.com/rails/rails-observers/blob/master/lib/rails/observers/active_model/observing.rb
|
34
3
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
rescue
|
39
|
-
str = "referer_tracking after create problem encoding cookie yml, probably non utf8 chars #{e}"
|
40
|
-
logger.error(str)
|
41
|
-
ref_mod[:cookies_yaml] = "error: #{str}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
ref_mod.save
|
4
|
+
def after_create(record)
|
5
|
+
if controller && controller.respond_to?(:referer_tracking_after_create)
|
6
|
+
controller.referer_tracking_after_create(record)
|
46
7
|
end
|
47
|
-
|
48
|
-
rescue Exception => e
|
49
|
-
Rails.logger.info "RefererTracking::Sweeper.after_create problem with creating record: #{e}"
|
50
8
|
end
|
51
9
|
|
52
|
-
def self.try_to_parse(url)
|
53
|
-
orig_url = url
|
54
|
-
rescued = false
|
55
|
-
err_count = 0
|
56
|
-
err_limit = 4
|
57
|
-
loop do
|
58
|
-
err = false
|
59
|
-
begin
|
60
|
-
URI.parse(url)
|
61
|
-
rescue URI::InvalidURIError
|
62
|
-
rescued = true
|
63
|
-
err = true
|
64
|
-
err_count+= 1
|
65
|
-
url = url[0...-1]
|
66
|
-
end
|
67
|
-
break if !err or err_count == err_limit
|
68
|
-
end
|
69
|
-
if(rescued && defined? logger) then logger.info("failed parsing with url: " +orig_url) end
|
70
|
-
return (err_count == err_limit) ? orig_url : url
|
71
|
-
end
|
72
10
|
end
|
73
11
|
|