Class: PostalCodes::GeonamesRefresh

Inherits:
Object
  • Object
show all
Defined in:
app/services/postal_codes/geonames_refresh.rb

Overview

Refreshes the PostalCode cache from the free GeoNames postal dataset
(https://download.geonames.org/export/zip/) — the replacement for the stale
2011 zipcodedownload.com import. Takes one representative row per postal
code and upserts +code+, +state_code+, +latitude+, +longitude+, stamping
+updated_at+ so PostalCode.fresh_record's TTL has a basis.

US codes are 5-digit ZIPs; the free CA dataset is FSA-level (3-char), which
PostalCode.state_for also consults.

Examples:

PostalCodes::GeonamesRefresh.new(%w[US]).run        # => 41_692
PostalCodes::GeonamesRefresh.new(%w[US], dry_run: true).run

Defined Under Namespace

Classes: InsufficientData

Constant Summary collapse

BASE_URL =
'https://download.geonames.org/export/zip'
BATCH =
5_000
REUSE_DOWNLOAD_FOR =

Re-download rather than reuse a local file older than this, so the monthly
run in a long-lived container can't keep parsing a months-old download.
(Freshly-written test fixtures stay within the window → no network.)

1.day
MIN_EXPECTED =

Minimum plausible row count per country (GeoNames US ≈ 41k, CA FSA ≈ 1.6k).
A parse below this means a bad download — abort the write.

{ 'US' => 40_000, 'CA' => 1_000 }.freeze

Instance Method Summary collapse

Constructor Details

#initialize(countries = %w[US],, dry_run: false, dir: Rails.root.join('tmp/geonames'), min_expected: MIN_EXPECTED) ⇒ GeonamesRefresh

Returns a new instance of GeonamesRefresh.

Parameters:

  • countries (Array<String>) (defaults to: %w[US],)

    ISO-2 codes, e.g. %w[US CA]

  • dry_run (Boolean) (defaults to: false)

    parse + count without writing

  • dir (Pathname, String) (defaults to: Rails.root.join('tmp/geonames'))

    working dir for downloaded files

  • min_expected (Hash{String=>Integer}) (defaults to: MIN_EXPECTED)

    per-country sanity floors



39
40
41
42
43
44
# File 'app/services/postal_codes/geonames_refresh.rb', line 39

def initialize(countries = %w[US], dry_run: false, dir: Rails.root.join('tmp/geonames'), min_expected: MIN_EXPECTED)
  @countries = Array(countries)
  @dry_run = dry_run
  @dir = Pathname(dir)
  @min_expected = min_expected
end

Instance Method Details

#runInteger

Returns total postal codes processed.

Returns:

  • (Integer)

    total postal codes processed



47
48
49
# File 'app/services/postal_codes/geonames_refresh.rb', line 47

def run
  @countries.sum { |country| refresh_country(country) }
end