metry 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/README.txt +1 -0
- data/TODO +5 -5
- data/example/example.rb +2 -2
- data/features/basic_tracking.feature +5 -1
- data/features/step_definitions/tracking.rb +8 -0
- data/features/support/env.rb +1 -3
- data/lib/metry.rb +2 -1
- data/lib/metry/rack/tracking.rb +1 -0
- data/lib/metry/tokyo.rb +50 -22
- data/radiant/example/features/metry.feature +0 -1
- data/radiant/example/features/step_definitions/radiant.rb +12 -6
- data/radiant/example/features/step_definitions/tracking.rb +8 -0
- data/radiant/example/features/step_definitions/web.rb +4 -0
- data/radiant/example/features/support/env.rb +6 -0
- data/radiant/extension/metry_extension.rb +7 -0
- metadata +2 -2
data/History.txt
CHANGED
data/README.txt
CHANGED
data/TODO
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
1
|
+
Switch to MongoDB
|
2
|
+
Add ability to track goals in Psycho
|
3
|
+
Allow ignoring requests in Metry, and have Psycho requests ignored
|
4
|
+
Switch to submodules for vendor'd libs
|
2
5
|
|
3
|
-
|
6
|
+
More unit tests
|
4
7
|
|
5
8
|
Add support for non-pageview event tracking
|
6
9
|
Via in-process call
|
7
10
|
Via web request
|
8
11
|
|
9
|
-
Add support for MongoDB
|
10
|
-
Add support for Tokyo Tyrant
|
11
|
-
|
12
12
|
Metry visitors can be spoofed - fix it
|
data/example/example.rb
CHANGED
@@ -4,9 +4,9 @@ require 'sinatra'
|
|
4
4
|
require File.dirname(__FILE__) + '/../lib/metry'
|
5
5
|
|
6
6
|
configure do
|
7
|
-
Metry.init Metry::Tokyo.new("tracking")
|
8
|
-
#Metry.init Metry::Memory.new
|
7
|
+
Metry.init(ENV["USE_MEMORY"] ? Metry::Memory.new : Metry::Tokyo.new("tracking"))
|
9
8
|
use Metry::Rack::Tracking
|
9
|
+
use Metry::Psycho, {:path => "/admin/metry"}
|
10
10
|
end
|
11
11
|
|
12
12
|
get '/' do
|
@@ -1,5 +1,5 @@
|
|
1
1
|
Feature: Access Tracking
|
2
|
-
In order to how users are using my site
|
2
|
+
In order to know how users are using my site
|
3
3
|
As an web application creator
|
4
4
|
I want to have all accesses to my application tracked
|
5
5
|
|
@@ -38,6 +38,7 @@ Feature: Access Tracking
|
|
38
38
|
And there should be a tracking event "2":
|
39
39
|
| key | value |
|
40
40
|
| visitor | 1 |
|
41
|
+
And there should be a visitor "1"
|
41
42
|
|
42
43
|
Scenario: Two visitors are tracked
|
43
44
|
Given I view "/"
|
@@ -49,6 +50,9 @@ Feature: Access Tracking
|
|
49
50
|
And there should be a tracking event "2":
|
50
51
|
| key | value |
|
51
52
|
| visitor | 2 |
|
53
|
+
And there should be 2 visitors
|
54
|
+
And there should be a visitor "1"
|
55
|
+
And there should be a visitor "2"
|
52
56
|
|
53
57
|
Scenario: All facets should be tracked
|
54
58
|
When I view "/"
|
@@ -6,6 +6,10 @@ Then /^there should be (\d+) tracking events?$/ do |event_count|
|
|
6
6
|
assert_equal(event_count.to_i, Metry.current.event_count)
|
7
7
|
end
|
8
8
|
|
9
|
+
Then /^there should be (\d+) visitors$/ do |visitor_count|
|
10
|
+
assert_equal(visitor_count.to_i, Metry.current.visitor_count)
|
11
|
+
end
|
12
|
+
|
9
13
|
When /^there should be a tracking event "(\d+)":$/ do |id, table|
|
10
14
|
event = Metry.current[id]
|
11
15
|
assert event, "Unable to lookup event #{id}."
|
@@ -33,3 +37,7 @@ Then /^there should be a visitor "([^\"]*)":$/ do |id, table|
|
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
40
|
+
|
41
|
+
Then /^there should be a visitor "([^\"]*)"$/ do |id|
|
42
|
+
assert Metry.current.visitor(id)
|
43
|
+
end
|
data/features/support/env.rb
CHANGED
data/lib/metry.rb
CHANGED
data/lib/metry/rack/tracking.rb
CHANGED
data/lib/metry/tokyo.rb
CHANGED
@@ -17,43 +17,71 @@ module Metry
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def next_visitor
|
20
|
-
|
20
|
+
access do |storage|
|
21
21
|
storage.incr("#{META_PREFIX}visitor")
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def visitor(id)
|
26
|
-
|
26
|
+
access do |storage|
|
27
27
|
(storage[visitor_id(id)] || {})
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
|
33
|
-
storage
|
31
|
+
def visitor_count
|
32
|
+
access do |storage|
|
33
|
+
storage.query do |q|
|
34
|
+
q.add '', :starts_with, VISITOR_PREFIX
|
35
|
+
q.pk_only
|
36
|
+
end.size
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def visitors
|
41
|
+
access do |storage|
|
42
|
+
r = storage.query do |q|
|
43
|
+
q.add '', :starts_with, VISITOR_PREFIX
|
44
|
+
end.to_a
|
45
|
+
r.each{|e| e[:pk].sub!(/^#{VISITOR_PREFIX}/, '')}
|
46
|
+
r
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def save_visitor(id, hash={})
|
51
|
+
access do |storage|
|
52
|
+
storage[visitor_id(id)] = (visitor(id) || {}).merge(hash)
|
34
53
|
end
|
35
54
|
end
|
36
55
|
|
37
56
|
def <<(event)
|
38
|
-
|
57
|
+
access do |storage|
|
39
58
|
storage[next_event_id(storage)] = event.inject({}){|a,(k,v)| a[k] = v.to_s; a}
|
40
59
|
end
|
41
60
|
end
|
42
61
|
|
43
62
|
def [](id)
|
44
|
-
|
63
|
+
access do |storage|
|
45
64
|
storage[event_id(id)]
|
46
65
|
end
|
47
66
|
end
|
48
67
|
|
49
68
|
def event_count
|
50
|
-
|
69
|
+
access do |storage|
|
51
70
|
storage.keys(:prefix => EVENT_PREFIX).size
|
52
71
|
end
|
53
72
|
end
|
54
73
|
|
74
|
+
def events_for(visitor)
|
75
|
+
access do |storage|
|
76
|
+
storage.query do |q|
|
77
|
+
q.add '', :starts_with, EVENT_PREFIX
|
78
|
+
q.add 'visitor', :eq, visitor
|
79
|
+
end.to_a
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
55
83
|
def last_events(count=1)
|
56
|
-
|
84
|
+
access do |storage|
|
57
85
|
storage.query do |q|
|
58
86
|
q.add '', :starts_with, EVENT_PREFIX
|
59
87
|
q.order_by "time", :numdesc
|
@@ -63,7 +91,7 @@ module Metry
|
|
63
91
|
end
|
64
92
|
|
65
93
|
def all_events
|
66
|
-
|
94
|
+
access do |storage|
|
67
95
|
storage.query do |q|
|
68
96
|
q.add '', :starts_with, EVENT_PREFIX
|
69
97
|
end.to_a
|
@@ -71,7 +99,7 @@ module Metry
|
|
71
99
|
end
|
72
100
|
|
73
101
|
def clear
|
74
|
-
|
102
|
+
access do |storage|
|
75
103
|
storage.clear
|
76
104
|
end
|
77
105
|
end
|
@@ -82,24 +110,24 @@ module Metry
|
|
82
110
|
event_id(storage.incr("#{META_PREFIX}event"))
|
83
111
|
end
|
84
112
|
|
85
|
-
def access
|
86
|
-
|
113
|
+
def access
|
114
|
+
key = "metry_storage"
|
115
|
+
created_storage ||= false
|
116
|
+
unless storage = Thread.current[key]
|
117
|
+
created_storage = true
|
118
|
+
Thread.current[key] = storage = @store.new(@file, :mode => "wc")
|
119
|
+
end
|
87
120
|
begin
|
88
121
|
result = yield(storage)
|
89
122
|
ensure
|
90
|
-
|
123
|
+
if created_storage
|
124
|
+
storage.close
|
125
|
+
Thread.current[key] = nil
|
126
|
+
end
|
91
127
|
end
|
92
128
|
result
|
93
129
|
end
|
94
130
|
|
95
|
-
def read(&block)
|
96
|
-
access("rc", &block)
|
97
|
-
end
|
98
|
-
|
99
|
-
def write(&block)
|
100
|
-
access("wc", &block)
|
101
|
-
end
|
102
|
-
|
103
131
|
def visitor_id(id)
|
104
132
|
"#{VISITOR_PREFIX}#{id}"
|
105
133
|
end
|
@@ -1,9 +1,3 @@
|
|
1
|
-
Given /^I have a layout$/ do
|
2
|
-
Layout.create!(:name => "basic", :content => <<EOC)
|
3
|
-
<r:content />
|
4
|
-
EOC
|
5
|
-
end
|
6
|
-
|
7
1
|
Given /^a page at "([^\"]*)" containing:$/ do |path, content|
|
8
2
|
page = Page.create!(:title => "test", :breadcrumb => "test", :slug => path, :status_id => 100)
|
9
3
|
page.parts.create!(:name => "body", :content => content)
|
@@ -11,4 +5,16 @@ end
|
|
11
5
|
|
12
6
|
When /^there is an empty Radiant cache$/ do
|
13
7
|
Radiant::Cache.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
Given /^I log in as an admin$/ do
|
11
|
+
visit '/admin/login'
|
12
|
+
fill_in 'Username', :with => 'admin'
|
13
|
+
fill_in 'Password', :with => 'radiant'
|
14
|
+
click_button 'Login'
|
15
|
+
Then(%(I should be on "/admin/pages"))
|
16
|
+
end
|
17
|
+
|
18
|
+
When /^I log out$/ do
|
19
|
+
visit "/admin/logout"
|
14
20
|
end
|
@@ -6,6 +6,10 @@ Then /^there should be (\d+) tracking events?$/ do |event_count|
|
|
6
6
|
assert_equal(event_count.to_i, Metry.current.event_count)
|
7
7
|
end
|
8
8
|
|
9
|
+
Then /^there should be (\d+) visitors$/ do |visitor_count|
|
10
|
+
assert_equal(visitor_count.to_i, Metry.current.visitor_count)
|
11
|
+
end
|
12
|
+
|
9
13
|
When /^there should be a tracking event "(\d+)":$/ do |id, table|
|
10
14
|
event = Metry.current[id]
|
11
15
|
assert event, "Unable to lookup event #{id}."
|
@@ -33,3 +37,7 @@ Then /^there should be a visitor "([^\"]*)":$/ do |id, table|
|
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
40
|
+
|
41
|
+
Then /^there should be a visitor "([^\"]*)"$/ do |id|
|
42
|
+
assert Metry.current.visitor(id)
|
43
|
+
end
|
@@ -19,6 +19,7 @@ World(Rack::Test::Methods)
|
|
19
19
|
|
20
20
|
$: << RAILS_ROOT + '/../../vendor/webrat/lib'
|
21
21
|
require 'webrat'
|
22
|
+
require 'webrat/rack_test'
|
22
23
|
|
23
24
|
Webrat.configure do |config|
|
24
25
|
config.mode = :rack_test
|
@@ -40,6 +41,11 @@ Before do
|
|
40
41
|
end
|
41
42
|
@__cucumber_ar_connection.begin_db_transaction
|
42
43
|
ActionMailer::Base.deliveries = [] if defined?(ActionMailer::Base)
|
44
|
+
|
45
|
+
Layout.create!(:name => "basic", :content => <<EOC)
|
46
|
+
<r:content />
|
47
|
+
EOC
|
48
|
+
User.create!(:name => "Administrator", :login => "admin", :password => "radiant", :password_confirmation => "radiant", :admin => true)
|
43
49
|
end
|
44
50
|
|
45
51
|
After do
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'metry'
|
2
2
|
|
3
|
+
load 'metry_authenticator.rb'
|
4
|
+
|
3
5
|
class MetryExtension < Radiant::Extension
|
4
6
|
version "1.0"
|
5
7
|
description "Provides Metry support to Radiant."
|
@@ -25,5 +27,10 @@ class MetryExtension < Radiant::Extension
|
|
25
27
|
|
26
28
|
Metry.init Metry::Tokyo.new(RAILS_ROOT + '/tracking/tracking')
|
27
29
|
Rails.configuration.middleware.insert_after ActionController::Failsafe, Metry::Rack::Tracking
|
30
|
+
Rails.configuration.middleware.use proc{Metry::Psycho}, {
|
31
|
+
:path => "/admin/metry",
|
32
|
+
:authorize => proc{|env| MetryAuthenticator.new(env).authorized?},
|
33
|
+
:on_deny => proc {|env| MetryAuthenticator.new(env).redirect},
|
34
|
+
}
|
28
35
|
end
|
29
36
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathaniel Talbott
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-30 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|