forked from countries/countries
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRakefile
executable file
·133 lines (112 loc) · 4.36 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env rake
require 'bundler/gem_tasks'
require 'rake'
require 'rspec/core/rake_task'
desc 'Run all examples'
RSpec::Core::RakeTask.new(:spec) do |t|
t.rspec_opts = %w(--color --warnings)
end
task default: [:spec]
task :update_yaml_structure do
require 'yaml'
require 'pry'
d = Dir['lib/countries/data/subdivisions/*.yaml']
d.each do |file|
puts "checking : #{file}"
data = YAML.load_file(file)
country_key = File.basename(file, ".yaml")
data = data.inject({}) do |a, (k,subd)|
a[k] ||= {}
a[k]["unofficial_names"] = subd.delete("names")
a[k]["translations"] = {'en' => subd['name']}
a[k]["geo"] = {
"latitude" => subd.delete("latitude"),
"longitude" => subd.delete("longitude"),
"min_latitude" => subd.delete("min_latitude"),
"min_longitude" => subd.delete("min_longitude"),
"max_latitude" => subd.delete("max_latitude"),
"max_longitude" => subd.delete("max_longitude")
}
a[k] = a[k].merge(subd)
a
end
File.open(file, 'w') { |f| f.write data.to_yaml }
begin
rescue
puts "failed to read #{file}: #{$ERROR_INFO}"
end
end
end
desc 'Update Cache'
task :update_cache do
require 'yaml'
require 'i18n_data'
codes = Dir['lib/countries/data/countries/*.yaml'].map {|x| File.basename(x, File.extname(x))}.uniq
data = {}
empty_translations_hash = {}
corrections = YAML.load_file(File.join(File.dirname(__FILE__), 'lib', 'countries', 'data', 'translation_corrections.yaml')) || {}
I18nData.languages.keys.each do |locale|
locale = locale.downcase
begin
local_names = I18nData.countries(locale)
rescue I18nData::NoTranslationAvailable
next
end
# Apply any known corrections to i18n_data
unless corrections[locale].nil?
corrections[locale].each do |alpha2, localized_name|
local_names[alpha2] = localized_name
end
end
File.open(File.join(File.dirname(__FILE__), 'lib', 'countries', 'cache', 'locales', "#{locale}.json"), 'wb') { |f| f.write(local_names.to_json) }
end
codes.each do |alpha2|
data[alpha2] ||= YAML.load_file(File.join(File.dirname(__FILE__), 'lib', 'countries', 'data', 'countries', "#{alpha2}.yaml"))[alpha2]
end
File.open(File.join(File.dirname(__FILE__), 'lib', 'countries', 'cache', 'countries.json'), 'wb') { |f| f.write(data.to_json) }
end
require 'geocoder'
require 'retryable'
# raise on geocoding errors such as query limit exceeded
Geocoder.configure(always_raise: :all)
# Try to geocode a given query, on exceptions it retries up to 3 times then gives up.
# @param [String] query string to geocode
# @return [Hash] first valid result or nil
def geocode(query)
Retryable.retryable(tries: 3, sleep: lambda { |n| 2**n }) do
Geocoder.search(query).first
end
rescue => e
warn "Attempts exceeded for query #{query}, last error was #{e.message}"
nil
end
desc 'Retrieve and store subdivisions coordinates'
task :fetch_subdivisions do
require 'countries'
# Iterate all countries with subdivisions
ISO3166::Country.all.select(&:subdivisions?).each do |c|
# Iterate subdivisions
state_data = c.subdivisions.dup
state_data.reject { |_, data| data['latitude'] }.each do |code, data|
location = "#{data['name']}, #{c.name}"
# Handle special geocoding cases where Google defaults to well known
# cities, instead of the states.
if c.alpha2 == 'US' && %w(NY WA OK).include?(code)
location = "#{data['name']} State, United States"
end
next unless (result = geocode(location))
geometry = result.geometry
if geometry['location']
state_data[code]['geo']['latitude'] = geometry['location']['lat']
state_data[code]['geo']['longitude'] = geometry['location']['lng']
end
next unless geometry['bounds']
state_data[code]['geo']['min_latitude'] = geometry['bounds']['southwest']['lat']
state_data[code]['geo']['min_longitude'] = geometry['bounds']['southwest']['lng']
state_data[code]['geo']['max_latitude'] = geometry['bounds']['northeast']['lat']
state_data[code]['geo']['max_longitude'] = geometry['bounds']['northeast']['lng']
end
# Write updated YAML for current country
File.open(File.join(File.dirname(__FILE__), 'lib','countries', 'data', 'subdivisions', "#{c.alpha2}.yaml"), 'w+') { |f| f.write state_data.to_yaml }
end
end