# frozen_string_literal: true
require "blather/client/dsl"
require "em_promise"
require "timeout"
module BlatherNotify
extend Blather::DSL
@ready = Queue.new
when_ready { @ready << :ready }
def self.start(jid, password)
# workqueue_count MUST be 0 or else Blather uses threads!
setup(jid, password, nil, nil, nil, nil, workqueue_count: 0)
EM.error_handler(&method(:panic))
@thread = Thread.new {
EM.run do
client.run
end
}
Timeout.timeout(30) { @ready.pop }
at_exit { wait_then_exit }
end
def self.panic(e)
warn e.message
warn e.backtrace
exit! 2
end
def self.wait_then_exit
disconnected { EM.stop }
EM.add_timer(30) { EM.stop }
shutdown
@thread.join
end
def self.timeout_promise(promise, timeout: 15)
timer = EM.add_timer(timeout) {
promise.reject(:timeout)
}
promise.then do
timer.cancel
end
end
def self.write_with_promise(stanza)
promise = EMPromise.new
timeout_promise(promise)
client.write_with_handler(stanza) do |s|
if s.error? || s.type == :error
promise.reject(s)
else
promise.fulfill(s)
end
end
promise
end
def self.command(node, sessionid=nil, action: :execute, form: nil)
Blather::Stanza::Iq::Command.new.tap do |cmd|
cmd.to = CONFIG[:sgx_jmp]
cmd.node = node
cmd.command[:sessionid] = sessionid if sessionid
cmd.action = action
cmd.command << form if form
end
end
def self.execute(command_node, form=nil)
write_with_promise(command(command_node)).then do |iq|
next iq unless form
write_with_promise(command(command_node, iq.sessionid, form: form))
end
end
end