totalizer 0.1.5 → 0.1.6
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.
- checksums.yaml +4 -4
- data/README.md +36 -10
- data/lib/tasks/totalizer.rake +12 -4
- data/lib/totalizer/base.rb +10 -0
- data/lib/totalizer/factory.rb +9 -2
- data/lib/totalizer/message.rb +14 -7
- data/lib/totalizer/version.rb +1 -1
- data/spec/lib/totalizer/factory_spec.rb +30 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4168eb566d3334c9710a3f461640552537773c8f
|
4
|
+
data.tar.gz: 40691a8c784e3d4ab21e40bb2321545dd9333b3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19fa70b6a453e6d137cebb9da4da276f16e4d5c6a50c730afb96928852a0dccc9a49484710d079f70df51a3d3202692f020aeaa841f2c7c49500071706cc3737
|
7
|
+
data.tar.gz: c3ed4b77d762ff54cf27b97c108e93be3d00eca03d3b8f5e8a4067c5fd60136fd8ea7d9f77310c754f27861187aa247df41fa16d1c7026e0e42cf0dc53fee251
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# Totalizer - Calculate and share
|
1
|
+
# Totalizer - Calculate and share product and engagement metrics in your Rails application.
|
2
2
|
|
3
|
-
Totalizer makes it easy for Ruby on Rails developers to report on
|
3
|
+
Totalizer makes it easy for Ruby on Rails developers to report on Product and Engagement metrics.
|
4
4
|
|
5
|
-
By defining
|
5
|
+
By defining three metrics, Growth, Vanity and Key Activity, you can generate reports on Acquisition, Activity, Vanity, Activation, Engagement, Retention and Churn.
|
6
6
|
|
7
7
|
Metrics are only worthwhile if your team sees them so Totalizer includes notifiers for Slack and email.
|
8
8
|
|
@@ -28,6 +28,7 @@ You need to define your Growth Metric and Key Activity Metric in order to use To
|
|
28
28
|
# config/initializers/totalizer.rb
|
29
29
|
|
30
30
|
Totalizer.growth_metric = Totalizer::Metric.new model: User
|
31
|
+
Totalizer.vanity_metric = Totalizer::Metric.new model: Post
|
31
32
|
Totalizer.activity_metric = Totalizer::Metric.new model: Post, map: 'user_id'
|
32
33
|
```
|
33
34
|
|
@@ -139,20 +140,21 @@ This will generate the following report:
|
|
139
140
|
|
140
141
|
```
|
141
142
|
Acquisition
|
142
|
-
Yesterday: 20 (∆ 10%)
|
143
|
-
Last 7 days: 100 (∆ 7%)
|
144
143
|
Signed up this period (with rate of change)
|
144
|
+
Yesterday: 20 (∆ 10%)
|
145
|
+
Vanity
|
146
|
+
Total this period (with rate of change)
|
147
|
+
Yesterday: 15 (∆ 5%)
|
145
148
|
Activity
|
146
|
-
Yesterday: 60 (∆ 9%)
|
147
|
-
Last 7 days: 120 (∆ 8%)
|
148
149
|
Key activities this period (with rate of change)
|
150
|
+
Yesterday: 60 (∆ 9%)
|
149
151
|
```
|
150
152
|
|
151
153
|
### Weekly
|
152
154
|
|
153
|
-
Every week it
|
155
|
+
Every week it's important to review your important metrics to ensure you are trending in the right direction.
|
154
156
|
|
155
|
-
Totalizer generates your Activation, Engagement, Retention and Churn for the previous week and previous month.
|
157
|
+
Totalizer generates your Acquisition, Vanity, Activity, Activation, Engagement, Retention and Churn for the previous week and previous month.
|
156
158
|
|
157
159
|
```
|
158
160
|
$ rake totalizer:weekly
|
@@ -161,6 +163,18 @@ $ rake totalizer:weekly
|
|
161
163
|
This will generate the following report:
|
162
164
|
|
163
165
|
```
|
166
|
+
Acquisition
|
167
|
+
Signed up this period (with rate of change)
|
168
|
+
Last 7 days: 77 (∆ 7%)
|
169
|
+
Last 30 days: 444 (∆ 10%)
|
170
|
+
Vanity
|
171
|
+
Total this period (with rate of change)
|
172
|
+
Last 7 days: 92 (∆ 4%)
|
173
|
+
Last 30 days: 412 (∆ 5%)
|
174
|
+
Activity
|
175
|
+
Key activities this period (with rate of change)
|
176
|
+
Last 7 days: 120 (∆ 8%)
|
177
|
+
Last 30 days: 250 (∆ 6%)
|
164
178
|
Activation
|
165
179
|
Created this period and did key activity
|
166
180
|
Last 7 days: 77 → 58 (75.32%)
|
@@ -179,6 +193,18 @@ Churn
|
|
179
193
|
Last 30 days: 3.29% (34/1032)
|
180
194
|
```
|
181
195
|
|
196
|
+
To change the descriptions for each metric you can add the following to your
|
197
|
+
initializer:
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
Totalizer.descriptions.acquisition = "New users"
|
201
|
+
Totalizer.descriptions.vanity = "Posts created"
|
202
|
+
Totalizer.descriptions.activity = "Users who created post"
|
203
|
+
Totalizer.descriptions.engagement = "Existing users who created post"
|
204
|
+
Totalizer.descriptions.retention = "Existing user who created post again"
|
205
|
+
Totalizer.descriptions.churn = "Existing user who did not do key activity"
|
206
|
+
```
|
207
|
+
|
182
208
|
### Combined
|
183
209
|
|
184
210
|
You can also run a single rake task every day which will run execute the daily
|
@@ -198,7 +224,7 @@ To change the week day add the following line to your initializer:
|
|
198
224
|
Totalizer.weekly_day = 0 #(0-6, Sunday is zero)
|
199
225
|
```
|
200
226
|
|
201
|
-
|
227
|
+
---
|
202
228
|
|
203
229
|
In addition to Metric, you can also use the following underlying objects.
|
204
230
|
|
data/lib/tasks/totalizer.rake
CHANGED
@@ -2,13 +2,15 @@ namespace :totalizer do
|
|
2
2
|
task validate: :environment do
|
3
3
|
abort '! Growth metric not defined. Please define your growth metric before running this task. See https://github.com/micdijkstra/totalizer' unless Totalizer.growth_metric
|
4
4
|
abort '! Activity metric not defined. Please define your growth metric before running this task. See https://github.com/micdijkstra/totalizer' unless Totalizer.activity_metric
|
5
|
+
abort '! Vanity metric not defined. Please define your vanity metric before running this task. See https://github.com/micdijkstra/totalizer' unless Totalizer.vanity_metric
|
5
6
|
end
|
6
7
|
|
7
8
|
task daily: :validate do
|
8
9
|
Totalizer.logger.info "Totalizer: Daily"
|
9
10
|
messages = {
|
10
|
-
acquisition: [Totalizer.generate(:acquisition, 1)
|
11
|
-
|
11
|
+
acquisition: [Totalizer.generate(:acquisition, 1)],
|
12
|
+
vanity: [Totalizer.generate(:vanity, 1)],
|
13
|
+
activity: [Totalizer.generate(:activity, 1)],
|
12
14
|
}
|
13
15
|
Totalizer.notify messages
|
14
16
|
end
|
@@ -16,6 +18,9 @@ namespace :totalizer do
|
|
16
18
|
task weekly: :validate do
|
17
19
|
Totalizer.logger.info "Totalizer: Weekly"
|
18
20
|
messages = {
|
21
|
+
acquisition: [Totalizer.generate(:acquisition, 7), Totalizer.generate(:acquisition, 30)],
|
22
|
+
vanity: [Totalizer.generate(:vanity, 7), Totalizer.generate(:vanity, 30)],
|
23
|
+
activity: [Totalizer.generate(:activity, 7), Totalizer.generate(:activity, 30)],
|
19
24
|
activation: [Totalizer.generate(:activation, 7), Totalizer.generate(:activation, 30)],
|
20
25
|
engagement: [Totalizer.generate(:engagement, 7), Totalizer.generate(:engagement, 30)],
|
21
26
|
retention: [Totalizer.generate(:retention, 7), Totalizer.generate(:retention, 30)],
|
@@ -25,7 +30,10 @@ namespace :totalizer do
|
|
25
30
|
end
|
26
31
|
|
27
32
|
task combined: :validate do
|
28
|
-
|
29
|
-
|
33
|
+
if DateTime.now.wday == Totalizer.weekly_day
|
34
|
+
Rake::Task["totalizer:weekly"].invoke
|
35
|
+
else
|
36
|
+
Rake::Task["totalizer:daily"].invoke
|
37
|
+
end
|
30
38
|
end
|
31
39
|
end
|
data/lib/totalizer/base.rb
CHANGED
@@ -3,6 +3,16 @@ module Totalizer
|
|
3
3
|
NOTIFIERS = { log: 'Totalizer::LogNotifier', action_mailer: 'Totalizer::ActionMailerNotifier', mandrill_mailer: 'Totalizer::MandrillMailerNotifier', slack: 'Totalizer::SlackNotifier' }
|
4
4
|
attr_reader :growth_metric, :activity_metric
|
5
5
|
|
6
|
+
def descriptions
|
7
|
+
@descriptions ||= OpenStruct.new acquisition: "Signed up this period (with rate of change)",
|
8
|
+
vanity: "Total this period (with rate of change)",
|
9
|
+
activity: "Did key activity this period (with rate of change)",
|
10
|
+
activation: "Created this period and did key activity",
|
11
|
+
engagement: "Created before this period and did key activity this period",
|
12
|
+
retention: "Did key activity the previous period and again this period",
|
13
|
+
churn: "Did key activity last period but not this period over the total who did key activity last period plus new users"
|
14
|
+
end
|
15
|
+
|
6
16
|
def growth_metric= metric
|
7
17
|
@growth_metric = validate_metric(metric)
|
8
18
|
end
|
data/lib/totalizer/factory.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Totalizer
|
2
2
|
class Factory
|
3
|
-
attr_accessor :growth_metric, :activity_metric, :date, :duration
|
3
|
+
attr_accessor :growth_metric, :activity_metric, :vanity_metric, :date, :duration
|
4
4
|
|
5
|
-
def initialize growth_metric, activity_metric, params={}
|
5
|
+
def initialize growth_metric, activity_metric, vanity_metric, params={}
|
6
6
|
self.growth_metric = growth_metric
|
7
7
|
self.activity_metric = activity_metric
|
8
|
+
self.vanity_metric = vanity_metric
|
8
9
|
self.date = params[:date] || DateTime.now.change(hour: 0)
|
9
10
|
self.duration = params[:duration] || 7
|
10
11
|
validate_attributes!
|
@@ -15,6 +16,11 @@ module Totalizer
|
|
15
16
|
AcqusitionMessage.new(growth_metric, duration)
|
16
17
|
end
|
17
18
|
|
19
|
+
def vanity
|
20
|
+
vanity_metric = Totalizer::Metric.new self.vanity_metric.attributes.merge(date: date, duration: duration)
|
21
|
+
VanityMessage.new(vanity_metric, duration)
|
22
|
+
end
|
23
|
+
|
18
24
|
def activation
|
19
25
|
growth_metric = Totalizer::Metric.new self.growth_metric.attributes.merge(date: date, duration: duration)
|
20
26
|
activity_metric = Totalizer::Metric.new self.activity_metric.attributes.merge(date: date, duration: duration)
|
@@ -52,6 +58,7 @@ module Totalizer
|
|
52
58
|
def validate_attributes!
|
53
59
|
raise Errors::InvalidMetric unless growth_metric.kind_of?(Totalizer::Metric)
|
54
60
|
raise Errors::InvalidMetric unless activity_metric.kind_of?(Totalizer::Metric)
|
61
|
+
raise Errors::InvalidMetric unless vanity_metric.kind_of?(Totalizer::Metric)
|
55
62
|
raise Errors::InvalidDate unless date.kind_of?(DateTime)
|
56
63
|
raise Errors::InvalidDuration unless duration.kind_of?(Integer)
|
57
64
|
end
|
data/lib/totalizer/message.rb
CHANGED
@@ -18,21 +18,28 @@ module Totalizer
|
|
18
18
|
class MetricMessage < Message
|
19
19
|
def initialize metric, duration
|
20
20
|
self.duration = duration
|
21
|
-
self.text = "#{period_string}: #{metric.value} (∆ #{percentage_string(metric.rate)})"
|
21
|
+
self.text = "#{period_string}: #{metric.value} (∆ #{percentage_string(metric.rate)} | Σ #{metric.finish})"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
class AcqusitionMessage < MetricMessage
|
26
26
|
def initialize metric, duration
|
27
27
|
super
|
28
|
-
self.description =
|
28
|
+
self.description = Totalizer.descriptions.acquisition
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class VanityMessage < MetricMessage
|
33
|
+
def initialize metric, duration
|
34
|
+
super
|
35
|
+
self.description = Totalizer.descriptions.vanity
|
29
36
|
end
|
30
37
|
end
|
31
38
|
|
32
39
|
class ActivityMessage < MetricMessage
|
33
40
|
def initialize metric, duration
|
34
41
|
super
|
35
|
-
self.description =
|
42
|
+
self.description = Totalizer.descriptions.activity
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
@@ -40,7 +47,7 @@ module Totalizer
|
|
40
47
|
def initialize step, duration
|
41
48
|
self.duration = duration
|
42
49
|
self.text = "#{period_string}: #{step.start} → #{step.finish} (#{percentage_string(step.rate)})"
|
43
|
-
self.description =
|
50
|
+
self.description = Totalizer.descriptions.activation
|
44
51
|
end
|
45
52
|
end
|
46
53
|
|
@@ -50,7 +57,7 @@ module Totalizer
|
|
50
57
|
|
51
58
|
existing_active = (growth_metric.start_ids & activity_metric.ids).size
|
52
59
|
self.text = "#{period_string}: #{percentage_string existing_active.to_f / growth_metric.start.to_f} (#{existing_active}/#{growth_metric.start})"
|
53
|
-
self.description =
|
60
|
+
self.description = Totalizer.descriptions.engagement
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
@@ -58,7 +65,7 @@ module Totalizer
|
|
58
65
|
def initialize step, duration
|
59
66
|
self.duration = duration
|
60
67
|
self.text = "#{period_string}: #{percentage_string(step.rate)} (#{step.finish}/#{step.start})"
|
61
|
-
self.description =
|
68
|
+
self.description = Totalizer.descriptions.retention
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
@@ -70,7 +77,7 @@ module Totalizer
|
|
70
77
|
lost_existing = (previous_activity_metric.ids - this_activity_metc.ids).size
|
71
78
|
final = new_and_existing - lost_existing
|
72
79
|
self.text = "#{period_string}: #{percentage_string lost_existing.to_f / new_and_existing.to_f} (#{lost_existing}/#{new_and_existing})"
|
73
|
-
self.description =
|
80
|
+
self.description = Totalizer.descriptions.churn
|
74
81
|
end
|
75
82
|
end
|
76
83
|
end
|
data/lib/totalizer/version.rb
CHANGED
@@ -3,29 +3,34 @@ require 'spec_helper'
|
|
3
3
|
describe Totalizer::Factory do
|
4
4
|
let(:growth_metric) { Totalizer::Metric.new model: User }
|
5
5
|
let(:activity_metric) { Totalizer::Metric.new model: Post, map: 'user_id' }
|
6
|
+
let(:vanity_metric) { Totalizer::Metric.new model: Post }
|
6
7
|
let(:duration) { nil }
|
7
8
|
let(:date) { nil }
|
8
|
-
let(:factory) { Totalizer::Factory.new growth_metric, activity_metric, date: date }
|
9
|
+
let(:factory) { Totalizer::Factory.new growth_metric, activity_metric, vanity_metric, date: date }
|
9
10
|
|
10
11
|
describe "Validate" do
|
11
12
|
it "requires metrics" do
|
12
|
-
expect{ Totalizer::Factory.new('fake', 'metric') }.to raise_exception(Totalizer::Errors::InvalidMetric)
|
13
|
+
expect{ Totalizer::Factory.new('fake', 'metric', 'here') }.to raise_exception(Totalizer::Errors::InvalidMetric)
|
13
14
|
end
|
14
15
|
|
15
16
|
it "requires activity metric" do
|
16
|
-
expect{ Totalizer::Factory.new(growth_metric, 'metric') }.to raise_exception(Totalizer::Errors::InvalidMetric)
|
17
|
+
expect{ Totalizer::Factory.new(growth_metric, 'metric', vanity_metric) }.to raise_exception(Totalizer::Errors::InvalidMetric)
|
17
18
|
end
|
18
19
|
|
19
20
|
it "requires growth metric" do
|
20
|
-
expect{ Totalizer::Factory.new('fake', activity_metric) }.to raise_exception(Totalizer::Errors::InvalidMetric)
|
21
|
+
expect{ Totalizer::Factory.new('fake', activity_metric, vanity_metric) }.to raise_exception(Totalizer::Errors::InvalidMetric)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "requires vanity metric" do
|
25
|
+
expect{ Totalizer::Factory.new(growth_metric, activity_metric, 'here') }.to raise_exception(Totalizer::Errors::InvalidMetric)
|
21
26
|
end
|
22
27
|
|
23
28
|
it "requires a valid datetime" do
|
24
|
-
expect{ Totalizer::Factory.new(growth_metric, activity_metric, date: 'Whenever') }.to raise_exception(Totalizer::Errors::InvalidDate)
|
29
|
+
expect{ Totalizer::Factory.new(growth_metric, activity_metric, vanity_metric, date: 'Whenever') }.to raise_exception(Totalizer::Errors::InvalidDate)
|
25
30
|
end
|
26
31
|
|
27
32
|
it "requires a duration" do
|
28
|
-
expect{ Totalizer::Factory.new(growth_metric, activity_metric, duration: 'Whatever') }.to raise_exception(Totalizer::Errors::InvalidDuration)
|
33
|
+
expect{ Totalizer::Factory.new(growth_metric, activity_metric, vanity_metric, duration: 'Whatever') }.to raise_exception(Totalizer::Errors::InvalidDuration)
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
@@ -37,6 +42,17 @@ describe Totalizer::Factory do
|
|
37
42
|
it "defaults to 7 day acquisition duration" do
|
38
43
|
expect(factory.duration).to eq 7
|
39
44
|
end
|
45
|
+
|
46
|
+
it "defaults description text" do
|
47
|
+
expect(factory.vanity.description).to eq "Total this period (with rate of change)"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "overrides description text" do
|
51
|
+
original = Totalizer.descriptions.vanity
|
52
|
+
Totalizer.descriptions.vanity = "Sites created"
|
53
|
+
expect(factory.vanity.description).to eq "Sites created"
|
54
|
+
Totalizer.descriptions.vanity = original
|
55
|
+
end
|
40
56
|
end
|
41
57
|
|
42
58
|
describe "Calculate" do
|
@@ -58,13 +74,19 @@ describe Totalizer::Factory do
|
|
58
74
|
|
59
75
|
describe "Acquisition" do
|
60
76
|
it "returns text" do
|
61
|
-
expect(factory.acquisition.text).to eq "Last 7 days: 2 (∆ 50%)"
|
77
|
+
expect(factory.acquisition.text).to eq "Last 7 days: 2 (∆ 50% | Σ 6)"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "Vanity" do
|
82
|
+
it "returns text" do
|
83
|
+
expect(factory.vanity.text).to eq "Last 7 days: 2 (∆ 50% | Σ 6)"
|
62
84
|
end
|
63
85
|
end
|
64
86
|
|
65
87
|
describe "Activity" do
|
66
88
|
it "returns text" do
|
67
|
-
expect(factory.activity.text).to eq "Last 7 days: 2 (∆ 25%)"
|
89
|
+
expect(factory.activity.text).to eq "Last 7 days: 2 (∆ 25% | Σ 5)"
|
68
90
|
end
|
69
91
|
end
|
70
92
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: totalizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Dijkstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|