badgeable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2010 Scott Burton
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,65 @@
1
+ = About Badgeable
2
+
3
+ Badgeable is an elegant DSL for awarding badges
4
+
5
+ == Overview
6
+
7
+ Badgeable provides an elegant DSL for describing and awarding badges
8
+ to your Ruby objects.
9
+
10
+ == Usage
11
+
12
+ Describe the badges you want to award using the badge block. The only
13
+ configuration directive required for each badge is the name of the badge
14
+ and the name constant of the awarding class:
15
+
16
+ class Person
17
+ include Mongoid::Document
18
+ include Badgeable
19
+ end
20
+
21
+ badge "Big Eater" do
22
+ thing Nacho
23
+ count 40
24
+ subject :person
25
+ conditions do |nacho|
26
+ nacho.spicy?
27
+ end
28
+ end
29
+
30
+ would award the "Big Eater" badge to each Person who eats 40 spicy nachos.
31
+
32
+ You can also award arbitrary badges using your own business logic by
33
+ calling #award_badge(badge_name) on any Badgeable instance:
34
+
35
+ yehuda = Person.create(:name => "Yehuda Katz")
36
+ yehuda.award_badge("Total Badass")
37
+
38
+
39
+ == Requirements
40
+
41
+ Currently Mongoid is the only ORM supported. Watch this space.
42
+
43
+ = License
44
+
45
+ Copyright (c) 2010 Scott Burton
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of this software and associated documentation files (the
49
+ "Software"), to deal in the Software without restriction, including
50
+ without limitation the rights to use, copy, modify, merge, publish,
51
+ distribute, sublicense, and/or sell copies of the Software, and to
52
+ permit persons to whom the Software is furnished to do so, subject to
53
+ the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be
56
+ included in all copies or substantial portions of the Software.
57
+
58
+
59
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
60
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
62
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
63
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
64
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
65
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,18 @@
1
+ module Badgeable
2
+ class Badge
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+
6
+ field :name
7
+ index :name
8
+
9
+ def self.find_or_create_by_name(name)
10
+ criteria.where(:name => name).first || create(:name => name)
11
+ end
12
+
13
+ def icon
14
+ "/images/#{name}"
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,78 @@
1
+ module Badgeable
2
+ class Config
3
+ # Configure a class to automatically award badges after creation.
4
+ # Assign a badge name and a block with configuration
5
+ # directives.
6
+ #
7
+ # Valid directives:
8
+ #
9
+ # thing (Required) a class constant in this namespace that
10
+ # awards the badge.
11
+ # subject (Optional, default = :user) a symbol that references
12
+ # the object to which the badge is awarded. This should
13
+ # be a related object that includes Badgeable, and will
14
+ # usually have referenced_in :thing, belongs_to :thing etc.
15
+ # count (Optional, default = 1) either an integer threshold value
16
+ # of :things related to :subject, or a block. If a block
17
+ # is given, the created instance of :thing is passed as
18
+ # the first block argument, and the block must return
19
+ # return true for the badge to be awarded.
20
+ # conditions (Optional) provide a block; if your block returns
21
+ # returns true, the badge is awarded. Works in
22
+ # conjunction with #count
23
+ #
24
+ # See README for usage examples
25
+ #
26
+ def self.badge(name, &block)
27
+ config = new
28
+ config.instance_eval(&block)
29
+ method_name = name.titleize.gsub(/\s/, "").underscore
30
+ config.klass.class_eval do
31
+ set_callback :create, :after, "award_#{method_name}_badge".to_sym
32
+ define_method "award_#{method_name}_badge".to_sym, Proc.new {
33
+ if config.conditions_array.all? {|p| p.call(self) }
34
+ self.send(config.subject_name).award_badge(name)
35
+ end
36
+ }
37
+ end
38
+ end
39
+
40
+ attr_reader :threshold, :klass, :conditions_array, :subject_name
41
+
42
+ def initialize
43
+ @conditions_array = [Proc.new {true}]
44
+ @subject_name = :user
45
+ end
46
+
47
+ def subject(sym)
48
+ @subject_name = sym
49
+ end
50
+
51
+ def count(n = 1, &block)
52
+ if block_given?
53
+ count_proc = Proc.new { |instance|
54
+ block.call(instance)
55
+ }
56
+ else
57
+ count_proc = Proc.new { |instance|
58
+ instance.instance_eval %Q{
59
+ #{klass}.where(:#{subject_name}_id => #{subject_name}.id).count >= #{n}
60
+ }
61
+ }
62
+ end
63
+ @conditions_array << count_proc
64
+ end
65
+
66
+ def thing(klass)
67
+ @klass = klass
68
+ end
69
+
70
+ def conditions(&block)
71
+ @conditions_array << Proc.new {|instance|
72
+ block.call(instance)
73
+ }
74
+ end
75
+
76
+
77
+ end
78
+ end
@@ -0,0 +1,18 @@
1
+ module Badgeable
2
+ module Subject
3
+ # Award a named badge to this object. If the badge doesn't exist
4
+ # in the database already, it's created by name.
5
+ def award_badge(name)
6
+ badge = Badgeable::Badge.find_or_create_by_name(name)
7
+ badges << badge unless has_badge?(badge)
8
+ end
9
+
10
+ def has_badge?(badge)
11
+ badges.include?(badge)
12
+ end
13
+
14
+ def has_badge_named?(name)
15
+ badges.map(&:name).include?(name)
16
+ end
17
+ end
18
+ end
data/lib/badgeable.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'active_support/core_ext'
2
+ require 'active_support/callbacks'
3
+ require 'active_support/inflector'
4
+ require 'mongoid'
5
+ require 'badgeable/badge'
6
+ require 'badgeable/config'
7
+ require 'badgeable/subject'
8
+
9
+ module Badgeable
10
+
11
+ VERSION = "0.0.1"
12
+
13
+ def self.included(receiver)
14
+ receiver.class_eval %Q{
15
+ references_many :badges, :stored_as => :array, :class_name => "Badgeable::Badge", :inverse_of => :#{receiver.to_s.tableize}
16
+ }
17
+
18
+ Badgeable::Badge.class_eval %Q{
19
+ references_many :#{receiver.to_s.tableize}, :inverse_of => :badges, :stored_as => :array, :inverse_of => :badges
20
+
21
+ def recipients
22
+ #{receiver}.where(:badge_ids => id)
23
+ end
24
+ }
25
+
26
+ receiver.send :include, Badgeable::Subject
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: badgeable
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Scott Burton
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-08 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Badgeable provides an elegant DSL for describing and awarding badges to your Ruby objects.
23
+ email:
24
+ - scottburton11@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - lib/badgeable/badge.rb
33
+ - lib/badgeable/config.rb
34
+ - lib/badgeable/subject.rb
35
+ - lib/badgeable.rb
36
+ - LICENSE
37
+ - README.rdoc
38
+ has_rdoc: true
39
+ homepage: http://github.com/scottburton11/badgeable
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 23
62
+ segments:
63
+ - 1
64
+ - 3
65
+ - 6
66
+ version: 1.3.6
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.7
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Badgeable is an elegant DSL for awarding badges
74
+ test_files: []
75
+