Skip to content

Commit

Permalink
Merge pull request #11 from ideal-postcodes/uri_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
cblanc authored Nov 18, 2021
2 parents 921f826 + 2b7ea78 commit 827ea65
Show file tree
Hide file tree
Showing 46 changed files with 3,005 additions and 2,928 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI
on:
push:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby:
- '2.5'
- '2.6'
- '2.7'
- '3.0'
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Run tests
run: bundle exec rake
9 changes: 0 additions & 9 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion lib/ideal_postcodes.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Allows to reference by ideal_postcodes
require 'idealpostcodes'
require 'idealpostcodes'
196 changes: 104 additions & 92 deletions lib/idealpostcodes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,99 +14,111 @@
require 'idealpostcodes/postcode'

module IdealPostcodes
@base_url = 'https://api.ideal-postcodes.co.uk'
@version = '1'

class << self
attr_accessor :api_key, :base_url, :version, :secret
end

def self.request(method, path, params = {})
unless @api_key
raise IdealPostcodes::AuthenticationError.new('No API Key provided. ' +
'Set your key with IdealPostcodes.api_key = #your_key')
end

url = URI.parse(resource_url(path))
params.merge! api_key: @api_key
url.query = Util.merge_params(params)
request_options = {
method: method.downcase.to_sym,
url: url.to_s
}

begin
response = generate_request(request_options)
rescue RestClient::ExceptionWithResponse => error
if rcode = error.http_code && rbody = error.http_body
handle_error(rcode, rbody)
else
handle_client_error(error)
end
rescue RestClient::Exception, Errno::ECONNREFUSED => error
handle_client_error(error)
end
parse response.body
end

def self.apply_secret(secret)
@secret = secret
end

def self.key_available
response = Key.lookup @api_key
response[:available]
end

def self.key_details
raise IdealPostcodes::AuthenticationError.new('No Secret Key provided. ' +
'Set your secret key with IdealPostcodes.apply_secret #your_key') if @secret.nil?
response = Key.lookup_details @api_key, @secret
end

private

def self.resource_url(path='')
URI.escape "#{@base_url}/v#{@version}/#{path}"
end

def self.generate_request(options)
RestClient::Request.execute(options)
end

def self.parse(response)
begin
Util.keys_to_sym JSON.parse(response)
rescue JSON::ParserError => e
raise handle_client_error(e)
@base_url = 'https://api.ideal-postcodes.co.uk'
@version = '1'

class << self
attr_accessor :api_key, :base_url, :version, :secret
end

def self.request(method, path, params = {})
unless @api_key
raise IdealPostcodes::AuthenticationError, 'No API Key provided. ' +
'Set your key with IdealPostcodes.api_key = #your_key'
end

url = URI.parse(resource_url(path))
params.merge! api_key: @api_key
url.query = Util.merge_params(params)
request_options = { method: method.downcase.to_sym, url: url.to_s }

begin
response = generate_request(request_options)
rescue RestClient::ExceptionWithResponse => e
if rcode = e.http_code && rbody = e.http_body
handle_error(rcode, rbody)
else
handle_client_error(e)
end
rescue RestClient::Exception, Errno::ECONNREFUSED => e
handle_client_error(e)
end
parse response.body
end

def self.apply_secret(secret)
@secret = secret
end

def self.key_available
response = Key.lookup @api_key
response[:available]
end

def self.key_details
if @secret.nil?
raise IdealPostcodes::AuthenticationError, 'No Secret Key provided. ' +
'Set your secret key with IdealPostcodes.apply_secret #your_key'
end
end
response = Key.lookup_details @api_key, @secret
end

def self.handle_error(http_code, http_body)
def self.resource_url(path = '')
IdealPostcodes::Util.escape "#{@base_url}/v#{@version}/#{path}"
end

def self.generate_request(options)
RestClient::Request.execute(options)
end

def self.parse(response)
Util.keys_to_sym JSON.parse(response)
rescue JSON::ParserError => e
raise handle_client_error(e)
end

def self.handle_error(http_code, http_body)
error = parse http_body

ideal_code, ideal_message = error[:code], error[:message]

case ideal_code
when 4010
raise AuthenticationError.new ideal_message, http_code, http_body, ideal_code
when 4020
raise TokenExhaustedError.new ideal_message, http_code, http_body, ideal_code
when 4021
raise LimitReachedError.new ideal_message, http_code, http_body, ideal_code
when 4040
raise ResourceNotFoundError.new ideal_message, http_code, http_body, ideal_code
else
raise IdealPostcodesError.new ideal_message, http_code, http_body, ideal_code
end
end

def self.handle_client_error(error)
raise IdealPostcodesError.new("An unexpected error occured: #{error.message})")
end

def self.general_error(response_code, response_body)
IdealPostcodesError.new 'Invalid response object', response_code, response_body
end

end
ideal_code = error[:code]
ideal_message = error[:message]

case ideal_code
when 4010
raise AuthenticationError.new ideal_message,
http_code,
http_body,
ideal_code
when 4020
raise TokenExhaustedError.new ideal_message,
http_code,
http_body,
ideal_code
when 4021
raise LimitReachedError.new ideal_message,
http_code,
http_body,
ideal_code
when 4040
raise ResourceNotFoundError.new ideal_message,
http_code,
http_body,
ideal_code
else
raise IdealPostcodesError.new ideal_message,
http_code,
http_body,
ideal_code
end
end

def self.handle_client_error(error)
raise IdealPostcodesError, "An unexpected error occured: #{error.message})"
end

def self.general_error(response_code, response_body)
IdealPostcodesError.new 'Invalid response object',
response_code,
response_body
end
end
56 changes: 28 additions & 28 deletions lib/idealpostcodes/address.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
module IdealPostcodes
module Address
class SearchResult
attr_reader :page, :limit, :addresses
def initialize response
@page = response[:result][:page]
@limit = response[:result][:limit]
@addresses = response[:result][:hits]
end
end
module Address
class SearchResult
attr_reader :page, :limit, :addresses
def initialize(response)
@page = response[:result][:page]
@limit = response[:result][:limit]
@addresses = response[:result][:hits]
end
end

def self.lookup udprn
begin
response = IdealPostcodes.request :get, "addresses/#{udprn}"
address = response[:result]
rescue IdealPostcodes::IdealPostcodesError => error
raise error unless error.response_code == 4044
address = nil
end
address
end
def self.lookup(udprn)
begin
response = IdealPostcodes.request :get, "addresses/#{udprn}"
address = response[:result]
rescue IdealPostcodes::IdealPostcodesError => error
raise error unless error.response_code == 4044
address = nil
end
address
end

def self.search search_term, options = {}
query = { query: search_term }
query[:limit] = options[:limit] unless options[:limit].nil?
query[:page] = options[:page] unless options[:page].nil?
response = IdealPostcodes.request :get, "addresses", query
SearchResult.new response
end
end
end
def self.search(search_term, options = {})
query = { query: search_term }
query[:limit] = options[:limit] unless options[:limit].nil?
query[:page] = options[:page] unless options[:page].nil?
response = IdealPostcodes.request :get, 'addresses', query
SearchResult.new response
end
end
end
57 changes: 31 additions & 26 deletions lib/idealpostcodes/errors.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
module IdealPostcodes
class IdealPostcodesError < StandardError
attr_reader :message
attr_reader :http_code
attr_reader :http_body
attr_reader :response_code
class IdealPostcodesError < StandardError
attr_reader :message
attr_reader :http_code
attr_reader :http_body
attr_reader :response_code

def initialize(message = nil, http_code = nil, http_body = nil, response_code = nil)
@message = message
@http_code = http_code
@http_body = http_body
@response_code = response_code
end
def initialize(
message = nil,
http_code = nil,
http_body = nil,
response_code = nil
)
@message = message
@http_code = http_code
@http_body = http_body
@response_code = response_code
end

def to_s
status = @http_code.nil? ? "" : "#{@http_code} error."
ideal_code = @response_code.nil? ? "" : "(#{@response_code})"
"#{status} error. (#{ideal_code}) #{message}"
end
end
def to_s
status = @http_code.nil? ? '' : "#{@http_code} error."
ideal_code = @response_code.nil? ? '' : "(#{@response_code})"
"#{status} error. (#{ideal_code}) #{message}"
end
end

class AuthenticationError< IdealPostcodesError
end
class AuthenticationError < IdealPostcodesError
end

class TokenExhaustedError < IdealPostcodesError
end
class TokenExhaustedError < IdealPostcodesError
end

class LimitReachedError < IdealPostcodesError
end
class LimitReachedError < IdealPostcodesError
end

class ResourceNotFoundError < IdealPostcodesError
end
end
class ResourceNotFoundError < IdealPostcodesError
end
end
23 changes: 12 additions & 11 deletions lib/idealpostcodes/key.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
module IdealPostcodes
module Key
def self.lookup api_key
response = IdealPostcodes.request :get, "keys/#{api_key}"
response[:result]
end
module Key
def self.lookup(api_key)
response = IdealPostcodes.request :get, "keys/#{api_key}"
response[:result]
end

def self.lookup_details api_key, secret
response = IdealPostcodes.request :get, "keys/#{api_key}", { user_token: secret }
response[:result]
end
end
end
def self.lookup_details(api_key, secret)
response =
IdealPostcodes.request :get, "keys/#{api_key}", { user_token: secret }
response[:result]
end
end
end
Loading

0 comments on commit 827ea65

Please sign in to comment.