scamp 1.2.0 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/README.md +41 -128
- data/examples/v2.rb +39 -0
- data/lib/scamp/adapter.rb +47 -0
- data/lib/scamp/matcher.rb +15 -91
- data/lib/scamp/matches.rb +22 -0
- data/lib/scamp/message.rb +39 -0
- data/lib/scamp/plugin.rb +33 -0
- data/lib/scamp/version.rb +1 -1
- data/lib/scamp.rb +33 -43
- data/scamp.gemspec +9 -10
- data/spec/lib/adapter_spec.rb +145 -0
- data/spec/lib/matcher_spec.rb +122 -0
- data/spec/lib/matches_spec.rb +29 -0
- data/spec/lib/message_spec.rb +52 -0
- data/spec/lib/plugin_spec.rb +33 -0
- data/spec/lib/scamp_spec.rb +119 -659
- data/spec/spec_helper.rb +23 -1
- metadata +55 -58
- data/examples/bot.rb +0 -72
- data/lib/scamp/action.rb +0 -70
- data/lib/scamp/connection.rb +0 -32
- data/lib/scamp/messages.rb +0 -35
- data/lib/scamp/rooms.rb +0 -116
- data/lib/scamp/users.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68ec4dbee8f688bce6bc1b63ea69e53a4a343c0d
|
4
|
+
data.tar.gz: 46806e4a3ac13a4c961e09f32cef1354830185c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8b6808337113e7ee703ee49536a297f053cb355a1200fb875f348335465f398dcc7f1ff7484b936b748695052bb7e101e9fd6ab54126635247c6f287caeac4c
|
7
|
+
data.tar.gz: 7e27db164920d26c8a75404b1c8c710e3addd3810022b06f847e1759cf4e047a298ab6cd69c0b6ad8525c32568f78e3818cfeca7bf60819fb36825db90bf165a
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -10,11 +10,11 @@ If you like or use Scamp I'd love to hear from you. Drop me at line at will at 3
|
|
10
10
|
|
11
11
|
## Requirements
|
12
12
|
|
13
|
-
Ruby >= 1.9.2
|
13
|
+
Ruby >= 1.9.2
|
14
14
|
|
15
15
|
## Installation
|
16
16
|
|
17
|
-
`gem install scamp` or
|
17
|
+
`gem install scamp` or `gem 'scamp'` in your Gemfile.
|
18
18
|
|
19
19
|
## Usage and Examples
|
20
20
|
|
@@ -22,30 +22,34 @@ Ruby >= 1.9.2 (At least for the named captures)
|
|
22
22
|
|
23
23
|
``` ruby
|
24
24
|
require 'scamp'
|
25
|
+
require 'scamp-campfire-adapter'
|
25
26
|
|
26
|
-
|
27
|
+
Scamp.new do |scamp|
|
28
|
+
scamp.adapter :campfire, Scamp::Campfire::Adapter, api_key: "YOUR API KEY",
|
29
|
+
subdomain: "yoursubdomain",
|
30
|
+
rooms: [293788]
|
27
31
|
|
28
|
-
scamp.behaviour do
|
29
32
|
# Simple matching based on regex or string:
|
30
|
-
match "ping" do
|
31
|
-
say "pong"
|
33
|
+
scamp.match "ping" do |room, msg|
|
34
|
+
room.say "pong"
|
32
35
|
end
|
33
36
|
end
|
34
|
-
|
35
|
-
# Connect and join some rooms
|
36
|
-
scamp.connect!([293788, "Monitoring"])
|
37
37
|
```
|
38
38
|
|
39
39
|
### Everyone wants an image search
|
40
40
|
|
41
41
|
``` ruby
|
42
42
|
require 'scamp'
|
43
|
+
require 'scamp-campfire-adapter'
|
44
|
+
require 'em-http-request'
|
43
45
|
require 'cgi'
|
44
46
|
|
45
|
-
|
47
|
+
Scamp.new do |scamp|
|
48
|
+
scamp.adapter :campfire, Scamp::Campfire::Adapter, api_key: "YOUR API KEY",
|
49
|
+
subdomain: "yoursubdomain",
|
50
|
+
rooms: [293788]
|
46
51
|
|
47
|
-
scamp.
|
48
|
-
match /^artme (?<search>\w+)/ do
|
52
|
+
scamp.match /^artme (?<search>\w+)/ do |room, msg|
|
49
53
|
url = "http://ajax.googleapis.com/ajax/services/search/images?rsz=large&start=0&v=1.0&q=#{CGI.escape(search)}"
|
50
54
|
http = EventMachine::HttpRequest.new(url).get
|
51
55
|
http.errback { say "Couldn't get #{url}: #{http.response_status.inspect}" }
|
@@ -53,20 +57,16 @@ scamp.behaviour do
|
|
53
57
|
if http.response_header.status == 200
|
54
58
|
results = Yajl::Parser.parse(http.response)
|
55
59
|
if results['responseData']['results'].size > 0
|
56
|
-
say results['responseData']['results'][0]['url']
|
60
|
+
room.say results['responseData']['results'][0]['url']
|
57
61
|
else
|
58
|
-
say "No images matched #{search}"
|
62
|
+
room.say "No images matched #{search}"
|
59
63
|
end
|
60
64
|
else
|
61
|
-
|
62
|
-
say "Couldn't get #{url}"
|
65
|
+
room.say "Couldn't get #{url}"
|
63
66
|
end
|
64
67
|
}
|
65
68
|
end
|
66
69
|
end
|
67
|
-
|
68
|
-
# Connect and join some rooms
|
69
|
-
scamp.connect!([293788, "Monitoring"])
|
70
70
|
```
|
71
71
|
|
72
72
|
### A more in-depth run through
|
@@ -77,139 +77,53 @@ Matchers are tested in order and all that satisfy the match and conditions will
|
|
77
77
|
require 'scamp'
|
78
78
|
|
79
79
|
# Add :verbose => true to get debug output, otherwise the logger will output INFO
|
80
|
-
|
80
|
+
Scamp.new do |scamp|
|
81
|
+
scamp.adapter :campfire, Scamp::Campfire::Adapter, api_key: "YOUR API KEY",
|
82
|
+
subdomain: "yoursubdomain",
|
83
|
+
rooms: [293788],
|
84
|
+
verbose: true
|
81
85
|
|
82
|
-
scamp.behaviour do
|
83
86
|
#
|
84
87
|
# Simple matching based on regex or string:
|
85
88
|
#
|
86
|
-
match /^repeat (\w+), (\w+)$/ do
|
87
|
-
say "You said #{matches[0]} and #{matches[1]}"
|
88
|
-
end
|
89
|
-
|
90
|
-
#
|
91
|
-
# You can specifically paste text:
|
92
|
-
#
|
93
|
-
|
94
|
-
match "paste stuff" do
|
95
|
-
paste "Awesome texts"
|
96
|
-
|
97
|
-
# say()'ing multiline strings will paste automatically however:
|
98
|
-
say <<-EOS
|
99
|
-
This will be pasted
|
100
|
-
even though you called say
|
101
|
-
EOS
|
102
|
-
end
|
103
|
-
|
104
|
-
#
|
105
|
-
# A special user and room method is available in match blocks.
|
106
|
-
#
|
107
|
-
match "a user said" do
|
108
|
-
say "#{user} said something in room #{room}"
|
109
|
-
end
|
110
|
-
|
111
|
-
match "Hello!" do
|
112
|
-
say "Hi there"
|
113
|
-
end
|
114
|
-
|
115
|
-
#
|
116
|
-
# You can play awesome sounds
|
117
|
-
#
|
118
|
-
match "ohmy" do
|
119
|
-
play "yeah"
|
120
|
-
end
|
121
|
-
|
122
|
-
#
|
123
|
-
# Limit the match to certain rooms, users or both.
|
124
|
-
#
|
125
|
-
match /^Lets match (.+)$/, :conditions => {:room => "Some Room"} do
|
126
|
-
say "Only said if room name matches 'Some Room'"
|
127
|
-
end
|
128
|
-
|
129
|
-
match "some text", :conditions => {:user => "Some User"} do
|
130
|
-
say "Only said if user name matches 'Some User'"
|
131
|
-
end
|
132
|
-
|
133
|
-
match /some other text/, :conditions => {:user => "Some User", :room => 123456} do
|
134
|
-
say "You can mix conditions"
|
135
|
-
end
|
136
|
-
|
137
|
-
match "some text", :conditions => {:room => ["Some Room", "Some Other Room"]} do
|
138
|
-
say "You can list multiple rooms"
|
89
|
+
scamp.match /^repeat (\w+), (\w+)$/ do |room, msg|
|
90
|
+
room.say "You said #{matches[0]} and #{matches[1]}"
|
139
91
|
end
|
140
92
|
|
141
93
|
#
|
142
94
|
# Named captures become available in your match block
|
143
95
|
#
|
144
|
-
match /^say (?<yousaid>.+)$/ do
|
145
|
-
say "You said #{yousaid}"
|
146
|
-
end
|
147
|
-
|
148
|
-
#
|
149
|
-
# You can say multiple times, and you can specify an alternate room.
|
150
|
-
# Default behaviour is to 'say' in the room that caused the match.
|
151
|
-
#
|
152
|
-
match "something" do
|
153
|
-
say "#{user} said something in room #{room}"
|
154
|
-
say "#{user} said something in room #{room}", 237872
|
155
|
-
say "#{user} said something in room #{room}", "System Administration"
|
156
|
-
end
|
157
|
-
|
158
|
-
#
|
159
|
-
# A list of commands is available as command_list this matcher uses it
|
160
|
-
# to format a help text
|
161
|
-
#
|
162
|
-
match "help" do
|
163
|
-
max_command_length = command_list.map{|cl| cl.first.to_s }.max_by(&:size).size
|
164
|
-
format_string = "%#{max_command_length + 1}s"
|
165
|
-
formatted_commands = command_list.map{|action, conds| "#{sprintf(format_string, action)} | #{conds.size == 0 ? '' : conds.inspect}"}
|
166
|
-
say <<-EOS
|
167
|
-
#{sprintf("%-#{max_command_length + 1}s", "Command match")} | Conditions
|
168
|
-
--------------------------------------------------------------------------------
|
169
|
-
#{formatted_commands.join("\n")}
|
170
|
-
EOS
|
96
|
+
scamp.match /^say (?<yousaid>.+)$/ do |room, msg|
|
97
|
+
room.say "You said #{msg.matches.yousaid}"
|
171
98
|
end
|
172
99
|
end
|
173
100
|
|
174
|
-
# Connect and join some rooms
|
175
|
-
scamp.connect!([293788, "Monitoring"])
|
176
101
|
```
|
177
102
|
|
178
|
-
|
103
|
+
Scamp will also run _all_ match blocks that an input string matches, you can make Scamp only run the first block it matches by passing in :first\_match\_only => true:
|
179
104
|
|
180
105
|
``` ruby
|
181
|
-
:
|
182
|
-
|
183
|
-
|
184
|
-
:conditions => {:user => "some string"}
|
185
|
-
:conditions => {:user => 123456}
|
186
|
-
|
187
|
-
say "#{user} said something in room #{room}", 237872
|
188
|
-
say "#{user} said something in room #{room}", "System Administration"
|
106
|
+
Scamp.new :first_match_only => true do |scamp|
|
107
|
+
end
|
189
108
|
```
|
190
109
|
|
191
|
-
|
110
|
+
## Adapters
|
192
111
|
|
193
|
-
|
194
|
-
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :ignore_self => true)
|
195
|
-
```
|
112
|
+
### Adapter channels
|
196
113
|
|
197
|
-
|
114
|
+
### Writing an adapter
|
198
115
|
|
199
|
-
``` ruby
|
200
|
-
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :first_match_only => true)
|
201
|
-
```
|
202
116
|
|
203
|
-
|
117
|
+
## Plugins
|
204
118
|
|
205
|
-
|
206
|
-
|
207
|
-
|
119
|
+
### Writing plugins
|
120
|
+
|
121
|
+
* TODO
|
208
122
|
|
209
|
-
Scamp will now require commands to begin with 'Bot: ' (or whatever you have specified), and will strip out this prefix before handing the message onto your match block.
|
210
123
|
|
211
124
|
## TODO
|
212
125
|
|
126
|
+
* Get messages working back to adapters
|
213
127
|
* Allow multiple values for conditions, eg: :conditions => {:user => ["Some User", "Some Other User"]}
|
214
128
|
|
215
129
|
## How to contribute
|
@@ -230,7 +144,8 @@ Take a look at the TODO list or known issues for some inspiration if you need it
|
|
230
144
|
|
231
145
|
## Authors
|
232
146
|
|
233
|
-
* Will Jessop
|
147
|
+
* [Will Jessop](http://willj.net/)
|
148
|
+
* [Adam Holt](http://adamholt.co.uk/)
|
234
149
|
|
235
150
|
## Thanks
|
236
151
|
|
@@ -238,8 +153,6 @@ First class support, commits and pull requests, thanks guys!
|
|
238
153
|
|
239
154
|
* [Caius Durling](http://caius.name/)
|
240
155
|
* Sudara Williams of [Ramen Music](http://ramenmusic.com)
|
241
|
-
* [Dom Hodgson](http://www.thehodge.co.uk/) (for the name)
|
242
|
-
* Pull requests: @mheffner
|
243
156
|
|
244
157
|
## License
|
245
158
|
|
data/examples/v2.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '../lib')
|
2
|
+
|
3
|
+
require 'scamp'
|
4
|
+
require 'scamp/adapter'
|
5
|
+
require 'scamp/message'
|
6
|
+
require 'scamp/plugin'
|
7
|
+
|
8
|
+
class PingPlugin < Scamp::Plugin
|
9
|
+
match /^ping/, :say_pong
|
10
|
+
|
11
|
+
def say_pong channel, msg
|
12
|
+
channel.say "pong"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class TestAdapter < Scamp::Adapter
|
17
|
+
class Context
|
18
|
+
def say msg
|
19
|
+
puts msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def connect!
|
24
|
+
EventMachine::PeriodicTimer.new(@opts[:delay]) do
|
25
|
+
msg = Scamp::Message.new(self, :body => "ping")
|
26
|
+
context = TestAdapter::Context.new
|
27
|
+
push [context, msg]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Scamp.new do |bot|
|
33
|
+
bot.adapter :test, TestAdapter, :delay => 1
|
34
|
+
bot.adapter :another, TestAdapter, :delay => 5
|
35
|
+
|
36
|
+
bot.plugin PingPlugin, :on => [:test]
|
37
|
+
|
38
|
+
bot.connect!
|
39
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Scamp
|
2
|
+
class Adapter
|
3
|
+
attr_accessor :bot
|
4
|
+
|
5
|
+
def initialize(bot, opts={})
|
6
|
+
@bot = bot
|
7
|
+
@opts = opts
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches_required_format?(msg)
|
11
|
+
return true unless msg
|
12
|
+
return true unless bot.required_format
|
13
|
+
if bot.required_format.is_a? String
|
14
|
+
msg.index(bot.required_format) == 0
|
15
|
+
elsif bot.required_format.is_a? Regexp
|
16
|
+
msg.match bot.required_format
|
17
|
+
else
|
18
|
+
raise ArgumentError, "You passed a :required_format that isn't a string or regexp, dont't know how to match it!"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def strip_prefix(msg)
|
23
|
+
# We only strip required prefxes if they are strings, and strip_prefix is set
|
24
|
+
return msg unless bot.required_format.is_a?(String) && bot.strip_prefix
|
25
|
+
msg.sub(bot.required_format, '').strip unless msg.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def subscribe &block
|
29
|
+
channel.subscribe &block
|
30
|
+
end
|
31
|
+
|
32
|
+
def push(msg)
|
33
|
+
channel.push msg
|
34
|
+
end
|
35
|
+
alias_method :<<, :push
|
36
|
+
|
37
|
+
def connect!
|
38
|
+
raise NotImplementedError, "connect! must be implemented"
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def channel
|
44
|
+
@channel ||= EM::Channel.new
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/scamp/matcher.rb
CHANGED
@@ -1,106 +1,30 @@
|
|
1
1
|
class Scamp
|
2
2
|
class Matcher
|
3
|
-
attr_accessor :conditions, :trigger, :action, :bot, :required_prefix
|
4
|
-
|
3
|
+
attr_accessor :on, :conditions, :trigger, :action, :bot, :required_prefix
|
4
|
+
|
5
5
|
def initialize(bot, params = {})
|
6
|
-
params ||= {}
|
7
6
|
params[:conditions] ||= {}
|
7
|
+
params[:on] ||= bot.adapters.keys
|
8
|
+
raise ArgumentError, "matcher must have a trigger" unless params[:trigger]
|
9
|
+
raise ArgumentError, "matcher must have a action" unless params[:action]
|
8
10
|
params.each { |k,v| send("#{k}=", v) }
|
9
11
|
@bot = bot
|
10
12
|
end
|
11
|
-
|
12
|
-
def attempt(msg)
|
13
|
-
|
14
|
-
|
15
|
-
if match
|
16
|
-
if match.is_a? MatchData
|
17
|
-
run(msg, match)
|
18
|
-
else
|
19
|
-
run(msg)
|
20
|
-
end
|
13
|
+
|
14
|
+
def attempt(channel, context, msg)
|
15
|
+
if listening?(channel) && msg.matches?(trigger) && msg.valid?(conditions)
|
16
|
+
run(context, msg)
|
21
17
|
return true
|
22
18
|
end
|
23
|
-
false
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def triggered_by(message_text)
|
29
|
-
if message_text && required_prefix
|
30
|
-
message_text = handle_prefix(message_text)
|
31
|
-
return false unless message_text
|
32
|
-
end
|
33
|
-
if trigger.is_a? String
|
34
|
-
return true if trigger == message_text
|
35
|
-
elsif trigger.is_a? Regexp
|
36
|
-
return trigger.match message_text
|
37
|
-
else
|
38
|
-
bot.logger.warn "Don't know what to do with #{trigger.inspect} at #{__FILE__}:#{__LINE__}"
|
39
|
-
end
|
40
|
-
false
|
19
|
+
return false
|
41
20
|
end
|
42
|
-
|
43
|
-
def
|
44
|
-
|
45
|
-
if required_prefix.is_a? String
|
46
|
-
if required_prefix == message_text[0...required_prefix.length]
|
47
|
-
message_text.gsub(required_prefix,'')
|
48
|
-
else
|
49
|
-
false
|
50
|
-
end
|
51
|
-
elsif required_prefix.is_a? Regexp
|
52
|
-
if required_prefix.match message_text
|
53
|
-
message_text.gsub(required_prefix,'')
|
54
|
-
else
|
55
|
-
false
|
56
|
-
end
|
57
|
-
else
|
58
|
-
false
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def run(msg, match = nil)
|
63
|
-
action_run = Action.new(bot, action, msg)
|
64
|
-
action_run.matches = match if match
|
65
|
-
action_run.run
|
21
|
+
|
22
|
+
def run(context, msg)
|
23
|
+
action.call(context, msg)
|
66
24
|
end
|
67
|
-
|
68
|
-
def conditions_satisfied_by(msg)
|
69
|
-
bot.logger.debug "Checking message against #{conditions.inspect}"
|
70
25
|
|
71
|
-
|
72
|
-
|
73
|
-
conditions.each do |item, cond|
|
74
|
-
bot.logger.debug "Checking #{item} against #{cond}"
|
75
|
-
bot.logger.debug "msg is #{msg.inspect}"
|
76
|
-
if cond.is_a? Integer
|
77
|
-
# bot.logger.debug "item is #{msg[{:room => :room_id, :user => :user_id}[item]]}"
|
78
|
-
return false unless msg[{:room => :room_id, :user => :user_id}[item]] == cond
|
79
|
-
elsif cond.is_a? String
|
80
|
-
case item
|
81
|
-
when :room
|
82
|
-
return false unless bot.room_name_for(msg[:room_id]) == cond
|
83
|
-
when :user
|
84
|
-
return false unless bot.username_for(msg[:user_id]) == cond
|
85
|
-
end
|
86
|
-
bot.logger.error "Don't know how to deal with a match item of #{item}, cond #{cond}"
|
87
|
-
elsif cond.is_a? Array
|
88
|
-
case item
|
89
|
-
when :room, :rooms
|
90
|
-
return cond.select {|e| e.is_a? Integer }.include?(msg[{:room => :room_id}[item]]) ||
|
91
|
-
cond.select {|e| e.is_a? String }.include?(bot.room_name_for(msg[:room_id]))
|
92
|
-
end
|
93
|
-
bot.logger.error "Don't know how to deal with a match item of #{item}, cond #{cond}"
|
94
|
-
elsif cond.is_a? Symbol
|
95
|
-
case item
|
96
|
-
when :type
|
97
|
-
return (cond == :text && msg[:type] == "TextMessage") ||
|
98
|
-
(cond == :paste && msg[:type] == "PasteMessage")
|
99
|
-
end
|
100
|
-
bot.logger.error "Don't know how to deal with a match item of #{item}, cond #{cond}"
|
101
|
-
end
|
102
|
-
end
|
103
|
-
true
|
26
|
+
def listening?(channel)
|
27
|
+
on.include?(channel)
|
104
28
|
end
|
105
29
|
end
|
106
30
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Scamp
|
2
|
+
class Matches
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize matches
|
6
|
+
@matches = matches
|
7
|
+
@matches.names.each do |name|
|
8
|
+
self.define_singleton_method name.to_sym do
|
9
|
+
matches[name.to_sym]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def [] index
|
15
|
+
@matches[1..-1][index]
|
16
|
+
end
|
17
|
+
|
18
|
+
def each
|
19
|
+
@matches[1..-1].each {|match| yield match }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'scamp/matches'
|
2
|
+
|
3
|
+
class Scamp
|
4
|
+
class Message
|
5
|
+
attr_reader :adapter, :match
|
6
|
+
|
7
|
+
def initialize(adapter, args={})
|
8
|
+
@adapter = adapter
|
9
|
+
args.each do |arg,value|
|
10
|
+
self.define_singleton_method arg do
|
11
|
+
value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid? conditions
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def matches? trigger
|
21
|
+
match? trigger, body
|
22
|
+
end
|
23
|
+
|
24
|
+
def matches
|
25
|
+
Scamp::Matches.new(match) if match
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def match?(trigger, message)
|
31
|
+
if trigger.is_a? String
|
32
|
+
return true if trigger == message
|
33
|
+
elsif trigger.is_a? Regexp
|
34
|
+
return true if (@match = trigger.match message)
|
35
|
+
end
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/scamp/plugin.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
class Scamp
|
2
|
+
class Plugin
|
3
|
+
def self.matchers
|
4
|
+
@matchers ||= []
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.match trigger, method
|
8
|
+
self.matchers << [trigger, method]
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :bot, :options
|
12
|
+
|
13
|
+
def initialize bot, opts={}
|
14
|
+
@bot = bot
|
15
|
+
@options = opts
|
16
|
+
|
17
|
+
attach_matchers
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def matcher_options
|
22
|
+
{
|
23
|
+
:on => options[:on]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def attach_matchers
|
28
|
+
self.class.matchers.each do |trigger, method_name|
|
29
|
+
@bot.match trigger, matcher_options, &Proc.new(&method(method_name))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/scamp/version.rb
CHANGED