1# frozen_string_literal: true
2
3require "cbor"
4require "json"
5
6require_relative "geo_code"
7
8class GeoCodeRepo
9 def initialize(memcache: MEMCACHE)
10 @memcache = memcache
11 end
12
13 def find(q)
14 cache(q) {
15 EM::HttpRequest.new(
16 "https://geocoder.ca/",
17 tls: { verify_peer: true }
18 ).aget(query: { json: 1, locate: q }).then { |res|
19 JSON.parse(res.response)
20 }
21 }.then(&GeoCode.method(:for))
22 end
23
24protected
25
26 def cache(k, &blk)
27 k = "geocode_#{k.gsub(/ /, '%20')}"
28 promise = EMPromise.new
29 @memcache.get(k, &promise.method(:fulfill))
30 promise.then { |cbor|
31 CBOR.decode(cbor)
32 }.catch(&blk).then { |result|
33 @memcache.set(k, result.to_cbor)
34 result
35 }
36 end
37end