campfire_logic 1.1.10 → 1.2.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.
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