safubot 0.0.3 → 0.0.4
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/.yardoc/checksums +5 -5
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/README.md +9 -9
- data/doc/Safubot/Bot.html +334 -218
- data/doc/Safubot/Evented.html +1 -1
- data/doc/Safubot/KnownUser.html +1 -1
- data/doc/Safubot/Log.html +1 -1
- data/doc/Safubot/Problem.html +130 -0
- data/doc/Safubot/Problematic.html +282 -0
- data/doc/Safubot/Query.html +50 -1
- data/doc/Safubot/Request.html +19 -2
- data/doc/Safubot/Response.html +19 -2
- data/doc/Safubot/Test.html +1 -1
- data/doc/Safubot/Twitter/Bot.html +248 -135
- data/doc/Safubot/Twitter/DirectMessage.html +22 -22
- data/doc/Safubot/Twitter/Tweet.html +40 -40
- data/doc/Safubot/Twitter.html +1 -1
- data/doc/Safubot/XMPP/Bot.html +47 -31
- data/doc/Safubot/XMPP/Message.html +1 -1
- data/doc/Safubot/XMPP.html +1 -1
- data/doc/Safubot.html +4 -4
- data/doc/_index.html +26 -4
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +11 -10
- data/doc/index.html +11 -10
- data/doc/method_list.html +103 -79
- data/doc/top-level-namespace.html +1 -1
- data/lib/safubot/bot.rb +100 -26
- data/lib/safubot/test_helper.rb +4 -0
- data/lib/safubot/twitter.rb +6 -7
- data/lib/safubot/version.rb +1 -1
- data/lib/safubot/xmpp.rb +9 -3
- data/safubot.gemspec +1 -0
- metadata +119 -113
data/lib/safubot/bot.rb
CHANGED
@@ -8,19 +8,51 @@ module Safubot
|
|
8
8
|
"#{e.inspect}\n#{e.backtrace.join("\n\t")}"
|
9
9
|
end
|
10
10
|
|
11
|
+
###
|
12
|
+
# An EmbeddedDocument for storing processing/dispatch errors.
|
13
|
+
class Problem
|
14
|
+
include MongoMapper::EmbeddedDocument
|
15
|
+
key :when, Time
|
16
|
+
key :error, String # Exception#to_s
|
17
|
+
key :type, String # Exception class
|
18
|
+
key :backtrace, Array, :default => nil
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# A mixin adding Problem handling.
|
23
|
+
module Problematic
|
24
|
+
##
|
25
|
+
# Adds a timestamped Problem to the list.
|
26
|
+
# @param e Exception from which the Problem is derived.
|
27
|
+
def add_problem(e)
|
28
|
+
problem = Problem.new(:error => e.to_s, :type => e.class.to_s,
|
29
|
+
:when => Time.now, :backtrace => e.backtrace)
|
30
|
+
self.problems.push(problem)
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Fetches the most recent Problem.
|
35
|
+
def last_problem
|
36
|
+
self.problems.sort { |x,y| x.when <=> y.when }.last
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
11
41
|
##
|
12
42
|
# Defines elements of the input queue, agnostic of the transfer medium.
|
13
43
|
# May be extended by service-specific modules.
|
14
44
|
class Request
|
15
45
|
include MongoMapper::Document
|
46
|
+
include Problematic
|
16
47
|
safe
|
17
|
-
key :
|
48
|
+
key :processing, Boolean, :default => false # Currently-processing lock.
|
18
49
|
key :processed, Boolean, :default => false # Have we processed this request?
|
19
50
|
key :success, Boolean, :default => false # Did we *successfully* process this request?
|
20
51
|
key :text, String # The actual content.
|
21
52
|
belongs_to :source, :polymorphic => true # The concrete medium-specific source.
|
22
|
-
belongs_to :user, :
|
53
|
+
belongs_to :user, :class_name => "Safubot::KnownUser"
|
23
54
|
many :responses, :class_name => "Safubot::Response"
|
55
|
+
many :problems # Hopefully not that many ;)
|
24
56
|
timestamps!
|
25
57
|
end
|
26
58
|
|
@@ -29,11 +61,13 @@ module Safubot
|
|
29
61
|
# May be extended by service-specific modules.
|
30
62
|
class Response
|
31
63
|
include MongoMapper::Document
|
64
|
+
include Problematic
|
32
65
|
safe
|
33
|
-
key :
|
66
|
+
key :dispatching, Boolean, :default => false # Dispatch lock.
|
34
67
|
key :dispatched, Boolean, :default => false
|
35
68
|
key :text, String
|
36
|
-
belongs_to :request, :
|
69
|
+
belongs_to :request, :class_name => "Safubot::Request"
|
70
|
+
many :problems
|
37
71
|
timestamps!
|
38
72
|
end
|
39
73
|
|
@@ -47,27 +81,54 @@ module Safubot
|
|
47
81
|
attr_reader :opts, :twitter, :xmpp
|
48
82
|
|
49
83
|
##
|
50
|
-
# Records an error and emits a corresponding :request_error event.
|
84
|
+
# Records an error in processing and emits a corresponding :request_error event.
|
51
85
|
# @param req The Request for which the error was encountered.
|
52
86
|
# @param e The caught Exception.
|
53
87
|
def request_error(req, e)
|
54
|
-
Log.error "Error processing #{req.source.class} '#{req.text}': #{e
|
55
|
-
req.
|
88
|
+
Log.error "Error processing #{req.source.class} '#{req.text}': #{error_report(e)}"
|
89
|
+
req.add_problem(e)
|
56
90
|
req.save
|
57
91
|
emit(:request_error, req, e)
|
58
92
|
end
|
59
93
|
|
94
|
+
##
|
95
|
+
# Records an error in dispatch and emits a corresponding :dispatch_error event.
|
96
|
+
# @param resp The Response for which the error was encountered.
|
97
|
+
# @param e The caught Exception.
|
98
|
+
def dispatch_error(resp, e)
|
99
|
+
Log.error "Error dispatching #{resp.request.source.class} '#{resp.text}': #{error_report(e)}"
|
100
|
+
resp.add_problem(e)
|
101
|
+
resp.save
|
102
|
+
emit(:dispatch_error, resp, e)
|
103
|
+
end
|
104
|
+
|
60
105
|
##
|
61
106
|
# Processes an individual request (synchronously).
|
62
107
|
# @param req An unprocessed Request.
|
63
108
|
def process_request(req)
|
109
|
+
req.reload
|
110
|
+
if req.processed
|
111
|
+
Log.debug "Request '#{req.text}' has already been processed, ignoring."
|
112
|
+
return
|
113
|
+
elsif req.processing
|
114
|
+
Log.debug "Request '#{req.text}' is currently in processing, ignoring."
|
115
|
+
return
|
116
|
+
end
|
117
|
+
|
64
118
|
begin
|
119
|
+
req.processing = true
|
120
|
+
req.save
|
65
121
|
emit(:request, req)
|
66
122
|
rescue Exception => e
|
67
123
|
request_error(req, e)
|
124
|
+
else
|
125
|
+
req.success = true
|
68
126
|
ensure
|
69
|
-
|
70
|
-
|
127
|
+
#if Safubot::mode == :production
|
128
|
+
req.processing = false
|
129
|
+
req.processed = true
|
130
|
+
req.save
|
131
|
+
#end
|
71
132
|
end
|
72
133
|
end
|
73
134
|
|
@@ -75,8 +136,26 @@ module Safubot
|
|
75
136
|
# Performs appropriate dispatch operation for response type.
|
76
137
|
# @param resp An undispatched Response.
|
77
138
|
def dispatch(resp)
|
139
|
+
resp.reload
|
140
|
+
if resp.dispatched
|
141
|
+
Log.debug "Response '#{resp.text}' has already been dispatched, ignoring."
|
142
|
+
return
|
143
|
+
elsif resp.dispatching
|
144
|
+
Log.debug "Response '#{resp.text}' is already in dispatch, ignoring."
|
145
|
+
return
|
146
|
+
elsif resp.problems.length > 10
|
147
|
+
Log.debug "Response '#{resp.text}' encountered more than ten dispatch errors, ignoring."
|
148
|
+
return
|
149
|
+
elsif !resp.problems.empty? && (Time.now - resp.last_problem.when) < 1.minute
|
150
|
+
Log.debug "Response '#{resp.text}' encountered a dispatch error <1 minute ago, ignoring."
|
151
|
+
return
|
152
|
+
end
|
153
|
+
|
78
154
|
begin
|
79
155
|
source = resp.request.source
|
156
|
+
resp.dispatching = true
|
157
|
+
resp.save
|
158
|
+
|
80
159
|
if Safubot::mode != :production
|
81
160
|
Log.info "#{source.class} Response to #{source.username}: #{resp.text}"
|
82
161
|
else
|
@@ -87,15 +166,15 @@ module Safubot
|
|
87
166
|
else
|
88
167
|
raise NotImplementedError, "Don't know how to send response to a #{source.class}!"
|
89
168
|
end
|
90
|
-
end
|
91
169
|
|
92
|
-
|
93
|
-
|
170
|
+
resp.dispatched = true
|
171
|
+
resp.save
|
172
|
+
end
|
94
173
|
rescue Exception => e
|
95
|
-
|
96
|
-
|
174
|
+
dispatch_error(resp, e)
|
175
|
+
ensure
|
176
|
+
resp.dispatching = false
|
97
177
|
resp.save
|
98
|
-
emit(:dispatch_error, resp, e)
|
99
178
|
end
|
100
179
|
end
|
101
180
|
|
@@ -112,18 +191,12 @@ module Safubot
|
|
112
191
|
end
|
113
192
|
|
114
193
|
##
|
115
|
-
# Adds a response to the queue.
|
194
|
+
# Adds a response to the queue and dispatches it.
|
116
195
|
# @param req Request to respond to.
|
117
196
|
# @param text Contents of the response.
|
118
197
|
def respond(req, text)
|
119
198
|
Log.info("#{req.user.name}: #{req.text}\nsafubot: #{text}")
|
120
|
-
Response.create(:request => req, :text => text)
|
121
|
-
end
|
122
|
-
|
123
|
-
# Respond + push
|
124
|
-
def respond_now(req, text)
|
125
|
-
respond(req, text)
|
126
|
-
push
|
199
|
+
dispatch(Response.create(:request => req, :text => text))
|
127
200
|
end
|
128
201
|
|
129
202
|
# Dispatches all undispatched Responses.
|
@@ -142,7 +215,6 @@ module Safubot
|
|
142
215
|
rescue Exception => e
|
143
216
|
request_error(req, e)
|
144
217
|
end
|
145
|
-
|
146
218
|
push
|
147
219
|
end
|
148
220
|
end
|
@@ -174,7 +246,8 @@ module Safubot
|
|
174
246
|
def enable_twitter(opts={})
|
175
247
|
@twitter = Twitter::Bot.new(opts)
|
176
248
|
@twitter.on(:request) do |req|
|
177
|
-
|
249
|
+
process_request(req)
|
250
|
+
req.responses.where(:dispatched => false).map(&method(:dispatch))
|
178
251
|
end
|
179
252
|
end
|
180
253
|
|
@@ -183,7 +256,8 @@ module Safubot
|
|
183
256
|
defaults = { :jid => nil, :password => nil }
|
184
257
|
@xmpp = XMPP::Bot.new(defaults.merge(options))
|
185
258
|
@xmpp.on(:request) do |req|
|
186
|
-
|
259
|
+
process_request(req)
|
260
|
+
req.responses.where(:dispatched => false).map(&method(:dispatch))
|
187
261
|
end
|
188
262
|
end
|
189
263
|
|
data/lib/safubot/test_helper.rb
CHANGED
data/lib/safubot/twitter.rb
CHANGED
@@ -170,7 +170,7 @@ module Safubot
|
|
170
170
|
if source.is_a?(DirectMessage)
|
171
171
|
@client.direct_message_create(source.raw['sender']['screen_name'], resp.text)
|
172
172
|
elsif source.is_a?(Tweet)
|
173
|
-
reply
|
173
|
+
reply source, resp.text
|
174
174
|
else
|
175
175
|
raise NotImplementedError, "Don't know how to send response to a #{req.source.class}!"
|
176
176
|
end
|
@@ -188,7 +188,7 @@ module Safubot
|
|
188
188
|
# @param message A raw JSON-derived direct message.
|
189
189
|
def handle_message(message)
|
190
190
|
return if message.sender.screen_name == @username
|
191
|
-
DirectMessage.from(message).make_request
|
191
|
+
handle_request(DirectMessage.from(message).make_request)
|
192
192
|
end
|
193
193
|
|
194
194
|
##
|
@@ -198,7 +198,7 @@ module Safubot
|
|
198
198
|
def handle_tweet(status)
|
199
199
|
return if status.user.screen_name == @username
|
200
200
|
if status.text.match(/@#{@username}/i)
|
201
|
-
Tweet.from(status).make_request
|
201
|
+
handle_request(Tweet.from(status).make_request)
|
202
202
|
else
|
203
203
|
emit(:timeline, Tweet.from(status))
|
204
204
|
end
|
@@ -239,8 +239,7 @@ module Safubot
|
|
239
239
|
@stream = TweetStream::Client.new(@opts)
|
240
240
|
|
241
241
|
@stream.on_direct_message do |message|
|
242
|
-
|
243
|
-
handle_request(req) if req.is_a? Request
|
242
|
+
handle_message(message)
|
244
243
|
end
|
245
244
|
|
246
245
|
@stream.on_error do |err|
|
@@ -253,6 +252,7 @@ module Safubot
|
|
253
252
|
|
254
253
|
@stream.on_inited do
|
255
254
|
Log.info("TweetStream client is online at @#{@username} :3")
|
255
|
+
emit(:ready)
|
256
256
|
end
|
257
257
|
end
|
258
258
|
|
@@ -260,8 +260,7 @@ module Safubot
|
|
260
260
|
def run_stream
|
261
261
|
begin
|
262
262
|
@stream.userstream do |status|
|
263
|
-
|
264
|
-
handle_request(req) if req.is_a? Request
|
263
|
+
handle_tweet(status)
|
265
264
|
end
|
266
265
|
rescue Exception => e
|
267
266
|
if e.is_a?(Interrupt) || e.is_a?(SignalException)
|
data/lib/safubot/version.rb
CHANGED
data/lib/safubot/xmpp.rb
CHANGED
@@ -113,11 +113,13 @@ module Safubot
|
|
113
113
|
# Runs the Blather client.
|
114
114
|
def run_blather
|
115
115
|
begin
|
116
|
-
EM::run {
|
116
|
+
EM::run {
|
117
|
+
@client.run
|
118
|
+
}
|
117
119
|
rescue Exception => e
|
118
120
|
if e.is_a?(Interrupt) || e.is_a?(SignalException)
|
119
121
|
stop
|
120
|
-
|
122
|
+
elsif @state == :running
|
121
123
|
Log.error "XMPP client exited unexpectedly: #{error_report(e)}"
|
122
124
|
Log.error "Restarting XMPP client in 5 seconds."
|
123
125
|
sleep 5; init_blather; run_blather
|
@@ -155,7 +157,11 @@ module Safubot
|
|
155
157
|
|
156
158
|
# Dispatch a Response via XMPP.
|
157
159
|
def send(resp)
|
158
|
-
|
160
|
+
if @state == :running
|
161
|
+
tell(resp.request.source.from, resp.text)
|
162
|
+
else
|
163
|
+
on(:ready) { send(resp) }
|
164
|
+
end
|
159
165
|
end
|
160
166
|
|
161
167
|
def initialize(opts)
|
data/safubot.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
+
s.add_dependency "activesupport", "= 3.1.0" # mongo_mapper seems to need this without specifying it.
|
22
23
|
s.add_dependency "eventmachine", "~> 0.12.10"
|
23
24
|
s.add_dependency "bson_ext", "~> 1.4.0"
|
24
25
|
s.add_dependency "mongo_mapper", "~> 0.10.1"
|
metadata
CHANGED
@@ -1,144 +1,159 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: safubot
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 0.0.4
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Jaiden Mispy
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
|
13
|
+
date: 2011-12-01 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - "="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 3.1.0
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
15
27
|
name: eventmachine
|
16
|
-
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
17
30
|
none: false
|
18
|
-
requirements:
|
31
|
+
requirements:
|
19
32
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
33
|
+
- !ruby/object:Gem::Version
|
21
34
|
version: 0.12.10
|
22
35
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
36
|
+
version_requirements: *id002
|
37
|
+
- !ruby/object:Gem::Dependency
|
26
38
|
name: bson_ext
|
27
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
28
41
|
none: false
|
29
|
-
requirements:
|
42
|
+
requirements:
|
30
43
|
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
44
|
+
- !ruby/object:Gem::Version
|
32
45
|
version: 1.4.0
|
33
46
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
37
49
|
name: mongo_mapper
|
38
|
-
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
39
52
|
none: false
|
40
|
-
requirements:
|
53
|
+
requirements:
|
41
54
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
55
|
+
- !ruby/object:Gem::Version
|
43
56
|
version: 0.10.1
|
44
57
|
type: :runtime
|
45
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
58
|
+
version_requirements: *id004
|
59
|
+
- !ruby/object:Gem::Dependency
|
48
60
|
name: twitter
|
49
|
-
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
50
63
|
none: false
|
51
|
-
requirements:
|
64
|
+
requirements:
|
52
65
|
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
66
|
+
- !ruby/object:Gem::Version
|
54
67
|
version: 2.0.0
|
55
68
|
type: :runtime
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
69
|
+
version_requirements: *id005
|
70
|
+
- !ruby/object:Gem::Dependency
|
59
71
|
name: tweetstream
|
60
|
-
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
61
74
|
none: false
|
62
|
-
requirements:
|
75
|
+
requirements:
|
63
76
|
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
77
|
+
- !ruby/object:Gem::Version
|
65
78
|
version: 1.1.3
|
66
79
|
type: :runtime
|
67
|
-
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Dependency
|
80
|
+
version_requirements: *id006
|
81
|
+
- !ruby/object:Gem::Dependency
|
70
82
|
name: blather
|
71
|
-
|
83
|
+
prerelease: false
|
84
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
72
85
|
none: false
|
73
|
-
requirements:
|
86
|
+
requirements:
|
74
87
|
- - ~>
|
75
|
-
- !ruby/object:Gem::Version
|
88
|
+
- !ruby/object:Gem::Version
|
76
89
|
version: 0.5.8
|
77
90
|
type: :runtime
|
78
|
-
|
79
|
-
|
80
|
-
- !ruby/object:Gem::Dependency
|
91
|
+
version_requirements: *id007
|
92
|
+
- !ruby/object:Gem::Dependency
|
81
93
|
name: rake
|
82
|
-
|
94
|
+
prerelease: false
|
95
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
83
96
|
none: false
|
84
|
-
requirements:
|
85
|
-
- -
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version:
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: "0"
|
88
101
|
type: :development
|
89
|
-
|
90
|
-
|
91
|
-
- !ruby/object:Gem::Dependency
|
102
|
+
version_requirements: *id008
|
103
|
+
- !ruby/object:Gem::Dependency
|
92
104
|
name: rspec
|
93
|
-
|
105
|
+
prerelease: false
|
106
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
94
107
|
none: false
|
95
|
-
requirements:
|
96
|
-
- -
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version:
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: "0"
|
99
112
|
type: :development
|
100
|
-
|
101
|
-
|
102
|
-
- !ruby/object:Gem::Dependency
|
113
|
+
version_requirements: *id009
|
114
|
+
- !ruby/object:Gem::Dependency
|
103
115
|
name: yard
|
104
|
-
|
116
|
+
prerelease: false
|
117
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
105
118
|
none: false
|
106
|
-
requirements:
|
107
|
-
- -
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version:
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: "0"
|
110
123
|
type: :development
|
111
|
-
|
112
|
-
|
113
|
-
- !ruby/object:Gem::Dependency
|
124
|
+
version_requirements: *id010
|
125
|
+
- !ruby/object:Gem::Dependency
|
114
126
|
name: bundler
|
115
|
-
|
127
|
+
prerelease: false
|
128
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
116
129
|
none: false
|
117
|
-
requirements:
|
118
|
-
- -
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
version:
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: "0"
|
121
134
|
type: :development
|
122
|
-
|
123
|
-
|
124
|
-
- !ruby/object:Gem::Dependency
|
135
|
+
version_requirements: *id011
|
136
|
+
- !ruby/object:Gem::Dependency
|
125
137
|
name: wirble
|
126
|
-
|
138
|
+
prerelease: false
|
139
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
127
140
|
none: false
|
128
|
-
requirements:
|
129
|
-
- -
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version:
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: "0"
|
132
145
|
type: :development
|
133
|
-
|
134
|
-
version_requirements: *24331220
|
146
|
+
version_requirements: *id012
|
135
147
|
description: A friendly event-driven chatbot framework. Supports Twitter and XMPP.
|
136
|
-
email:
|
148
|
+
email:
|
137
149
|
- ^_^@mispy.me
|
138
150
|
executables: []
|
151
|
+
|
139
152
|
extensions: []
|
153
|
+
|
140
154
|
extra_rdoc_files: []
|
141
|
-
|
155
|
+
|
156
|
+
files:
|
142
157
|
- .gitignore
|
143
158
|
- .yardoc/checksums
|
144
159
|
- .yardoc/objects/root.dat
|
@@ -152,6 +167,8 @@ files:
|
|
152
167
|
- doc/Safubot/Evented.html
|
153
168
|
- doc/Safubot/KnownUser.html
|
154
169
|
- doc/Safubot/Log.html
|
170
|
+
- doc/Safubot/Problem.html
|
171
|
+
- doc/Safubot/Problematic.html
|
155
172
|
- doc/Safubot/Query.html
|
156
173
|
- doc/Safubot/Request.html
|
157
174
|
- doc/Safubot/Response.html
|
@@ -196,44 +213,33 @@ files:
|
|
196
213
|
- spec/safubot/known_user_spec.rb
|
197
214
|
- spec/safubot/twitter_spec.rb
|
198
215
|
- spec/safubot/xmpp_spec.rb
|
199
|
-
homepage:
|
216
|
+
homepage: ""
|
200
217
|
licenses: []
|
218
|
+
|
201
219
|
post_install_message:
|
202
220
|
rdoc_options: []
|
203
|
-
|
221
|
+
|
222
|
+
require_paths:
|
204
223
|
- lib
|
205
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
224
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
225
|
none: false
|
207
|
-
requirements:
|
208
|
-
- -
|
209
|
-
- !ruby/object:Gem::Version
|
210
|
-
version:
|
211
|
-
|
212
|
-
- 0
|
213
|
-
hash: 401033843839902587
|
214
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: "0"
|
230
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
215
231
|
none: false
|
216
|
-
requirements:
|
217
|
-
- -
|
218
|
-
- !ruby/object:Gem::Version
|
219
|
-
version:
|
220
|
-
segments:
|
221
|
-
- 0
|
222
|
-
hash: 401033843839902587
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: "0"
|
223
236
|
requirements: []
|
237
|
+
|
224
238
|
rubyforge_project: safubot
|
225
|
-
rubygems_version: 1.8.
|
239
|
+
rubygems_version: 1.8.11
|
226
240
|
signing_key:
|
227
241
|
specification_version: 3
|
228
242
|
summary: A friendly event-driven chatbot framework. Supports Twitter and XMPP.
|
229
|
-
test_files:
|
230
|
-
|
231
|
-
- spec/fixtures/twitter/tweet
|
232
|
-
- spec/fixtures/xmpp/message
|
233
|
-
- spec/helper.rb
|
234
|
-
- spec/safubot/bot_spec.rb
|
235
|
-
- spec/safubot/evented_spec.rb
|
236
|
-
- spec/safubot/known_user_spec.rb
|
237
|
-
- spec/safubot/twitter_spec.rb
|
238
|
-
- spec/safubot/xmpp_spec.rb
|
243
|
+
test_files: []
|
244
|
+
|
239
245
|
has_rdoc:
|