recognition 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -54,15 +54,14 @@ app/controllers/profiles_controller.rb:
54
54
  end
55
55
  end
56
56
 
57
- Note:
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
@@ -30,3 +30,7 @@ task :default => :spec
30
30
 
31
31
  Bundler::GemHelper.install_tasks
32
32
 
33
+ YARD::Rake::YardocTask.new do |t|
34
+ t.files = ['lib/**/*.rb', 'CHANGELOG.txt', 'LICENSE.txt', 'CONTRIBUTING.txt']
35
+ t.options = ['--any', '--extra', '--opts']
36
+ end
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)
@@ -1,6 +1,7 @@
1
1
  require "recognition/database"
2
2
 
3
3
  module Recognition
4
+ # Extending ActiveRecord
4
5
  module ActionControllerExtension
5
6
  def self.included(base)
6
7
  base.extend ClassMethods
@@ -8,8 +8,8 @@ module Recognition
8
8
  base.class_attribute :recognizable
9
9
  end
10
10
 
11
- module ClassMethods #:nodoc:
12
- # to be called from user-model
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 #:nodoc:
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 #:nodoc:
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
@@ -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
- end
14
- end
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
@@ -1,3 +1,4 @@
1
1
  module Recognition
2
- VERSION = "0.2.0"
2
+ # Current Version
3
+ VERSION = "0.3.0"
3
4
  end
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.2.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-13 00:00:00.000000000 Z
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: -334073944928313035
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: -334073944928313035
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: