metry 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +14 -69
- data/TODO +2 -3
- data/cucumber.yml +1 -0
- data/example/example.rb +1 -1
- data/features/psycho/dashboard.feature +17 -0
- data/features/psycho/goals.feature +24 -0
- data/features/psycho/visitor_tracking.feature +32 -0
- data/features/step_definitions/goals.rb +3 -0
- data/features/step_definitions/tracking.rb +1 -1
- data/features/step_definitions/web.rb +14 -2
- data/features/support/env.rb +4 -0
- data/lib/metry.rb +4 -6
- data/lib/metry/experiment.rb +6 -8
- data/lib/metry/psycho.rb +112 -0
- data/lib/metry/psycho/dashboard.erb +14 -0
- data/lib/metry/psycho/layout.erb +8 -0
- data/lib/metry/psycho/new_goal.erb +9 -0
- data/lib/metry/psycho/visitor.erb +7 -0
- data/lib/metry/rack/tracking.rb +17 -13
- data/lib/metry/storage.rb +116 -0
- data/radiant/example/features/metry.feature +8 -8
- data/radiant/example/features/psycho.feature +13 -0
- data/radiant/example/features/step_definitions/experiments.rb +2 -2
- data/radiant/example/features/step_definitions/tracking.rb +1 -1
- data/radiant/example/features/support/env.rb +3 -0
- data/radiant/extension/lib/metry_authenticator.rb +30 -0
- data/radiant/extension/lib/metry_tags.rb +2 -1
- data/radiant/extension/metry_extension.rb +1 -1
- data/test/{test_tokyo.rb → test_storage.rb} +3 -3
- metadata +17 -72
- data/lib/metry/memory.rb +0 -27
- data/lib/metry/tokyo.rb +0 -181
- data/vendor/rufus-tokyo/CHANGELOG.txt +0 -112
- data/vendor/rufus-tokyo/CREDITS.txt +0 -27
- data/vendor/rufus-tokyo/LICENSE.txt +0 -21
- data/vendor/rufus-tokyo/README.txt +0 -310
- data/vendor/rufus-tokyo/Rakefile +0 -118
- data/vendor/rufus-tokyo/TODO.txt +0 -25
- data/vendor/rufus-tokyo/doc/decision_table.numbers +0 -0
- data/vendor/rufus-tokyo/doc/rdoc-style.css +0 -320
- data/vendor/rufus-tokyo/lib/rufus-edo.rb +0 -3
- data/vendor/rufus-tokyo/lib/rufus-tokyo.rb +0 -3
- data/vendor/rufus-tokyo/lib/rufus/edo.rb +0 -39
- data/vendor/rufus-tokyo/lib/rufus/edo/README.txt +0 -106
- data/vendor/rufus-tokyo/lib/rufus/edo/cabcore.rb +0 -333
- data/vendor/rufus-tokyo/lib/rufus/edo/cabinet/abstract.rb +0 -219
- data/vendor/rufus-tokyo/lib/rufus/edo/cabinet/table.rb +0 -159
- data/vendor/rufus-tokyo/lib/rufus/edo/error.rb +0 -36
- data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant.rb +0 -4
- data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant/abstract.rb +0 -137
- data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant/table.rb +0 -141
- data/vendor/rufus-tokyo/lib/rufus/edo/tabcore.rb +0 -567
- data/vendor/rufus-tokyo/lib/rufus/tokyo.rb +0 -58
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/abstract.rb +0 -568
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/lib.rb +0 -230
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/table.rb +0 -753
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/util.rb +0 -425
- data/vendor/rufus-tokyo/lib/rufus/tokyo/config.rb +0 -161
- data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia.rb +0 -43
- data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/lib.rb +0 -65
- data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/words.rb +0 -71
- data/vendor/rufus-tokyo/lib/rufus/tokyo/hmethods.rb +0 -111
- data/vendor/rufus-tokyo/lib/rufus/tokyo/query.rb +0 -102
- data/vendor/rufus-tokyo/lib/rufus/tokyo/transactions.rb +0 -74
- data/vendor/rufus-tokyo/lib/rufus/tokyo/ttcommons.rb +0 -59
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant.rb +0 -35
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/abstract.rb +0 -146
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/lib.rb +0 -153
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/table.rb +0 -162
- data/vendor/rufus-tokyo/rufus-tokyo.gemspec +0 -25
- data/vendor/rufus-tokyo/spec/cabinet_spec.rb +0 -472
- data/vendor/rufus-tokyo/spec/cabinetconfig_spec.rb +0 -82
- data/vendor/rufus-tokyo/spec/edo_cabinet_spec.rb +0 -447
- data/vendor/rufus-tokyo/spec/edo_ntyrant_spec.rb +0 -299
- data/vendor/rufus-tokyo/spec/edo_ntyrant_table_spec.rb +0 -462
- data/vendor/rufus-tokyo/spec/edo_table_spec.rb +0 -560
- data/vendor/rufus-tokyo/spec/hmethods_spec.rb +0 -44
- data/vendor/rufus-tokyo/spec/incr.lua +0 -20
- data/vendor/rufus-tokyo/spec/spec.rb +0 -9
- data/vendor/rufus-tokyo/spec/spec_base.rb +0 -23
- data/vendor/rufus-tokyo/spec/start_tyrants.sh +0 -26
- data/vendor/rufus-tokyo/spec/stop_tyrants.sh +0 -9
- data/vendor/rufus-tokyo/spec/table_spec.rb +0 -567
- data/vendor/rufus-tokyo/spec/tyrant_spec.rb +0 -309
- data/vendor/rufus-tokyo/spec/tyrant_table_spec.rb +0 -479
- data/vendor/rufus-tokyo/spec/util_list_spec.rb +0 -200
- data/vendor/rufus-tokyo/spec/util_map_spec.rb +0 -132
- data/vendor/rufus-tokyo/tasks/dev.rb +0 -70
- data/vendor/rufus-tokyo/test/bm0.rb +0 -353
- data/vendor/rufus-tokyo/test/bm1_compression.rb +0 -54
- data/vendor/rufus-tokyo/test/con0.rb +0 -30
- data/vendor/rufus-tokyo/test/mem.rb +0 -49
- data/vendor/rufus-tokyo/test/mem1.rb +0 -44
- data/vendor/rufus-tokyo/test/readme0.rb +0 -17
- data/vendor/rufus-tokyo/test/readme1.rb +0 -21
- data/vendor/rufus-tokyo/test/readme2.rb +0 -15
- data/vendor/rufus-tokyo/test/readme3.rb +0 -24
- data/vendor/rufus-tokyo/test/readmes_test.sh +0 -17
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -3,18 +3,27 @@ Manifest.txt
|
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
5
|
TODO
|
6
|
+
cucumber.yml
|
6
7
|
example/example.rb
|
7
8
|
features/app_tracking.feature
|
8
9
|
features/basic_tracking.feature
|
10
|
+
features/psycho/dashboard.feature
|
11
|
+
features/psycho/goals.feature
|
12
|
+
features/psycho/visitor_tracking.feature
|
9
13
|
features/sample_application.feature
|
14
|
+
features/step_definitions/goals.rb
|
10
15
|
features/step_definitions/tracking.rb
|
11
16
|
features/step_definitions/web.rb
|
12
17
|
features/support/env.rb
|
13
18
|
lib/metry.rb
|
14
19
|
lib/metry/experiment.rb
|
15
|
-
lib/metry/
|
20
|
+
lib/metry/psycho.rb
|
21
|
+
lib/metry/psycho/dashboard.erb
|
22
|
+
lib/metry/psycho/layout.erb
|
23
|
+
lib/metry/psycho/new_goal.erb
|
24
|
+
lib/metry/psycho/visitor.erb
|
16
25
|
lib/metry/rack/tracking.rb
|
17
|
-
lib/metry/
|
26
|
+
lib/metry/storage.rb
|
18
27
|
radiant/example/CHANGELOG
|
19
28
|
radiant/example/CONTRIBUTORS
|
20
29
|
radiant/example/INSTALL
|
@@ -31,6 +40,7 @@ radiant/example/config/environments/test.rb
|
|
31
40
|
radiant/example/config/routes.rb
|
32
41
|
radiant/example/db/schema.rb
|
33
42
|
radiant/example/features/metry.feature
|
43
|
+
radiant/example/features/psycho.feature
|
34
44
|
radiant/example/features/step_definitions/experiments.rb
|
35
45
|
radiant/example/features/step_definitions/radiant.rb
|
36
46
|
radiant/example/features/step_definitions/tracking.rb
|
@@ -97,77 +107,12 @@ radiant/example/script/spec_server
|
|
97
107
|
radiant/example/script/version
|
98
108
|
radiant/extension/README
|
99
109
|
radiant/extension/Rakefile
|
110
|
+
radiant/extension/lib/metry_authenticator.rb
|
100
111
|
radiant/extension/lib/metry_tags.rb
|
101
112
|
radiant/extension/lib/tasks/metry_extension_tasks.rake
|
102
113
|
radiant/extension/metry_extension.rb
|
103
114
|
test/shared.rb
|
104
|
-
test/
|
105
|
-
vendor/rufus-tokyo/CHANGELOG.txt
|
106
|
-
vendor/rufus-tokyo/CREDITS.txt
|
107
|
-
vendor/rufus-tokyo/LICENSE.txt
|
108
|
-
vendor/rufus-tokyo/README.txt
|
109
|
-
vendor/rufus-tokyo/Rakefile
|
110
|
-
vendor/rufus-tokyo/TODO.txt
|
111
|
-
vendor/rufus-tokyo/doc/decision_table.numbers
|
112
|
-
vendor/rufus-tokyo/doc/rdoc-style.css
|
113
|
-
vendor/rufus-tokyo/lib/rufus-edo.rb
|
114
|
-
vendor/rufus-tokyo/lib/rufus-tokyo.rb
|
115
|
-
vendor/rufus-tokyo/lib/rufus/edo.rb
|
116
|
-
vendor/rufus-tokyo/lib/rufus/edo/README.txt
|
117
|
-
vendor/rufus-tokyo/lib/rufus/edo/cabcore.rb
|
118
|
-
vendor/rufus-tokyo/lib/rufus/edo/cabinet/abstract.rb
|
119
|
-
vendor/rufus-tokyo/lib/rufus/edo/cabinet/table.rb
|
120
|
-
vendor/rufus-tokyo/lib/rufus/edo/error.rb
|
121
|
-
vendor/rufus-tokyo/lib/rufus/edo/ntyrant.rb
|
122
|
-
vendor/rufus-tokyo/lib/rufus/edo/ntyrant/abstract.rb
|
123
|
-
vendor/rufus-tokyo/lib/rufus/edo/ntyrant/table.rb
|
124
|
-
vendor/rufus-tokyo/lib/rufus/edo/tabcore.rb
|
125
|
-
vendor/rufus-tokyo/lib/rufus/tokyo.rb
|
126
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/abstract.rb
|
127
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/lib.rb
|
128
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/table.rb
|
129
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/util.rb
|
130
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/config.rb
|
131
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/dystopia.rb
|
132
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/lib.rb
|
133
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/words.rb
|
134
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/hmethods.rb
|
135
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/query.rb
|
136
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/transactions.rb
|
137
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/ttcommons.rb
|
138
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/tyrant.rb
|
139
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/abstract.rb
|
140
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/lib.rb
|
141
|
-
vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/table.rb
|
142
|
-
vendor/rufus-tokyo/rufus-tokyo.gemspec
|
143
|
-
vendor/rufus-tokyo/spec/cabinet_spec.rb
|
144
|
-
vendor/rufus-tokyo/spec/cabinetconfig_spec.rb
|
145
|
-
vendor/rufus-tokyo/spec/edo_cabinet_spec.rb
|
146
|
-
vendor/rufus-tokyo/spec/edo_ntyrant_spec.rb
|
147
|
-
vendor/rufus-tokyo/spec/edo_ntyrant_table_spec.rb
|
148
|
-
vendor/rufus-tokyo/spec/edo_table_spec.rb
|
149
|
-
vendor/rufus-tokyo/spec/hmethods_spec.rb
|
150
|
-
vendor/rufus-tokyo/spec/incr.lua
|
151
|
-
vendor/rufus-tokyo/spec/spec.rb
|
152
|
-
vendor/rufus-tokyo/spec/spec_base.rb
|
153
|
-
vendor/rufus-tokyo/spec/start_tyrants.sh
|
154
|
-
vendor/rufus-tokyo/spec/stop_tyrants.sh
|
155
|
-
vendor/rufus-tokyo/spec/table_spec.rb
|
156
|
-
vendor/rufus-tokyo/spec/tyrant_spec.rb
|
157
|
-
vendor/rufus-tokyo/spec/tyrant_table_spec.rb
|
158
|
-
vendor/rufus-tokyo/spec/util_list_spec.rb
|
159
|
-
vendor/rufus-tokyo/spec/util_map_spec.rb
|
160
|
-
vendor/rufus-tokyo/tasks/dev.rb
|
161
|
-
vendor/rufus-tokyo/test/bm0.rb
|
162
|
-
vendor/rufus-tokyo/test/bm1_compression.rb
|
163
|
-
vendor/rufus-tokyo/test/con0.rb
|
164
|
-
vendor/rufus-tokyo/test/mem.rb
|
165
|
-
vendor/rufus-tokyo/test/mem1.rb
|
166
|
-
vendor/rufus-tokyo/test/readme0.rb
|
167
|
-
vendor/rufus-tokyo/test/readme1.rb
|
168
|
-
vendor/rufus-tokyo/test/readme2.rb
|
169
|
-
vendor/rufus-tokyo/test/readme3.rb
|
170
|
-
vendor/rufus-tokyo/test/readmes_test.sh
|
115
|
+
test/test_storage.rb
|
171
116
|
vendor/webrat/.document
|
172
117
|
vendor/webrat/History.txt
|
173
118
|
vendor/webrat/MIT-LICENSE.txt
|
data/TODO
CHANGED
data/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: --require features/support/ --require features/step_definitions/
|
data/example/example.rb
CHANGED
@@ -4,7 +4,7 @@ require 'sinatra'
|
|
4
4
|
require File.dirname(__FILE__) + '/../lib/metry'
|
5
5
|
|
6
6
|
configure do
|
7
|
-
Metry.init(
|
7
|
+
Metry.init("tracking")
|
8
8
|
use Metry::Rack::Tracking
|
9
9
|
use Metry::Psycho, {:path => "/admin/metry"}
|
10
10
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: Psycho Dashboard
|
2
|
+
|
3
|
+
Scenario: Basics
|
4
|
+
Given an empty tracking database
|
5
|
+
And I add a goal named "sweet" with path "/"
|
6
|
+
And I am a new visitor
|
7
|
+
And I view "/"
|
8
|
+
And I view "/subpage"
|
9
|
+
And I am a new visitor
|
10
|
+
And I view "/"
|
11
|
+
When I view "/admin/metry"
|
12
|
+
Then I should see "Goals"
|
13
|
+
And I should see "sweet: 2 visits"
|
14
|
+
And I should see "Recent Visitors"
|
15
|
+
And I should see "Visitor 1"
|
16
|
+
And I should see "Visitor 2"
|
17
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Feature: Track Goals
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given an empty tracking database
|
5
|
+
|
6
|
+
Scenario: No goals
|
7
|
+
When I view "/admin/metry"
|
8
|
+
Then the page should have "#goals"
|
9
|
+
And the page should not have "#goals .goal"
|
10
|
+
|
11
|
+
Scenario: Create a goal
|
12
|
+
Given I view "/admin/metry"
|
13
|
+
And I follow "New Goal"
|
14
|
+
And I fill in "name" with "Cool goal"
|
15
|
+
And I fill in "path" with "/goal"
|
16
|
+
And I press "Create"
|
17
|
+
Then I should be on "/admin/metry/"
|
18
|
+
And the page should have "#goals .goal"
|
19
|
+
|
20
|
+
Scenario: Goal count
|
21
|
+
Given I add a goal named "My Goal" with path "/"
|
22
|
+
And I view "/"
|
23
|
+
When I view "/admin/metry"
|
24
|
+
Then I should see "My Goal: 1 visits"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Feature: Psycho Visitor Tracking
|
2
|
+
In order to see how visitors are using my site
|
3
|
+
As a site admin
|
4
|
+
I want to see visitors and drill down into their behavior
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given an empty tracking database
|
8
|
+
And I am a new visitor
|
9
|
+
|
10
|
+
Scenario: See list of visitors
|
11
|
+
Given I view "/"
|
12
|
+
And I am a new visitor
|
13
|
+
And I view "/"
|
14
|
+
When I view "/admin/metry"
|
15
|
+
Then I should see "Visitor 1"
|
16
|
+
And I should see "Visitor 2"
|
17
|
+
|
18
|
+
Scenario: View visitor detail
|
19
|
+
Given I view "/"
|
20
|
+
And I view "/subpage"
|
21
|
+
And I am a new visitor
|
22
|
+
And I view "/"
|
23
|
+
When I view "/admin/metry"
|
24
|
+
And I follow "Visitor 1"
|
25
|
+
Then I should see "/"
|
26
|
+
And I should see "/subpage"
|
27
|
+
|
28
|
+
Scenario: Psycho visits should not be tracked
|
29
|
+
Given I view "/admin/metry"
|
30
|
+
And I view "/admin/metry"
|
31
|
+
When I view "/admin/metry"
|
32
|
+
Then I should not see "Visitor 1"
|
@@ -11,7 +11,7 @@ Then /^there should be (\d+) visitors$/ do |visitor_count|
|
|
11
11
|
end
|
12
12
|
|
13
13
|
When /^there should be a tracking event "(\d+)":$/ do |id, table|
|
14
|
-
event = Metry.current
|
14
|
+
event = Metry.current.event(id)
|
15
15
|
assert event, "Unable to lookup event #{id}."
|
16
16
|
table.hashes.each do |hash|
|
17
17
|
expected = hash["value"]
|
@@ -11,7 +11,19 @@ When /^I (post|put) to "([^\"]*)":$/ do |meth, path, params|
|
|
11
11
|
end
|
12
12
|
|
13
13
|
Then /^I should see "([^\"]*)"$/ do |string|
|
14
|
-
|
14
|
+
assert_contain(string)
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^I should not see "([^\"]*)"$/ do |string|
|
18
|
+
assert_not_contain(string)
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^the page should have "([^\"]*)"$/ do |selector|
|
22
|
+
assert_have_selector selector
|
23
|
+
end
|
24
|
+
|
25
|
+
Then /^the page should not have "([^\"]*)"$/ do |selector|
|
26
|
+
assert_have_no_selector selector
|
15
27
|
end
|
16
28
|
|
17
29
|
When /^I follow "([^\"]*)"$/ do |link|
|
@@ -27,5 +39,5 @@ When /^I press "([^\"]*)"$/ do |button|
|
|
27
39
|
end
|
28
40
|
|
29
41
|
Then /^I should be on "([^\"]*)"$/ do |path|
|
30
|
-
assert_equal path,
|
42
|
+
assert_equal path, current_url
|
31
43
|
end
|
data/features/support/env.rb
CHANGED
@@ -3,6 +3,7 @@ World(Test::Unit::Assertions)
|
|
3
3
|
|
4
4
|
require 'rack/test'
|
5
5
|
|
6
|
+
$: << File.dirname(__FILE__) + "/../../lib"
|
6
7
|
$: << File.dirname(__FILE__) + "/../../vendor/webrat/lib"
|
7
8
|
require 'webrat'
|
8
9
|
require 'logger'
|
@@ -14,6 +15,9 @@ World(Rack::Test::Methods)
|
|
14
15
|
World(Webrat::Methods)
|
15
16
|
World(Webrat::Matchers)
|
16
17
|
|
18
|
+
require 'metry'
|
19
|
+
Metry::Storage.predictable_keys = true
|
20
|
+
|
17
21
|
require File.dirname(__FILE__) + '/../../example/example.rb'
|
18
22
|
def app
|
19
23
|
Sinatra::Application
|
data/lib/metry.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
1
|
$: << File.dirname(__FILE__)
|
2
|
-
$: << File.dirname(__FILE__) + '/../vendor/rufus-tokyo/lib'
|
3
2
|
|
3
|
+
require 'metry/storage'
|
4
4
|
require 'metry/rack/tracking'
|
5
|
-
require 'metry/memory'
|
6
|
-
require 'metry/tokyo'
|
7
5
|
require 'metry/experiment'
|
8
6
|
require 'metry/psycho'
|
9
7
|
|
10
8
|
module Metry
|
11
|
-
VERSION = '
|
9
|
+
VERSION = '2.0.0'
|
12
10
|
|
13
|
-
def self.init(
|
14
|
-
@storage =
|
11
|
+
def self.init(dbname)
|
12
|
+
@storage = Storage.new(dbname)
|
15
13
|
end
|
16
14
|
|
17
15
|
def self.current
|
data/lib/metry/experiment.rb
CHANGED
@@ -2,21 +2,19 @@ module Metry
|
|
2
2
|
class Experiment
|
3
3
|
METHODS = {
|
4
4
|
"rand" => proc{|list, visitor| list.sort_by{rand}.first},
|
5
|
-
"mod_visitor" => proc{|list, visitor| list[(visitor.to_i-1)%list.size]},
|
5
|
+
"mod_visitor" => proc{|list, visitor| list[(visitor['_id'].to_i-1)%list.size]}, # mod_visitor will only work with predictable_keys = true
|
6
6
|
}
|
7
7
|
|
8
|
-
def initialize(name, event)
|
9
|
-
@key = "experiment
|
8
|
+
def initialize(name, event, visitor)
|
9
|
+
@key = "experiment:#{name}"
|
10
10
|
@event = event
|
11
|
-
@visitor =
|
12
|
-
@storage = Metry.current
|
11
|
+
@visitor = visitor
|
13
12
|
end
|
14
13
|
|
15
14
|
def choose(options, method=nil)
|
16
|
-
|
17
|
-
unless choice = visitor_hash[@key]
|
15
|
+
unless choice = @visitor[@key]
|
18
16
|
choice = METHODS[method || "rand"][options.keys, @visitor]
|
19
|
-
@
|
17
|
+
@visitor[@key] = choice
|
20
18
|
end
|
21
19
|
@event[@key] = choice
|
22
20
|
options[choice]
|
data/lib/metry/psycho.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Metry
|
4
|
+
class Psycho < Sinatra::Base
|
5
|
+
def initialize(app, options={})
|
6
|
+
super(app)
|
7
|
+
@options = options
|
8
|
+
path = options[:path] || "/psycho"
|
9
|
+
auth = options[:authorize] || proc{true}
|
10
|
+
on_deny = options[:on_deny] || proc{[403, {"Content-Type" => "text/plain"}, "You must log in."]}
|
11
|
+
|
12
|
+
self.class.class_eval do
|
13
|
+
set :views, File.dirname(__FILE__) + '/psycho'
|
14
|
+
|
15
|
+
before do
|
16
|
+
if unescape(@request.path_info) =~ /^#{path}/
|
17
|
+
@request.env["metry.ignore"] = "true"
|
18
|
+
if !auth.call(env)
|
19
|
+
reply = on_deny.call(env)
|
20
|
+
status reply.first
|
21
|
+
response.header.merge!(reply[1])
|
22
|
+
halt reply.last
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
get "#{path}/?" do
|
28
|
+
@visitors = Visitor.all
|
29
|
+
@goals = Goal.all
|
30
|
+
erb :dashboard
|
31
|
+
end
|
32
|
+
|
33
|
+
get "#{path}/visitor/:id" do
|
34
|
+
@visitor = Visitor.find(params["id"])
|
35
|
+
erb :visitor
|
36
|
+
end
|
37
|
+
|
38
|
+
post "#{path}/goals" do
|
39
|
+
Goal.create!(params[:name], params[:path])
|
40
|
+
redirect url('/')
|
41
|
+
end
|
42
|
+
|
43
|
+
get "#{path}/goals/new" do
|
44
|
+
erb :new_goal
|
45
|
+
end
|
46
|
+
|
47
|
+
helpers do
|
48
|
+
define_method(:url) do |url|
|
49
|
+
"#{path}#{url}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Goal
|
56
|
+
def self.create!(name, path)
|
57
|
+
Metry.current.add_goal('name' => name, 'path' => path)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.all
|
61
|
+
Metry.current.goals.collect{|e| new(e)}
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_reader :name, :path
|
65
|
+
|
66
|
+
def initialize(hash)
|
67
|
+
@name = hash['name']
|
68
|
+
@path = hash['path']
|
69
|
+
end
|
70
|
+
|
71
|
+
def visits
|
72
|
+
Metry.current.all_events({'path' => @path}).size
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Visitor
|
77
|
+
def self.all
|
78
|
+
Metry.current.visitors.collect{|e| new(e)}.select{|e| e.has_events?}
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.find(id)
|
82
|
+
new(Metry.current.visitor(id))
|
83
|
+
end
|
84
|
+
|
85
|
+
def initialize(visitor)
|
86
|
+
@visitor = visitor
|
87
|
+
end
|
88
|
+
|
89
|
+
def id
|
90
|
+
@visitor['_id']
|
91
|
+
end
|
92
|
+
|
93
|
+
def events
|
94
|
+
Metry.current.events_for(id).collect{|e| Event.new(e)}
|
95
|
+
end
|
96
|
+
|
97
|
+
def has_events?
|
98
|
+
!events.empty?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class Event
|
103
|
+
def initialize(event)
|
104
|
+
@event = event
|
105
|
+
end
|
106
|
+
|
107
|
+
def path
|
108
|
+
@event["path"]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|