rumpy 0.9.21 → 0.9.22
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/lib/rumpy.rb +4 -317
- metadata +6 -8
data/lib/rumpy.rb
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require 'xmpp4r/version'
|
5
|
-
require 'active_record'
|
6
|
-
require 'logger'
|
2
|
+
require 'rumpy/version'
|
3
|
+
require 'rumpy/bot'
|
7
4
|
|
8
5
|
module Rumpy
|
9
6
|
|
10
7
|
# Start bot in new process,
|
11
8
|
# detach this process and save the pid of process in pid_file
|
12
9
|
def self.start(bot)
|
13
|
-
pf
|
10
|
+
pf = pid_file bot
|
14
11
|
return false if File.exist? pf
|
15
12
|
|
16
|
-
bot.log_file
|
13
|
+
bot.log_file = "#{bot.class.to_s.downcase}.log"
|
17
14
|
|
18
15
|
pid = fork do
|
19
16
|
bot.start
|
@@ -51,314 +48,4 @@ module Rumpy
|
|
51
48
|
pid_file = bot.class.to_s.downcase + '.pid' unless pid_file
|
52
49
|
pid_file
|
53
50
|
end
|
54
|
-
|
55
|
-
# include this module into your bot's class
|
56
|
-
module Bot
|
57
|
-
attr_reader :pid_file
|
58
|
-
|
59
|
-
# if @log_file isn't set, initialize it
|
60
|
-
def log_file=(logfile)
|
61
|
-
@log_file ||= logfile
|
62
|
-
end
|
63
|
-
|
64
|
-
# one and only public function, defined in this module
|
65
|
-
# simply initializes bot's variables, connection, etc.
|
66
|
-
# and starts bot
|
67
|
-
def start
|
68
|
-
logger_init
|
69
|
-
|
70
|
-
init
|
71
|
-
|
72
|
-
connect
|
73
|
-
|
74
|
-
set_iq_callback
|
75
|
-
set_subscription_callback
|
76
|
-
set_message_callback
|
77
|
-
|
78
|
-
start_backend_thread
|
79
|
-
start_output_queue_thread
|
80
|
-
|
81
|
-
prepare_users
|
82
|
-
|
83
|
-
@logger.info 'Bot is going ONLINE'
|
84
|
-
@output_queue.enq Jabber::Presence.new(nil, @status, @priority)
|
85
|
-
|
86
|
-
add_signal_trap
|
87
|
-
|
88
|
-
Thread.stop
|
89
|
-
rescue => ex
|
90
|
-
general_error ex
|
91
|
-
exit
|
92
|
-
end # def start
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def logger_init
|
97
|
-
unless @logger
|
98
|
-
@log_file ||= STDERR
|
99
|
-
@log_level ||= Logger::INFO
|
100
|
-
@logger = Logger.new @log_file, @log_shift_age, @log_shift_size
|
101
|
-
@logger.level = @log_level
|
102
|
-
@logger.datetime_format = "%Y-%m-%d %H:%M:%S"
|
103
|
-
end
|
104
|
-
|
105
|
-
@logger.info 'starting bot'
|
106
|
-
end
|
107
|
-
|
108
|
-
def init
|
109
|
-
@config_path ||= 'config'
|
110
|
-
@main_model ||= :user
|
111
|
-
|
112
|
-
@logger.debug 'initializing some variables'
|
113
|
-
|
114
|
-
xmppconfig = YAML::load_file @config_path + '/xmpp.yml'
|
115
|
-
@logger.info 'loaded xmpp.yml'
|
116
|
-
@logger.debug "xmpp.yml: #{xmppconfig.inspect}"
|
117
|
-
@lang = YAML::load_file @config_path + '/lang.yml'
|
118
|
-
@logger.info 'loaded lang.yml'
|
119
|
-
@logger.debug "lang.yml: #{@lang.inspect}"
|
120
|
-
@jid = Jabber::JID.new xmppconfig['jid']
|
121
|
-
@priority = xmppconfig['priority']
|
122
|
-
@status = xmppconfig['status']
|
123
|
-
@password = xmppconfig['password']
|
124
|
-
@client = Jabber::Client.new @jid
|
125
|
-
Jabber::Version::SimpleResponder.new(@client, @bot_name || self.class.to_s, @bot_version || '1.0.0', RUBY_PLATFORM)
|
126
|
-
|
127
|
-
if @models_files
|
128
|
-
dbconfig = YAML::load_file @config_path + '/database.yml'
|
129
|
-
@logger.info 'loaded database.yml'
|
130
|
-
@logger.debug "database.yml: #{dbconfig.inspect}"
|
131
|
-
ActiveRecord::Base.establish_connection dbconfig
|
132
|
-
@logger.info 'database connection established'
|
133
|
-
@models_files.each do |file|
|
134
|
-
self.class.require file
|
135
|
-
@logger.info "added models file '#{file}'"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
@main_model = Object.const_get @main_model.to_s.capitalize
|
140
|
-
@logger.info "main model set to #{@main_model}"
|
141
|
-
|
142
|
-
@queues = Hash.new do |h, k|
|
143
|
-
h[k] = Queue.new
|
144
|
-
end
|
145
|
-
|
146
|
-
@output_queue = Queue.new
|
147
|
-
end # def init
|
148
|
-
|
149
|
-
def connect
|
150
|
-
@logger.debug 'establishing xmpp connection'
|
151
|
-
|
152
|
-
@client.connect
|
153
|
-
@client.auth @password
|
154
|
-
@roster = Jabber::Roster::Helper.new @client
|
155
|
-
@roster.wait_for_roster
|
156
|
-
|
157
|
-
@logger.info 'xmpp connection established'
|
158
|
-
end
|
159
|
-
|
160
|
-
def set_iq_callback
|
161
|
-
@client.add_iq_callback do |iq|
|
162
|
-
@logger.debug "got iq #{iq}"
|
163
|
-
if iq.type == :get # hack for pidgin (STOP USING IT)
|
164
|
-
response = iq.answer true
|
165
|
-
if iq.elements['time'] == "<time xmlns='urn:xmpp:time'/>"
|
166
|
-
@logger.debug 'this is time request, okay'
|
167
|
-
response.set_type :result
|
168
|
-
tm = Time.now
|
169
|
-
response.elements['time'].add REXML::Element.new('tzo')
|
170
|
-
response.elements['time/tzo'].text = tm.xmlschema[-6..-1]
|
171
|
-
response.elements['time'].add REXML::Element.new('utc')
|
172
|
-
response.elements['time/utc'].text = tm.utc.xmlschema
|
173
|
-
else
|
174
|
-
response.set_type :error
|
175
|
-
end # if iq.elements['time']
|
176
|
-
@output_queue.enq response
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end # def set_iq_callback
|
180
|
-
|
181
|
-
def set_subscription_callback
|
182
|
-
@roster.add_subscription_request_callback do |item, presence|
|
183
|
-
jid = presence.from
|
184
|
-
@roster.accept_subscription jid
|
185
|
-
@output_queue.enq presence.answer.set_type :subscribe
|
186
|
-
@output_queue.enq Jabber::Message.new(jid, @lang['hello']).set_type :chat
|
187
|
-
|
188
|
-
@logger.info "#{jid} just subscribed"
|
189
|
-
end
|
190
|
-
@roster.add_subscription_callback do |item, presence|
|
191
|
-
begin
|
192
|
-
case presence.type
|
193
|
-
when :unsubscribed, :unsubscribe
|
194
|
-
@logger.info "#{item.jid} wanna unsubscribe"
|
195
|
-
@queues[item.jid.strip.to_s].enq :unsubscribe
|
196
|
-
item.remove
|
197
|
-
when :subscribed
|
198
|
-
user = @main_model.new
|
199
|
-
user.jid = item.jid.strip.to_s
|
200
|
-
user.save
|
201
|
-
start_user_thread user
|
202
|
-
|
203
|
-
@logger.info "added new user: #{user.jid}"
|
204
|
-
@output_queue.enq Jabber::Message.new(item.jid, @lang['authorized']).set_type :chat
|
205
|
-
end
|
206
|
-
rescue ActiveRecord::StatementInvalid
|
207
|
-
statement_invalid_error
|
208
|
-
retry
|
209
|
-
rescue ActiveRecord::ConnectionTimeoutError
|
210
|
-
connection_timeout_error
|
211
|
-
retry
|
212
|
-
rescue => ex
|
213
|
-
general_error ex
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end # def set_subscription_callback
|
217
|
-
|
218
|
-
def set_message_callback
|
219
|
-
@client.add_message_callback do |msg|
|
220
|
-
if msg.type != :error && msg.body && msg.from
|
221
|
-
if @roster[msg.from] && @roster[msg.from].subscription == :both
|
222
|
-
@logger.debug "got normal message #{msg}"
|
223
|
-
|
224
|
-
@queues[msg.from.strip.to_s].enq msg
|
225
|
-
else
|
226
|
-
@logger.debug "user not in roster: #{msg.from}"
|
227
|
-
|
228
|
-
@output_queue.enq msg.answer.set_body @lang['stranger']
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end # def set_message_callback
|
233
|
-
|
234
|
-
def start_backend_thread
|
235
|
-
Thread.new do
|
236
|
-
begin
|
237
|
-
loop do
|
238
|
-
backend_func().each do |result|
|
239
|
-
message = Jabber::Message.new(*result).set_type :chat
|
240
|
-
@output_queue.enq message if message.body && message.to
|
241
|
-
end
|
242
|
-
end
|
243
|
-
rescue ActiveRecord::StatementInvalid
|
244
|
-
statement_invalid_error
|
245
|
-
retry
|
246
|
-
rescue ActiveRecord::ConnectionTimeoutError
|
247
|
-
connection_timeout_error
|
248
|
-
retry
|
249
|
-
rescue => ex
|
250
|
-
general_error ex
|
251
|
-
end # begin
|
252
|
-
end if self.respond_to? :backend_func
|
253
|
-
end # def start_backend_thread
|
254
|
-
|
255
|
-
def start_output_queue_thread
|
256
|
-
Thread.new do
|
257
|
-
@logger.info "Output queue initialized"
|
258
|
-
until (msg = @output_queue.deq) == :halt do
|
259
|
-
if msg.nil?
|
260
|
-
@logger.debug "got nil message. wtf?"
|
261
|
-
else
|
262
|
-
@logger.debug "sending message #{msg}"
|
263
|
-
@client.send msg
|
264
|
-
end
|
265
|
-
end
|
266
|
-
@logger.info "Output queue destroyed"
|
267
|
-
end
|
268
|
-
end # def start_output_queue_thread
|
269
|
-
|
270
|
-
def add_signal_trap
|
271
|
-
Signal.trap :TERM do |signo| # soft stop
|
272
|
-
@logger.info 'Bot is unavailable'
|
273
|
-
@output_queue.enq Jabber::Presence.new.set_type :unavailable
|
274
|
-
|
275
|
-
@queues.each do |user, queue|
|
276
|
-
queue.enq :halt
|
277
|
-
end
|
278
|
-
sleep 1 until @queues.empty?
|
279
|
-
|
280
|
-
@output_queue.enq :halt
|
281
|
-
sleep 1 until @output_queue.empty?
|
282
|
-
|
283
|
-
@client.close
|
284
|
-
|
285
|
-
@logger.info 'terminating'
|
286
|
-
@logger.close
|
287
|
-
exit
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
def prepare_users
|
292
|
-
@logger.debug 'clear wrong users'
|
293
|
-
|
294
|
-
@roster.items.each do |jid, item|
|
295
|
-
user = @main_model.find_by_jid jid.strip.to_s
|
296
|
-
if user.nil? || item.subscription != :both
|
297
|
-
@logger.info "deleting from roster user with jid #{jid}"
|
298
|
-
item.remove
|
299
|
-
end
|
300
|
-
end
|
301
|
-
@main_model.find_each do |user|
|
302
|
-
items = @roster.find user.jid
|
303
|
-
if items.empty?
|
304
|
-
@logger.info "deleting from database user with jid #{user.jid}"
|
305
|
-
user.destroy
|
306
|
-
else
|
307
|
-
start_user_thread user
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
@main_model.connection_pool.release_connection
|
312
|
-
end # def prepare_users
|
313
|
-
|
314
|
-
def start_user_thread(user)
|
315
|
-
Thread.new(user) do |user|
|
316
|
-
@logger.debug "thread for user #{user.jid} started"
|
317
|
-
|
318
|
-
until (msg = @queues[user.jid].deq).kind_of? Symbol do
|
319
|
-
begin
|
320
|
-
pars_results = parser_func msg.body
|
321
|
-
@logger.debug "parsed message: #{pars_results.inspect}"
|
322
|
-
answer = do_func user, pars_results
|
323
|
-
@output_queue.enq msg.answer.set_body answer unless answer.nil? or answer.empty?
|
324
|
-
rescue ActiveRecord::StatementInvalid
|
325
|
-
statement_invalid_error
|
326
|
-
retry
|
327
|
-
rescue ActiveRecord::ConnectionTimeoutError
|
328
|
-
connection_timeout_error
|
329
|
-
retry
|
330
|
-
rescue => ex
|
331
|
-
general_error ex
|
332
|
-
end # begin
|
333
|
-
|
334
|
-
@main_model.connection_pool.release_connection
|
335
|
-
end # until (msg = @queues[user.jid].deq).kind_of? Symbol do
|
336
|
-
|
337
|
-
if msg == :unsubscribe
|
338
|
-
@logger.info "removing user #{user.jid}"
|
339
|
-
user.destroy
|
340
|
-
end
|
341
|
-
|
342
|
-
@queues.delete user.jid
|
343
|
-
|
344
|
-
end # Thread.new do
|
345
|
-
end # def start_user_thread(user)
|
346
|
-
|
347
|
-
def statement_invalid_error
|
348
|
-
@logger.warn 'Statement Invalid catched'
|
349
|
-
@logger.info 'Reconnecting to database'
|
350
|
-
@main_model.connection.reconnect!
|
351
|
-
end
|
352
|
-
|
353
|
-
def connection_timeout_error
|
354
|
-
@logger.warn 'ActiveRecord::ConnectionTimeoutError'
|
355
|
-
@logger.info 'sleep and retry again'
|
356
|
-
sleep 3
|
357
|
-
end
|
358
|
-
|
359
|
-
def general_error(exception)
|
360
|
-
@logger.error exception.inspect
|
361
|
-
@logger.error exception.backtrace
|
362
|
-
end
|
363
|
-
end # module Rumpy::Bot
|
364
51
|
end # module Rumpy
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rumpy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 22
|
10
|
+
version: 0.9.22
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tsokurov A.G.
|
@@ -16,8 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
20
|
-
default_executable:
|
19
|
+
date: 2011-11-20 00:00:00 Z
|
21
20
|
dependencies:
|
22
21
|
- !ruby/object:Gem::Dependency
|
23
22
|
name: activerecord
|
@@ -62,7 +61,6 @@ extra_rdoc_files:
|
|
62
61
|
files:
|
63
62
|
- lib/rumpy.rb
|
64
63
|
- README.rdoc
|
65
|
-
has_rdoc: true
|
66
64
|
homepage: https://github.com/Ximik/Rumpy
|
67
65
|
licenses:
|
68
66
|
- MIT
|
@@ -93,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
91
|
requirements: []
|
94
92
|
|
95
93
|
rubyforge_project:
|
96
|
-
rubygems_version: 1.
|
94
|
+
rubygems_version: 1.8.10
|
97
95
|
signing_key:
|
98
96
|
specification_version: 3
|
99
97
|
summary: Rumpy == jabber bot framework
|