~singpolyma/jmp-pay

ref: 68ed9c34b0d4a2eaa0e49def372deabe4eb55daf jmp-pay/lib/blather_notify.rb -rw-r--r-- 1.6 KiB
68ed9c34Stephen Paul Weber Run billing 3 at a time 1 year, 7 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
# 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