Forgot files

Stephen Paul Weber created

Change summary

lib/area_code_repo.rb | 25 +++++++++++++++++++++++++
lib/geo_code.rb       | 24 ++++++++++++++++++++++++
lib/geo_code_repo.rb  | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+)

Detailed changes

lib/area_code_repo.rb 🔗

@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require "json"
+
+require_relative "geo_code_repo"
+
+class AreaCodeRepo
+	def initialize(db: DB, geo_code_repo: GeoCodeRepo.new)
+		@db = db
+		@geo_code_repo = geo_code_repo
+	end
+
+	def find(q, limit: 3)
+		@geo_code_repo.find(q).then { |geo|
+			@db.query_defer(<<~SQL, [geo.country, geo.sql_point, limit])
+				SELECT area_code FROM area_codes
+				WHERE country=$1
+				ORDER BY location <-> $2
+				LIMIT $3
+			SQL
+		}.then { |rows|
+			rows.map { |row| row["area_code"] }
+		}
+	end
+end

lib/geo_code.rb 🔗

@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require "value_semantics/monkey_patched"
+
+class GeoCode
+	def self.for(data)
+		new(data)
+	end
+
+	def initialize(data)
+		@data = data
+	end
+
+	def country
+		return "US" unless @data["postal"]
+		return "US" if @data["postal"] =~ /\A\d+\Z/
+
+		"CA"
+	end
+
+	def sql_point
+		"POINT(#{'%.10f' % @data['longt']} #{'%.10f' % @data['latt']})"
+	end
+end

lib/geo_code_repo.rb 🔗

@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require "cbor"
+require "json"
+
+require_relative "geo_code"
+
+class GeoCodeRepo
+	def initialize(memcache: MEMCACHE)
+		@memcache = memcache
+	end
+
+	def find(q)
+		cache(q) {
+			EM::HttpRequest.new(
+				"https://geocoder.ca/",
+				tls: { verify_peer: true }
+			).aget(query: { json: 1, locate: q }).then { |res|
+				JSON.parse(res.response)
+			}
+		}.then(&GeoCode.method(:for))
+	end
+
+protected
+
+	def cache(k, &blk)
+		k = "geocode_#{k.gsub(/ /, '%20')}"
+		promise = EMPromise.new
+		@memcache.get(k, &promise.method(:fulfill))
+		promise.then { |cbor|
+			CBOR.decode(cbor)
+		}.catch(&blk).then { |result|
+			@memcache.set(k, result.to_cbor)
+			result
+		}
+	end
+end