campfire_logic 1.1.10 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,13 +2,14 @@ source 'http://rubygems.org'
2
2
 
3
3
  gem 'bson_ext'
4
4
  gem 'fastercsv'
5
- gem 'google_maps_geocoder'
6
- gem 'mongoid'
5
+ gem 'geocoder'
7
6
  gem 'mongoid-tree'
8
7
  gem 'rails', '~> 3.0.0'
8
+ gem 'redis'
9
9
  gem 'scaffold_logic'
10
10
  gem 'stateflow'
11
11
  gem 'stringex'
12
+ gem 'SystemTimer'
12
13
 
13
14
  group :development do
14
15
  gem 'jeweler'
@@ -18,7 +19,6 @@ group :test do
18
19
  gem 'be_valid_asset'
19
20
  gem 'cucumber-rails'
20
21
  gem 'database_cleaner'
21
- gem 'launchy'
22
22
  gem 'mocha'
23
23
  gem 'rspec-rails'
24
- end
24
+ end
data/Gemfile.local CHANGED
@@ -2,12 +2,14 @@ source 'http://rubygems.org'
2
2
 
3
3
  gem 'bson_ext'
4
4
  gem 'fastercsv'
5
- gem 'google_maps_geocoder', :path => '~/Documents/projects/google_maps_geocoder'
5
+ gem 'geocoder'
6
6
  gem 'mongoid-tree'
7
- gem 'rails', '3.0.10'
7
+ gem 'rails', '~> 3.0.0'
8
+ gem 'redis'
8
9
  gem 'scaffold_logic', :path => '~/Documents/projects/scaffold_logic'
9
10
  gem 'stateflow'
10
11
  gem 'stringex'
12
+ gem 'SystemTimer'
11
13
 
12
14
  group :development do
13
15
  gem 'jeweler'
@@ -17,7 +19,6 @@ group :test do
17
19
  gem 'be_valid_asset'
18
20
  gem 'cucumber-rails'
19
21
  gem 'database_cleaner'
20
- gem 'launchy'
21
22
  gem 'mocha'
22
23
  gem 'rspec-rails'
23
24
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.10
1
+ 1.2.0
@@ -51,10 +51,7 @@ class DirectoryController < ApplicationController
51
51
  end
52
52
 
53
53
  def search_by_zip
54
- # find matching zip or create one
55
- _zip = ZipCode.first(:conditions => {:zip => params[:criteria]}) || ZipCode.create(:zip => params[:criteria])
56
-
57
- @locations = Location.near(:lat_lng => _zip.lat_lng).limit(10)
54
+ @locations = Location.near(params[:criteria]).limit(10)
58
55
  end
59
56
 
60
57
  # Returns a hash specifying the abbreviation for a two-letter query or the name otherwise. Blank queries return null.
@@ -0,0 +1,106 @@
1
+ require 'active_support'
2
+ require 'logger'
3
+ require 'net/http'
4
+ require 'rack'
5
+
6
+ class GeocoderGoogleResult
7
+ # Returns the complete formatted address with standardized abbreviations.
8
+ attr_reader :formatted_address
9
+ # Returns the formatted street address with standardized abbreviations.
10
+ attr_reader :formatted_street_address
11
+ # Self-explanatory
12
+ attr_reader :city, :country_long_name, :country_short_name, :county, :lat, :lng, :postal_code, :state_long_name, :state_short_name
13
+
14
+ # Instance Methods: Overrides ====================================================================
15
+
16
+ # Returns a GeocoderGoogleResult initialized with the specified Google geocoding results.
17
+ #
18
+ # ==== Attributes
19
+ #
20
+ # * +google_result+ - a hash of Google geocoding results
21
+ #
22
+ # ==== Examples
23
+ #
24
+ # white_house = GoogleMapsGeocoder.new '1600 Pennsylvania Washington'
25
+ # white_house.formatted_address
26
+ # => "1600 Pennsylvania Ave NW, Washington D.C., DC 20500, USA"
27
+ def initialize google_result
28
+ @json = google_result
29
+ @city, @country_short_name, @country_long_name, @county, @formatted_address, @formatted_street_address, @lat, @lng, @postal_code, @state_long_name, @state_short_name = parse_city, parse_country_short_name, parse_country_long_name, parse_county, parse_formatted_address, parse_formatted_street_address, parse_lat, parse_lng, parse_postal_code, parse_state_long_name, parse_state_short_name
30
+ end
31
+
32
+ # Instance Methods ===============================================================================
33
+
34
+ # Returns true if the address Google returns is an exact match.
35
+ #
36
+ # ==== Examples
37
+ #
38
+ # white_house = GoogleMapsGeocoder.new('1600 Pennsylvania Ave')
39
+ # white_house.exact_match?
40
+ # => true
41
+ def exact_match?
42
+ ! self.partial_match?
43
+ end
44
+
45
+ # Returns true if the address Google returns isn't an exact match.
46
+ #
47
+ # ==== Examples
48
+ #
49
+ # white_house = GoogleMapsGeocoder.new('1600 Pennsylvania Washington')
50
+ # white_house.exact_match?
51
+ # => false
52
+ def partial_match?
53
+ @json['partial_match'] == true
54
+ end
55
+
56
+ private
57
+
58
+ def parse_address_component_type(type, name='long_name')
59
+ _address_component = @json['address_components'].detect{ |ac| ac['types'] && ac['types'].include?(type) }
60
+ _address_component && _address_component[name]
61
+ end
62
+
63
+ def parse_city
64
+ parse_address_component_type('sublocality') || parse_address_component_type('locality')
65
+ end
66
+
67
+ def parse_country_long_name
68
+ parse_address_component_type('country')
69
+ end
70
+
71
+ def parse_country_short_name
72
+ parse_address_component_type('country', 'short_name')
73
+ end
74
+
75
+ def parse_county
76
+ parse_address_component_type('administrative_area_level_2')
77
+ end
78
+
79
+ def parse_formatted_address
80
+ @json['formatted_address']
81
+ end
82
+
83
+ def parse_formatted_street_address
84
+ "#{parse_address_component_type('street_number')} #{parse_address_component_type('route')}"
85
+ end
86
+
87
+ def parse_lat
88
+ @json['geometry']['location']['lat']
89
+ end
90
+
91
+ def parse_lng
92
+ @json['geometry']['location']['lng']
93
+ end
94
+
95
+ def parse_postal_code
96
+ parse_address_component_type('postal_code')
97
+ end
98
+
99
+ def parse_state_long_name
100
+ parse_address_component_type('administrative_area_level_1')
101
+ end
102
+
103
+ def parse_state_short_name
104
+ parse_address_component_type('administrative_area_level_1', 'short_name')
105
+ end
106
+ end
data/app/models/locale.rb CHANGED
@@ -3,23 +3,20 @@ class Locale
3
3
  require 'stringex'
4
4
 
5
5
  include LuckySneaks::StringExtensions
6
+ include Geocoder::Model::Mongoid
6
7
  include Mongoid::Document
7
8
  include Mongoid::Timestamps
8
9
  include Mongoid::Tree
9
10
 
10
- # Constants ======================================================================================
11
-
12
11
  # Mongo Config ===================================================================================
12
+ belongs_to :location
13
13
  field :name
14
14
  field :abbreviation
15
15
  field :slug
16
16
  field :accuracy, :type => Integer
17
- field :lat_lng, :type => Array
17
+ field :coordinates, :type => Array
18
18
  field :kind
19
- index [[ :lat_lng, Mongo::GEO2D ]], :min => -200, :max => 200
20
-
21
- # Relationships ==================================================================================
22
- referenced_in :location
19
+ index [[ :coordinates, Mongo::GEO2D ]], :min => -200, :max => 200
23
20
 
24
21
  # Scopes =========================================================================================
25
22
  scope :canada, :where => {:name => 'Canada'}
@@ -34,6 +31,7 @@ class Locale
34
31
 
35
32
  # Macros =========================================================================================
36
33
  attr_accessor :skip_geocoding
34
+ geocoded_by :geocoding_address
37
35
 
38
36
  # Class Methods: Initialization ==================================================================
39
37
 
@@ -54,7 +52,7 @@ class Locale
54
52
 
55
53
  def post_process
56
54
  self.set_slug
57
- self.geocode
55
+ self.geocode unless self.skip_geocoding || self.geocoding_address.blank?
58
56
  self.set_kind
59
57
  self.save
60
58
  end
@@ -62,8 +60,8 @@ class Locale
62
60
  # Instance methods: Overrides ====================================================================
63
61
 
64
62
  # Returns this locale's latitude/longitude, delegating to location as needed (to prevent duplicate/conflicting coordinates).
65
- def lat_lng
66
- self.location ? self.location.lat_lng : self[:lat_lng]
63
+ def coordinates
64
+ self.location ? self.location.coordinates : self[:coordinates]
67
65
  end
68
66
 
69
67
  def friendly_name
@@ -81,25 +79,9 @@ class Locale
81
79
 
82
80
  # Instance methods: Geocoding ====================================================================
83
81
 
84
- # Geocodes this location.
85
- def geocode
86
- return if self.skip_geocoding || self.geocoding_address.blank?
87
-
88
- unless @geocoder
89
- @geocoder = GoogleMapsGeocoder.new(self.geocoding_address)
90
- self.lat_lng = [@geocoder.lat, @geocoder.lng]
91
- end
92
-
93
- @geocoder
94
- rescue SocketError
95
- Rails.logger.error "Can't geocode without a network connection!"
96
- rescue RuntimeError
97
- Rails.logger.error "Can't geocode, over query limit!"
98
- end
99
-
100
82
  # Returns true if this location has a latitude and longitude.
101
83
  def geocoded?
102
- self.lat_lng.is_a?(Array)
84
+ self.coordinates.is_a?(Array)
103
85
  end
104
86
 
105
87
  # Returns this locale's address for geocoding.
@@ -2,6 +2,7 @@ Stateflow.persistence = :mongoid
2
2
 
3
3
  class Location
4
4
  include CampfireLogic::Base
5
+ include Geocoder::Model::Mongoid
5
6
  include Mongoid::Document
6
7
  include Mongoid::Timestamps
7
8
  include Stateflow
@@ -26,18 +27,24 @@ class Location
26
27
  field :meta_description
27
28
  field :accuracy, :type => Integer
28
29
  field :address_status
29
- field :lat_lng, :type => Array
30
+ field :coordinates, :type => Array
30
31
  field :validated_address1
31
32
  field :validated_city
32
33
  field :validated_zip
33
- index [[ :lat_lng, Mongo::GEO2D ]], :min => -200, :max => 200
34
- references_one :locale, :dependent => :destroy
35
- references_and_referenced_in_many :services, :inverse_of => :locations
36
-
37
- # Callbacks ======================================================================================
34
+ has_and_belongs_to_many :services, :inverse_of => :locations
35
+ has_one :locale, :dependent => :destroy
36
+ index [[ :coordinates, Mongo::GEO2D ]], :min => -200, :max => 200
38
37
 
39
38
  # Macros =========================================================================================
40
- attr_reader :geocoder
39
+ attr_accessor :geocoder_result
40
+ geocoded_by :geocoding_address do |location, results|
41
+ if geo = results.first
42
+ location.geocoder_result = GeocoderGoogleResult.new geo.data
43
+ location.country, location.country_long_name, location[:state], location.state_long_name = geo.country_code, geo.country, geo.state_code, geo.state
44
+ location.coordinates = [geo.longitude, geo.latitude]
45
+ end
46
+ end
47
+
41
48
  trimmed_fields :address1, :address2, :city, :email, :fax, :location_number, :name, :phone, :state, :zip
42
49
  validates_presence_of :address1, :city, :state
43
50
 
@@ -60,7 +67,7 @@ class Location
60
67
 
61
68
  # Validates this location's address by geocoding. Partial matches are flagged; exact matches are flagged as "validated".
62
69
  event :validate_address do
63
- transitions :from => any, :to => [:new, :partial_match, :validated], :decide => :geocode
70
+ transitions :from => any, :to => [:new, :partial_match, :validated], :decide => :call_geocode
64
71
  end
65
72
  end
66
73
 
@@ -95,38 +102,26 @@ class Location
95
102
  # Instance methods: Geocoding ====================================================================
96
103
 
97
104
  # Geocodes this location.
98
- def geocode
105
+ def call_geocode
99
106
  return :new if self.geocoding_address.blank?
100
-
101
- unless @geocoder
102
- @geocoder = GoogleMapsGeocoder.new(self.geocoding_address)
103
- self.country, self.country_long_name, self[:state], self.state_long_name = @geocoder.country_short_name, @geocoder.country_long_name, @geocoder.state_short_name, @geocoder.state_long_name
104
- self.lat_lng = [@geocoder.lat, @geocoder.lng]
105
- audit_address
106
- end
107
-
108
- @geocoder.partial_match? ? :partial_match : :validated
109
- rescue SocketError
110
- Rails.logger.error "Can't geocode without a network connection!"
111
- :new
112
- rescue RuntimeError
113
- Rails.logger.error "Can't geocode!"
114
- :new
107
+ geocode
108
+ audit_address
109
+ self.geocoder_result.try(:partial_match?) ? :partial_match : :validated
115
110
  end
116
111
 
117
112
  # Returns true if this location has a latitude and longitude.
118
113
  def geocoded?
119
- self.lat_lng.is_a?(Array)
114
+ self.coordinates.is_a?(Array)
120
115
  end
121
116
 
122
117
  # Returns true if the specified address field matches the geocoder's results.
123
118
  def matches_geocoder?(attribute)
124
- @geocoder.blank? || self.send(attribute) == @geocoder.send(GOOGLE_MAPS_GEOCODER_FIELDS_BY_LOCATION_FIELD[attribute])
119
+ geocoder_result.blank? || self.send(attribute) == geocoder_result.send(GOOGLE_MAPS_GEOCODER_FIELDS_BY_LOCATION_FIELD[attribute])
125
120
  end
126
121
 
127
122
  # Returns the n nearest locations.
128
123
  def nearby_locations(n = 5)
129
- Location.near(:lat_lng => self.lat_lng).limit(n + 1).select{ |l| l != self }
124
+ Location.near(:coordinates => self.coordinates).limit(n + 1).select{ |l| l != self }
130
125
  end
131
126
 
132
127
  # Instance methods: Locales ======================================================================
@@ -157,18 +152,18 @@ class Location
157
152
 
158
153
  # Compares this location's address with the geocoder's results.
159
154
  def audit_address
160
- if @geocoder.partial_match?
155
+ if self.geocoder_result && self.geocoder_result.partial_match?
161
156
  GOOGLE_MAPS_GEOCODER_FIELDS_BY_LOCATION_FIELD.keys.each do |field|
162
157
  # set "validated_" field to geocoder's result
163
- self.send("validated_#{field}=", @geocoder.send(GOOGLE_MAPS_GEOCODER_FIELDS_BY_LOCATION_FIELD[field])) unless self.matches_geocoder?(field)
158
+ self.send("validated_#{field}=", geocoder_result.send(GOOGLE_MAPS_GEOCODER_FIELDS_BY_LOCATION_FIELD[field])) unless self.matches_geocoder?(field)
164
159
  end
165
160
  end
166
161
  end
167
162
 
168
163
  # Clears all addressing data set by the geocoder.
169
164
  def clear_geocoding
170
- @geocoder = nil
171
- self.country, self.country_long_name, self.lat_lng, self.state_long_name, self.validated_address1, self.validated_city, self.validated_zip = nil
165
+ self.geocoder_result = nil
166
+ self.country, self.country_long_name, self.coordinates, self.state_long_name, self.validated_address1, self.validated_city, self.validated_zip = nil
172
167
  clear_address
173
168
  end
174
169
 
@@ -5,9 +5,9 @@
5
5
  var directionsService = new google.maps.DirectionsService();
6
6
  var locations = [
7
7
  <%- if place && place.location? && place.geocoded? -%>
8
- <%= raw "['#{h(escape_javascript place.location.name)}', #{place.lat_lng[0]}, #{place.lat_lng[1]}, '#{h(escape_javascript place.location.name)}<br />#{h(escape_javascript place.location.address1)}<br />#{h(escape_javascript place.location.city)}, #{h(escape_javascript place.location.state)} #{h(escape_javascript place.location.zip)}<br /><br />Directions: <a href=\"javascript:showDirectionsTo(0)\">To here<\/a> / <a href=\"javascript:showDirectionsFrom(0)\">From here<\/a>']" -%>
8
+ <%= raw "['#{h(escape_javascript place.location.name)}', #{place.coordinates[0]}, #{place.coordinates[1]}, '#{h(escape_javascript place.location.name)}<br />#{h(escape_javascript place.location.address1)}<br />#{h(escape_javascript place.location.city)}, #{h(escape_javascript place.location.state)} #{h(escape_javascript place.location.zip)}<br /><br />Directions: <a href=\"javascript:showDirectionsTo(0)\">To here<\/a> / <a href=\"javascript:showDirectionsFrom(0)\">From here<\/a>']" -%>
9
9
  <%- else -%>
10
- <%= raw locations.select{ |l| l.geocoded? }.inject([]) { |a, l| i = a.size; a << "['#{h(escape_javascript l.name)}', #{l.lat_lng[0]}, #{l.lat_lng[1]}, '#{link_to h(escape_javascript l.name), l.locale.to_url}<br />#{h(escape_javascript l.address1)}<br />#{h(escape_javascript l.city)}, #{h(escape_javascript l.state)} #{h(escape_javascript l.zip)}<br /><br />Directions: <a href=\"javascript:showDirectionsTo(#{i})\">To here<\/a> / <a href=\"javascript:showDirectionsFrom(#{i})\">From here<\/a>']"; a } * ",\r" -%>
10
+ <%= raw locations.select{ |l| l.geocoded? }.inject([]) { |a, l| i = a.size; a << "['#{h(escape_javascript l.name)}', #{l.coordinates[0]}, #{l.coordinates[1]}, '#{link_to h(escape_javascript l.name), l.locale.to_url}<br />#{h(escape_javascript l.address1)}<br />#{h(escape_javascript l.city)}, #{h(escape_javascript l.state)} #{h(escape_javascript l.zip)}<br /><br />Directions: <a href=\"javascript:showDirectionsTo(#{i})\">To here<\/a> / <a href=\"javascript:showDirectionsFrom(#{i})\">From here<\/a>']"; a } * ",\r" -%>
11
11
  <%- end -%>
12
12
  ];
13
13
  var map;
@@ -18,9 +18,9 @@
18
18
  var myOptions = {
19
19
  zoom: <%= place && place.zoom_level || 4 -%>,
20
20
  <%- if place && place.geocoded? -%>
21
- center: new google.maps.LatLng(<%= place.lat_lng[0] -%>, <%= place.lat_lng[1] -%>),
21
+ center: new google.maps.LatLng(<%= place.coordinates[0] -%>, <%= place.coordinates[1] -%>),
22
22
  <%- elsif place && place.parent && place.parent.geocoded? -%>
23
- center: new google.maps.LatLng(<%= place.parent.lat_lng[0] -%>, <%= place.parent.lat_lng[1] -%>),
23
+ center: new google.maps.LatLng(<%= place.parent.coordinates[0] -%>, <%= place.parent.coordinates[1] -%>),
24
24
  <%- else -%>
25
25
  center: new google.maps.LatLng(37.09024, -95.712891),
26
26
  <%- end -%>
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "campfire_logic"
8
- s.version = "1.1.10"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Roderick Monje"]
12
- s.date = "2012-01-23"
12
+ s.date = "2012-01-29"
13
13
  s.description = "Users can browse locations by country, city, and state and search locations by string or zip code. Administrators can manage locations and the services they offer."
14
14
  s.email = "rod@seologic.com"
15
15
  s.extra_rdoc_files = [
@@ -26,12 +26,11 @@ Gem::Specification.new do |s|
26
26
  "app/controllers/locations_controller.rb",
27
27
  "app/controllers/services_controller.rb",
28
28
  "app/helpers/application_helper.rb",
29
+ "app/models/geocoder_google_result.rb",
29
30
  "app/models/locale.rb",
30
31
  "app/models/location.rb",
31
32
  "app/models/location_import.rb",
32
33
  "app/models/service.rb",
33
- "app/models/zip_code.rb",
34
- "app/models/zip_code_import.rb",
35
34
  "app/views/directory/_search_form.html.erb",
36
35
  "app/views/directory/_show_children.html.erb",
37
36
  "app/views/directory/_show_location.html.erb",
@@ -62,6 +61,7 @@ Gem::Specification.new do |s|
62
61
  "config/environment.rb",
63
62
  "config/environments/test.rb",
64
63
  "config/initializers/campfire_logic.rb",
64
+ "config/initializers/geocoder.rb",
65
65
  "config/initializers/metric_fu.rb",
66
66
  "config/initializers/secret_token.rb",
67
67
  "config/initializers/session_store.rb",
@@ -69,7 +69,6 @@ Gem::Specification.new do |s|
69
69
  "config/mongoid.yml",
70
70
  "config/routes.rb",
71
71
  "db/seeds.rb",
72
- "db/zip_codes.txt",
73
72
  "features/admin_manages_locations.feature",
74
73
  "features/customer_browses_directory.feature",
75
74
  "features/customer_searches_directory.feature",
@@ -141,7 +140,7 @@ Gem::Specification.new do |s|
141
140
  ]
142
141
  s.homepage = "http://github.com/ivanoblomov/campfire_logic"
143
142
  s.require_paths = ["lib"]
144
- s.rubygems_version = "1.8.10"
143
+ s.rubygems_version = "1.8.11"
145
144
  s.summary = "Rails engine that adds a location directory to your web app"
146
145
 
147
146
  if s.respond_to? :specification_version then
@@ -150,38 +149,41 @@ Gem::Specification.new do |s|
150
149
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
151
150
  s.add_runtime_dependency(%q<bson_ext>, [">= 0"])
152
151
  s.add_runtime_dependency(%q<fastercsv>, [">= 0"])
153
- s.add_runtime_dependency(%q<google_maps_geocoder>, [">= 0"])
154
- s.add_runtime_dependency(%q<mongoid>, [">= 0"])
152
+ s.add_runtime_dependency(%q<geocoder>, [">= 0"])
155
153
  s.add_runtime_dependency(%q<mongoid-tree>, [">= 0"])
156
154
  s.add_runtime_dependency(%q<rails>, ["~> 3.0.0"])
155
+ s.add_runtime_dependency(%q<redis>, [">= 0"])
157
156
  s.add_runtime_dependency(%q<scaffold_logic>, [">= 0"])
158
157
  s.add_runtime_dependency(%q<stateflow>, [">= 0"])
159
158
  s.add_runtime_dependency(%q<stringex>, [">= 0"])
159
+ s.add_runtime_dependency(%q<SystemTimer>, [">= 0"])
160
160
  s.add_development_dependency(%q<jeweler>, [">= 0"])
161
161
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
162
162
  else
163
163
  s.add_dependency(%q<bson_ext>, [">= 0"])
164
164
  s.add_dependency(%q<fastercsv>, [">= 0"])
165
- s.add_dependency(%q<google_maps_geocoder>, [">= 0"])
166
- s.add_dependency(%q<mongoid>, [">= 0"])
165
+ s.add_dependency(%q<geocoder>, [">= 0"])
167
166
  s.add_dependency(%q<mongoid-tree>, [">= 0"])
168
167
  s.add_dependency(%q<rails>, ["~> 3.0.0"])
168
+ s.add_dependency(%q<redis>, [">= 0"])
169
169
  s.add_dependency(%q<scaffold_logic>, [">= 0"])
170
170
  s.add_dependency(%q<stateflow>, [">= 0"])
171
171
  s.add_dependency(%q<stringex>, [">= 0"])
172
+ s.add_dependency(%q<SystemTimer>, [">= 0"])
172
173
  s.add_dependency(%q<jeweler>, [">= 0"])
173
174
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
174
175
  end
175
176
  else
176
177
  s.add_dependency(%q<bson_ext>, [">= 0"])
177
178
  s.add_dependency(%q<fastercsv>, [">= 0"])
178
- s.add_dependency(%q<google_maps_geocoder>, [">= 0"])
179
- s.add_dependency(%q<mongoid>, [">= 0"])
179
+ s.add_dependency(%q<geocoder>, [">= 0"])
180
180
  s.add_dependency(%q<mongoid-tree>, [">= 0"])
181
181
  s.add_dependency(%q<rails>, ["~> 3.0.0"])
182
+ s.add_dependency(%q<redis>, [">= 0"])
182
183
  s.add_dependency(%q<scaffold_logic>, [">= 0"])
183
184
  s.add_dependency(%q<stateflow>, [">= 0"])
184
185
  s.add_dependency(%q<stringex>, [">= 0"])
186
+ s.add_dependency(%q<SystemTimer>, [">= 0"])
185
187
  s.add_dependency(%q<jeweler>, [">= 0"])
186
188
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
187
189
  end
@@ -1,3 +1,4 @@
1
+ ENV['REDISTOGO_URL'] = 'redis://redistogo:7002f835e9680a65750e24a03065319e@perch.redistogo.com:9744'
1
2
  CampfireLogic::Application.configure do
2
3
  config.cache_classes = true
3
4
  config.whiny_nils = true
@@ -0,0 +1,5 @@
1
+ uri = URI.parse ENV['REDISTOGO_URL']
2
+ REDIS = Redis.new :host => uri.host, :port => uri.port, :password => uri.password
3
+ Geocoder::Configuration.cache = REDIS
4
+ Geocoder::Configuration.lookup = :google
5
+ Geocoder::Configuration.timeout = 15
data/db/seeds.rb CHANGED
@@ -1,4 +1,2 @@
1
- puts 'Importing zip codes...'
2
- ZipCodeImport.test
3
1
  puts 'Importing locations...'
4
2
  LocationImport.test
@@ -11,7 +11,6 @@ Then /^the directory shows an address vcard$/ do
11
11
  end
12
12
 
13
13
  Given /^zip-coded locations$/ do
14
- ZipCode.expects(:first).returns(ZipCode.new :lat_lng => [0, 0])
15
14
  Location.expects(:near).returns(Location.all)
16
15
  end
17
16
 
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe DirectoryController do
4
4
  it 'show action should render show template' do
5
- Locale.stubs(:find).returns(Locale.new :lat_lng => [], :slug => 'foo')
5
+ Locale.stubs(:find).returns(Locale.new :coordinates => [], :slug => 'foo')
6
6
  Locale.stubs(:us).returns([Locale.find])
7
7
  Locale.any_instance.stubs(:children).returns([])
8
8
  get :show, :slug => 'foo'
@@ -4,7 +4,6 @@ describe Locale do
4
4
  before :all do
5
5
  Locale.delete_all
6
6
  Locale.init_root
7
- GoogleMapsGeocoder.stubs(:new).returns(stub('prospect park zoo', :city => 'Brooklyn', :country_long_name => 'United States', :country_short_name => 'US', :formatted_address => '450 Flatbush Avenue', :formatted_street_address => '450 Flatbush Avenue', :lat => 1, :lng => 1, :partial_match? => false, :postal_code => '11217', :state_long_name => 'New York', :state_short_name => 'NY'))
8
7
  location = Location.new :address1 => '450 Flatbush Avenue', :city => 'Brooklyn', :name => 'Prospect Park Zoo', :state => 'NY'
9
8
  location.validate_address!
10
9
  location.localize
@@ -1,10 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Location do
4
- it 'handles query-limit errors' do
5
- ActiveSupport::JSON.stubs(:decode)
6
- location = Location.new(:city => 'new york').geocode.should == :new
7
- end
4
+ it 'handles query-limit errors'
8
5
  end
9
6
 
10
7
  describe Location do
@@ -14,22 +11,18 @@ describe Location do
14
11
  end
15
12
 
16
13
  before(:each) do
17
- GoogleMapsGeocoder.stubs(:new).returns(stub('white house', :city => 'Washington', :country_short_name => 'US', :country_long_name => 'United States', :formatted_address => '1600 Pennsylvania Ave NW', :formatted_street_address => '1600 Pennsylvania Ave NW', :lat => 1, :lng => 1, :partial_match? => true, :postal_code => '20500', :state_long_name => 'District of Columbia', :state_short_name => 'DC'))
18
14
  @white_house = Location.new :address1 => '1600 Pennsylvania', :city => 'Washington', :name => 'White House'
19
15
  @white_house.validate_address!
20
16
  @white_house.localize
21
17
 
22
- GoogleMapsGeocoder.stubs(:new).returns(stub('tea lounge', :city => 'Brooklyn', :country_short_name => 'US', :country_long_name => 'United States', :formatted_address => '837 Union St', :formatted_street_address => '837 Union St', :lat => 1, :lng => 1, :partial_match? => false, :postal_code => '11217', :state_long_name => 'New York', :state_short_name => 'NY'))
23
- @tea_lounge = Location.new :address1 => ' 837 Union St ', :address2 => ' Suite 1 ', :city => ' Brooklyn ', :name => ' Tea Lounge ', :state => ' NY ', :zip => ' 11217 '
18
+ @tea_lounge = Location.new :address1 => ' 837 Union St ', :address2 => ' Suite 1 ', :city => ' Brooklyn ', :name => ' Tea Lounge ', :state => ' NY ', :zip => ' 11215 '
24
19
  @tea_lounge.validate_address!
25
20
  @tea_lounge.localize
26
21
 
27
- GoogleMapsGeocoder.stubs(:new).returns(stub('two boots', :city => 'Brooklyn', :country_short_name => 'US', :country_long_name => 'United States', :formatted_address => '837 Union St', :formatted_street_address => '837 Union St', :lat => 1, :lng => 1, :partial_match? => false, :postal_code => '11217', :state_long_name => 'New York', :state_short_name => 'NY'))
28
22
  @two_boots = Location.new(:address1 => '514 2nd Street', :city => 'Brooklyn', :name => 'Two Boots of Brooklyn', :state => 'NY')
29
23
  @two_boots.validate_address!
30
24
  @two_boots.localize
31
25
 
32
- GoogleMapsGeocoder.stubs(:new).returns(stub('new park', :city => 'Howard Beach', :country_short_name => 'US', :country_long_name => 'United States', :formatted_address => '15671 Crossbay Boulevard', :formatted_street_address => '15671 Crossbay Boulevard', :lat => 1, :lng => 1, :partial_match? => false, :postal_code => '11217', :state_long_name => 'New York', :state_short_name => 'NY'))
33
26
  @new_park = Location.new(:address1 => '15671 Crossbay Boulevard', :city => 'Howard Beach', :name => 'New Park Pizza', :state => 'NY')
34
27
  @new_park.validate_address!
35
28
  @new_park.localize
@@ -87,7 +80,6 @@ describe Location do
87
80
 
88
81
  it 're-validates modified addresses with Google Maps' do
89
82
  @white_house.address1 = ''
90
- GoogleMapsGeocoder.stubs(:new).returns(stub('white house', :city => 'Washington', :country_short_name => 'US', :country_long_name => 'United States', :formatted_address => '1600 Pennsylvania Ave NW', :formatted_street_address => '1600 Pennsylvania Ave NW', :lat => 1, :lng => 1, :partial_match? => false, :postal_code => '20500', :state_long_name => 'District of Columbia', :state_short_name => 'DC'))
91
83
  @white_house.validate_address!
92
84
  @white_house.should be_validated
93
85
  end
@@ -99,8 +91,7 @@ describe Location do
99
91
 
100
92
  it 'clears geocoding if any address field is modified' do
101
93
  @white_house.city = 'New York'
102
- @white_house.geocoder.should be_nil
103
- @white_house.lat_lng.should be_nil
94
+ @white_house.coordinates.should be_nil
104
95
  @white_house.state_long_name.should be_nil
105
96
  @white_house.validated_address1.should be_nil
106
97
  @white_house.validated_city.should be_nil
@@ -148,7 +139,6 @@ describe Location do
148
139
  @tea_lounge.address1 = '1600 Pennsylvania Ave NW'
149
140
  @tea_lounge.city = 'Washington'
150
141
  @tea_lounge.state = 'DC'
151
- GoogleMapsGeocoder.stubs(:new).returns(stub('overridden tea lounge', :city => 'Washington', :country_short_name => 'US', :country_long_name => 'United States', :formatted_address => '1600 Pennsylvania Ave NW', :formatted_street_address => '1600 Pennsylvania Ave NW', :lat => 1, :lng => 1, :partial_match? => false, :postal_code => '20500', :state_long_name => 'District of Columbia', :state_short_name => 'DC'))
152
142
  @tea_lounge.validate_address!
153
143
  @tea_lounge.localize
154
144
  @tea_lounge.city_locale.city?.should be_true