recognition 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +22 -0
- data/README.md +100 -0
- data/Rakefile +32 -0
- data/lib/generators/recognition/install_generator.rb +12 -0
- data/lib/generators/recognition/templates/recognition.rb +6 -0
- data/lib/generators/recognition/templates/recognition.yml +4 -0
- data/lib/recognition.rb +32 -0
- data/lib/recognition/action_controller_extension.rb +30 -0
- data/lib/recognition/active_record_extension.rb +92 -0
- data/lib/recognition/backend.rb +10 -0
- data/lib/recognition/condition.rb +12 -0
- data/lib/recognition/database.rb +97 -0
- data/lib/recognition/engine.rb +10 -0
- data/lib/recognition/railtie.rb +21 -0
- data/lib/recognition/transaction.rb +11 -0
- data/lib/recognition/version.rb +3 -0
- data/lib/tasks/recognition_tasks.rake +4 -0
- metadata +164 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Raya Social Media
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# Recognition
|
2
|
+
|
3
|
+
A fully-fledged reward system for Rails 3.1+.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'recognition'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Then, you need to run the generator:
|
16
|
+
|
17
|
+
$ rails generate recogintion:install
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Assuming you have two models User and Post and you want to give users points for the following:
|
22
|
+
|
23
|
+
5 points for registration
|
24
|
+
7 points for adding new posts, can be earned multiple times with no limit
|
25
|
+
2 point for deleting posts, can be earned twice
|
26
|
+
2 points for visiting their profile, earned once
|
27
|
+
|
28
|
+
app/models/user.rb:
|
29
|
+
|
30
|
+
class User < ActiveRecord::Base
|
31
|
+
attr_accessible :name
|
32
|
+
has_many :posts
|
33
|
+
acts_as_recognizable initial: 5
|
34
|
+
end
|
35
|
+
|
36
|
+
app/models/post.rb:
|
37
|
+
|
38
|
+
class Post < ActiveRecord::Base
|
39
|
+
attr_accessible :title, :user_id
|
40
|
+
belongs_to :user
|
41
|
+
recognize :user, for: :create, gain: 7
|
42
|
+
recognize :user, for: :destroy, loss: 2, maximum: 4
|
43
|
+
end
|
44
|
+
|
45
|
+
app/controllers/profiles_controller.rb:
|
46
|
+
|
47
|
+
class ProfilesController < ApplicationController
|
48
|
+
recognize :current_user, for: :index, amount: 6, maximum: 12
|
49
|
+
def index
|
50
|
+
@user = User.find(params[:id])
|
51
|
+
respond_to do |format|
|
52
|
+
format.html
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Note:
|
58
|
+
=====
|
59
|
+
Due to the way Ruby method aliasing work, if you need to recognize users for
|
60
|
+
non-ActiveRecord actions (anything that's not :create, :update and :destroy),
|
61
|
+
make sure you add the `recognize` line *after* the method you want to
|
62
|
+
recognize the user for.
|
63
|
+
|
64
|
+
Example:
|
65
|
+
-------
|
66
|
+
The following won't work:
|
67
|
+
|
68
|
+
class Post < ActiveRecord::Base
|
69
|
+
attr_accessible :title, :user_id
|
70
|
+
recognize :user, for: :foo, gain: 2
|
71
|
+
def foo
|
72
|
+
# do something useful
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
This one will:
|
77
|
+
|
78
|
+
class Post < ActiveRecord::Base
|
79
|
+
attr_accessible :title, :user_id
|
80
|
+
def foo
|
81
|
+
# do something useful
|
82
|
+
end
|
83
|
+
recognize :user, for: :foo, gain: 2
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
## Contributing
|
89
|
+
|
90
|
+
Please see CONTRIBUTING.md for details.
|
91
|
+
|
92
|
+
## Credits
|
93
|
+
recognition was originally written by Omar Abdel-Wahab.
|
94
|
+
|
95
|
+
![RSM](http://rayasocialmedia.com/images/logo.png)
|
96
|
+
|
97
|
+
recognition is maintained and funded by Raya Social Media.
|
98
|
+
|
99
|
+
## License
|
100
|
+
recognition is Copyright © 2013 Raya Social Media. It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Recognition'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
require 'rspec/core/rake_task'
|
28
|
+
RSpec::Core::RakeTask.new(:spec)
|
29
|
+
task :default => :spec
|
30
|
+
|
31
|
+
Bundler::GemHelper.install_tasks
|
32
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Recognition
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../templates", __FILE__)
|
5
|
+
|
6
|
+
def copy_files
|
7
|
+
template "recognition.rb", "config/initializers/recognition.rb"
|
8
|
+
template "recognition.yml", "config/recognition.yml"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/recognition.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "recognition/engine"
|
2
|
+
require "recognition/version"
|
3
|
+
require "recognition/railtie"
|
4
|
+
require "redis"
|
5
|
+
|
6
|
+
module Recognition
|
7
|
+
mattr_accessor :redis
|
8
|
+
@@redis = 'localhost:6378'
|
9
|
+
|
10
|
+
mattr_accessor :backend
|
11
|
+
@@backend = nil
|
12
|
+
|
13
|
+
def self.setup
|
14
|
+
yield self
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.backend
|
18
|
+
if self.redis['redis://']
|
19
|
+
@@backend = Redis.connect(:url => self.redis, :thread_safe => true)
|
20
|
+
else
|
21
|
+
self.redis, namespace = self.redis.split('/', 2)
|
22
|
+
host, port, db = self.redis.split(':')
|
23
|
+
|
24
|
+
@@backend = Redis.new(
|
25
|
+
:host => host,
|
26
|
+
:port => port,
|
27
|
+
:db => db,
|
28
|
+
:thread_safe => true
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "recognition/database"
|
2
|
+
|
3
|
+
module Recognition
|
4
|
+
module ActionControllerExtension
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
base.class_attribute :recognitions
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def recognize recognizable, condition
|
12
|
+
include InstanceMethods
|
13
|
+
self.recognitions ||= {}
|
14
|
+
self.recognitions[condition[:for]] = { recognizable: recognizable, amount: condition[:amount], maximum: condition[:maximum] || 0 }
|
15
|
+
after_filter :recognize_actions
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
module InstanceMethods
|
21
|
+
def recognize_actions
|
22
|
+
action = params[:action].to_sym
|
23
|
+
if self.class.recognitions.keys.include? action
|
24
|
+
# update_points current_user.id, action, self.class.recognitions[action][:amount]
|
25
|
+
Database.update_points self, action, self.class.recognitions[action]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "recognition/database"
|
2
|
+
|
3
|
+
module Recognition
|
4
|
+
module ActiveRecordExtension
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
base.class_attribute :recognitions
|
8
|
+
base.class_attribute :recognizable
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods #:nodoc:
|
12
|
+
# to be called from user-model
|
13
|
+
def acts_as_recognizable options = {}
|
14
|
+
include RecognizableInstanceMethods
|
15
|
+
self.recognizable = true
|
16
|
+
self.recognitions ||= {}
|
17
|
+
self.recognitions[:initial] = {
|
18
|
+
amount: options[:initial]
|
19
|
+
}
|
20
|
+
after_save :add_initial_points
|
21
|
+
end
|
22
|
+
|
23
|
+
def recognize recognizable, condition
|
24
|
+
include ObjectInstanceMethods
|
25
|
+
self.recognitions ||= {}
|
26
|
+
self.recognitions[condition[:for]] = {
|
27
|
+
recognizable: recognizable,
|
28
|
+
bucket: condition[:group],
|
29
|
+
gain: condition[:gain],
|
30
|
+
loss: condition[:loss],
|
31
|
+
maximum: condition[:maximum]
|
32
|
+
}
|
33
|
+
# Due to the lack of ActiveRecord before_filter,
|
34
|
+
# we will have to alias the original method in order to intercept
|
35
|
+
if [:create, :update, :destroy].include? condition[:for]
|
36
|
+
include ActiveModel::Dirty
|
37
|
+
else
|
38
|
+
method = condition[:for]
|
39
|
+
define_method "#{method}_with_recognition" do |*args|
|
40
|
+
if self.send("#{method}_without_recognition", *args)
|
41
|
+
Database.update_points self, condition[:for], self.class.recognitions[condition[:for]]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
alias_method_chain method, 'recognition'
|
45
|
+
end
|
46
|
+
# For actions that can be intercepted using ActiveRecord callbacks
|
47
|
+
before_destroy :recognize_destroying
|
48
|
+
after_save :recognize_updating
|
49
|
+
# We use after_save for creation to make sure all associations
|
50
|
+
# have been persisted
|
51
|
+
after_save :recognize_creating
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module RecognizableInstanceMethods #:nodoc:
|
56
|
+
def points
|
57
|
+
Database.get_user_points self.id
|
58
|
+
end
|
59
|
+
|
60
|
+
def recognition_counter bucket
|
61
|
+
Database.get_user_counter self.id, bucket
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_initial_points
|
65
|
+
Database.update_points self, :initial, self.class.recognitions[:initial]
|
66
|
+
end
|
67
|
+
|
68
|
+
def update_points amount, bucket
|
69
|
+
Database.log(self.id, amount.to_i, bucket)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
module ObjectInstanceMethods #:nodoc:
|
74
|
+
def recognize_creating
|
75
|
+
if self.id_changed? # Unless we are creating
|
76
|
+
Database.update_points self, :create, self.class.recognitions[:create] unless self.class.recognitions[:create].nil?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def recognize_updating
|
81
|
+
unless self.id_changed? # Unless we are creating
|
82
|
+
Database.update_points self, :update, self.class.recognitions[:update] unless self.class.recognitions[:update].nil?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def recognize_destroying
|
87
|
+
Database.update_points self, :destroy, self.class.recognitions[:destroy] unless self.class.recognitions[:destroy].nil?
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "recognition/transaction"
|
2
|
+
|
3
|
+
module Recognition
|
4
|
+
module Database
|
5
|
+
def self.log id, amount, bucket
|
6
|
+
hash = Time.now.to_f.to_s
|
7
|
+
Recognition.backend.multi do
|
8
|
+
# Recognition.backend.incrby "recognition:user:#{ id }:points", amount
|
9
|
+
Recognition.backend.hincrby "recognition:user:#{ id }:counters", 'points', amount
|
10
|
+
Recognition.backend.hincrby "recognition:user:#{ id }:counters", bucket, amount
|
11
|
+
Recognition.backend.zadd "recognition:user:#{ id }:transactions", hash, { hash: hash, amount: amount, bucket: bucket, datetime: DateTime.now.to_s }.to_json
|
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
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.get key
|
31
|
+
Recognition.backend.get key
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get_user_points id
|
35
|
+
get_user_counter id, 'points'
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.get_user_counter id, counter
|
39
|
+
counter = Recognition.backend.hget("recognition:user:#{ id }:counters", counter)
|
40
|
+
counter.to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def self.update_points object, action, condition
|
45
|
+
if condition[:bucket].nil?
|
46
|
+
bucket = "#{ object.class.to_s.camelize }:#{ action }"
|
47
|
+
else
|
48
|
+
bucket = condition[:bucket]
|
49
|
+
end
|
50
|
+
user = parse_user(object, condition)
|
51
|
+
if condition[:amount].nil? && condition[:gain].nil? && condition[:loss].nil?
|
52
|
+
false
|
53
|
+
else
|
54
|
+
total = parse_amount(condition[:amount], object) + parse_amount(condition[:gain], object) - parse_amount(condition[:loss], object)
|
55
|
+
ground_total = user.recognition_counter(bucket) + total
|
56
|
+
if condition[:maximum].nil? || ground_total <= condition[:maximum]
|
57
|
+
Database.log(user.id, total.to_i, bucket)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.parse_user object, condition
|
63
|
+
if condition[:recognizable].nil?
|
64
|
+
user = object
|
65
|
+
else
|
66
|
+
case condition[:recognizable].class.to_s
|
67
|
+
when 'Symbol'
|
68
|
+
user = object.send(condition[:recognizable])
|
69
|
+
when 'String'
|
70
|
+
user = object.send(condition[:recognizable].to_sym)
|
71
|
+
when 'Proc'
|
72
|
+
user = object.call(condition[:proc_params])
|
73
|
+
else
|
74
|
+
user = condition[:recognizable]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
user
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.parse_amount amount, object
|
81
|
+
case amount.class.to_s
|
82
|
+
when 'Integer'
|
83
|
+
when 'Fixnum'
|
84
|
+
value = amount
|
85
|
+
when 'Symbol'
|
86
|
+
value = object.send(amount)
|
87
|
+
when 'Proc'
|
88
|
+
value = amount.call(object)
|
89
|
+
when 'NilClass'
|
90
|
+
# Do not complain about nil amounts
|
91
|
+
else
|
92
|
+
raise ArgumentError, "type mismatch for amount: expecting 'Integer', 'Fixnum', 'Symbol' or 'Proc' but got '#{ amount.class.to_s }' instead."
|
93
|
+
end
|
94
|
+
value || 0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "recognition/active_record_extension"
|
2
|
+
require "recognition/action_controller_extension"
|
3
|
+
require "rails"
|
4
|
+
|
5
|
+
module Recognition
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer 'recognition.initialize' do
|
8
|
+
ActiveSupport.on_load(:active_record) do
|
9
|
+
ActiveRecord::Base.send :include, ActiveRecordExtension
|
10
|
+
end
|
11
|
+
ActiveSupport.on_load(:action_controller) do
|
12
|
+
ActionController::Base.send(:include, ActionControllerExtension)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
#
|
16
|
+
# initializer 'recognition.database' do
|
17
|
+
# #TODO: use a Rails initializer
|
18
|
+
# $REDIS = Redis.new #(host: 'localhost', port: redis_config[:port])
|
19
|
+
# end
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: recognition
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Omar Abdel-Wahab
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.9
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.9
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: redis
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sqlite3
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec-rails
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: database_cleaner
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: capybara
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: Recognize users by giving them points and rewards for their actions
|
111
|
+
email:
|
112
|
+
- owahab@gmail.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- lib/generators/recognition/install_generator.rb
|
118
|
+
- lib/generators/recognition/templates/recognition.rb
|
119
|
+
- lib/generators/recognition/templates/recognition.yml
|
120
|
+
- lib/recognition/action_controller_extension.rb
|
121
|
+
- lib/recognition/active_record_extension.rb
|
122
|
+
- lib/recognition/backend.rb
|
123
|
+
- lib/recognition/condition.rb
|
124
|
+
- lib/recognition/database.rb
|
125
|
+
- lib/recognition/engine.rb
|
126
|
+
- lib/recognition/railtie.rb
|
127
|
+
- lib/recognition/transaction.rb
|
128
|
+
- lib/recognition/version.rb
|
129
|
+
- lib/recognition.rb
|
130
|
+
- lib/tasks/recognition_tasks.rake
|
131
|
+
- LICENSE.txt
|
132
|
+
- Rakefile
|
133
|
+
- README.md
|
134
|
+
homepage: http://github.com/owahab/recognition
|
135
|
+
licenses: []
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
segments:
|
147
|
+
- 0
|
148
|
+
hash: -334073944928313035
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ! '>='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
segments:
|
156
|
+
- 0
|
157
|
+
hash: -334073944928313035
|
158
|
+
requirements: []
|
159
|
+
rubyforge_project:
|
160
|
+
rubygems_version: 1.8.23
|
161
|
+
signing_key:
|
162
|
+
specification_version: 3
|
163
|
+
summary: Recognize users by giving them points and rewards for their actions
|
164
|
+
test_files: []
|