M Gemfile => Gemfile +1 -0
@@ 5,6 5,7 @@ source "https://rubygems.org"
gem "blather"
gem "braintree"
gem "dhall"
+gem "em_promise.rb"
gem "money-open-exchange-rates"
gem "pg"
gem "redis"
M bin/billing_monthly_cronjob => bin/billing_monthly_cronjob +23 -1
@@ 19,6 19,9 @@ require "pg"
require "redis"
require_relative "../lib/blather_notify"
+require_relative "../lib/to_form"
+
+using ToForm
CONFIG = Dhall.load(<<-DHALL).sync
let Quota = < unlimited | limited: { included: Natural, price: Natural } >
@@ 26,6 29,7 @@ CONFIG = Dhall.load(<<-DHALL).sync
in
(#{ARGV[0]}) : {
healthchecks_url: Text,
+ sgx_jmp: Text,
notify_using: {
jid: Text,
password: Text,
@@ 71,6 75,7 @@ end
stats = Stats.new(
not_renewed: 0,
renewed: 0,
+ not_registered: 0,
revenue: BigDecimal(0)
)
@@ 219,7 224,24 @@ db.transaction do
WHERE expires_at <= NOW()
SQL
).each do |row|
- ExpiredCustomer.for(row, db).try_renew(db, stats)
+ one = Queue.new
+ EM.next_tick do
+ BlatherNotify.execute(
+ "customer info",
+ { q: row["customer_id"] }.to_form(:submit)
+ ).then(
+ ->(x) { one << x },
+ ->(e) { one << RuntimeError.new(e.to_s) }
+ )
+ end
+ info = one.pop
+ raise info if info.is_a?(Exception)
+
+ if info.form.field("tel")&.value
+ ExpiredCustomer.for(row, db).try_renew(db, stats)
+ else
+ stats.add(:not_registered, 1)
+ end
end
end
M lib/blather_notify.rb => lib/blather_notify.rb +33 -1
@@ 1,6 1,7 @@
# frozen_string_literal: true
require "blather/client/dsl"
+require "em_promise"
require "timeout"
module BlatherNotify
@@ 28,7 29,8 @@ module BlatherNotify
def self.panic(e)
warn e.message
- exit 2
+ warn e.backtrace
+ exit! 2
end
def self.wait_then_exit
@@ 37,4 39,34 @@ module BlatherNotify
shutdown
@thread.join
end
+
+ def self.write_with_promise(stanza)
+ promise = EMPromise.new
+ client.write_with_handler(stanza) do |s|
+ if s.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
A lib/to_form.rb => lib/to_form.rb +17 -0
@@ 0,0 1,17 @@
+# frozen_string_literal: true
+
+require "blather"
+
+module ToForm
+ refine ::Hash do
+ def to_fields
+ map { |k, v| { var: k.to_s, value: v.to_s } }
+ end
+
+ def to_form(type)
+ Blather::Stanza::Iq::X.new(type).tap do |form|
+ form.fields = to_fields
+ end
+ end
+ end
+end