merge stylistic lint changes and RuboCop settings

Denver Gingerich created

The one item I might change later is to put the parens back on
user_cap_identities and user_cap_features, but it's not that big of a
deal so I'll leave them for now.

See merge request !2 for the discussion and details behind this merge.

Change summary

.rubocop.yml    |  86 ++++++++++++
Gemfile         |   6 
mpx-catapult.rb |  39 +++-
sgx-catapult.rb | 361 ++++++++++++++++++++++++++++----------------------
4 files changed, 320 insertions(+), 172 deletions(-)

Detailed changes

.rubocop.yml 🔗

@@ -0,0 +1,86 @@
+Metrics/LineLength:
+  Max: 80
+
+Style/Tab:
+   Enabled: false
+
+Style/IndentationWidth:
+  Width: 1 # one tab
+
+Lint/EndAlignment:
+  EnforcedStyleAlignWith: variable
+
+Metrics/AbcSize:
+  Max: 111
+
+Metrics/BlockLength:
+  Max: 200
+
+Metrics/BlockNesting:
+  Max: 5
+
+Metrics/ClassLength:
+  Max: 200
+
+Metrics/CyclomaticComplexity:
+  Max: 20
+
+Metrics/MethodLength:
+  Max: 200
+
+Metrics/ModuleLength:
+  Max: 1000
+
+Metrics/PerceivedComplexity:
+  Max: 20
+
+Style/AndOr:
+  Enabled: false
+
+Style/BlockDelimiters:
+  Enabled: false
+
+Style/Documentation:
+  Enabled: false
+
+Style/FormatString:
+  EnforcedStyle: percent
+
+# Offense count: 1
+Style/IfInsideElse:
+  Exclude:
+    - 'sgx-catapult.rb'
+
+Style/LeadingCommentSpace:
+  Enabled: false
+
+Style/MultilineMethodCallBraceLayout:
+  Enabled: false
+
+Style/MultilineOperationIndentation:
+  Enabled: false
+
+Style/Next:
+  Enabled: false
+
+Style/Not:
+  Enabled: false
+
+Style/NumericPredicate:
+  Enabled: false
+
+Style/SpaceAroundOperators:
+  Enabled: false
+
+Style/SpaceInsideHashLiteralBraces:
+  EnforcedStyle: no_space
+
+Style/StringLiterals:
+  EnforcedStyle: double_quotes
+  Enabled: false
+
+Style/NegatedIf:
+  Enabled: false
+
+Style/RedundantReturn:
+  Enabled: false

Gemfile 🔗

@@ -1,7 +1,7 @@
 source 'https://rubygems.org'
 
-gem 'blather'
 gem 'activesupport', '<5.0.0'
+gem 'blather'
 gem 'eventmachine', '1.0.0'
 
 gem 'hiredis', '~> 0.6.0'
@@ -11,3 +11,7 @@ gem 'goliath'
 gem 'log4r'
 
 gem 'uuid'
+
+group :development do
+	gem 'rubocop', require: false
+end

mpx-catapult.rb 🔗

@@ -26,8 +26,8 @@ require 'net/http'
 require 'redis/connection/hiredis'
 require 'uri'
 
-if ARGV.size != 3 then
-	puts "Usage: mpx-catapult.rb <http_listen_port> " +
+if ARGV.size != 3
+	puts "Usage: mpx-catapult.rb <http_listen_port> "\
 		"<redis_hostname> <redis_port>"
 	exit 0
 end
@@ -50,8 +50,11 @@ class WebhookHandler < Goliath::API
 			conn.connect(ARGV[1], ARGV[2].to_i)
 		rescue => e
 			puts 'ERROR: Redis connection failed: ' + e.inspect
-			return [500, {'Content-Type' => 'text/plain'},
-				e.inspect]
+			return [
+				500,
+				{'Content-Type' => 'text/plain'},
+				e.inspect
+			]
 		end
 
 		conn.write ["EXISTS", cred_key]
@@ -59,8 +62,11 @@ class WebhookHandler < Goliath::API
 			conn.disconnect
 
 			puts 'ERROR: invalid path rqst: ' + env['REQUEST_PATH']
-			return [404, {'Content-Type' => 'text/plain'},
-				'not found']
+			return [
+				404,
+				{'Content-Type' => 'text/plain'},
+				'not found'
+			]
 		end
 
 		conn.write ["LRANGE", cred_key, 0, 3]
@@ -80,8 +86,11 @@ class WebhookHandler < Goliath::API
 				'/media/' +env['REQUEST_PATH'].split('/', 3)[2])
 		else
 			puts 'ERROR: received non-HEAD/-GET request'
-			return [500, {'Content-Type' => 'text/plain'},
-				e.inspect]
+			return [
+				500,
+				{'Content-Type' => 'text/plain'},
+				e.inspect
+			]
 		end
 		request.basic_auth api_token, api_secret
 		response = http.request(request)
@@ -93,12 +102,18 @@ class WebhookHandler < Goliath::API
 			puts 'ERROR: unexpected return code ' + response.code
 
 			if response.code == '404'
-				return [404, {'Content-Type' => 'text/plain'},
-					'not found']
+				return [
+					404,
+					{'Content-Type' => 'text/plain'},
+					'not found'
+				]
 			end
 
-			return [response.code, {'Content-Type' => 'text/plain'},
-				'unexpected error']
+			return [
+				response.code,
+				{'Content-Type' => 'text/plain'},
+				'unexpected error'
+			]
 		end
 
 		# TODO: maybe need to reflect more headers (multi-part?)

sgx-catapult.rb 🔗

@@ -35,10 +35,10 @@ $stdout.sync = true
 
 puts "Soprani.ca/SMS Gateway for XMPP - Catapult        v0.031\n\n"
 
-if ARGV.size != 9 then
-	puts "Usage: sgx-catapult.rb <component_jid> <component_password> " +
-		"<server_hostname> <server_port> " +
-		"<redis_hostname> <redis_port> <delivery_receipt_url> " +
+if ARGV.size != 9
+	puts "Usage: sgx-catapult.rb <component_jid> <component_password> "\
+		"<server_hostname> <server_port> "\
+		"<redis_hostname> <redis_port> <delivery_receipt_url> "\
 		"<http_listen_port> <mms_proxy_prefix_url>"
 	exit 0
 end
@@ -49,9 +49,9 @@ puts "LOG %d.%09d: starting...\n\n" % [t.to_i, t.nsec]
 module SGXcatapult
 	extend Blather::DSL
 
-	@jingle_sids = Hash.new
-	@jingle_fnames = Hash.new
-	@partial_data = Hash.new
+	@jingle_sids = {}
+	@jingle_fnames = {}
+	@partial_data = {}
 	@uuid_gen = UUID.new
 
 	def self.run
@@ -97,8 +97,10 @@ module SGXcatapult
 				num_dest = num_and_context[0]
 			else
 				# TODO: text re num not (yet) supportd/implmentd
-				write_to_stream error_msg(m.reply, m.body,
-					:cancel, 'item-not-found')
+				write_to_stream error_msg(
+					m.reply, m.body,
+					:cancel, 'item-not-found'
+				)
 				next
 			end
 		end
@@ -114,8 +116,10 @@ module SGXcatapult
 			conn.disconnect
 
 			# TODO: add text re credentials not being registered
-			write_to_stream error_msg(m.reply, m.body, :auth,
-				'registration-required')
+			write_to_stream error_msg(
+				m.reply, m.body, :auth,
+				'registration-required'
+			)
 			next
 		end
 
@@ -166,7 +170,7 @@ module SGXcatapult
 			'/messages')
 		request.basic_auth api_token, api_secret
 		request.add_field('Content-Type', 'application/json')
-		request.body = JSON.dump({
+		request.body = JSON.dump(
 			'from'			=> users_num,
 			'to'			=> num_dest,
 			'text'			=> m.body,
@@ -174,10 +178,11 @@ module SGXcatapult
 				# callbacks need both the id and resourcepart
 				WEBrick::HTTPUtils.escape(m.id) + ' ' +
 				WEBrick::HTTPUtils.escape(
-					m.from.to_s.split('/', 2)[1] ),
+					m.from.to_s.split('/', 2)[1]
+				),
 			'receiptRequested'	=> 'all',
 			'callbackUrl'		=> ARGV[6]
-		})
+		)
 		response = http.request(request)
 
 		puts 'API response to send: ' + response.to_s + ' with code ' +
@@ -185,34 +190,35 @@ module SGXcatapult
 
 		if response.code != '201'
 			# TODO: add text re unexpected code; mention code number
-			write_to_stream error_msg(m.reply, m.body, :cancel,
-				'internal-server-error')
+			write_to_stream error_msg(
+				m.reply, m.body, :cancel,
+				'internal-server-error'
+			)
 			next
 		end
 	end
 
-	def self.user_cap_identities()
-		[{:category => 'client', :type => 'sms'}]
+	def self.user_cap_identities
+		[{category: 'client', type: 'sms'}]
 	end
 
-	def self.user_cap_features()
-	[
-		"urn:xmpp:receipts",
-		"urn:xmpp:jingle:1", "urn:xmpp:jingle:transports:ibb:1",
+	def self.user_cap_features
+		[
+			"urn:xmpp:receipts",
+			"urn:xmpp:jingle:1", "urn:xmpp:jingle:transports:ibb:1",
 
-		# TODO: eventually add more efficient file transfer mechanisms
-		#"urn:xmpp:jingle:transports:s5b:1",
+			# TODO: add more efficient file transfer mechanisms
+			#"urn:xmpp:jingle:transports:s5b:1",
 
-		# TODO: MUST add all relevant/reasonable vers of file-transfer
-		#"urn:xmpp:jingle:apps:file-transfer:4"
-		"urn:xmpp:jingle:apps:file-transfer:3"
-	]
+			# TODO: MUST add all reasonable vers of file-transfer
+			#"urn:xmpp:jingle:apps:file-transfer:4"
+			"urn:xmpp:jingle:apps:file-transfer:3"
+		]
 	end
 
 	presence :subscribe? do |p|
 		puts "PRESENCE1: #{p.inspect}"
 
-
 		# subscriptions are allowed from anyone - send reply immediately
 		msg = Blather::Stanza::Presence.new
 		msg.to = p.from
@@ -222,14 +228,13 @@ module SGXcatapult
 		puts 'RESPONSE5a: ' + msg.inspect
 		write_to_stream msg
 
-
 		# send a <presence> immediately; not automatically probed for it
 		# TODO: refactor so no "presence :probe? do |p|" duplicate below
 		caps = Blather::Stanza::Capabilities.new
 		# TODO: user a better node URI (?)
 		caps.node = 'http://catapult.sgx.soprani.ca/'
-		caps.identities = user_cap_identities()
-		caps.features = user_cap_features()
+		caps.identities = user_cap_identities
+		caps.features = user_cap_features
 
 		msg = caps.c
 		msg.to = p.from
@@ -238,7 +243,6 @@ module SGXcatapult
 		puts 'RESPONSE5b: ' + msg.inspect
 		write_to_stream msg
 
-
 		# need to subscribe back so Conversations displays images inline
 		msg = Blather::Stanza::Presence.new
 		msg.to = p.from.to_s.split('/', 2)[0]
@@ -255,8 +259,8 @@ module SGXcatapult
 		caps = Blather::Stanza::Capabilities.new
 		# TODO: user a better node URI (?)
 		caps.node = 'http://catapult.sgx.soprani.ca/'
-		caps.identities = user_cap_identities()
-		caps.features = user_cap_features()
+		caps.identities = user_cap_identities
+		caps.features = user_cap_features
 
 		msg = caps.c
 		msg.to = p.from
@@ -266,7 +270,7 @@ module SGXcatapult
 		write_to_stream msg
 	end
 
-	iq '/iq/ns:jingle', :ns => 'urn:xmpp:jingle:1' do |i, jn|
+	iq '/iq/ns:jingle', ns: 'urn:xmpp:jingle:1' do |i, jn|
 		puts "IQj: #{i.inspect}"
 
 		if jn[0]['action'] == 'transport-accept'
@@ -302,7 +306,7 @@ module SGXcatapult
 
 		ibb_found = false
 		last_sid = ''
-		for child in cn.children
+		cn.children.each do |child|
 			if child.element_name == 'transport'
 				puts 'TPORT: ' + child.namespace.href
 				last_sid = child['sid']
@@ -315,17 +319,17 @@ module SGXcatapult
 			end
 		end
 
-		j = Nokogiri::XML::Node.new 'jingle',msg.document
+		j = Nokogiri::XML::Node.new 'jingle', msg.document
 		j['xmlns'] = 'urn:xmpp:jingle:1'
 		j['sid'] = jn[0]['sid']
 		msg.add_child(j)
 
-		content = Nokogiri::XML::Node.new 'content',msg.document
+		content = Nokogiri::XML::Node.new 'content', msg.document
 		content['name'] = cn['name']
 		content['creator'] = 'initiator'
 		j.add_child(content)
 
-		transport = Nokogiri::XML::Node.new 'transport',msg.document
+		transport = Nokogiri::XML::Node.new 'transport', msg.document
 		# TODO: make block-size more variable and/or dependent on sender
 		transport['block-size'] = '4096'
 		transport['xmlns'] = 'urn:xmpp:jingle:transports:ibb:1'
@@ -334,7 +338,7 @@ module SGXcatapult
 			j['action'] = 'session-accept'
 			j['responder'] = i.from
 
-			dsc = Nokogiri::XML::Node.new 'description',msg.document
+			dsc = Nokogiri::XML::Node.new 'description', msg.document
 			dsc['xmlns'] = 'urn:xmpp:jingle:apps:file-transfer:3'
 			content.add_child(dsc)
 		else
@@ -349,35 +353,31 @@ module SGXcatapult
 
 		# TODO: save <date> as well? Gajim sends, Conversations does not
 		# TODO: save/validate <size> with eventual full received length
-		fname = cn.children.find { |v| v.element_name == "description"
-			}.children.find { |w| w.element_name == "offer"
-			}.children.find { |x| x.element_name == "file"
-			}.children.find { |y| y.element_name == "name" }
+		fname =
+			cn
+			.children.find { |v| v.element_name == "description" }
+			.children.find { |w| w.element_name == "offer" }
+			.children.find { |x| x.element_name == "file" }
+			.children.find { |y| y.element_name == "name" }
 		@jingle_fnames[transport['sid']] = fname.text
 
 		puts "RESPONSE9: #{msg.inspect}"
 		write_to_stream msg
 	end
 
-	iq '/iq/ns:open', :ns =>
-		'http://jabber.org/protocol/ibb' do |i, on|
-
+	iq '/iq/ns:open', ns:	'http://jabber.org/protocol/ibb' do |i, on|
 		puts "IQo: #{i.inspect}"
 
 		@partial_data[on[0]['sid']] = ''
 		write_to_stream i.reply
 	end
 
-	iq '/iq/ns:data', :ns =>
-		'http://jabber.org/protocol/ibb' do |i, dn|
-
+	iq '/iq/ns:data', ns:	'http://jabber.org/protocol/ibb' do |i, dn|
 		@partial_data[dn[0]['sid']] += Base64.decode64(dn[0].text)
 		write_to_stream i.reply
 	end
 
-	iq '/iq/ns:close', :ns =>
-		'http://jabber.org/protocol/ibb' do |i, cn|
-
+	iq '/iq/ns:close', ns:	'http://jabber.org/protocol/ibb' do |i, cn|
 		puts "IQc: #{i.inspect}"
 		write_to_stream i.reply
 
@@ -394,8 +394,10 @@ module SGXcatapult
 				num_dest = num_and_context[0]
 			else
 				# TODO: text re num not (yet) supportd/implmentd
-				write_to_stream error_msg(i.reply, nil,
-					:cancel, 'item-not-found')
+				write_to_stream error_msg(
+					i.reply, nil,
+					:cancel, 'item-not-found'
+				)
 				next
 			end
 		end
@@ -412,8 +414,10 @@ module SGXcatapult
 			conn.disconnect
 
 			# TODO: add text re credentials not being registered
-			write_to_stream error_msg(i.reply, nil, :auth,
-				'registration-required')
+			write_to_stream error_msg(
+				i.reply, nil, :auth,
+				'registration-required'
+			)
 			next
 		end
 
@@ -449,8 +453,10 @@ module SGXcatapult
 
 		if response.code != '200'
 			# TODO: add text re unexpected code; mention code number
-			write_to_stream error_msg(i.reply, nil, :cancel,
-				'internal-server-error')
+			write_to_stream error_msg(
+				i.reply, nil, :cancel,
+				'internal-server-error'
+			)
 			next
 		end
 
@@ -461,24 +467,26 @@ module SGXcatapult
 			'/messages')
 		request.basic_auth api_token, api_secret
 		request.add_field('Content-Type', 'application/json')
-		request.body = JSON.dump({
+		request.body = JSON.dump(
 			'from'			=> users_num,
 			'to'			=> num_dest,
 			'text'			=> '',
 			'media'			=> [
 				'https://api.catapult.inetwork.com/v1/users/' +
-				user_id + '/media/' + media_name],
+				user_id + '/media/' + media_name
+			],
 			'tag'			=>
 				# callbacks need both the id and resourcepart
 				WEBrick::HTTPUtils.escape(i.id) + ' ' +
 				WEBrick::HTTPUtils.escape(
-					i.from.to_s.split('/', 2)[1] )
+					i.from.to_s.split('/', 2)[1]
+				)
 			# TODO: add back when Bandwidth AP supports it (?); now:
 			#  "The ''messages'' resource property
 			#  ''receiptRequested'' is not supported for MMS"
 			#'receiptRequested'	=> 'all',
 			#'callbackUrl'		=> ARGV[6]
-		})
+		)
 		response = http.request(request)
 
 		puts 'mAPI response to send: ' + response.to_s + ' with code ' +
@@ -486,8 +494,10 @@ module SGXcatapult
 
 		if response.code != '201'
 			# TODO: add text re unexpected code; mention code number
-			write_to_stream error_msg(i.reply, nil, :cancel,
-				'internal-server-error')
+			write_to_stream error_msg(
+				i.reply, nil, :cancel,
+				'internal-server-error'
+			)
 			next
 		end
 
@@ -498,14 +508,14 @@ module SGXcatapult
 		msg.to = i.from
 		msg.from = i.to
 
-		j = Nokogiri::XML::Node.new 'jingle',msg.document
+		j = Nokogiri::XML::Node.new 'jingle', msg.document
 		j['xmlns'] = 'urn:xmpp:jingle:1'
 		j['action'] = 'session-terminate'
 		j['sid'] = @jingle_sids[cn[0]['sid']]
 		msg.add_child(j)
 
-		r = Nokogiri::XML::Node.new 'reason',msg.document
-		s = Nokogiri::XML::Node.new 'success',msg.document
+		r = Nokogiri::XML::Node.new 'reason', msg.document
+		s = Nokogiri::XML::Node.new 'success', msg.document
 		r.add_child(s)
 		j.add_child(r)
 
@@ -513,23 +523,19 @@ module SGXcatapult
 		write_to_stream msg
 	end
 
-	iq '/iq/ns:query', :ns =>
-		'http://jabber.org/protocol/disco#items' do |i, xpath_result|
-
+	iq '/iq/ns:query', ns:	'http://jabber.org/protocol/disco#items' do |i|
 		write_to_stream i.reply
 	end
 
-	iq '/iq/ns:query', :ns =>
-		'http://jabber.org/protocol/disco#info' do |i, xpath_result|
-
+	iq '/iq/ns:query', ns:	'http://jabber.org/protocol/disco#info' do |i|
 		# respond to capabilities request for an sgx-catapult number JID
 		if i.to.node
 			# TODO: confirm the node URL is expected using below
 			#puts "XR[node]: #{xpath_result[0]['node']}"
 
 			msg = i.reply
-			msg.identities = user_cap_identities()
-			msg.features = user_cap_features()
+			msg.identities = user_cap_identities
+			msg.features = user_cap_features
 
 			puts 'RESPONSE7: ' + msg.inspect
 			write_to_stream msg
@@ -538,18 +544,22 @@ module SGXcatapult
 
 		# respond to capabilities request for sgx-catapult itself
 		msg = i.reply
-		msg.identities = [{:name =>
-			'Soprani.ca Gateway to XMPP - Catapult',
-			:type => 'sms-ctplt', :category => 'gateway'}]
-		msg.features = ["jabber:iq:register",
-			"jabber:iq:gateway", "jabber:iq:private",
+		msg.identities = [{
+			name: 'Soprani.ca Gateway to XMPP - Catapult',
+			type: 'sms-ctplt', category: 'gateway'
+		}]
+		msg.features = [
+			"jabber:iq:register",
+			"jabber:iq:gateway",
+			"jabber:iq:private",
 			"http://jabber.org/protocol/disco#info",
 			"http://jabber.org/protocol/commands",
-			"http://jabber.org/protocol/muc"]
+			"http://jabber.org/protocol/muc"
+		]
 		write_to_stream msg
 	end
 
-	iq '/iq/ns:query', :ns => 'jabber:iq:register' do |i, qn|
+	iq '/iq/ns:query', ns: 'jabber:iq:register' do |i, qn|
 		puts "IQ: #{i.inspect}"
 
 		if i.type == :set
@@ -561,19 +571,24 @@ module SGXcatapult
 			phone_num = ''
 
 			if xn.nil?
-				user_id = qn.children.find {
-					|v| v.element_name == "nick" }
-				api_token = qn.children.find {
-					|v| v.element_name == "username" }
-				api_secret = qn.children.find {
-					|v| v.element_name == "password" }
-				phone_num = qn.children.find {
-					|v| v.element_name == "phone" }
+				user_id = qn.children.find { |v|
+					v.element_name == "nick"
+				}
+				api_token = qn.children.find { |v|
+					v.element_name == "username"
+				}
+				api_secret = qn.children.find { |v|
+					v.element_name == "password"
+				}
+				phone_num = qn.children.find { |v|
+					v.element_name == "phone"
+				}
 			else
-				for field in xn.children
+				xn.children.each do |field|
 					if field.element_name == "field"
 						val = field.children.find { |v|
-						v.element_name == "value" }
+							v.element_name == "value"
+						}
 
 						case field['var']
 						when 'nick'
@@ -594,8 +609,10 @@ module SGXcatapult
 
 			if phone_num[0] != '+'
 				# TODO: add text re number not (yet) supported
-				write_to_stream error_msg(i.reply, qn, :cancel,
-					'item-not-found')
+				write_to_stream error_msg(
+					i.reply, qn, :cancel,
+					'item-not-found'
+				)
 				next
 			end
 
@@ -657,14 +674,14 @@ module SGXcatapult
 						next
 					end
 
-					conn.write ["RPUSH",cred_key,user_id]
-					conn.write ["RPUSH",cred_key,api_token]
-					conn.write ["RPUSH",cred_key,api_secret]
-					conn.write ["RPUSH",cred_key,phone_num]
+					conn.write ["RPUSH", cred_key, user_id]
+					conn.write ["RPUSH", cred_key, api_token]
+					conn.write ["RPUSH", cred_key, api_secret]
+					conn.write ["RPUSH", cred_key, phone_num]
 
 					# TODO: confirm cred_key list size == 4
 
-					for n in 1..4 do
+					(1..4).each do |n|
 						# TODO: catch/relay RuntimeError
 						result = conn.read
 						if result != n
@@ -683,21 +700,29 @@ module SGXcatapult
 					write_to_stream i.reply
 				else
 					# TODO: add text re number disabled
-					write_to_stream error_msg(i.reply, qn,
-						:modify, 'not-acceptable')
+					write_to_stream error_msg(
+						i.reply, qn,
+						:modify, 'not-acceptable'
+					)
 				end
 			elsif response.code == '401'
 				# TODO: add text re bad credentials
-				write_to_stream error_msg(i.reply, qn, :auth,
-					'not-authorized')
+				write_to_stream error_msg(
+					i.reply, qn, :auth,
+					'not-authorized'
+				)
 			elsif response.code == '404'
 				# TODO: add text re number not found or disabled
-				write_to_stream error_msg(i.reply, qn, :cancel,
-					'item-not-found')
+				write_to_stream error_msg(
+					i.reply, qn, :cancel,
+					'item-not-found'
+				)
 			else
 				# TODO: add text re misc error, and mention code
-				write_to_stream error_msg(i.reply, qn, :modify,
-					'not-acceptable')
+				write_to_stream error_msg(
+					i.reply, qn, :modify,
+					'not-acceptable'
+				)
 			end
 
 		elsif i.type == :get
@@ -712,27 +737,29 @@ module SGXcatapult
 			existing_number = conn.read
 			conn.disconnect
 
-			msg = Nokogiri::XML::Node.new 'query',orig.document
+			msg = Nokogiri::XML::Node.new 'query', orig.document
 			msg['xmlns'] = 'jabber:iq:register'
 
 			if existing_number
-				msg.add_child(Nokogiri::XML::Node.new('registered', msg.document))
+				msg.add_child(
+					Nokogiri::XML::Node.new('registered', msg.document)
+				)
 			end
 
-			n1 = Nokogiri::XML::Node.new 'instructions',msg.document
-			n1.content= "Enter the information from your Account " +
-				"page as well as the Phone Number\nin your " +
-				"account you want to use (ie. '+12345678901')" +
-				".\nUser Id is nick, API Token is username, " +
-				"API Secret is password, Phone Number is phone"+
-				".\n\nThe source code for this gateway is at " +
-				"https://gitlab.com/ossguy/sgx-catapult ." +
-				"\nCopyright (C) 2017  Denver Gingerich and " +
+			n1 = Nokogiri::XML::Node.new 'instructions', msg.document
+			n1.content= "Enter the information from your Account "\
+				"page as well as the Phone Number\nin your "\
+				"account you want to use (ie. '+12345678901')"\
+				".\nUser Id is nick, API Token is username, "\
+				"API Secret is password, Phone Number is phone"\
+				".\n\nThe source code for this gateway is at "\
+				"https://gitlab.com/ossguy/sgx-catapult ."\
+				"\nCopyright (C) 2017  Denver Gingerich and "\
 				"others, licensed under AGPLv3+."
-			n2 = Nokogiri::XML::Node.new 'nick',msg.document
-			n3 = Nokogiri::XML::Node.new 'username',msg.document
-			n4 = Nokogiri::XML::Node.new 'password',msg.document
-			n5 = Nokogiri::XML::Node.new 'phone',msg.document
+			n2 = Nokogiri::XML::Node.new 'nick', msg.document
+			n3 = Nokogiri::XML::Node.new 'username', msg.document
+			n4 = Nokogiri::XML::Node.new 'password', msg.document
+			n5 = Nokogiri::XML::Node.new 'phone', msg.document
 			n5.content = existing_number.to_s
 			msg.add_child(n1)
 			msg.add_child(n2)
@@ -741,24 +768,32 @@ module SGXcatapult
 			msg.add_child(n5)
 
 			x = Blather::Stanza::X.new :form, [
-				{:required => true, :type => :"text-single",
-				:label => 'User Id', :var => 'nick'},
-				{:required => true, :type => :"text-single",
-				:label => 'API Token', :var => 'username'},
-				{:required => true, :type => :"text-private",
-				:label => 'API Secret', :var => 'password'},
-				{:required => true, :type => :"text-single",
-				:label => 'Phone Number', :var => 'phone',
-				:value => existing_number.to_s}
+				{
+					required: true, type: :"text-single",
+					label: 'User Id', var: 'nick'
+				},
+				{
+					required: true, type: :"text-single",
+					label: 'API Token', var: 'username'
+				},
+				{
+					required: true, type: :"text-private",
+					label: 'API Secret', var: 'password'
+				},
+				{
+					required: true, type: :"text-single",
+					label: 'Phone Number', var: 'phone',
+					value: existing_number.to_s
+				}
 			]
-			x.title= 'Register for ' +
+			x.title= 'Register for '\
 				'Soprani.ca Gateway to XMPP - Catapult'
-			x.instructions= "Enter the details from your Account " +
-				"page as well as the Phone Number\nin your " +
-				"account you want to use (ie. '+12345678901')" +
-				".\n\nThe source code for this gateway is at " +
-				"https://gitlab.com/ossguy/sgx-catapult ." +
-				"\nCopyright (C) 2017  Denver Gingerich and " +
+			x.instructions= "Enter the details from your Account "\
+				"page as well as the Phone Number\nin your "\
+				"account you want to use (ie. '+12345678901')"\
+				".\n\nThe source code for this gateway is at "\
+				"https://gitlab.com/ossguy/sgx-catapult ."\
+				"\nCopyright (C) 2017  Denver Gingerich and "\
 				"others, licensed under AGPLv3+."
 			msg.add_child(x)
 
@@ -848,7 +883,7 @@ class WebhookHandler < Goliath::API
 
 		if others_num[0] != '+'
 			# TODO: check that others_num actually a shortcode first
-			others_num = others_num +
+			others_num +=
 				';phone-context=ca-us.phone-context.soprani.ca'
 		end
 
@@ -882,31 +917,34 @@ class WebhookHandler < Goliath::API
 			when 'mms'
 				has_media = false
 				params['media'].each do |media_url|
-					if not media_url.end_with?('.smil',
-						'.txt', '.xml')
+					if not media_url.end_with?(
+						'.smil', '.txt', '.xml'
+					)
 
 						has_media = true
-						send_media(others_num + '@' +
+						send_media(
+							others_num + '@' +
 							ARGV[0],
-							bare_jid, media_url)
+							bare_jid, media_url
+						)
 					end
 				end
 
 				if params['text'].empty?
 					if not has_media
-						text = '[suspected group msg ' +
+						text = '[suspected group msg '\
 							'with no text (odd)]'
 					end
 				else
-					if has_media
+					text = if has_media
 						# TODO: write/use a caption XEP
-						text = params['text']
+						params['text']
 					else
-						text = '[suspected group msg ' +
-							'(recipient list not ' +
-							'available) with ' +
-							'following text] ' +
-							params['text']
+						'[suspected group msg '\
+						'(recipient list not '\
+						'available) with '\
+						'following text] ' +
+						params['text']
 					end
 				end
 
@@ -920,10 +958,10 @@ class WebhookHandler < Goliath::API
 
 				return [200, {}, "OK"]
 			else
-				text = "unknown type (#{params['eventType']})" +
+				text = "unknown type (#{params['eventType']})"\
 					" with text: " + params['text']
 
-				# TODO log/notify of this properly
+				# TODO: log/notify of this properly
 				puts text
 			end
 
@@ -942,8 +980,11 @@ class WebhookHandler < Goliath::API
 				msg['id'] = id
 
 				# create an error reply to the bare message
-				msg = Blather::StanzaError.new(msg,
-					'recipient-unavailable', :wait).to_node
+				msg = Blather::StanzaError.new(
+					msg,
+					'recipient-unavailable',
+					:wait
+				).to_node
 			when 'delivered'
 				msg = ReceiptMessage.new(bare_jid)
 
@@ -952,8 +993,10 @@ class WebhookHandler < Goliath::API
 				msg['id'] = uuid_gen.generate
 
 				# TODO: send only when requested per XEP-0184
-				rcvd = Nokogiri::XML::Node.new 'received',
+				rcvd = Nokogiri::XML::Node.new(
+					'received',
 					msg.document
+				)
 				rcvd['xmlns'] = 'urn:xmpp:receipts'
 				rcvd['id'] = id
 				msg.add_child(rcvd)
@@ -963,7 +1006,7 @@ class WebhookHandler < Goliath::API
 				return [200, {}, "OK"]
 			else
 				# TODO: notify somehow of unknown state receivd?
-				puts "message with id #{id} has " +
+				puts "message with id #{id} has "\
 					"other state #{params['deliveryState']}"
 				return [200, {}, "OK"]
 			end