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 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: