recognition 0.2.0 → 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.
- data/README.md +3 -4
- data/Rakefile +4 -0
- data/lib/recognition.rb +4 -0
- data/lib/recognition/action_controller_extension.rb +1 -0
- data/lib/recognition/active_record_extension.rb +61 -4
- data/lib/recognition/database.rb +39 -16
- data/lib/recognition/version.rb +2 -1
- metadata +37 -4
data/README.md
CHANGED
@@ -54,15 +54,14 @@ app/controllers/profiles_controller.rb:
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
|
58
|
-
|
57
|
+
|
58
|
+
### Note
|
59
59
|
Due to the way Ruby method aliasing work, if you need to recognize users for
|
60
60
|
non-ActiveRecord actions (anything that's not :create, :update and :destroy),
|
61
61
|
make sure you add the `recognize` line *after* the method you want to
|
62
62
|
recognize the user for.
|
63
63
|
|
64
|
-
Example
|
65
|
-
-------
|
64
|
+
## Example
|
66
65
|
The following won't work:
|
67
66
|
|
68
67
|
class Post < ActiveRecord::Base
|
data/Rakefile
CHANGED
data/lib/recognition.rb
CHANGED
@@ -5,15 +5,19 @@ require "redis"
|
|
5
5
|
|
6
6
|
module Recognition
|
7
7
|
mattr_accessor :redis
|
8
|
+
# Redis Db connection parameters
|
8
9
|
@@redis = 'localhost:6378'
|
9
10
|
|
10
11
|
mattr_accessor :backend
|
12
|
+
# Redis Db active connection
|
11
13
|
@@backend = nil
|
12
14
|
|
15
|
+
# Initialize recognition
|
13
16
|
def self.setup
|
14
17
|
yield self
|
15
18
|
end
|
16
19
|
|
20
|
+
# Connect to Redis Db
|
17
21
|
def self.backend
|
18
22
|
if self.redis['redis://']
|
19
23
|
@@backend = Redis.connect(:url => self.redis, :thread_safe => true)
|
@@ -8,8 +8,8 @@ module Recognition
|
|
8
8
|
base.class_attribute :recognizable
|
9
9
|
end
|
10
10
|
|
11
|
-
module ClassMethods
|
12
|
-
# to be called from user
|
11
|
+
module ClassMethods
|
12
|
+
# to be called from user model
|
13
13
|
def acts_as_recognizable options = {}
|
14
14
|
include RecognizableInstanceMethods
|
15
15
|
self.recognizable = true
|
@@ -18,8 +18,10 @@ module Recognition
|
|
18
18
|
amount: options[:initial]
|
19
19
|
}
|
20
20
|
after_save :add_initial_points
|
21
|
+
|
21
22
|
end
|
22
23
|
|
24
|
+
# to be called from other models
|
23
25
|
def recognize recognizable, condition
|
24
26
|
include ObjectInstanceMethods
|
25
27
|
self.recognitions ||= {}
|
@@ -50,9 +52,17 @@ module Recognition
|
|
50
52
|
# have been persisted
|
51
53
|
after_save :recognize_creating
|
52
54
|
end
|
55
|
+
|
56
|
+
# to be called from user-model
|
57
|
+
def acts_as_voucher options = {}
|
58
|
+
include VoucherInstanceMethods
|
59
|
+
self.recognitions = options
|
60
|
+
before_create :regenerate_code
|
61
|
+
end
|
53
62
|
end
|
54
63
|
|
55
|
-
module RecognizableInstanceMethods
|
64
|
+
module RecognizableInstanceMethods
|
65
|
+
# Determine user current balance of points
|
56
66
|
def points
|
57
67
|
Database.get_user_points self.id
|
58
68
|
end
|
@@ -68,9 +78,13 @@ module Recognition
|
|
68
78
|
def update_points amount, bucket
|
69
79
|
Database.log(self.id, amount.to_i, bucket)
|
70
80
|
end
|
81
|
+
|
82
|
+
def transactions page = 0, per = 20
|
83
|
+
Database.get_user_transactions self.id, page, per
|
84
|
+
end
|
71
85
|
end
|
72
86
|
|
73
|
-
module ObjectInstanceMethods
|
87
|
+
module ObjectInstanceMethods
|
74
88
|
def recognize_creating
|
75
89
|
if self.id_changed? # Unless we are creating
|
76
90
|
Database.update_points self, :create, self.class.recognitions[:create] unless self.class.recognitions[:create].nil?
|
@@ -88,5 +102,48 @@ module Recognition
|
|
88
102
|
end
|
89
103
|
|
90
104
|
end
|
105
|
+
|
106
|
+
module VoucherInstanceMethods
|
107
|
+
def regenerate_code
|
108
|
+
l = self.class.recognitions[:code_length] || 10
|
109
|
+
dict = [('a'..'z'),('A'..'Z'),(0..9)].map{|i| i.to_a}.flatten
|
110
|
+
code = (1..l).map{ dict[rand(dict.length)] }.join
|
111
|
+
# Prevent code collision at all costs
|
112
|
+
if self.class.to_s.constantize.find_all_by_code(code).any?
|
113
|
+
regenerate_code
|
114
|
+
else
|
115
|
+
self.code = code
|
116
|
+
self
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def redeem recognizable
|
121
|
+
# Make sure we have an amount beforehand
|
122
|
+
if defined? self.amount
|
123
|
+
if self.redeemable? recognizable
|
124
|
+
Database.redeem_voucher recognizable.id, self.code, self.amount
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def redeemable? recognizable
|
130
|
+
# default: not redeemable
|
131
|
+
pass = false
|
132
|
+
# has the voucher ever been redeemed?
|
133
|
+
if Database.get_voucher_transactions(self.code).any?
|
134
|
+
# has the voucher ever been redeemed by this user?
|
135
|
+
if Database.get_user_voucher(recognizable.id, code) != 0
|
136
|
+
pass = false
|
137
|
+
# is the voucher reusable?
|
138
|
+
elsif defined?(self.reusable?) && self.reusable?
|
139
|
+
pass = true
|
140
|
+
end
|
141
|
+
else
|
142
|
+
pass = true
|
143
|
+
end
|
144
|
+
pass
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
91
148
|
end
|
92
149
|
end
|
data/lib/recognition/database.rb
CHANGED
@@ -1,29 +1,18 @@
|
|
1
1
|
require "recognition/transaction"
|
2
2
|
|
3
3
|
module Recognition
|
4
|
+
# Handle all Transactions and logging to Redis
|
4
5
|
module Database
|
5
|
-
def self.log id, amount, bucket
|
6
|
+
def self.log id, amount, bucket, code = nil
|
6
7
|
hash = Time.now.to_f.to_s
|
7
8
|
Recognition.backend.multi do
|
8
|
-
# Recognition.backend.incrby "recognition:user:#{ id }:points", amount
|
9
9
|
Recognition.backend.hincrby "recognition:user:#{ id }:counters", 'points', amount
|
10
10
|
Recognition.backend.hincrby "recognition:user:#{ id }:counters", bucket, amount
|
11
11
|
Recognition.backend.zadd "recognition:user:#{ id }:transactions", hash, { hash: hash, amount: amount, bucket: bucket, datetime: DateTime.now.to_s }.to_json
|
12
12
|
Recognition.backend.zadd 'recognition:transactions', hash, { hash: hash, id: id, amount: amount, bucket: bucket, datetime: DateTime.now.to_s }.to_json
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def self.record transaction
|
17
|
-
unless transaction.class.to_s == Recognition::Transaction
|
18
|
-
raise ArgumentError, 'parameter should be of type Recognition::Transaction'
|
19
|
-
end
|
20
|
-
hash = Time.now.to_f.to_s
|
21
|
-
Recognition.backend.multi do
|
22
|
-
# Recognition.backend.incrby "recognition:user:#{ id }:points", amount
|
23
|
-
Recognition.backend.hincrby "recognition:user:#{ id }:counters", 'points', transactions.amount
|
24
|
-
Recognition.backend.hincrby "recognition:user:#{ id }:counters", transactions.bucket, transactions.amount
|
25
|
-
Recognition.backend.zadd "recognition:user:#{ id }:transactions", hash, { amount: transactions.amount, bucket: transactions.bucket, datetime: DateTime.now.to_s }.to_json
|
26
|
-
Recognition.backend.zadd 'recognition:transactions', hash, { id: id, amount: transactions.amount, bucket: transactions.bucket, datetime: DateTime.now.to_s }.to_json
|
13
|
+
unless code.nil?
|
14
|
+
Recognition.backend.zadd "recognition:voucher:#{ code }:transactions", hash, { hash: hash, id: id, bucket: bucket, datetime: DateTime.now.to_s }.to_json
|
15
|
+
end
|
27
16
|
end
|
28
17
|
end
|
29
18
|
|
@@ -40,6 +29,19 @@ module Recognition
|
|
40
29
|
counter.to_i
|
41
30
|
end
|
42
31
|
|
32
|
+
def self.get_user_transactions id, page = 0, per = 20
|
33
|
+
start = page * per
|
34
|
+
stop = (1 + page) * per
|
35
|
+
keypart = "user:#{ id }"
|
36
|
+
self.get_transactions keypart, start, stop
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.get_voucher_transactions code, page = 0, per = 20
|
40
|
+
start = page * per
|
41
|
+
stop = (1 + page) * per
|
42
|
+
keypart = "voucher:#{ code }"
|
43
|
+
self.get_transactions keypart, start, stop
|
44
|
+
end
|
43
45
|
|
44
46
|
def self.update_points object, action, condition
|
45
47
|
if condition[:bucket].nil?
|
@@ -59,6 +61,27 @@ module Recognition
|
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
64
|
+
def self.redeem_voucher id, code, amount
|
65
|
+
bucket = "Voucher:redeem##{ code }"
|
66
|
+
Database.log(id, amount.to_i, bucket, code)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.get_user_voucher id, code
|
70
|
+
bucket = "Voucher:redeem##{ code }"
|
71
|
+
Database.get_user_counter id, bucket
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def self.get_transactions keypart, start, stop
|
77
|
+
transactions = []
|
78
|
+
range = Recognition.backend.zrange "recognition:#{ keypart }:transactions", start, stop
|
79
|
+
range.each do |transaction|
|
80
|
+
transactions << JSON.parse(transaction, { symbolize_names: true })
|
81
|
+
end
|
82
|
+
transactions
|
83
|
+
end
|
84
|
+
|
62
85
|
def self.parse_user object, condition
|
63
86
|
if condition[:recognizable].nil?
|
64
87
|
user = object
|
data/lib/recognition/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: recognition
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -107,6 +107,38 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: yard
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: redcarpet
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
110
142
|
description: Recognize users by giving them points and rewards for their actions
|
111
143
|
email:
|
112
144
|
- owahab@gmail.com
|
@@ -145,7 +177,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
145
177
|
version: '0'
|
146
178
|
segments:
|
147
179
|
- 0
|
148
|
-
hash: -
|
180
|
+
hash: -2843760632124197996
|
149
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
182
|
none: false
|
151
183
|
requirements:
|
@@ -154,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
186
|
version: '0'
|
155
187
|
segments:
|
156
188
|
- 0
|
157
|
-
hash: -
|
189
|
+
hash: -2843760632124197996
|
158
190
|
requirements: []
|
159
191
|
rubyforge_project:
|
160
192
|
rubygems_version: 1.8.23
|
@@ -162,3 +194,4 @@ signing_key:
|
|
162
194
|
specification_version: 3
|
163
195
|
summary: Recognize users by giving them points and rewards for their actions
|
164
196
|
test_files: []
|
197
|
+
has_rdoc:
|