postcodes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -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)
@@ -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: []