|
|
|
class PostcodeService
|
|
|
|
def initialize
|
|
|
|
@pio = Postcodes::IO.new
|
|
|
|
end
|
|
|
|
|
|
|
|
def lookup(postcode)
|
|
|
|
# Avoid network calls when postcode is invalid
|
|
|
|
return unless postcode.match(POSTCODE_REGEXP)
|
|
|
|
|
|
|
|
postcode_lookup = nil
|
|
|
|
|
|
|
|
begin
|
|
|
|
# URI encoding only supports ASCII characters
|
|
|
|
ascii_postcode = self.class.clean(postcode)
|
|
|
|
Timeout.timeout(5) { postcode_lookup = @pio.lookup(ascii_postcode) }
|
|
|
|
rescue Timeout::Error
|
|
|
|
Rails.logger.warn("Postcodes.io lookup timed out")
|
|
|
|
end
|
|
|
|
|
|
|
|
if postcode_lookup && postcode_lookup.info.present?
|
|
|
|
OpenStruct.new({
|
|
|
|
location_code: postcode_lookup.codes["admin_district"],
|
|
|
|
location_admin_district: postcode_lookup.admin_district,
|
|
|
|
incode: postcode_lookup.incode,
|
|
|
|
outcode: postcode_lookup.outcode,
|
|
|
|
result?: postcode_lookup.outcode.present?,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.clean(postcode)
|
|
|
|
postcode.encode("ASCII", "UTF-8", invalid: :replace, undef: :replace, replace: "").delete(" ").upcase
|
|
|
|
end
|
|
|
|
end
|