countries 4.2.3 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codeql-analysis.yml +70 -0
  3. data/.github/workflows/tests.yml +1 -5
  4. data/.rubocop.yml +40 -1
  5. data/.rubocop_todo.yml +8 -41
  6. data/CHANGELOG.md +7 -2
  7. data/Gemfile +5 -3
  8. data/README.markdown +22 -5
  9. data/Rakefile +13 -31
  10. data/bin/console +1 -0
  11. data/countries.gemspec +7 -5
  12. data/lib/countries/cache/countries.json +1 -1
  13. data/lib/countries/configuration.rb +2 -0
  14. data/lib/countries/country/class_methods.rb +12 -97
  15. data/lib/countries/country/currency_methods.rb +2 -0
  16. data/lib/countries/country/emoji.rb +2 -3
  17. data/lib/countries/country/finder_methods.rb +81 -0
  18. data/lib/countries/country.rb +3 -40
  19. data/lib/countries/data/countries/KN.yaml +0 -1
  20. data/lib/countries/data.rb +34 -37
  21. data/lib/countries/global.rb +2 -0
  22. data/lib/countries/iso3166.rb +3 -0
  23. data/lib/countries/kwarg_struct.rb +2 -0
  24. data/lib/countries/mongoid.rb +2 -0
  25. data/lib/countries/sources/cldr/downloader.rb +8 -8
  26. data/lib/countries/sources/cldr/subdivision.rb +3 -0
  27. data/lib/countries/sources/cldr/subdivision_updater.rb +23 -17
  28. data/lib/countries/sources/local/cached_loader.rb +3 -0
  29. data/lib/countries/sources/local/subdivision.rb +5 -2
  30. data/lib/countries/sources.rb +2 -0
  31. data/lib/countries/structure.rb +1 -1
  32. data/lib/countries/subdivision.rb +2 -0
  33. data/lib/countries/tasks/geocoding.rake +15 -6
  34. data/lib/countries/tasks/postal_codes.rake +5 -3
  35. data/lib/countries/timezones.rb +5 -2
  36. data/lib/countries/translations.rb +2 -0
  37. data/lib/countries/version.rb +3 -1
  38. data/lib/countries.rb +2 -0
  39. data/spec/00_global_spec.rb +2 -0
  40. data/spec/configuration_spec.rb +11 -5
  41. data/spec/country_spec.rb +71 -22
  42. data/spec/data_spec.rb +24 -18
  43. data/spec/mongoid_spec.rb +2 -2
  44. data/spec/perf_spec.rb +16 -16
  45. data/spec/spec_helper.rb +2 -0
  46. data/spec/subdivision_spec.rb +6 -4
  47. data/spec/thread_safety_spec.rb +4 -3
  48. data/spec/timezone_spec.rb +2 -0
  49. metadata +14 -12
  50. data/lib/countries/setup.rb +0 -18
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ISO3166
2
4
  class << self
3
5
  attr_writer :configuration
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sixarm_ruby_unaccent'
2
4
 
3
5
  module ISO3166
4
6
  UNSEARCHABLE_METHODS = [:translations].freeze
5
7
 
6
- def self::Country(country_data_or_country)
8
+ def self.Country(country_data_or_country)
7
9
  case country_data_or_country
8
10
  when ISO3166::Country
9
11
  country_data_or_country
@@ -15,9 +17,6 @@ module ISO3166
15
17
  end
16
18
 
17
19
  module CountryClassMethods
18
- FIND_BY_REGEX = /^find_(all_)?(country_|countries_)?by_(.+)/
19
- SEARCH_TERM_FILTER_REGEX = /\(|\)|\[\]|,/
20
-
21
20
  def new(country_data)
22
21
  super if country_data.is_a?(Hash) || codes.include?(country_data.to_s.upcase)
23
22
  end
@@ -33,10 +32,6 @@ module ISO3166
33
32
 
34
33
  alias countries all
35
34
 
36
- def all_translated(locale = 'en')
37
- translations(locale).values
38
- end
39
-
40
35
  def all_names_with_codes(locale = 'en')
41
36
  Country.all.map do |c|
42
37
  lc = (c.translation(locale) || c.iso_short_name)
@@ -50,6 +45,10 @@ module ISO3166
50
45
  end
51
46
  end
52
47
 
48
+ def all_translated(locale = 'en')
49
+ translations(locale).values
50
+ end
51
+
53
52
  def translations(locale = 'en')
54
53
  i18n_data_countries = I18nData.countries(locale.upcase)
55
54
 
@@ -62,54 +61,6 @@ module ISO3166
62
61
  i18n_data_countries.merge(custom_countries)
63
62
  end
64
63
 
65
- def search(query)
66
- country = new(query.to_s.upcase)
67
- country && country.valid? ? country : nil
68
- end
69
-
70
- def [](query)
71
- search(query)
72
- end
73
-
74
- def method_missing(method_name, *arguments)
75
- matches = method_name.to_s.match(FIND_BY_REGEX)
76
- return_all = matches[1]
77
- super unless matches
78
-
79
- if matches[3] == 'names'
80
- if RUBY_VERSION =~ /^3\.\d\.\d/
81
- warn "DEPRECATION WARNING: 'find_by_name' and 'find_*_by_name' methods are deprecated, please refer to the README file for more information on this change.", uplevel: 1, category: :deprecated
82
- else
83
- warn "DEPRECATION WARNING: 'find_by_name' and 'find_*_by_name' methods are deprecated, please refer to the README file for more information on this change.", uplevel: 1
84
- end
85
- end
86
-
87
- countries = find_by(matches[3], arguments[0], matches[2])
88
- return_all ? countries : countries.last
89
- end
90
-
91
- def respond_to_missing?(method_name, include_private = false)
92
- matches = method_name.to_s.match(FIND_BY_REGEX)
93
- if matches && matches[3]
94
- instance_methods.include?(matches[3].to_sym)
95
- else
96
- super
97
- end
98
- end
99
-
100
- def find_all_by(attribute, val)
101
- attributes, lookup_value = parse_attributes(attribute, val)
102
-
103
- ISO3166::Data.cache.select do |_, v|
104
- country = Country.new(v)
105
- attributes.any? do |attr|
106
- Array(country.send(attr)).any? do |n|
107
- lookup_value === cached(n) { parse_value(n) }
108
- end
109
- end
110
- end
111
- end
112
-
113
64
  def subdivisions(alpha2)
114
65
  @subdivisions ||= {}
115
66
  @subdivisions[alpha2] ||= create_subdivisions(subdivision_data(alpha2))
@@ -124,51 +75,14 @@ module ISO3166
124
75
 
125
76
  protected
126
77
 
127
- def strip_accents(v)
128
- if v.is_a?(Regexp)
129
- Regexp.new(v.source.unaccent, 'i')
78
+ def strip_accents(string)
79
+ if string.is_a?(Regexp)
80
+ Regexp.new(string.source.unaccent, 'i')
130
81
  else
131
- v.to_s.unaccent.downcase
132
- end
133
- end
134
-
135
- def parse_attributes(attribute, val)
136
- raise "Invalid attribute name '#{attribute}'" unless searchable_attribute?(attribute.to_sym)
137
-
138
- attributes = Array(attribute.to_s)
139
- if attribute.to_s == 'name'
140
- if RUBY_VERSION =~ /^3\.\d\.\d/
141
- warn "DEPRECATION WARNING: 'find_by_name' and 'find_*_by_name' methods are deprecated, please refer to the README file for more information on this change.", uplevel: 1, category: :deprecated
142
- else
143
- warn "DEPRECATION WARNING: 'find_by_name' and 'find_*_by_name' methods are deprecated, please refer to the README file for more information on this change.", uplevel: 1
144
- end
145
- # 'find_by_name' and 'find_*_by_name' will be changed for 5.0
146
- # The addition of 'iso_short_name' here ensures the behaviour of 4.1 is kept for 4.2
147
- attributes = %w[iso_short_name unofficial_names translated_names]
148
- end
149
-
150
- [attributes, parse_value(val)]
151
- end
152
-
153
- def searchable_attribute?(attribute)
154
- searchable_attributes.include?(attribute.to_sym)
155
- end
156
-
157
- def searchable_attributes
158
- instance_methods - UNSEARCHABLE_METHODS
159
- end
160
-
161
- def find_by(attribute, value, obj = nil)
162
- find_all_by(attribute.downcase, value).map do |country|
163
- obj.nil? ? country : new(country.last)
82
+ string.to_s.unaccent.downcase
164
83
  end
165
84
  end
166
85
 
167
- def parse_value(value)
168
- value = value.gsub(SEARCH_TERM_FILTER_REGEX, '') if value.respond_to?(:gsub)
169
- strip_accents(value)
170
- end
171
-
172
86
  def subdivision_data(alpha2)
173
87
  file = subdivision_file_path(alpha2)
174
88
  File.exist?(file) ? YAML.load_file(file) : {}
@@ -190,6 +104,7 @@ module ISO3166
190
104
  def cached(value)
191
105
  @_parsed_values_cache ||= {}
192
106
  return @_parsed_values_cache[value] if @_parsed_values_cache[value]
107
+
193
108
  @_parsed_values_cache[value] = yield
194
109
  end
195
110
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'money'
2
4
 
3
5
  module ISO3166
@@ -1,5 +1,4 @@
1
- #!/bin/env ruby
2
- # encoding: utf-8
1
+ # frozen_string_literal: true
3
2
 
4
3
  module ISO3166
5
4
  module Emoji
@@ -36,7 +35,7 @@ module ISO3166
36
35
  #
37
36
  # The emoji flag for this country, using Unicode Regional Indicator characters. e.g: "U+1F1FA U+1F1F8" for 🇺🇸
38
37
  def emoji_flag
39
- alpha2.downcase.chars.map { |c| CODE_POINTS[c] }.join('')
38
+ alpha2.downcase.chars.map { |c| CODE_POINTS[c] }.join
40
39
  end
41
40
  end
42
41
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ISO3166
4
+ module CountryFinderMethods
5
+ FIND_BY_REGEX = /^find_(all_)?(country_|countries_)?by_(.+)/.freeze
6
+ SEARCH_TERM_FILTER_REGEX = /\(|\)|\[\]|,/.freeze
7
+
8
+ def search(query)
9
+ country = new(query.to_s.upcase)
10
+ country&.valid? ? country : nil
11
+ end
12
+
13
+ def [](query)
14
+ search(query)
15
+ end
16
+
17
+ def find_all_by(attribute, val)
18
+ attributes, lookup_value = parse_attributes(attribute, val)
19
+
20
+ ISO3166::Data.cache.select do |_, v|
21
+ country = Country.new(v)
22
+ attributes.any? do |attr|
23
+ Array(country.send(attr)).any? do |n|
24
+ lookup_value === cached(n) { parse_value(n) }
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def method_missing(method_name, *arguments)
31
+ matches = method_name.to_s.match(FIND_BY_REGEX)
32
+ return_all = matches[1]
33
+ super unless matches
34
+
35
+ countries = find_by(matches[3], arguments[0], matches[2])
36
+ return_all ? countries : countries.last
37
+ end
38
+
39
+ def respond_to_missing?(method_name, include_private = false)
40
+ matches = method_name.to_s.match(FIND_BY_REGEX)
41
+ if matches && matches[3]
42
+ instance_methods.include?(matches[3].to_sym)
43
+ else
44
+ super
45
+ end
46
+ end
47
+
48
+ protected
49
+
50
+ def find_by(attribute, value, obj = nil)
51
+ find_all_by(attribute.downcase, value).map do |country|
52
+ obj.nil? ? country : new(country.last)
53
+ end
54
+ end
55
+
56
+ def parse_attributes(attribute, val)
57
+ raise "Invalid attribute name '#{attribute}'" unless searchable_attribute?(attribute.to_sym)
58
+
59
+ attributes = Array(attribute.to_s)
60
+ if attribute.to_s == 'any_name'
61
+ attributes = %w[iso_long_name iso_short_name unofficial_names translated_names]
62
+ end
63
+
64
+ [attributes, parse_value(val)]
65
+ end
66
+
67
+ def parse_value(value)
68
+ value = value.gsub(SEARCH_TERM_FILTER_REGEX, '') if value.respond_to?(:gsub)
69
+ strip_accents(value)
70
+ end
71
+
72
+ def searchable_attribute?(attribute)
73
+ searchable_attributes.include?(attribute.to_sym)
74
+ end
75
+
76
+ def searchable_attributes
77
+ # Add name and names until we complete the deprecation of the finders
78
+ instance_methods - UNSEARCHABLE_METHODS + [:name, :names, :any_name]
79
+ end
80
+ end
81
+ end
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ISO3166
2
4
  class Country
3
5
  extend CountryClassMethods
6
+ extend CountryFinderMethods
4
7
  include Emoji
5
8
  attr_reader :data
6
9
 
@@ -31,24 +34,6 @@ module ISO3166
31
34
  alias zip_format postal_code_format
32
35
  alias languages languages_official
33
36
 
34
- def latitude_dec
35
- if RUBY_VERSION =~ /^3\.\d\.\d/
36
- warn "DEPRECATION WARNING: The Country#latitude_dec method has been deprecated and will be removed in 5.0. Please use Country#latitude instead.", uplevel: 1, category: :deprecated
37
- else
38
- warn "DEPRECATION WARNING: The Country#latitude_dec method has been deprecated and will be removed in 5.0. Please use Country#latitude instead.", uplevel: 1
39
- end
40
- latitude
41
- end
42
-
43
- def longitude_dec
44
- if RUBY_VERSION =~ /^3\.\d\.\d/
45
- warn "DEPRECATION WARNING: The Country#longitude_dec method has been deprecated and will be removed in 5.0. Please use Country#longitude instead.", uplevel: 1, category: :deprecated
46
- else
47
- warn "DEPRECATION WARNING: The Country#longitude_dec method has been deprecated and will be removed in 5.0. Please use Country#longitude instead.", uplevel: 1
48
- end
49
- longitude
50
- end
51
-
52
37
  def ==(other)
53
38
  other.respond_to?(:alpha2) && other.alpha2 == alpha2
54
39
  end
@@ -136,28 +121,6 @@ module ISO3166
136
121
  @local_name ||= local_names.first
137
122
  end
138
123
 
139
- # @return [String] This Country's ISO Short Name
140
- # @deprecated Use {#iso_short_name} instead.
141
- def name
142
- if RUBY_VERSION =~ /^3\.\d\.\d/
143
- warn "DEPRECATION WARNING: The Country#name method has been deprecated. Please use Country#iso_short_name instead or refer to the README file for more information on this change.", uplevel: 1, category: :deprecated
144
- else
145
- warn "DEPRECATION WARNING: The Country#name method has been deprecated. Please use Country#iso_short_name instead or refer to the README file for more information on this change.", uplevel: 1
146
- end
147
- iso_short_name
148
- end
149
-
150
- # @return [Array<String>] Array of unofficial, slang names or aliases for this Country
151
- # @deprecated Use {#unofficial_names} instead.
152
- def names
153
- if RUBY_VERSION =~ /^3\.\d\.\d/
154
- warn "DEPRECATION WARNING: The Country#names method has been deprecated. Please use Country#unofficial_names instead or refer to the README file for more information on this change.", uplevel: 1, category: :deprecated
155
- else
156
- warn "DEPRECATION WARNING: The Country#names method has been deprecated. Please use Country#unofficial_names instead or refer to the README file for more information on this change.", uplevel: 1
157
- end
158
- unofficial_names
159
- end
160
-
161
124
  # @!attribute alpha2
162
125
  # @return [String] the ISO3166 alpha-2 code for this Country
163
126
  #
@@ -9,7 +9,6 @@ KN:
9
9
  geo:
10
10
  latitude: 17.357822
11
11
  longitude: -62.782998
12
- longitude_dec: "-62.643184661865234"
13
12
  max_latitude: 17.4205891
14
13
  max_longitude: -62.52369989999999
15
14
  min_latitude: 17.07861
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ISO3166
2
4
  # Handles building the in memory store of countries data
3
5
  class Data
4
- @@cache_dir = [File.dirname(__FILE__), 'cache']
5
- @@cache = {}
6
- @@registered_data = {}
7
- @@mutex = Mutex.new
6
+ @cache_dir = [File.dirname(__FILE__), 'cache']
7
+ @cache = {}
8
+ @registered_data = {}
9
+ @mutex = Mutex.new
8
10
 
9
11
  def initialize(alpha2)
10
12
  @alpha2 = alpha2.to_s.upcase
@@ -15,30 +17,23 @@ module ISO3166
15
17
  end
16
18
 
17
19
  class << self
18
- def cache_dir
19
- @@cache_dir
20
- end
21
-
22
- def cache_dir=(value)
23
- @@cache_dir = value
24
- end
25
20
 
26
21
  # Registers a new Country with custom data.
27
22
  # If you are overriding an existing country, this does not perform a deep merge so you will need to __bring in all data you wish to be available__.
28
23
  # Overriding an existing country will also remove it from the internal management of translations.
29
24
  def register(data)
30
25
  alpha2 = data[:alpha2].upcase
31
- @@registered_data[alpha2] = deep_stringify_keys(data)
32
- @@registered_data[alpha2]['translations'] = \
26
+ @registered_data[alpha2] = deep_stringify_keys(data)
27
+ @registered_data[alpha2]['translations'] = \
33
28
  Translations.new.merge(data['translations'] || {})
34
- @@cache = cache.merge(@@registered_data)
29
+ @cache = cache.merge(@registered_data)
35
30
  end
36
31
 
37
32
  # Removes a country from the loaded data
38
33
  def unregister(alpha2)
39
34
  alpha2 = alpha2.to_s.upcase
40
- @@cache.delete(alpha2)
41
- @@registered_data.delete(alpha2)
35
+ @cache.delete(alpha2)
36
+ @registered_data.delete(alpha2)
42
37
  end
43
38
 
44
39
  def cache
@@ -47,8 +42,8 @@ module ISO3166
47
42
 
48
43
  # Resets the loaded data and cache
49
44
  def reset
50
- @@cache = {}
51
- @@registered_data = {}
45
+ @cache = {}
46
+ @registered_data = {}
52
47
  ISO3166.configuration.loaded_locales = []
53
48
  end
54
49
 
@@ -60,16 +55,19 @@ module ISO3166
60
55
  def update_cache
61
56
  load_data!
62
57
  sync_translations!
63
- @@cache
58
+ @cache
64
59
  end
65
60
 
61
+ private
62
+
66
63
  def load_data!
67
- return @@cache unless load_required?
64
+ return @cache unless load_required?
65
+
68
66
  synchronized do
69
- @@cache = load_cache %w(countries.json)
70
- @@_country_codes = @@cache.keys
71
- @@cache = @@cache.merge(@@registered_data)
72
- @@cache
67
+ @cache = load_cache %w[countries.json]
68
+ @_country_codes = @cache.keys
69
+ @cache = @cache.merge(@registered_data)
70
+ @cache
73
71
  end
74
72
  end
75
73
 
@@ -85,11 +83,9 @@ module ISO3166
85
83
  end
86
84
  end
87
85
 
88
- private
89
-
90
86
  def synchronized(&block)
91
87
  if use_mutex?
92
- @@mutex.synchronize(&block)
88
+ @mutex.synchronize(&block)
93
89
  else
94
90
  block.call
95
91
  end
@@ -102,17 +98,17 @@ module ISO3166
102
98
 
103
99
  def load_required?
104
100
  synchronized do
105
- @@cache.empty?
101
+ @cache.empty?
106
102
  end
107
103
  end
108
104
 
109
105
  def loaded_codes
110
- @@cache.keys
106
+ @cache.keys
111
107
  end
112
108
 
113
109
  # Codes that we have translations for in dataset
114
110
  def internal_codes
115
- @@_country_codes - @@registered_data.keys
111
+ @_country_codes - @registered_data.keys
116
112
  end
117
113
 
118
114
  def cache_flush_required?
@@ -139,9 +135,9 @@ module ISO3166
139
135
  synchronized do
140
136
  locale_names = load_cache(['locales', "#{locale}.json"])
141
137
  internal_codes.each do |alpha2|
142
- @@cache[alpha2]['translations'] ||= Translations.new
143
- @@cache[alpha2]['translations'][locale] = locale_names[alpha2].freeze
144
- @@cache[alpha2]['translated_names'] = @@cache[alpha2]['translations'].values.freeze
138
+ @cache[alpha2]['translations'] ||= Translations.new
139
+ @cache[alpha2]['translations'][locale] = locale_names[alpha2].freeze
140
+ @cache[alpha2]['translated_names'] = @cache[alpha2]['translations'].values.freeze
145
141
  end
146
142
  ISO3166.configuration.loaded_locales << locale
147
143
  end
@@ -150,8 +146,8 @@ module ISO3166
150
146
  def unload_translations(locale)
151
147
  synchronized do
152
148
  internal_codes.each do |alpha2|
153
- @@cache[alpha2]['translations'].delete(locale)
154
- @@cache[alpha2]['translated_names'] = @@cache[alpha2]['translations'].values.freeze
149
+ @cache[alpha2]['translations'].delete(locale)
150
+ @cache[alpha2]['translated_names'] = @cache[alpha2]['translations'].values.freeze
155
151
  end
156
152
  ISO3166.configuration.loaded_locales.delete(locale)
157
153
  end
@@ -163,7 +159,7 @@ module ISO3166
163
159
  end
164
160
 
165
161
  def datafile_path(file_array)
166
- File.join([@@cache_dir] + file_array)
162
+ File.join([@cache_dir] + file_array)
167
163
  end
168
164
 
169
165
  def deep_stringify_keys(data)
@@ -171,7 +167,8 @@ module ISO3166
171
167
  data.transform_values! do |v|
172
168
  v.is_a?(Hash) ? deep_stringify_keys(v) : v
173
169
  end
174
- return data
170
+
171
+ data
175
172
  end
176
173
  end
177
174
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'countries'
2
4
 
3
5
  # Some apps might not want to constantly call +ISO3166::Country+. This gem has a helper that can provide a Country class
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
  require 'json'
3
5
  require 'i18n_data'
@@ -8,6 +10,7 @@ require 'countries/data'
8
10
  require 'countries/structure'
9
11
  require 'countries/translations'
10
12
  require 'countries/country/class_methods'
13
+ require 'countries/country/finder_methods'
11
14
  require 'countries/country/emoji'
12
15
  require 'countries/country'
13
16
  require 'countries/subdivision'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ISO3166
2
4
  class KwargStruct < Struct
3
5
  # Override the initialize to handle hashes of named parameters
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ISO3166
2
4
  class Country
3
5
  def mongoize
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
  require 'net/http'
3
5
  require 'nokogiri'
@@ -19,19 +21,17 @@ module Sources
19
21
  def download_folder(type)
20
22
  folder = File.join(ISO3166_ROOT_PATH, 'tmp', 'cldr', 'trunk', 'common', type)
21
23
  FileUtils.mkdir_p(folder)
22
- url = URI.parse("https://api.github.com/repos/unicode-org/cldr/contents/common/" + type)
24
+ url = URI.parse("https://api.github.com/repos/unicode-org/cldr/contents/common/#{type}")
23
25
  path_listing = JSON.parse(Net::HTTP.get_response(url).body)
24
26
  path_listing.each do |path|
25
- if path['name'] =~ /\.xml$/
26
- File.open(File.join(folder, path['name']), 'w') do |f|
27
- raw_url = URI.parse(path['download_url'])
28
- f.write(Net::HTTP.get_response(raw_url).body)
29
- end
27
+ next unless path['name'] =~ /\.xml$/
28
+
29
+ File.open(File.join(folder, path['name']), 'w') do |f|
30
+ raw_url = URI.parse(path['download_url'])
31
+ f.write(Net::HTTP.get_response(raw_url).body)
30
32
  end
31
33
  end
32
34
  end
33
-
34
35
  end
35
36
  end
36
37
  end
37
-
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sources
2
4
  module CLDR
3
5
  # Auxiliary Subdivision class to support loading Unicode CLDR data to update local files
4
6
  class Subdivision
5
7
  attr_reader :xml, :language_code
8
+
6
9
  def initialize(language_code:, xml:)
7
10
  @language_code = language_code
8
11
  @xml = xml
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support'
2
4
  require 'active_support/core_ext/hash/deep_merge'
3
5
  require 'nokogiri'
@@ -9,25 +11,29 @@ module Sources
9
11
  class SubdivisionUpdater
10
12
  def call
11
13
  d = Dir['./tmp/cldr/trunk/common/subdivisions/*.xml']
12
- loader = Sources::Local::CachedLoader.new(Sources::Local::Subdivision)
13
- d.each do |file_path|
14
- language_data = Nokogiri::XML(File.read(file_path))
15
- language_code = File.basename(file_path, '.*')
16
- subdivisions = language_data.css('subdivision')
17
- next if subdivisions.empty?
18
- last_country_code_seen = nil
14
+ @loader = Sources::Local::CachedLoader.new(Sources::Local::Subdivision)
15
+ d.each { |file_path| update_locale(file_path) }
16
+ end
17
+
18
+ def update_locale(file_path)
19
+ language_data = Nokogiri::XML(File.read(file_path))
20
+ language_code = File.basename(file_path, '.*')
21
+ subdivisions = language_data.css('subdivision')
22
+ next if subdivisions.empty?
23
+
24
+ last_country_code_seen = nil
19
25
 
20
- subdivisions.each_with_index do |subdivision, index|
21
- subdivision = Sources::CLDR::Subdivision.new(language_code: language_code, xml: subdivision)
22
- data = loader.load(subdivision.country_code)
23
- data[subdivision.code] ||= {}
24
- data[subdivision.code] = data[subdivision.code].deep_merge(subdivision.to_h)
25
- if (last_country_code_seen && last_country_code_seen != subdivision.country_code) || index == subdivisions.size - 1
26
- puts "Updated #{subdivision.country_code} with language_code #{language_code}"
27
- loader.save(subdivision.country_code, data)
28
- end
29
- last_country_code_seen = subdivision.country_code
26
+ subdivisions.each_with_index do |subdivision, index|
27
+ subdivision = Sources::CLDR::Subdivision.new(language_code: language_code, xml: subdivision)
28
+ data = @loader.load(subdivision.country_code)
29
+ data[subdivision.code] ||= {}
30
+ data[subdivision.code] = data[subdivision.code].deep_merge(subdivision.to_h)
31
+ if (last_country_code_seen && last_country_code_seen != subdivision.country_code) ||
32
+ index == subdivisions.size - 1
33
+ puts "Updated #{subdivision.country_code} with language_code #{language_code}"
34
+ @loader.save(subdivision.country_code, data)
30
35
  end
36
+ last_country_code_seen = subdivision.country_code
31
37
  end
32
38
  end
33
39
  end
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sources
2
4
  # Support code to allow updating subdivision data from the Unicode CLDR repository
3
5
  module Local
4
6
  # Loader for locally-cached data, to allow merging Unicode CLDR data with existing local data
5
7
  class CachedLoader
6
8
  attr_reader :klass
9
+
7
10
  def initialize(klass)
8
11
  @klass = klass
9
12
  @loaded_countries = {}
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sources
2
4
  module Local
3
5
  # Auxiliary Subdivision class to support loading the local subdivision data to be updated with Unicode CLDR data
4
6
  class Subdivision
5
7
  attr_reader :code
8
+
6
9
  def initialize(code)
7
10
  @code = code
8
11
  end
@@ -16,8 +19,8 @@ module Sources
16
19
  end
17
20
 
18
21
  def save(data)
19
- File.open(file_path, 'w') { |f| f.write data.to_yaml }
20
- rescue
22
+ File.write(file_path, data.to_yaml)
23
+ rescue StandardError
21
24
  puts "failed to read #{file}: #{$ERROR_INFO}"
22
25
  end
23
26