geocode_records 0.0.3

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: edc2c231e4b2b56695ce060e5712a20f5af64b53
4
+ data.tar.gz: 1aa1438ca13d54c8fcf042ada691e7d5c3c53175
5
+ SHA512:
6
+ metadata.gz: 71e2a3a9fe9d42bd815c02844c6d14cdde9599f7e6480459a2d217290b06fddeb13faf3027402e5bc222aa74de568bb09ccf56bc734f4aec4991f88b29b2101c
7
+ data.tar.gz: 629c638c72442db0d31409066e9ba09917463b588c8a1117256475dcee54fd5886b1420e69342f9092ca751175b82f33570f43172e960befe3cc55d466e6d2a3
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ /node_modules/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
data/CHANGELOG ADDED
@@ -0,0 +1,17 @@
1
+ 0.0.3 / 2015-03-27
2
+
3
+ * Enhancements
4
+
5
+ * Respect ENV['DATABASE_URL'] instead of expecting `psql DBNAME` to always work
6
+ * Require a good version of https://www.npmjs.com/package/smartystreets to be installed
7
+ * More resistant to postcodes like 5753 (aka 05753), 53703.0, and even 5753.0
8
+
9
+ 0.0.2 / 2015-01-23
10
+
11
+ * Enhancements
12
+
13
+ * bin/geocode_records table_name - extremely basic CLI
14
+
15
+ 0.0.1 / 2015-01-23
16
+
17
+ initial release!
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in geocode_records.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Seamus Abshere
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,31 @@
1
+ # GeocodeRecords
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'geocode_records'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install geocode_records
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/geocode_records/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'logger'
4
+
5
+ require 'geocode_records'
6
+
7
+ ActiveRecord::Base.establish_connection ENV.fetch('DATABASE_URL')
8
+
9
+ # http://gray.fm/2013/09/17/unknown-oid-with-rails-and-postgresql/
10
+ require 'active_record/connection_adapters/postgresql/oid'
11
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.tap do |klass|
12
+ klass::OID.register_type('geometry', klass::OID::Identity.new)
13
+ end
14
+
15
+ logger = Logger.new($stderr)
16
+ logger.level = Logger::WARN
17
+ ActiveRecord::Base.logger = logger
18
+ Upsert.logger = logger
19
+
20
+ class Whatever < ActiveRecord::Base
21
+ self.table_name = ARGV[0]
22
+ end
23
+
24
+ GeocodeRecords.new(Whatever.all).perform
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'geocode_records/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "geocode_records"
8
+ spec.version = GeocodeRecords::VERSION
9
+ spec.authors = ["Seamus Abshere"]
10
+ spec.email = ["seamus@abshere.net"]
11
+ spec.summary = %q{Geocode an ActiveRecord::Relation with node_smartystreets}
12
+ spec.description = %q{A quick way to re-geocode a table}
13
+ spec.homepage = "https://github.com/seamusabshere/geocode_records"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
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_runtime_dependency 'activerecord', '~>4.1.9'
22
+ spec.add_runtime_dependency 'pg'
23
+ spec.add_runtime_dependency 'attr_extras'
24
+ spec.add_runtime_dependency 'zaru'
25
+ spec.add_runtime_dependency 'upsert'
26
+ spec.add_runtime_dependency 'pasqual'
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.7"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "rspec"
31
+ end
@@ -0,0 +1,18 @@
1
+ class DumpSqlToCsv
2
+ attr_private :sql
3
+ attr_private :pasqual
4
+
5
+ def initialize(pasqual, sql, ignored_options = {})
6
+ @pasqual = pasqual
7
+ @sql = sql
8
+ end
9
+
10
+ def path
11
+ @path = Dir::Tmpname.create(sql[0,64].delete('"').gsub(/\W/,'_').squeeze) {}
12
+
13
+ pasqual.command "\\copy (#{sql}) TO '#{@path}' DELIMITER ',' CSV HEADER"
14
+
15
+ @path
16
+ end
17
+
18
+ end
@@ -0,0 +1,112 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+ require 'csv'
4
+ require 'shellwords'
5
+ require 'zaru'
6
+
7
+ # copied from hotdog/app/services/file_geocoder.rb with seamus variations
8
+ class GeocodeRecords
9
+ class GeocodeCsv
10
+ attr_reader :glob
11
+
12
+ def initialize(input_path, options = {})
13
+ @input_path = input_path
14
+ options ||= {}
15
+ @glob = options[:glob]
16
+ @mutex = Mutex.new
17
+ end
18
+
19
+ def path
20
+ return if @path
21
+ @mutex.synchronize do
22
+ return if @path
23
+ geocode
24
+ recode
25
+ @path = @recoded_path
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ attr_private :input_path
32
+ attr_private :geocoded_path
33
+ attr_private :recoded_path
34
+
35
+ def input_map
36
+ @input_map ||= if glob
37
+ { 'street' => 'glob' }
38
+ else
39
+ {
40
+ 'street' => 'house_number_and_street',
41
+ 'zipcode' => 'postcode',
42
+ }
43
+ end
44
+ end
45
+
46
+ def geocode
47
+ @geocoded_path = Dir::Tmpname.create(Zaru.sanitize!(input_path + '.geocode')) {}
48
+ args = [
49
+ smartystreets_bin_path,
50
+ '-i', input_path,
51
+ '-o', geocoded_path,
52
+ '--auth-id', ENV.fetch('SMARTY_STREETS_AUTH_ID'),
53
+ '--auth-token', ENV.fetch('SMARTY_STREETS_AUTH_TOKEN')
54
+ ]
55
+ input_map.each do |ss, local|
56
+ args += [ "--#{ss}-col", local.to_s ]
57
+ end
58
+ puts Shellwords.join(args)
59
+ system(*args)
60
+ raise "Geocoding failed on #{input_path.inspect} with args #{Shellwords.join(args)}" unless $?.success?
61
+ end
62
+
63
+ def recode
64
+ @recoded_path = Dir::Tmpname.create(Zaru.sanitize!(input_path + '.recode')) {}
65
+ File.open(@recoded_path, 'w') do |f|
66
+ f.write output_columns.to_csv
67
+ CSV.foreach(@geocoded_path, headers: true) do |geocoded_row|
68
+ f.write recode_columns.map { |k| geocoded_row[k] }.to_csv
69
+ end
70
+ end
71
+ File.unlink @geocoded_path
72
+ end
73
+
74
+ def output_columns
75
+ @output_columns ||= (File.open(input_path) { |f| CSV.parse_line(f.gets) } + RECODE_MAP.keys).uniq
76
+ end
77
+
78
+ # no street yet - street_name, street_suffix
79
+ RECODE_MAP = {
80
+ 'house_number_and_street' => 'ss_delivery_line_1',
81
+ 'house_number' => 'ss_primary_number',
82
+ 'unit_number' => 'ss_secondary_number',
83
+ 'city' => 'ss_city_name',
84
+ 'state' => 'ss_state_abbreviation',
85
+ 'postcode' => 'ss_zipcode',
86
+ 'latitude' => 'ss_latitude',
87
+ 'longitude' => 'ss_longitude',
88
+ }.freeze
89
+
90
+ def recode_columns
91
+ @recode_columns ||= output_columns.map do |output_k|
92
+ RECODE_MAP[output_k] || output_k
93
+ end
94
+ end
95
+
96
+ def smartystreets_bin_path
97
+ @smartystreets_bin_path ||= begin
98
+ memo = if File.exist?('node_modules/.bin/smartystreets')
99
+ 'node_modules/.bin/smartystreets'
100
+ else
101
+ 'smartystreets'
102
+ end
103
+ `#{memo} -V` =~ /\A(\d+)\.(\d+)\.(\d+)/
104
+ major, minor, patch = [$1, $2, $3].map(&:to_i)
105
+ unless major >= 1 and minor >= 3 and patch >= 2
106
+ raise "smartystreets >= 1.3.2 required, got #{major}.#{minor}.#{patch}"
107
+ end
108
+ memo
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,31 @@
1
+ require 'csv'
2
+ require 'upsert'
3
+
4
+ class GeocodeRecords
5
+ class UpdateTableFromCsv
6
+ attr_private :connection
7
+ attr_private :table_name
8
+ attr_private :csv_path
9
+ attr_private :upsert
10
+ def initialize(connection, table_name, csv_path, ignored_options = {})
11
+ @upsert = Upsert.new connection, table_name
12
+ @csv_path = csv_path
13
+ end
14
+ def perform
15
+ count = 0
16
+ CSV.foreach(csv_path, headers: true) do |row|
17
+ next unless row['postcode']
18
+ row = row.to_hash
19
+ if hn = row['house_number']
20
+ row['house_number'] = hn.to_i
21
+ end
22
+ selector = { id: row.delete('id') }
23
+ setter = row
24
+ upsert.row selector, setter
25
+ # $stderr.write "U#{count}..." if count % 1000 == 0
26
+ count += 1
27
+ end
28
+ count
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ class GeocodeRecords
2
+ VERSION = '0.0.3'
3
+ end
@@ -0,0 +1,67 @@
1
+ require 'active_record'
2
+ require 'attr_extras'
3
+ require 'pasqual'
4
+
5
+ require_relative 'geocode_records/version'
6
+ require_relative 'geocode_records/dump_sql_to_csv'
7
+ require_relative 'geocode_records/geocode_csv'
8
+ require_relative 'geocode_records/update_table_from_csv'
9
+
10
+ class GeocodeRecords
11
+
12
+ attr_reader :records
13
+ attr_reader :options
14
+ def initialize(records, options = {})
15
+ records.is_a?(ActiveRecord::Relation) or raise(ArgumentError, "expected AR::Relation, got #{records.class}")
16
+ @options = options || {}
17
+ @records = records
18
+ end
19
+
20
+ def perform
21
+ if records.count > 0
22
+ # $stderr.puts "GeocodeRecords: #{records.count} to go!"
23
+ ungeocoded_path = DumpSqlToCsv.new(pasqual, to_sql, options).path
24
+ geocoded_path = GeocodeCsv.new(ungeocoded_path, options).path
25
+ UpdateTableFromCsv.new(connection, table_name, geocoded_path, options).perform
26
+ set_the_geom
27
+ File.unlink geocoded_path
28
+ File.unlink ungeocoded_path
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def glob
35
+ !!options[:glob]
36
+ end
37
+
38
+ def set_the_geom
39
+ records.update_all <<-SQL
40
+ the_geom = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326),
41
+ the_geom_webmercator = ST_Transform(ST_SetSRID(ST_MakePoint(longitude, latitude), 4326), 3857)
42
+ SQL
43
+ end
44
+
45
+ def to_sql
46
+ c = connection
47
+ c.unprepared_statement do
48
+ if glob
49
+ c.to_sql records.select('id', 'glob').arel, records.bind_values
50
+ else
51
+ c.to_sql records.select('id', 'house_number_and_street', 'house_number', 'unit_number', 'city', 'state', "left(regexp_replace(postcode, '.0$', ''), 5) AS postcode").arel, records.bind_values
52
+ end
53
+ end
54
+ end
55
+
56
+ def connection
57
+ records.connection
58
+ end
59
+
60
+ def table_name
61
+ options[:table_name] || records.engine.table_name
62
+ end
63
+
64
+ def pasqual
65
+ @pasqual ||= Pasqual.for ENV.fetch('DATABASE_URL')
66
+ end
67
+ end
data/package.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "rolodeck",
3
+ "private": true,
4
+ "dependencies": {
5
+ "smartystreets": "^1.3.2"
6
+ }
7
+ }
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ dbname = 'geocode_records_test'
4
+ ENV['DATABASE_URL'] = "postgresql://127.0.0.1/#{dbname}"
5
+
6
+ unless ENV['FAST'] == 'true'
7
+ system 'dropdb', '--if-exists', dbname
8
+ system 'createdb', dbname
9
+ system 'psql', dbname, '--command', 'CREATE EXTENSION postgis'
10
+ system 'psql', dbname, '--command', 'CREATE TABLE homes (id serial primary key, the_geom geometry(Geometry,4326), the_geom_webmercator geometry(Geometry,3857), house_number_and_street text, house_number int, unit_number text, city text, state text, postcode text, latitude float, longitude float)'
11
+ end
12
+
13
+ require 'active_record'
14
+ ActiveRecord::Base.establish_connection
15
+ # http://gray.fm/2013/09/17/unknown-oid-with-rails-and-postgresql/
16
+ require 'active_record/connection_adapters/postgresql/oid'
17
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.tap do |klass|
18
+ klass::OID.register_type('geometry', klass::OID::Identity.new)
19
+ end
20
+
21
+ class Home < ActiveRecord::Base
22
+ end
23
+
24
+ describe GeocodeRecords do
25
+ it 'has a version number' do
26
+ expect(GeocodeRecords::VERSION).not_to be nil
27
+ end
28
+
29
+ it "geocodes an AR::Relation" do
30
+ home = Home.create! house_number_and_street: '1038 e deyton st', postcode: '53703'
31
+ GeocodeRecords.new(Home.all).perform
32
+ home.reload
33
+ expect(home.house_number_and_street).to eq('1038 E Dayton St')
34
+ end
35
+
36
+ it "doesn't break on float-format postcode" do
37
+ home = Home.create! house_number_and_street: '1038 e deyton st', postcode: '53703.0'
38
+ GeocodeRecords.new(Home.all).perform
39
+ home.reload
40
+ expect(home.house_number_and_street).to eq('1038 E Dayton St')
41
+ end
42
+
43
+ it "doesn't break on unzeropadded postcode" do
44
+ home = Home.create! house_number_and_street: '36 main st', postcode: '5753'
45
+ GeocodeRecords.new(Home.all).perform
46
+ home.reload
47
+ expect(home.house_number_and_street).to eq('36 Main St')
48
+ end
49
+
50
+ it "doesn't break on unzeropadded float-format postcode" do
51
+ home = Home.create! house_number_and_street: '36 main st', postcode: '5753.0'
52
+ GeocodeRecords.new(Home.all).perform
53
+ home.reload
54
+ expect(home.house_number_and_street).to eq('36 Main St')
55
+ end
56
+
57
+ describe 'known issues' do
58
+ it "doesn't fix float-format postcode on records that it can't geocode" do
59
+ home = Home.create! house_number_and_street: 'gibberish', postcode: '53703.0'
60
+ GeocodeRecords.new(Home.all).perform
61
+ home.reload
62
+ expect(home.house_number_and_street).to eq('gibberish')
63
+ expect(home.postcode).to eq('53703.0')
64
+ end
65
+
66
+ it "doesn't fix unzeropadded postcode on records that it can't geocode" do
67
+ home = Home.create! house_number_and_street: 'gibberish', postcode: '5753'
68
+ GeocodeRecords.new(Home.all).perform
69
+ home.reload
70
+ expect(home.house_number_and_street).to eq('gibberish')
71
+ expect(home.postcode).to eq('5753')
72
+ end
73
+ end
74
+
75
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'geocode_records'
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geocode_records
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Seamus Abshere
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.1.9
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.1.9
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: attr_extras
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: zaru
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
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: upsert
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
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: pasqual
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
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: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.7'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.7'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: A quick way to re-geocode a table
140
+ email:
141
+ - seamus@abshere.net
142
+ executables:
143
+ - geocode_records
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - ".rspec"
149
+ - ".travis.yml"
150
+ - CHANGELOG
151
+ - Gemfile
152
+ - LICENSE.txt
153
+ - README.md
154
+ - Rakefile
155
+ - bin/geocode_records
156
+ - geocode_records.gemspec
157
+ - lib/geocode_records.rb
158
+ - lib/geocode_records/dump_sql_to_csv.rb
159
+ - lib/geocode_records/geocode_csv.rb
160
+ - lib/geocode_records/update_table_from_csv.rb
161
+ - lib/geocode_records/version.rb
162
+ - package.json
163
+ - spec/geocode_records_spec.rb
164
+ - spec/spec_helper.rb
165
+ homepage: https://github.com/seamusabshere/geocode_records
166
+ licenses:
167
+ - MIT
168
+ metadata: {}
169
+ post_install_message:
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: '0'
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements: []
184
+ rubyforge_project:
185
+ rubygems_version: 2.2.2
186
+ signing_key:
187
+ specification_version: 4
188
+ summary: Geocode an ActiveRecord::Relation with node_smartystreets
189
+ test_files:
190
+ - spec/geocode_records_spec.rb
191
+ - spec/spec_helper.rb