postcodes 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/README.md +49 -0
- data/lib/postcodes.rb +94 -0
- data/lib/postcodes/errors.rb +39 -0
- data/lib/postcodes/postcode.rb +35 -0
- data/lib/postcodes/util.rb +29 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4ca63fb1e521a07e8d555646be9f4133ff741fa8
|
4
|
+
data.tar.gz: 5883e86c9cce783fbc293d26dfcd7fcde377abb1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: df0c13a6702cc09f0db334b01cd9368d6b04fabf3bec8b0b6f8071f94ccc672e702aed5803061e1b8c57713596cd81e6245c08c7c5e74fdb8e0f09c3ea6d2f37
|
7
|
+
data.tar.gz: 27a3591660a99b014685dc234bf4ab09469e23372ac1a9ced7641b5a36002dae88327e943c41000c45ed34837206278ccb5f9e7f5640350afb03cf17e0ce7cfc
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Open Postcodes API Ruby Wrapper
|
2
|
+
|
3
|
+
Retrieve a list of addresses for any postcode in the United Kingdom using the Open Postcodes API.
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
__Installation__
|
8
|
+
|
9
|
+
```bash
|
10
|
+
gem install postcodes
|
11
|
+
```
|
12
|
+
|
13
|
+
__Get an API Key__
|
14
|
+
|
15
|
+
Get a key at [Open Postcodes](https://openpostcodes.com), then try out our service with our testing postcodes e.g. 'XA1 0XX'
|
16
|
+
|
17
|
+
__Implement it__
|
18
|
+
|
19
|
+
You can complete a full address lookup with just a couple of lines of Ruby.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'postcodes'
|
23
|
+
|
24
|
+
Postcodes.api_key = "your_key_here"
|
25
|
+
|
26
|
+
postcode = Postcodes::Postcode.lookup "XA1 0XX"
|
27
|
+
|
28
|
+
# postcode.addresses =>
|
29
|
+
#
|
30
|
+
# [
|
31
|
+
# {
|
32
|
+
# :postcode=>"XA1 0XX",
|
33
|
+
# :post_town=>"LONDON",
|
34
|
+
# :line_1=>"The Pavilion",
|
35
|
+
# :line_2=>"Oaks Avenue",
|
36
|
+
# :line_3=>""
|
37
|
+
# },
|
38
|
+
# ... and so on
|
39
|
+
```
|
40
|
+
|
41
|
+
## Registering
|
42
|
+
|
43
|
+
Open Postcodes provides street level address data for website, mobile and desktop applications at a competitive price.
|
44
|
+
|
45
|
+
We charge _1p_ per public lookup; take a look at our [pricing](https://openpostcodes.com/pricing)
|
46
|
+
|
47
|
+
## Documentation
|
48
|
+
|
49
|
+
More in-depth documentation can be found [here](https://openpostcodes.com/documentation#examples-ruby)
|
data/lib/postcodes.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'uri'
|
3
|
+
require 'multi_json'
|
4
|
+
require 'cgi'
|
5
|
+
require 'postcodes/postcode'
|
6
|
+
require 'postcodes/util'
|
7
|
+
require 'postcodes/errors'
|
8
|
+
|
9
|
+
module Postcodes
|
10
|
+
@base_url = 'https://api.openpostcodes.com'
|
11
|
+
@version = '1'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_accessor :api_key, :base_url, :version
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.request(method, path, params = {})
|
18
|
+
unless @api_key
|
19
|
+
raise Postcodes::AuthenticationError.new('No API Key provided. ' +
|
20
|
+
'Set your API key using Postcodes.api_key = #your_key')
|
21
|
+
end
|
22
|
+
|
23
|
+
url = URI.parse(resource_url(path))
|
24
|
+
params.merge! api_key: @api_key
|
25
|
+
url.query = Util.merge_params(params)
|
26
|
+
request_options = {
|
27
|
+
method: method.downcase.to_sym,
|
28
|
+
url: url.to_s
|
29
|
+
}
|
30
|
+
|
31
|
+
begin
|
32
|
+
response = generate_request(request_options)
|
33
|
+
rescue RestClient::ExceptionWithResponse => error
|
34
|
+
if rcode = error.http_code && rbody = error.http_body
|
35
|
+
handle_error(rcode, rbody)
|
36
|
+
else
|
37
|
+
handle_client_error(error)
|
38
|
+
end
|
39
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => error
|
40
|
+
handle_client_error(e)
|
41
|
+
end
|
42
|
+
parse response.body
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def self.resource_url(path='')
|
48
|
+
URI.escape "#{@base_url}/v#{@version}/#{path}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.generate_request(options)
|
52
|
+
RestClient::Request.execute(options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parse(response)
|
56
|
+
begin
|
57
|
+
Util.keys_to_sym MultiJson.load(response)
|
58
|
+
rescue MultiJson::DecodeError => e
|
59
|
+
raise handle_client_error(e)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.handle_error(http_code, http_body)
|
64
|
+
error = parse http_body
|
65
|
+
|
66
|
+
opc_code, opc_message = error[:code], error[:message]
|
67
|
+
|
68
|
+
case opc_code
|
69
|
+
when 4010
|
70
|
+
raise AuthenticationError.new opc_message, http_code, http_body, opc_code
|
71
|
+
when 4011
|
72
|
+
raise RefererExcludedError.new opc_message, http_code, http_body, opc_code
|
73
|
+
when 4020
|
74
|
+
raise TokenExhaustedError.new opc_message, http_code, http_body, opc_code
|
75
|
+
when 4021
|
76
|
+
raise LimitReachedError.new opc_message, http_code, http_body, opc_code
|
77
|
+
when 4040
|
78
|
+
raise ResourceNotFoundError.new opc_message, http_code, http_body, opc_code
|
79
|
+
when 4220
|
80
|
+
raise InvalidInputError.new opc_message, http_code, http_body, opc_code
|
81
|
+
else
|
82
|
+
raise PostcodesError.new opc_message, http_code, http_body, opc_code
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.handle_client_error(error)
|
87
|
+
raise PostcodesError.new("Unexpected error occurred: #{error.message})")
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.general_error(response_code, response_body)
|
91
|
+
PostcodesError.new "Invalid response object", response_code, response_body
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Postcodes
|
2
|
+
class PostcodesError < StandardError
|
3
|
+
attr_reader :message
|
4
|
+
attr_reader :http_code
|
5
|
+
attr_reader :http_body
|
6
|
+
attr_reader :response_code
|
7
|
+
|
8
|
+
def initialize(message = nil, http_code = nil, http_body = nil, response_code = nil)
|
9
|
+
@message = message
|
10
|
+
@http_code = http_code
|
11
|
+
@http_body = http_body
|
12
|
+
@response_code = response_code
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
status = @http_code.nil? ? "" : "#{@http_code} error."
|
17
|
+
opc_code = @response_code.nil ? "" : "(#{@response_code})"
|
18
|
+
"#{status} error. (#{opc_code}) #{message}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class AuthenticationError < PostcodesError
|
23
|
+
end
|
24
|
+
|
25
|
+
class RefererExcludedError < PostcodesError
|
26
|
+
end
|
27
|
+
|
28
|
+
class TokenExhaustedError < PostcodesError
|
29
|
+
end
|
30
|
+
|
31
|
+
class LimitReachedError < PostcodesError
|
32
|
+
end
|
33
|
+
|
34
|
+
class ResourceNotFoundError < PostcodesError
|
35
|
+
end
|
36
|
+
|
37
|
+
class InvalidInputError < PostcodesError
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Postcodes
|
2
|
+
class Postcode
|
3
|
+
|
4
|
+
attr_reader :postcode_data, :postcode, :addresses
|
5
|
+
|
6
|
+
def initialize(postcode = nil, postcode_data = nil)
|
7
|
+
@raw = postcode_data
|
8
|
+
@addresses = (postcode_data.nil? || postcode_data[:result].nil?) ? [] : postcode_data[:result]
|
9
|
+
@postcode = postcode
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.lookup(postcode)
|
13
|
+
begin
|
14
|
+
response = Postcodes.request :get, "postcodes/#{postcode}"
|
15
|
+
rescue Postcodes::ResourceNotFoundError => error
|
16
|
+
raise error unless error.response_code == 4040
|
17
|
+
response = nil
|
18
|
+
end
|
19
|
+
new postcode, response
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty?
|
23
|
+
@raw.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def addresses
|
27
|
+
@addresses
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
addresses.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Postcodes
|
2
|
+
class Util
|
3
|
+
|
4
|
+
def self.merge_params(hash)
|
5
|
+
result = []
|
6
|
+
hash.each do |key, value|
|
7
|
+
result << "#{CGI.escape(key.to_s)}=#{CGI.escape(value)}"
|
8
|
+
end
|
9
|
+
result.join("&")
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.keys_to_sym(object)
|
13
|
+
case object
|
14
|
+
when Hash
|
15
|
+
temp = {}
|
16
|
+
object.each do |key, value|
|
17
|
+
key = (key.to_sym rescue key) || key
|
18
|
+
temp[key] = keys_to_sym(value)
|
19
|
+
end
|
20
|
+
temp
|
21
|
+
when Array
|
22
|
+
object.map { |elem| keys_to_sym(elem) }
|
23
|
+
else
|
24
|
+
object
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: postcodes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Open Postcodes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: multi_json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.7.9
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.7.9
|
41
|
+
description: Open Postcodes provides a postcode lookup API for UK addresses. More
|
42
|
+
information https://openpostcodes.com
|
43
|
+
email:
|
44
|
+
- support@openpostcodes.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- Gemfile
|
50
|
+
- README.md
|
51
|
+
- lib/postcodes.rb
|
52
|
+
- lib/postcodes/errors.rb
|
53
|
+
- lib/postcodes/postcode.rb
|
54
|
+
- lib/postcodes/util.rb
|
55
|
+
homepage: https://openpostcodes.com
|
56
|
+
licenses:
|
57
|
+
- Public Domain
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.0.14
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: A wrapper for the OpenPostcodes.com API
|
79
|
+
test_files: []
|