Module: Crawler::Address

Includes:
Base
Defined in:
lib/crawler/address.rb,
lib/crawler/address/core/version.rb

Defined Under Namespace

Modules: Core

Constant Summary collapse

PROVIDERS =
{}
SCORES =
{}

Class Method Summary collapse

Class Method Details

.add_provider(provider_name, options = {}) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/crawler/address.rb', line 13

def self.add_provider(provider_name, options = {})
  options.assert_valid_keys :score, :insert_at, :country, :countries

  countries = options[:countries] || []
  countries += [options[:country].to_s || 'all'] if countries.empty?

  countries.each do |country|
    PROVIDERS[country] ||= []
    PROVIDERS[country].insert(options[:insert_at] || -1, provider_name)
  end

  if (score = options[:score])
    SCORES[provider_name] = score
  end
end

.best(street, zipcode, city, country) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/crawler/address.rb', line 56

def self.best(street, zipcode, city, country)
  data = search(street, zipcode, city, country)&.max_by do |_, addresses|
    address = addresses.max_by do |address|
      address[:score]
    end

    address[:score]
  end

  data&.last&.max_by do |address|
    address[:score]
  end&.dig(:data)
end

.search(street, zipcode, city, country) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/crawler/address.rb', line 29

def self.search(street, zipcode, city, country)
  providers = PROVIDERS['all'] || []
  providers += PROVIDERS[country.to_s] || []

  addresses = providers.flat_map do |provider_name|
    camelized = ActiveSupport::Inflector.camelize("crawler/address/providers/#{provider_name.to_s}")
    klass = ActiveSupport::Inflector.constantize(camelized)
    addresses = klass.resolve(street, zipcode, city, country)

    addresses.map do |address|
      provider_score = SCORES[provider_name] || 0.5
      street_score = Utils.levenshtein_score(street, address[:street])
      zipcode_score = zipcode.to_s == address[:zipcode].to_s ? 1.0 : 0.9
      city_score = Utils.levenshtein_score(city, address[:city])

      {
        data: address,
        score: provider_score * street_score * zipcode_score * city_score
      }
    end
  end

  addresses.group_by do |address|
    [Utils.transliterate(address[:data][:street]), Utils.transliterate(address[:data][:zipcode]), Utils.transliterate(address[:data][:city])]
  end
end