badgeable 0.0.1

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/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
+