scamp 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.md +19 -0
- data/README.md +171 -126
- data/lib/scamp/action.rb +5 -1
- data/lib/scamp/matcher.rb +7 -0
- data/lib/scamp/messages.rb +5 -1
- data/lib/scamp/rooms.rb +1 -4
- data/lib/scamp/version.rb +1 -1
- data/spec/lib/scamp_spec.rb +76 -27
- metadata +15 -14
data/LICENSE.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2011 by Will Jessop
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -18,135 +18,197 @@ Ruby >= 1.9.2 (At least for the named captures)
|
|
18
18
|
|
19
19
|
### The most simple example:
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
``` ruby
|
22
|
+
require 'scamp'
|
23
|
+
|
24
|
+
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :verbose => true)
|
25
|
+
|
26
|
+
scamp.behaviour do
|
27
|
+
# Simple matching based on regex or string:
|
28
|
+
match "ping" do
|
29
|
+
say "pong"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Connect and join some rooms
|
34
|
+
scamp.connect!([293788, "Monitoring"])
|
35
|
+
```
|
36
|
+
|
37
|
+
### Everyone wants an image search
|
38
|
+
|
39
|
+
``` ruby
|
40
|
+
require 'scamp'
|
41
|
+
require 'cgi'
|
42
|
+
|
43
|
+
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :verbose => true)
|
44
|
+
|
45
|
+
scamp.behaviour do
|
46
|
+
match /^artme (?<search>\w+)/ do
|
47
|
+
url = "http://ajax.googleapis.com/ajax/services/search/images?rsz=large&start=0&v=1.0&q=#{CGI.escape(search)}"
|
48
|
+
http = EventMachine::HttpRequest.new(url).get
|
49
|
+
http.errback { say "Couldn't get #{url}: #{http.response_status.inspect}" }
|
50
|
+
http.callback {
|
51
|
+
if http.response_header.status == 200
|
52
|
+
results = Yajl::Parser.parse(http.response)
|
53
|
+
if results['responseData']['results'].size > 0
|
54
|
+
say results['responseData']['results'][0]['url']
|
55
|
+
else
|
56
|
+
say "No images matched #{search}"
|
57
|
+
end
|
58
|
+
else
|
59
|
+
# logger.warn "Couldn't get #{url}"
|
60
|
+
say "Couldn't get #{url}"
|
29
61
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Connect and join some rooms
|
67
|
+
scamp.connect!([293788, "Monitoring"])
|
68
|
+
```
|
34
69
|
|
35
70
|
### A more in-depth run through
|
36
71
|
|
37
72
|
Matchers are tested in order and all that satisfy the match and conditions will be run. Careful, Scamp listens to itself, you could easily create an infinite loop. Look in the examples dir for more.
|
38
73
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
74
|
+
``` ruby
|
75
|
+
require 'scamp'
|
76
|
+
|
77
|
+
# Add :verbose => true to get debug output, otherwise the logger will output INFO
|
78
|
+
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :verbose => true)
|
79
|
+
|
80
|
+
scamp.behaviour do
|
81
|
+
#
|
82
|
+
# Simple matching based on regex or string:
|
83
|
+
#
|
84
|
+
match /^repeat (\w+), (\w+)$/ do
|
85
|
+
say "You said #{matches[0]} and #{matches[1]}"
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# You can specifically paste text:
|
90
|
+
#
|
91
|
+
|
92
|
+
match "paste stuff" do
|
93
|
+
paste "Awesome texts"
|
43
94
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
95
|
+
# say()'ing multiline strings will paste automatically however:
|
96
|
+
say <<-EOS
|
97
|
+
This will be pasted
|
98
|
+
even though you called say
|
99
|
+
EOS
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# A special user and room method is available in match blocks.
|
104
|
+
#
|
105
|
+
match "a user said" do
|
106
|
+
say "#{user} said something in room #{room}"
|
107
|
+
end
|
108
|
+
|
109
|
+
match "Hello!" do
|
110
|
+
say "Hi there"
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# You can play awesome sounds
|
115
|
+
#
|
116
|
+
match "ohmy" do
|
117
|
+
play "yeah"
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Limit the match to certain rooms, users or both.
|
122
|
+
#
|
123
|
+
match /^Lets match (.+)$/, :conditions => {:room => "Some Room"} do
|
124
|
+
say "Only said if room name matches 'Some Room'"
|
125
|
+
end
|
126
|
+
|
127
|
+
match "some text", :conditions => {:user => "Some User"} do
|
128
|
+
say "Only said if user name matches 'Some User'"
|
129
|
+
end
|
130
|
+
|
131
|
+
match /some other text/, :conditions => {:user => "Some User", :room => 123456} do
|
132
|
+
say "You can mix conditions"
|
133
|
+
end
|
134
|
+
|
135
|
+
match "some text", :conditions => {:room => ["Some Room", "Some Other Room"]} do
|
136
|
+
say "You can list multiple rooms"
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Named captures become available in your match block
|
141
|
+
#
|
142
|
+
match /^say (?<yousaid>.+)$/ do
|
143
|
+
say "You said #{yousaid}"
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
# You can say multiple times, and you can specify an alternate room.
|
148
|
+
# Default behaviour is to 'say' in the room that caused the match.
|
149
|
+
#
|
150
|
+
match "something" do
|
151
|
+
say "#{user} said something in room #{room}"
|
152
|
+
say "#{user} said something in room #{room}", 237872
|
153
|
+
say "#{user} said something in room #{room}", "System Administration"
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# A list of commands is available as command_list this matcher uses it
|
158
|
+
# to format a help text
|
159
|
+
#
|
160
|
+
match "help" do
|
161
|
+
max_command_length = command_list.map{|cl| cl.first.to_s }.max_by(&:size).size
|
162
|
+
format_string = "%#{max_command_length + 1}s"
|
163
|
+
formatted_commands = command_list.map{|action, conds| "#{sprintf(format_string, action)} | #{conds.size == 0 ? '' : conds.inspect}"}
|
164
|
+
say <<-EOS
|
165
|
+
#{sprintf("%-#{max_command_length + 1}s", "Command match")} | Conditions
|
166
|
+
--------------------------------------------------------------------------------
|
167
|
+
#{formatted_commands.join("\n")}
|
168
|
+
EOS
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Connect and join some rooms
|
173
|
+
scamp.connect!([293788, "Monitoring"])
|
174
|
+
```
|
120
175
|
|
121
176
|
In the room/user conditions and say/play commands you can use the name or ID of a user or room, eg:
|
122
177
|
|
123
|
-
|
124
|
-
|
178
|
+
``` ruby
|
179
|
+
:conditions => {:room => "some string"}
|
180
|
+
:conditions => {:room => 123456}
|
125
181
|
|
126
|
-
|
127
|
-
|
182
|
+
:conditions => {:user => "some string"}
|
183
|
+
:conditions => {:user => 123456}
|
128
184
|
|
129
|
-
|
130
|
-
|
185
|
+
say "#{user} said something in room #{room}", 237872
|
186
|
+
say "#{user} said something in room #{room}", "System Administration"
|
187
|
+
```
|
131
188
|
|
132
189
|
By default Scamp listens to itself. This could either be fun, or dangerous, you decide. You can turn this off by passing :ignore\_self => true in the initialisation options:
|
133
190
|
|
134
|
-
|
191
|
+
``` ruby
|
192
|
+
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :ignore_self => true)
|
193
|
+
```
|
135
194
|
|
136
195
|
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:
|
137
196
|
|
138
|
-
|
197
|
+
``` ruby
|
198
|
+
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :first_match_only => true)
|
199
|
+
```
|
139
200
|
|
140
201
|
Scamp will listen to all messages that are sent on the rooms it is listening on and doesn't need to be addressed by name. If you prefer to only trigger bot commands when you address your bot directly add the :required\_prefix initialisation option:
|
141
202
|
|
142
|
-
|
203
|
+
``` ruby
|
204
|
+
scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :required_prefix => 'Bot: ')
|
205
|
+
```
|
143
206
|
|
144
207
|
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.
|
145
208
|
|
146
209
|
## TODO
|
147
210
|
|
148
|
-
* Allow multiple values for conditions, eg: :conditions => {:
|
149
|
-
* Add paste support
|
211
|
+
* Allow multiple values for conditions, eg: :conditions => {:user => ["Some User", "Some Other User"]}
|
150
212
|
|
151
213
|
## How to contribute
|
152
214
|
|
@@ -156,10 +218,11 @@ Here's the most direct way to get your work merged into the project:
|
|
156
218
|
2. Clone down your fork
|
157
219
|
3. Create a feature branch
|
158
220
|
4. Add your feature + tests
|
159
|
-
5.
|
160
|
-
6.
|
161
|
-
7.
|
162
|
-
8.
|
221
|
+
5. Document new features in the README
|
222
|
+
6. Make sure everything still passes by running the tests
|
223
|
+
7. If necessary, rebase your commits into logical chunks, without errors
|
224
|
+
8. Push the branch up
|
225
|
+
9. Send a pull request for your branch
|
163
226
|
|
164
227
|
Take a look at the TODO list or known issues for some inspiration if you need it.
|
165
228
|
|
@@ -172,22 +235,4 @@ First class support, commits and pull requests, thanks guys!
|
|
172
235
|
|
173
236
|
## License
|
174
237
|
|
175
|
-
|
176
|
-
|
177
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
178
|
-
of this software and associated documentation files (the "Software"), to deal
|
179
|
-
in the Software without restriction, including without limitation the rights
|
180
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
181
|
-
copies of the Software, and to permit persons to whom the Software is
|
182
|
-
furnished to do so, subject to the following conditions:
|
183
|
-
|
184
|
-
The above copyright notice and this permission notice shall be included in
|
185
|
-
all copies or substantial portions of the Software.
|
186
|
-
|
187
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
188
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
189
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
190
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
191
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
192
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
193
|
-
THE SOFTWARE.
|
238
|
+
See LICENSE.md
|
data/lib/scamp/action.rb
CHANGED
@@ -60,7 +60,11 @@ class Scamp
|
|
60
60
|
def say(msg, room_id_or_name = room_id)
|
61
61
|
bot.say(msg, room_id_or_name)
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
|
+
def paste(msg, room_id_or_name = room_id)
|
65
|
+
bot.paste(msg, room_id_or_name)
|
66
|
+
end
|
67
|
+
|
64
68
|
def play(sound, room_id_or_name = room_id)
|
65
69
|
bot.play(sound, room_id_or_name)
|
66
70
|
end
|
data/lib/scamp/matcher.rb
CHANGED
@@ -84,6 +84,13 @@ class Scamp
|
|
84
84
|
return false unless bot.username_for(msg[:user_id]) == cond
|
85
85
|
end
|
86
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}"
|
87
94
|
end
|
88
95
|
end
|
89
96
|
true
|
data/lib/scamp/messages.rb
CHANGED
@@ -4,7 +4,11 @@ class Scamp
|
|
4
4
|
def say(message, room_id_or_name)
|
5
5
|
send_message(room_id_or_name, message, "Textmessage")
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
|
+
def paste(message, room_id_or_name)
|
9
|
+
send_message(room_id_or_name, message, "PasteMessage")
|
10
|
+
end
|
11
|
+
|
8
12
|
def play(sound, room_id_or_name)
|
9
13
|
send_message(room_id_or_name, sound, "SoundMessage")
|
10
14
|
end
|
data/lib/scamp/rooms.rb
CHANGED
@@ -4,10 +4,7 @@ class Scamp
|
|
4
4
|
# PasteMessage (pre-formatted message, rendered in a fixed-width font),
|
5
5
|
# SoundMessage (plays a sound as determined by the message, which can be either “rimshot”, “crickets”, or “trombone”),
|
6
6
|
# TweetMessage (a Twitter status URL to be fetched and inserted into the chat)
|
7
|
-
|
8
|
-
def paste(text, room)
|
9
|
-
end
|
10
|
-
|
7
|
+
|
11
8
|
def upload
|
12
9
|
end
|
13
10
|
|
data/lib/scamp/version.rb
CHANGED
data/spec/lib/scamp_spec.rb
CHANGED
@@ -106,34 +106,69 @@ describe Scamp do
|
|
106
106
|
describe "matching" do
|
107
107
|
|
108
108
|
context "with conditions" do
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
109
|
+
context "for room" do
|
110
|
+
|
111
|
+
it "should limit matches by id" do
|
112
|
+
canary = mock
|
113
|
+
canary.expects(:lives).once
|
114
|
+
canary.expects(:bang).never
|
115
|
+
|
116
|
+
bot = a Scamp
|
117
|
+
bot.behaviour do
|
118
|
+
match("a string", :conditions => {:room => 123}) {canary.lives}
|
119
|
+
match("a string", :conditions => {:room => 456}) {canary.bang}
|
120
|
+
end
|
121
|
+
|
122
|
+
bot.send(:process_message, {:room_id => 123, :body => "a string"})
|
118
123
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
124
|
+
|
125
|
+
it "should limit matches by array of IDs" do
|
126
|
+
canary = mock
|
127
|
+
canary.expects(:lives).once
|
128
|
+
canary.expects(:bang).never
|
129
|
+
|
130
|
+
bot = a Scamp
|
131
|
+
bot.behaviour do
|
132
|
+
match("a string", :conditions => {:room => [123]}) {canary.lives}
|
133
|
+
match("a string", :conditions => {:room => [456]}) {canary.bang}
|
134
|
+
end
|
135
|
+
|
136
|
+
bot.room_cache = @valid_room_cache_data
|
137
|
+
|
138
|
+
bot.send(:process_message, {:room_id => 123, :body => "a string"})
|
132
139
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
140
|
+
|
141
|
+
it "should limit matches by array in complex form" do
|
142
|
+
canary = mock
|
143
|
+
canary.expects(:lives).once
|
144
|
+
canary.expects(:bang).never
|
145
|
+
|
146
|
+
bot = a Scamp
|
147
|
+
bot.behaviour do
|
148
|
+
match("a string", :conditions => {:rooms => ["foo", 777]}) {canary.lives}
|
149
|
+
match("a string", :conditions => {:room => ["bar"]}) {canary.bang}
|
150
|
+
end
|
151
|
+
|
152
|
+
bot.room_cache = @valid_room_cache_data
|
153
|
+
bot.send(:process_message, {:room_id => 123, :body => "a string"})
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should limit matches by name" do
|
157
|
+
canary = mock
|
158
|
+
canary.expects(:lives).once
|
159
|
+
canary.expects(:bang).never
|
160
|
+
|
161
|
+
bot = a Scamp
|
162
|
+
bot.behaviour do
|
163
|
+
match("a string", :conditions => {:room => "foo"}) {canary.lives}
|
164
|
+
match("a string", :conditions => {:room => "bar"}) {canary.bang}
|
165
|
+
end
|
166
|
+
|
167
|
+
bot.room_cache = @valid_room_cache_data
|
168
|
+
|
169
|
+
bot.send(:process_message, {:room_id => 123, :body => "a string"})
|
170
|
+
end
|
171
|
+
|
137
172
|
end
|
138
173
|
|
139
174
|
it "should limit matches by user id" do
|
@@ -606,6 +641,7 @@ describe Scamp do
|
|
606
641
|
before do
|
607
642
|
@message_post_url = "https://#{@valid_params[:subdomain]}.campfirenow.com/room/123/speak.json"
|
608
643
|
end
|
644
|
+
|
609
645
|
it "should send a message" do
|
610
646
|
mock_logger
|
611
647
|
bot = a Scamp
|
@@ -618,7 +654,20 @@ describe Scamp do
|
|
618
654
|
}
|
619
655
|
logger_output.should =~ /DEBUG.*Posted message "Hi" to room 123/
|
620
656
|
end
|
621
|
-
|
657
|
+
|
658
|
+
it "should paste a message" do
|
659
|
+
mock_logger
|
660
|
+
bot = a Scamp
|
661
|
+
|
662
|
+
EM.run_block {
|
663
|
+
stub_request(:post, @message_post_url).
|
664
|
+
with(:headers => {'Authorization'=>[@valid_params[:api_key], 'X'], 'Content-Type' => 'application/json'}).
|
665
|
+
to_return(:status => 201, :body => Yajl::Encoder.encode(:room => @valid_room_cache_data[123]), :headers => {})
|
666
|
+
bot.send(:send_message, 123, "Hi", "PasteMessage")
|
667
|
+
}
|
668
|
+
logger_output.should =~ /DEBUG.*Posted message "Hi" to room 123/
|
669
|
+
end
|
670
|
+
|
622
671
|
it "should handle HTTP errors fetching individual room data" do
|
623
672
|
mock_logger
|
624
673
|
bot = a Scamp
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scamp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-10-03 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement: &
|
16
|
+
requirement: &2156161720 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.0.0.beta.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2156161720
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: yajl-ruby
|
27
|
-
requirement: &
|
27
|
+
requirement: &2156160320 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.8.3
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2156160320
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: em-http-request
|
38
|
-
requirement: &
|
38
|
+
requirement: &2156158160 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.0.0.beta.4
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2156158160
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &2156156720 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 2.6.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2156156720
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: mocha
|
60
|
-
requirement: &
|
60
|
+
requirement: &2156154880 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 0.10.0
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2156154880
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: webmock
|
71
|
-
requirement: &
|
71
|
+
requirement: &2156151200 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: 1.7.6
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *2156151200
|
80
80
|
description: Eventmachine based Campfire bot framework
|
81
81
|
email:
|
82
82
|
- will@willj.net
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- .gitignore
|
88
88
|
- .rspec
|
89
89
|
- Gemfile
|
90
|
+
- LICENSE.md
|
90
91
|
- README.md
|
91
92
|
- Rakefile
|
92
93
|
- examples/bot.rb
|