geocoder-sensis 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ee86bd708259c0c624d03ebd1623a4de4a65b16
4
+ data.tar.gz: e4746d5443ffe168b4dc680f70f5aef401c11f2c
5
+ SHA512:
6
+ metadata.gz: b4319a758539ec3aef97e2475266f25cb132e8b06b649989929d61aa83b88e9c2eb1077849b2b6bc6b3e776de04ad138b658e1eaf64572b8b7e1e4a5d39695a4
7
+ data.tar.gz: 42f229bda8568a4f737a754987e942be1fc3cad05365f6fa0de1808109e482e5fbacb961ab0ab744f307bfb2ccd10ed04c99824ca3180d64567d71829ebbf757
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ secrets
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in geocoder-sensis.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Daniel Heath
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Geocoder::Sensis
2
+
3
+ Implements a Sensis Geocoder backend for the geocoder gem.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'geocoder-sensis'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install geocoder-sensis
18
+
19
+ ## Usage
20
+
21
+ Geocoder.configure(
22
+ :lookup => :sensis,
23
+ :api_key => "..."
24
+ )
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it ( http://github.com/DanielHeath/geocoder-sensis/fork )
29
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
30
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
31
+ 4. Push to the branch (`git push origin my-new-feature`)
32
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'geocoder/sensis/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "geocoder-sensis"
8
+ spec.version = Geocoder::Sensis::VERSION
9
+ spec.authors = ["Daniel Heath"]
10
+ spec.email = ["daniel@heath.cc"]
11
+ spec.summary = %q{Implements a Sensis Geocoder backend for the geocoder gem.}
12
+ spec.description = %q{}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "geocoder"
22
+ spec.add_development_dependency "bundler", "~> 1.5"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "webmock"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "pry-debugger"
28
+ end
@@ -0,0 +1,131 @@
1
+ require "geocoder"
2
+ require "geocoder/sensis/version"
3
+
4
+ module Geocoder
5
+
6
+ module Lookup
7
+
8
+ # Yuck. Geocoder gem doesn't offer a straightforward way
9
+ # to register new implementations. This module patches
10
+ # the 'sensis' lookup method into the known geocoders array
11
+ module AddSensisToStreetServices
12
+ def street_services
13
+ super + [:sensis_unstructured, :sensis_structured]
14
+ end
15
+ end
16
+ extend AddSensisToStreetServices
17
+
18
+ # Actual implementation
19
+ class SensisBase < Base
20
+
21
+ def required_api_key_parts
22
+ ["auth token", "auth password"]
23
+ end
24
+
25
+ def query_url(query)
26
+ "https://#{sensis_host}/v2/service/geocode/#{request_type}" + url_query_string(query)
27
+ end
28
+
29
+ def protocol
30
+ "https"
31
+ end
32
+
33
+ def results(query)
34
+ doc = fetch_data(query)
35
+ return [] unless doc
36
+ raise Exception.new('Incorrect API key') if doc["code"] == 401
37
+ doc["results"]
38
+ end
39
+
40
+ ##
41
+ # Override the base method because it's hard-coded to use Get.
42
+ # TODO: Raise PR upstream to allow other request methods.
43
+ #
44
+ def make_api_request(query)
45
+ timeout(configuration.timeout) do
46
+ uri = URI.parse(query_url(query))
47
+ http_client.start(uri.host, uri.port, :use_ssl => true) do |client|
48
+ req = Net::HTTP::Post.new(uri.request_uri, configuration.http_headers)
49
+ req.basic_auth(uri.user, uri.password) if uri.user and uri.password
50
+ req.body = sensis_query_json(query)
51
+ req.content_type = 'application/json'
52
+ req['X-Auth-Token'] = configuration.api_key[0]
53
+ req['X-Auth-Password'] = configuration.api_key[1]
54
+ client.request(req)
55
+ end
56
+ end
57
+ end
58
+
59
+ def result_class
60
+ ::Geocoder::Result::Sensis
61
+ end
62
+
63
+ private
64
+
65
+ def sensis_host
66
+ ENV["SENSIS_GEOCODE_HOST"] || "api-ems-cstage.ext.sensis.com.au"
67
+ end
68
+
69
+ # Structured or unstructured
70
+ def request_type
71
+ fail
72
+ end
73
+
74
+ # A json hash
75
+ def sensis_query_json(query)
76
+ fail
77
+ end
78
+
79
+ end
80
+
81
+ class SensisUnstructured < SensisBase
82
+ def name
83
+ :sensis_unstructured
84
+ end
85
+
86
+ def request_type
87
+ :unstructured
88
+ end
89
+
90
+ def sensis_query_json(query)
91
+ {"query" => query.text}.to_json
92
+ end
93
+
94
+ end
95
+
96
+ class SensisStructured < SensisBase
97
+ def name
98
+ :sensis_structured
99
+ end
100
+
101
+ def request_type
102
+ :structured
103
+ end
104
+
105
+ def sensis_query_json(query)
106
+ {"address" => query.text}.to_json
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+ module Result
114
+
115
+ class Sensis < Base
116
+
117
+ def coordinates
118
+ ['lat', 'lon'].map{ |i| @data['geometry']['centre'][i] }
119
+ end
120
+
121
+ def precision
122
+ granularity
123
+ end
124
+
125
+ def granularity
126
+ @data["granularity"]
127
+ end
128
+ end
129
+
130
+ end
131
+ end
@@ -0,0 +1,5 @@
1
+ module Geocoder
2
+ module Sensis
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'geocoder/sensis'
3
+
4
+ describe Geocoder::Sensis do
5
+
6
+ describe "Geocoding an address via unstructured api" do
7
+ before do
8
+ Geocoder.configure(
9
+ :lookup => :sensis_unstructured,
10
+ :api_key => [sensis_api_token, sensis_api_password],
11
+ :use_https => true,
12
+ :timeout => 30000
13
+ )
14
+ end
15
+
16
+ it "patches the known geocoders array to include sensis" do
17
+ expect(Geocoder::Lookup.street_services).to include(:sensis_unstructured)
18
+ expect(Geocoder::Lookup.street_services).to include(:sensis_structured)
19
+ end
20
+
21
+ it "connects to sensis" do
22
+ api = mock_sensis_api :request_type => :unstructured
23
+ Geocoder.coordinates('12 Powlett Street, East Melbourne')
24
+ api.should have_been_requested
25
+ end
26
+
27
+ it "returns the geocode from sensis" do
28
+ mock_sensis_api :request_type => :unstructured,
29
+ :latitude => 44.66,
30
+ :longitude => 55.66
31
+ coords = Geocoder.coordinates('12 Powlett Street, East Melbourne')
32
+ expect(coords).to eq [44.66, 55.66]
33
+ end
34
+
35
+ end
36
+
37
+ describe "Geocoding an address via structured api" do
38
+ before do
39
+ Geocoder.configure(
40
+ :lookup => :sensis_structured,
41
+ :api_key => [sensis_api_token, sensis_api_password],
42
+ :use_https => true,
43
+ :timeout => 30000
44
+ )
45
+ mock_sensis_api :request_type => :structured,
46
+ :address => '12 Powlett Street, East Melbourne',
47
+ :latitude => 44.66,
48
+ :longitude => 55.66
49
+ end
50
+
51
+ it "returns the geocode from sensis" do
52
+ coords = Geocoder.coordinates(
53
+ "state" => "Vic",
54
+ "suburb" => "Richmond",
55
+ "postcode" => "3121",
56
+ "number" => "9",
57
+ "street" => {
58
+ "name" => "Victoria",
59
+ "type" => "Street",
60
+ "suffix" => ""
61
+ })
62
+
63
+ expect(coords).to eq [44.66, 55.66]
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ require 'webmock/rspec'
5
+ require 'support/mock_sensis'
6
+
7
+ TEST_AGAINST_REAL_SENSIS = ENV["TEST_REMOTE_API"]
8
+
9
+ if TEST_AGAINST_REAL_SENSIS
10
+ WebMock.allow_net_connect!
11
+ else
12
+ WebMock.disable_net_connect!
13
+ end
@@ -0,0 +1,93 @@
1
+ require 'json'
2
+
3
+ def sensis_api_token
4
+ if TEST_AGAINST_REAL_SENSIS
5
+ File.read("secrets/token").strip
6
+ else
7
+ "SAMPLE_API_TOKEN"
8
+ end
9
+ end
10
+
11
+ def sensis_api_password
12
+ if TEST_AGAINST_REAL_SENSIS
13
+ File.read("secrets/password").strip
14
+ else
15
+ "SAMPLE_API_PASSWORD"
16
+ end
17
+ end
18
+
19
+ def mock_sensis_api(options = {})
20
+ sensis_response = SensisResponse.new(options)
21
+
22
+ stub_request(:post, sensis_response.uri).
23
+ with(
24
+ :headers => {
25
+ 'X-Auth-Token' => sensis_api_token,
26
+ 'X-Auth-Password' => sensis_api_password
27
+ }).
28
+ to_return(:status => sensis_response.code, :body => sensis_response.raw, :headers => {})
29
+ end
30
+
31
+
32
+ class SensisResponse
33
+ attr_reader :request_address, :request_type, :latitude, :longitude, :street_lat, :street_lon, :granularity, :code, :state, :suburb
34
+
35
+ def initialize(options = {})
36
+ defaults.merge(options).each do |k, v|
37
+ self.instance_variable_set("@#{k}", v)
38
+ end
39
+ end
40
+
41
+ def defaults
42
+ {
43
+ suburb: "RICHMOND",
44
+ state: "VIC",
45
+ response_code: 200,
46
+ granularity: "PROPERTY",
47
+ address: "678 Victoria street, Richmond, Vic",
48
+ latitude: -37.812571,
49
+ longitude: 145.014029,
50
+ street_lat: -37.1234343,
51
+ street_lon: 145.069672934
52
+ }
53
+ end
54
+
55
+ def host
56
+ ENV["SENSIS_GEOCODE_HOST"] || "api-ems-cstage.ext.sensis.com.au"
57
+ end
58
+
59
+ def uri
60
+ "https://#{host}/v2/service/geocode/#{request_type}"
61
+ end
62
+
63
+ def address
64
+ request_address.to_s.upcase
65
+ end
66
+
67
+ def raw
68
+ raw_hash.to_json
69
+ end
70
+
71
+ def raw_hash
72
+ {results: [{
73
+ approximated: false,
74
+ granularity: granularity,
75
+ address: {
76
+ display: address,
77
+ state: state,
78
+ suburb: suburb
79
+ },
80
+ geometry: {
81
+ centre: {
82
+ lon: longitude,
83
+ lat: latitude
84
+ },
85
+ street: {
86
+ lon: street_lon,
87
+ lat: street_lat
88
+ }
89
+ }
90
+ }]}
91
+ end
92
+
93
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geocoder-sensis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Heath
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: geocoder
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-debugger
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: ''
112
+ email:
113
+ - daniel@heath.cc
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - Gemfile
120
+ - LICENSE.txt
121
+ - README.md
122
+ - Rakefile
123
+ - geocoder-sensis.gemspec
124
+ - lib/geocoder/sensis.rb
125
+ - lib/geocoder/sensis/version.rb
126
+ - spec/lib/geocoder/sensis_spec.rb
127
+ - spec/spec_helper.rb
128
+ - spec/support/mock_sensis.rb
129
+ homepage: ''
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.2.0
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: Implements a Sensis Geocoder backend for the geocoder gem.
153
+ test_files:
154
+ - spec/lib/geocoder/sensis_spec.rb
155
+ - spec/spec_helper.rb
156
+ - spec/support/mock_sensis.rb