lita-karma 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fa005d01f58fb03aa07984d4441b9caa058d9598
4
+ data.tar.gz: 041ea5301d6b8190b847497e59489d58b860979d
5
+ SHA512:
6
+ metadata.gz: 14d8b05cf3a25c8bba3e6fd010d089915ac93982993497ccf34575a929c0dc580be77e74f7570db9d93521c416873df1db77c27d06347627dc320437cd5d25db
7
+ data.tar.gz: b0683a98f70347a1e16ddd58cab5d7c0b64d0d862bcb7e6db60a30468fddb4228b9fad9f9f9269c3afd509f4ef8e77c622bcfa9efd75edd8a0f50da3d1787afb
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # lita-karma
2
+
3
+ **lita-karma** is a handler for [Lita](https://github.com/jimmycuadra/lita) that tracks karma points for arbitrary terms. It listens for upvotes and downvotes and keeps a tally of the scores for them in Redis.
4
+
5
+ ## Installation
6
+
7
+ Add lita-karma to your Lita instance's Gemfile:
8
+
9
+ ``` ruby
10
+ gem "lita-karma"
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Lita will add a karma point whenever it hears a term upvoted:
16
+
17
+ ```
18
+ term++
19
+ ```
20
+
21
+ It will subtract a karma point whenever it hears a term downvoted:
22
+
23
+ ```
24
+ term--
25
+ ```
26
+
27
+ To check the current karma for a term without modifying it:
28
+
29
+ ```
30
+ term~~
31
+ ```
32
+
33
+ To list the top scoring terms:
34
+
35
+ ```
36
+ Lita: karma
37
+ ```
38
+
39
+ To list the worst scoring terms:
40
+
41
+ ```
42
+ Lita: karma worst
43
+ ```
44
+
45
+ These commands will list 5 terms by default. To specify a number, pass a second argument to the karma command:
46
+
47
+ ```
48
+ Lita: karma best 10
49
+ ```
50
+
51
+ You can also link terms together. This adds one term's karma to another's whenever it is displayed. A link is uni-directional and non-destructive. You can unlink terms at any time.
52
+
53
+ ```
54
+ foo++
55
+ > foo: 1
56
+ bar++
57
+ > bar: 1
58
+ Lita: foo += bar
59
+ > bar has been linked to foo.
60
+ foo~~
61
+ > foo: 2
62
+ bar~~
63
+ > bar: 1
64
+ Lita: foo -= bar
65
+ > bar has been unlinked from foo.
66
+ foo~~
67
+ > foo: 1
68
+ ```
69
+
70
+ ## License
71
+
72
+ [MIT](http://opensource.org/licenses/MIT)
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/lita-karma.rb ADDED
@@ -0,0 +1 @@
1
+ require "lita/handlers/karma"
@@ -0,0 +1,102 @@
1
+ require "lita"
2
+
3
+ module Lita
4
+ module Handlers
5
+ class Karma < Handler
6
+ route %r{([^\s]{2,})\+\+}, to: :increment
7
+ route %r{([^\s]{2,})\-\-}, to: :decrement
8
+ route %r{([^\s]{2,})~~}, to: :check
9
+ route %r{karma}, to: :list, command: true
10
+ route %r{([^\s]{2,})\s*\+=\s*([^\s]{2,})}, to: :link, command: true
11
+ route %r{([^\s]{2,})\s*-=\s*([^\s]{2,})}, to: :unlink, command: true
12
+
13
+ def increment(matches)
14
+ modify(matches, 1)
15
+ end
16
+
17
+ def decrement(matches)
18
+ modify(matches, -1)
19
+ end
20
+
21
+ def check(matches)
22
+ output = []
23
+
24
+ matches.each do |match|
25
+ term = match[0]
26
+ score = redis.zscore("terms", term).to_i
27
+ redis.smembers("links:#{term}").each do |link|
28
+ score += redis.zscore("terms", link).to_i
29
+ end
30
+ output << "#{term}: #{score}"
31
+ end
32
+
33
+ reply *output
34
+ end
35
+
36
+ def list(matches)
37
+ redis_command = case args.first
38
+ when "worst"
39
+ :zrange
40
+ else
41
+ :zrevrange
42
+ end
43
+
44
+ n = (args[1] || 5).to_i - 1
45
+
46
+ terms_scores = redis.public_send(
47
+ redis_command, "terms", 0, n, with_scores: true
48
+ )
49
+
50
+ output = terms_scores.each_with_index.map do |term_score, index|
51
+ "#{index + 1}. #{term_score[0]} (#{term_score[1].to_i})"
52
+ end.join("\n")
53
+
54
+ if output.length == 0
55
+ reply "There are no terms being tracked yet."
56
+ else
57
+ reply output
58
+ end
59
+ end
60
+
61
+ def link(matches)
62
+ matches.each do |match|
63
+ term1, term2 = match
64
+
65
+ if redis.sadd("links:#{term1}", term2)
66
+ reply "#{term2} has been linked to #{term1}."
67
+ else
68
+ reply "#{term2} is already linked to #{term1}."
69
+ end
70
+ end
71
+ end
72
+
73
+ def unlink(matches)
74
+ matches.each do |match|
75
+ term1, term2 = match
76
+
77
+ if redis.srem("links:#{term1}", term2)
78
+ reply "#{term2} has been unlinked from #{term1}."
79
+ else
80
+ reply "#{term2} is not linked to #{term1}."
81
+ end
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def modify(matches, delta)
88
+ output = []
89
+
90
+ matches.each do |match|
91
+ term = match[0]
92
+ score = redis.zincrby("terms", delta, term).to_i
93
+ output << "#{term}: #{score}"
94
+ end
95
+
96
+ reply *output
97
+ end
98
+ end
99
+
100
+ Lita.register_handler(Karma)
101
+ end
102
+ end
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "lita-karma"
3
+ spec.version = "0.0.1"
4
+ spec.authors = ["Jimmy Cuadra"]
5
+ spec.email = ["jimmy@jimmycuadra.com"]
6
+ spec.description = %q{A Lita handler for tracking karma points for arbitrary terms.}
7
+ spec.summary = %q{A Lita handler for tracking karma points for arbitrary terms.}
8
+ spec.homepage = "https://github.com/jimmycuadra/lita-karma"
9
+ spec.license = "MIT"
10
+
11
+ spec.files = `git ls-files`.split($/)
12
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
+ spec.require_paths = ["lib"]
15
+
16
+ spec.add_runtime_dependency "lita", "~> 0.0.1"
17
+
18
+ spec.add_development_dependency "bundler", "~> 1.3"
19
+ spec.add_development_dependency "rake"
20
+ spec.add_development_dependency "rspec", ">= 2.14.0rc1"
21
+ end
@@ -0,0 +1,166 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Handlers::Karma, lita_handler: true do
4
+ it { routes("foo++").to(:increment) }
5
+ it { routes("foo--").to(:decrement) }
6
+ it { routes("foo~~").to(:check) }
7
+ it { routes("#{robot.name}: karma").to(:list) }
8
+ it { routes("#{robot.name}: foo += bar").to(:link) }
9
+ it { routes("#{robot.name}: foo -= bar").to(:unlink) }
10
+
11
+ let(:source) { an_instance_of(Lita::Source) }
12
+
13
+ describe "#increment" do
14
+ it "increases the term's score by one and says the new score" do
15
+ expect(robot).to receive(:send_messages).with(source, "foo: 1")
16
+ send_test_message("foo++")
17
+ end
18
+
19
+ it "matches multiple terms in one message" do
20
+ expect(robot).to receive(:send_messages).with(source, "foo: 1", "bar: 1")
21
+ send_test_message("foo++ bar++")
22
+ end
23
+
24
+ it "doesn't start from zero if the term already has a positive score" do
25
+ allow(robot).to receive(:send_messages)
26
+ send_test_message("foo++")
27
+ expect(robot).to receive(:send_messages).with(source, "foo: 2")
28
+ send_test_message("foo++")
29
+ end
30
+ end
31
+
32
+ describe "#decrement" do
33
+ it "decreases the term's score by one and says the new score" do
34
+ expect(robot).to receive(:send_messages).with(source, "foo: -1")
35
+ send_test_message("foo--")
36
+ end
37
+
38
+ it "matches multiple terms in one message" do
39
+ expect(robot).to receive(:send_messages).with(
40
+ source,
41
+ "foo: -1",
42
+ "bar: -1"
43
+ )
44
+ send_test_message("foo-- bar--")
45
+ end
46
+
47
+ it "doesn't start from zero if the term already has a positive score" do
48
+ allow(robot).to receive(:send_messages)
49
+ send_test_message("foo++")
50
+ expect(robot).to receive(:send_messages).with(source, "foo: 0")
51
+ send_test_message("foo--")
52
+ end
53
+ end
54
+
55
+ describe "#check" do
56
+ it "says the term's current score" do
57
+ expect(robot).to receive(:send_messages).with(source, "foo: 0")
58
+ send_test_message("foo~~")
59
+ end
60
+
61
+ it "matches multiple terms in one message" do
62
+ expect(robot).to receive(:send_messages).with(
63
+ source,
64
+ "foo: 0",
65
+ "bar: 0"
66
+ )
67
+ send_test_message("foo~~ bar~~")
68
+ end
69
+ end
70
+
71
+ describe "#list" do
72
+ before do
73
+ allow(robot).to receive(:send_messages)
74
+ send_test_message(
75
+ "one++ one++ one++ two++ two++ three++ four++ four-- five--"
76
+ )
77
+ end
78
+
79
+ it "lists the top 5 terms by default" do
80
+ expect(robot).to receive(:send_messages).with source, <<-MSG.chomp
81
+ 1. one (3)
82
+ 2. two (2)
83
+ 3. three (1)
84
+ 4. four (0)
85
+ 5. five (-1)
86
+ MSG
87
+ send_test_message("#{robot.name}: karma")
88
+ end
89
+
90
+ it 'lists the bottom 5 terms when passed "worst"' do
91
+ expect(robot).to receive(:send_messages).with source, <<-MSG.chomp
92
+ 1. five (-1)
93
+ 2. four (0)
94
+ 3. three (1)
95
+ 4. two (2)
96
+ 5. one (3)
97
+ MSG
98
+ send_test_message("#{robot.name}: karma worst")
99
+ end
100
+
101
+ it "limits the list to the count passed as the second argument" do
102
+ expect(robot).to receive(:send_messages).with source, <<-MSG.chomp
103
+ 1. one (3)
104
+ 2. two (2)
105
+ MSG
106
+ send_test_message("#{robot.name}: karma best 2")
107
+ end
108
+ end
109
+
110
+ describe "#link" do
111
+ it "says that it's linked term 2 to term 1" do
112
+ expect(robot).to receive(:send_messages).with(
113
+ source,
114
+ "bar has been linked to foo."
115
+ )
116
+ send_test_message("#{robot.name}: foo += bar")
117
+ end
118
+
119
+ it "says that term 2 was already linked to term 1 if it was" do
120
+ allow(robot).to receive(:send_messages)
121
+ send_test_message("#{robot.name}: foo += bar")
122
+ expect(robot).to receive(:send_messages).with(
123
+ source,
124
+ "bar is already linked to foo."
125
+ )
126
+ send_test_message("#{robot.name}: foo += bar")
127
+ end
128
+
129
+ it "causes term 1's score to be modified by term 2's" do
130
+ allow(robot).to receive(:send_messages)
131
+ send_test_message("foo++ bar++")
132
+ send_test_message("#{robot.name}: foo += bar")
133
+ expect(robot).to receive(:send_messages).with(source, "foo: 2")
134
+ send_test_message("foo~~")
135
+ end
136
+ end
137
+
138
+ describe "#unlink" do
139
+ it "says that it's unlinked term 2 from term 1" do
140
+ allow(robot).to receive(:send_messages)
141
+ send_test_message("#{robot.name}: foo += bar")
142
+ expect(robot).to receive(:send_messages).with(
143
+ source,
144
+ "bar has been unlinked from foo."
145
+ )
146
+ send_test_message("#{robot.name}: foo -= bar")
147
+ end
148
+
149
+ it "says that term 2 was not linked to term 1 if it wasn't" do
150
+ expect(robot).to receive(:send_messages).with(
151
+ source,
152
+ "bar is not linked to foo."
153
+ )
154
+ send_test_message("#{robot.name}: foo -= bar")
155
+ end
156
+
157
+ it "causes term 1's score to stop being modified by term 2's" do
158
+ allow(robot).to receive(:send_messages)
159
+ send_test_message("foo++ bar++")
160
+ send_test_message("#{robot.name}: foo += bar")
161
+ send_test_message("#{robot.name}: foo -= bar")
162
+ expect(robot).to receive(:send_messages).with(source, "foo: 1")
163
+ send_test_message("foo~~")
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,3 @@
1
+ require "lita-karma"
2
+
3
+ require "lita/rspec"
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-karma
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jimmy Cuadra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lita
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.14.0rc1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: 2.14.0rc1
69
+ description: A Lita handler for tracking karma points for arbitrary terms.
70
+ email:
71
+ - jimmy@jimmycuadra.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - README.md
79
+ - Rakefile
80
+ - lib/lita-karma.rb
81
+ - lib/lita/handlers/karma.rb
82
+ - lita-karma.gemspec
83
+ - spec/lita/handlers/karma_spec.rb
84
+ - spec/spec_helper.rb
85
+ homepage: https://github.com/jimmycuadra/lita-karma
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.0.3
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: A Lita handler for tracking karma points for arbitrary terms.
109
+ test_files:
110
+ - spec/lita/handlers/karma_spec.rb
111
+ - spec/spec_helper.rb
112
+ has_rdoc: