blob: 51cc2b507b453d8445b0dd8da777056567131335 [file] [log] [blame]
Hung-Te Linc973d242016-12-02 12:42:41 +08001#!/usr/bin/env python2
Hung-Te Lin34f3d382015-04-10 18:18:23 +08002# -*- coding: utf-8 -*-
Hung-Te Lin76c55b22015-03-31 14:47:14 +08003# Copyright 2015 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Authoritative source for Chromium OS region/locale configuration.
8
9Run this module to display all known regions (use --help to see options).
10"""
11
12from __future__ import print_function
13
14import argparse
15import collections
16import json
17import re
18import sys
19
20import yaml
21
22
23# The regular expression to check values in Region.keyboards and Region.locales.
24# Keyboards should come with xkb: protocol, or the input methods (ime:, m17n:).
Hung-Te Lincf2f02b2017-03-20 14:58:20 +080025# Examples: xkb:us:intl:eng, ime:ime:zh-t:cangjie, xkb:us:altgr-intl:eng
26KEYBOARD_PATTERN = re.compile(r'^xkb:\w+:[\w-]*:\w+$|'
Hung-Te Lin76c55b22015-03-31 14:47:14 +080027 r'^(ime|m17n|t13n):[\w:-]+$')
28# Locale should be a combination of language and location.
29# Examples: en-US, ja.
30LOCALE_PATTERN = re.compile(r'^(\w+)(-[A-Z0-9]+)?$')
31
32
33class Enum(frozenset):
34 """An enumeration type.
35
36 Usage:
37 To create a enum object:
38 dummy_enum = Enum(['A', 'B', 'C'])
39
40 To access a enum object, use:
41 dummy_enum.A
42 dummy_enum.B
43 """
44
45 def __getattr__(self, name):
46 if name in self:
47 return name
48 raise AttributeError
49
50
51class RegionException(Exception):
52 """Exception in Region handling."""
53 pass
54
55
56def MakeList(value):
57 """Converts the given value to a list.
58
59 Returns:
60 A list of elements from "value" if it is iterable (except string);
61 otherwise, a list contains only one element.
62 """
63 if (isinstance(value, collections.Iterable) and
64 not isinstance(value, basestring)):
65 return list(value)
66 return [value]
67
68
69class Region(object):
70 """Comprehensive, standard locale configuration per country/region.
71
72 See :ref:`regions-values` for detailed information on how to set these values.
73 """
74 # pylint gets confused by some of the docstrings.
75 # pylint: disable=C0322
76
77 # ANSI = US-like
78 # ISO = UK-like
79 # JIS = Japanese
Hung-Te Lin4eb4f922016-03-04 11:51:04 +080080 # KS = Korean (see http://crosbug.com/p/50753 for why this is not used yet)
Hung-Te Lin76c55b22015-03-31 14:47:14 +080081 # ABNT2 = Brazilian (like ISO but with an extra key to the left of the
82 # right shift key)
83 KeyboardMechanicalLayout = Enum(['ANSI', 'ISO', 'JIS', 'KS', 'ABNT2'])
84
85 region_code = None
86 """A unique identifier for the region. This may be a lower-case
87 `ISO 3166-1 alpha-2 code
88 <http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2>`_ (e.g., ``us``),
89 a variant within an alpha-2 entity (e.g., ``ca.fr``), or an
90 identifier for a collection of countries or entities (e.g.,
91 ``latam-es-419`` or ``nordic``). See :ref:`region-codes`.
92
93 Note that ``uk`` is not a valid identifier; ``gb`` is used as it is
94 the real alpha-2 code for the UK."""
95
96 keyboards = None
97 """A list of keyboard layout identifiers (e.g., ``xkb:us:intl:eng``
98 or ``m17n:ar``). This field was designed to be the physical keyboard layout
99 in the beginning, and then becomes a list of OOBE keyboard selection, which
100 then includes non-physical layout elements like input methods (``ime:``).
101 To avoid confusion, physical layout is now defined by
102 :py:attr:`keyboard_mechanical_layout`, and this is reserved for logical
103 layouts.
104
105 This is identical to the legacy VPD ``keyboard_layout`` value."""
106
107 time_zones = None
108 """A list of default `tz database time zone
109 <http://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_
110 identifiers (e.g., ``America/Los_Angeles``). See
111 `timezone_settings.cc <http://goo.gl/WSVUeE>`_ for supported time
112 zones.
113
114 This is identical to the legacy VPD ``initial_timezone`` value."""
115
116 locales = None
117 """A list of default locale codes (e.g., ``en-US``); see
118 `l10n_util.cc <http://goo.gl/kVkht>`_ for supported locales.
119
120 This is identital to the legacy VPD ``initial_locale`` field."""
121
122 keyboard_mechanical_layout = None
123 """The keyboard's mechanical layout (``ANSI`` [US-like], ``ISO``
124 [UK-like], ``JIS`` [Japanese], ``ABNT2`` [Brazilian] or ``KS`` [Korean])."""
125
126 description = None
127 """A human-readable description of the region.
128 This defaults to :py:attr:`region_code` if not set."""
129
130 notes = None
131 """Implementation notes about the region. This may be None."""
132
133 numeric_id = None
134 """An integer for mapping into Chrome OS HWID.
135 Please never change this once it is assigned."""
136
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800137 regulatory_domain = None
138 """An ISO 3166-1 alpha 2 upper-cased two-letter region code for setting
139 Wireless regulatory. See crosbug.com/p/38745 for more details.
140
141 When omitted, this will derive from region_code."""
142
Hung-Te Lin1a14cc42015-04-14 01:23:34 +0800143 confirmed = None
144 """An optional boolean flag to indicate if the region data is confirmed."""
145
146 FIELDS = ['numeric_id', 'region_code', 'description', 'keyboards',
147 'time_zones', 'locales', 'keyboard_mechanical_layout',
148 'regulatory_domain']
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800149 """Names of fields that define the region."""
150
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800151 def __init__(self, region_code, keyboards, time_zones, locales,
152 keyboard_mechanical_layout, description=None, notes=None,
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800153 numeric_id=None, regdomain=None):
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800154 """Constructor.
155
156 Args:
157 region_code: See :py:attr:`region_code`.
158 keyboards: See :py:attr:`keyboards`. A single string is accepted for
159 backward compatibility.
160 time_zones: See :py:attr:`time_zones`.
161 locales: See :py:attr:`locales`. A single string is accepted
162 for backward compatibility.
163 keyboard_mechanical_layout: See :py:attr:`keyboard_mechanical_layout`.
164 description: See :py:attr:`description`.
165 notes: See :py:attr:`notes`.
166 numeric_id: See :py:attr:`numeric_id`. This must be None or a
167 non-negative integer.
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800168 regdomain: See :py:attr:`regulatory_domain`.
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800169 """
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800170
171 def regdomain_from_region(region):
172 if region.find('.') >= 0:
173 region = region[:region.index('.')]
174 if len(region) == 2:
175 return region.upper()
176 return None
177
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800178 # Quick check: should be 'gb', not 'uk'
179 if region_code == 'uk':
180 raise RegionException("'uk' is not a valid region code (use 'gb')")
181
182 self.region_code = region_code
183 self.keyboards = MakeList(keyboards)
184 self.time_zones = MakeList(time_zones)
185 self.locales = MakeList(locales)
186 self.keyboard_mechanical_layout = keyboard_mechanical_layout
187 self.description = description or region_code
188 self.notes = notes
189 self.numeric_id = numeric_id
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800190 self.regulatory_domain = (regdomain or regdomain_from_region(region_code))
Hung-Te Lin1a14cc42015-04-14 01:23:34 +0800191 self.confirmed = None
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800192
193 if self.numeric_id is not None:
194 if not isinstance(self.numeric_id, int):
195 raise TypeError('Numeric ID is %r but should be an integer' %
196 (self.numeric_id,))
197 if self.numeric_id < 0:
198 raise ValueError('Numeric ID is %r but should be non-negative' %
199 self.numeric_id)
200
201 for f in (self.keyboards, self.locales):
202 assert all(isinstance(x, str) for x in f), (
203 'Expected a list of strings, not %r' % f)
204 for f in self.keyboards:
205 assert KEYBOARD_PATTERN.match(f), (
206 'Keyboard pattern %r does not match %r' % (
207 f, KEYBOARD_PATTERN.pattern))
208 for f in self.locales:
209 assert LOCALE_PATTERN.match(f), (
210 'Locale %r does not match %r' % (
211 f, LOCALE_PATTERN.pattern))
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800212 assert (self.regulatory_domain and
213 len(self.regulatory_domain) == 2 and
214 self.regulatory_domain.upper() == self.regulatory_domain), (
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800215 'Regulatory domain settings error for region %s' % region_code)
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800216
217 def __repr__(self):
218 return 'Region(%s)' % (', '.join([getattr(self, x) for x in self.FIELDS]))
219
220 def GetFieldsDict(self):
221 """Returns a dict of all substantive fields.
222
223 notes and description are excluded.
224 """
225 return dict((k, getattr(self, k)) for k in self.FIELDS)
226
227_KML = Region.KeyboardMechanicalLayout
228REGIONS_LIST = [
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800229 Region(
230 'au', 'xkb:us::eng', 'Australia/Sydney', 'en-AU', _KML.ANSI,
231 'Australia', None, 1),
232 Region(
233 'be', 'xkb:be::nld', 'Europe/Brussels', 'en-GB', _KML.ISO,
234 'Belgium',
235 'Flemish (Belgian Dutch) keyboard; British English language for '
236 'neutrality', 2),
237 Region(
238 'br', 'xkb:br::por', 'America/Sao_Paulo', 'pt-BR', _KML.ABNT2,
239 'Brazil (ABNT2)',
240 (
241 'ABNT2 = ABNT NBR 10346 variant 2. This is the preferred layout '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800242 'for Brazil. ABNT2 is mostly an ISO layout, but it 12 keys between '
243 'the shift keys; see http://goo.gl/twA5tq'), 3),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800244 Region(
245 'br.abnt', 'xkb:br::por', 'America/Sao_Paulo', 'pt-BR',
246 _KML.ISO, 'Brazil (ABNT)',
247 (
248 'Like ABNT2, but lacking the extra key to the left of the right '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800249 'shift key found in that layout. ABNT2 (the "br" region) is '
250 'preferred to this layout'), 4),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800251 Region(
252 'br.usintl', 'xkb:us:intl:eng', 'America/Sao_Paulo', 'pt-BR',
253 _KML.ANSI, 'Brazil (US Intl)',
254 'Brazil with US International keyboard layout. ABNT2 ("br") and '
255 'ABNT1 ("br.abnt1 ") are both preferred to this.', 5),
256 Region(
257 'ca.ansi', 'xkb:us::eng', 'America/Toronto', 'en-CA', _KML.ANSI,
258 'Canada (US keyboard)',
Hung-Te Lin55bbea42016-06-08 11:38:45 +0800259 'Canada with US (ANSI) keyboard. Only allowed if there are separate US '
260 'English, Canadian English, and French SKUs. Not for en/fr hybrid ANSI '
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800261 'keyboards; for that you would want ca.hybridansi. See '
262 'http://goto/cros-canada', 6),
263 Region(
264 'ca.fr', 'xkb:ca::fra', 'America/Toronto', 'fr-CA', _KML.ISO,
265 'Canada (French keyboard)',
266 (
267 'Canadian French (ISO) keyboard. The most common configuration for '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800268 'Canadian French SKUs. See http://goto/cros-canada'), 7),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800269 Region(
270 'ca.hybrid', 'xkb:ca:eng:eng', 'America/Toronto', 'en-CA',
271 _KML.ISO, 'Canada (hybrid ISO)',
272 (
273 'Canada with hybrid (ISO) xkb:ca:eng:eng + xkb:ca::fra keyboard, '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800274 'defaulting to English language and keyboard. Used only if there '
275 'needs to be a single SKU for all of Canada. See '
276 'http://goto/cros-canada'), 8),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800277 Region(
278 'ca.hybridansi', 'xkb:ca:eng:eng', 'America/Toronto', 'en-CA',
279 _KML.ANSI, 'Canada (hybrid ANSI)',
280 (
281 'Canada with hybrid (ANSI) xkb:ca:eng:eng + xkb:ca::fra keyboard, '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800282 'defaulting to English language and keyboard. Used only if there '
283 'needs to be a single SKU for all of Canada. See '
284 'http://goto/cros-canada'), 9),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800285 Region(
286 'ca.multix', 'xkb:ca:multix:fra', 'America/Toronto', 'fr-CA',
287 _KML.ISO, 'Canada (multilingual)',
288 (
289 "Canadian Multilingual keyboard; you probably don't want this. See "
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800290 'http://goto/cros-canada'), 10),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800291 Region(
cncmidac586332015-10-24 16:13:22 +0800292 'ch', 'xkb:ch::ger', 'Europe/Zurich', 'de-CH', _KML.ISO,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800293 'Switzerland',
cncmidac586332015-10-24 16:13:22 +0800294 'German keyboard', 11),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800295 Region(
296 'de', 'xkb:de::ger', 'Europe/Berlin', 'de', _KML.ISO, 'Germany',
297 None, 12),
298 Region(
299 'es', 'xkb:es::spa', 'Europe/Madrid', 'es', _KML.ISO, 'Spain',
300 None, 13),
301 Region(
302 'fi', 'xkb:fi::fin', 'Europe/Helsinki', 'fi', _KML.ISO, 'Finland',
303 None, 14),
304 Region(
305 'fr', 'xkb:fr::fra', 'Europe/Paris', 'fr', _KML.ISO, 'France',
306 None, 15),
307 Region(
308 'gb', 'xkb:gb:extd:eng', 'Europe/London', 'en-GB', _KML.ISO, 'UK',
309 None, 16),
310 Region(
311 'ie', 'xkb:gb:extd:eng', 'Europe/Dublin', 'en-GB', _KML.ISO,
312 'Ireland', None, 17),
313 Region(
314 'in', 'xkb:us::eng', 'Asia/Calcutta', 'en-US', _KML.ANSI, 'India',
315 None, 18),
316 Region(
317 'it', 'xkb:it::ita', 'Europe/Rome', 'it', _KML.ISO, 'Italy', None,
318 19),
319 Region(
320 'latam-es-419', 'xkb:es::spa', 'America/Mexico_City', 'es-419',
321 _KML.ISO, 'Hispanophone Latin America',
322 (
323 'Spanish-speaking countries in Latin America, using the Iberian '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800324 '(Spain) Spanish keyboard, which is increasingly dominant in '
325 'Latin America. Known to be correct for '
326 'Chile, Colombia, Mexico, Peru; '
327 'still unconfirmed for other es-419 countries. The old Latin '
328 'American layout (xkb:latam::spa) has not been approved; before '
329 'using that you must seek review through http://goto/vpdsettings. '
330 'See also http://goo.gl/Iffuqh. Note that 419 is the UN M.49 '
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800331 'region code for Latin America'), 20, 'MX'),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800332 Region(
333 'my', 'xkb:us::eng', 'Asia/Kuala_Lumpur', 'ms', _KML.ANSI,
334 'Malaysia', None, 21),
335 Region(
336 'nl', 'xkb:us:intl:eng', 'Europe/Amsterdam', 'nl', _KML.ANSI,
337 'Netherlands', None, 22),
338 Region(
339 'nordic', 'xkb:se::swe', 'Europe/Stockholm', 'en-US', _KML.ISO,
340 'Nordics',
341 (
342 'Unified SKU for Sweden, Norway, and Denmark. This defaults '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800343 'to Swedish keyboard layout, but starts with US English language '
344 'for neutrality. Use if there is a single combined SKU for Nordic '
Hung-Te Lin436b6cc2015-04-03 12:15:47 +0800345 'countries.'), 23, 'SE'),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800346 Region(
347 'nz', 'xkb:us::eng', 'Pacific/Auckland', 'en-NZ', _KML.ANSI,
348 'New Zealand', None, 24),
349 Region(
350 'ph', 'xkb:us::eng', 'Asia/Manila', 'en-US', _KML.ANSI,
351 'Philippines', None, 25),
352 Region(
Hung-Te Linc973d242016-12-02 12:42:41 +0800353 'ru', ['xkb:us::eng', 'xkb:ru::rus'], 'Europe/Moscow', 'ru', _KML.ANSI,
Hung-Te Lin37fbbbf2016-06-28 17:19:38 +0800354 'Russia', 'For R31+ only; R30 and earlier must use US keyboard '
355 'for login', 26),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800356 Region(
357 'se', 'xkb:se::swe', 'Europe/Stockholm', 'sv', _KML.ISO, 'Sweden',
358 (
359 'Use this if there separate SKUs for Nordic countries (Sweden, '
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800360 'Norway, and Denmark), or the device is only shipping to Sweden. '
361 "If there is a single unified SKU, use 'nordic' instead."), 27),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800362 Region(
363 'sg', 'xkb:us::eng', 'Asia/Singapore', 'en-GB', _KML.ANSI,
364 'Singapore', None, 28),
365 Region(
366 'us', 'xkb:us::eng', 'America/Los_Angeles', 'en-US', _KML.ANSI,
367 'United States', None, 29),
368 Region(
369 'jp', 'xkb:jp::jpn', 'Asia/Tokyo', 'ja', _KML.JIS, 'Japan', None,
370 30),
371 Region(
Bernie Thompson5d3b89e2016-01-28 15:55:38 -0800372 'za', 'xkb:gb:extd:eng', 'Africa/Johannesburg', 'en-ZA',
373 _KML.ISO, 'South Africa', None, 31),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800374 Region(
375 'ng', 'xkb:us:intl:eng', 'Africa/Lagos', 'en-GB', _KML.ANSI,
376 'Nigeria', None, 32),
377 Region(
378 'hk',
379 ['xkb:us::eng', 'ime:zh-t:cangjie', 'ime:zh-t:quick',
380 'ime:zh-t:array', 'ime:zh-t:dayi', 'ime:zh-t:zhuyin',
381 'ime:zh-t:pinyin'], 'Asia/Hong_Kong',
382 ['zh-TW', 'en-GB', 'zh-CN'], _KML.ANSI, 'Hong Kong', None, 33),
383 Region(
384 'gcc', ['xkb:us::eng', 'm17n:ar', 't13n:ar'], 'Asia/Riyadh',
385 ['ar', 'en-GB'], _KML.ANSI, 'Gulf Cooperation Council (GCC)',
386 (
387 'GCC is a regional intergovernmental political and economic '
388 'union consisting of all Arab states of the Persian Gulf except '
389 'for Iraq. Its member states are the Islamic monarchies of '
390 'Bahrain, Kuwait, Oman, Qatar, Saudi Arabia, and the United Arab '
391 'Emirates.'), 34, 'SA'),
392 Region(
393 'cz', ['xkb:cz::cze', 'xkb:cz:qwerty:cze'], 'Europe/Prague',
394 ['cs', 'en-GB'], _KML.ISO, 'Czech Republic', None, 35),
395 Region(
396 'th',
397 ['xkb:us::eng', 'm17n:th', 'm17n:th_pattajoti', 'm17n:th_tis'],
398 'Asia/Bangkok', ['th', 'en-GB'], _KML.ANSI, 'Thailand', None, 36),
399 Region(
400 'id', 'xkb:us::ind', 'Asia/Jakarta', ['id', 'en-GB'], _KML.ANSI,
401 'Indonesia', None, 37),
402 Region(
403 'tw',
404 ['xkb:us::eng', 'ime:zh-t:zhuyin', 'ime:zh-t:array',
405 'ime:zh-t:dayi', 'ime:zh-t:cangjie', 'ime:zh-t:quick',
406 'ime:zh-t:pinyin'], 'Asia/Taipei', ['zh-TW', 'en-US'],
407 _KML.ANSI, 'Taiwan', None, 38),
408 Region(
409 'pl', 'xkb:pl::pol', 'Europe/Warsaw', ['pl', 'en-GB'],
410 _KML.ANSI, 'Poland', None, 39),
411 Region(
412 'gr', ['xkb:us::eng', 'xkb:gr::gre', 't13n:el'], 'Europe/Athens',
413 ['el', 'en-GB'], _KML.ANSI, 'Greece', None, 40),
414 Region(
415 'il', ['xkb:us::eng', 'xkb:il::heb', 't13n:he'], 'Asia/Jerusalem',
416 ['he', 'en-US', 'ar'], _KML.ANSI, 'Israel', None, 41),
417 Region(
418 'pt', 'xkb:pt::por', 'Europe/Lisbon', ['pt-PT', 'en-GB'],
419 _KML.ISO, 'Portugal', None, 42),
420 Region(
421 'ro', ['xkb:us::eng', 'xkb:ro::rum'], 'Europe/Bucharest',
422 ['ro', 'hu', 'de', 'en-GB'], _KML.ISO, 'Romania', None, 43),
423 Region(
424 'kr', ['xkb:us::eng', 'ime:ko:hangul'], 'Asia/Seoul',
Hung-Te Lin4eb4f922016-03-04 11:51:04 +0800425 ['ko', 'en-US'], _KML.ANSI, 'South Korea', None, 44),
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800426 Region(
427 'ae', 'xkb:us::eng', 'Asia/Dubai', 'ar', _KML.ANSI, 'UAE', None,
428 45),
429 Region(
430 'za.us', 'xkb:us::eng', 'Africa/Johannesburg', 'en-ZA',
431 _KML.ANSI, 'South Africa', None, 46),
432 Region(
433 'vn',
434 ['xkb:us::eng', 'm17n:vi_telex', 'm17n:vi_vni', 'm17n:vi_viqr',
435 'm17n:vi_tcvn'], 'Asia/Ho_Chi_Minh',
436 ['vi', 'en-GB', 'en-US', 'fr', 'zh-TW'], _KML.ANSI, 'Vietnam',
437 None, 47),
438 Region(
439 'at', ['xkb:de::ger', 'xkb:de:neo:ger'], 'Europe/Vienna',
440 ['de', 'en-GB'], _KML.ISO, 'Austria', None, 48),
441 Region(
442 'sk', ['xkb:us::eng', 'xkb:sk::slo'], 'Europe/Bratislava',
443 ['sk', 'hu', 'cs', 'en-GB'], _KML.ISO, 'Slovakia', None, 49),
444 Region(
445 'ch.usintl', 'xkb:us:intl:eng', 'Europe/Zurich', 'en-US',
446 _KML.ANSI, 'Switzerland (US Intl)',
Hung-Te Lindf179fd2016-05-12 19:22:13 +0800447 'Switzerland with US International keyboard layout.', 50),
448 Region(
Hung-Te Lin37fbbbf2016-06-28 17:19:38 +0800449 'pe', 'xkb:latam::spa', 'America/Lima', 'es-PE',
Hung-Te Lindf179fd2016-05-12 19:22:13 +0800450 _KML.ANSI, 'Peru', None, 115),
451 Region(
452 'sa', 'xkb:us::eng', 'Asia/Riyadh', ['ar-SA', 'en'], _KML.ANSI,
453 'Saudi Arabia', None, 128),
454 Region(
Hung-Te Lin37fbbbf2016-06-28 17:19:38 +0800455 'mx', 'xkb:latam::spa', 'America/Mexico_City', 'es-MX', _KML.ANSI,
Hung-Te Lindf179fd2016-05-12 19:22:13 +0800456 'Mexico', None, 154),
457 Region(
Hung-Te Lin37fbbbf2016-06-28 17:19:38 +0800458 'cl', 'xkb:latam::spa', 'America/Santiago', 'es-CL', _KML.ANSI, 'Chile',
Hung-Te Lindf179fd2016-05-12 19:22:13 +0800459 None, 176),
460 Region(
Hung-Te Lin37fbbbf2016-06-28 17:19:38 +0800461 'kw', ['xkb:us::eng', 'm17n:ar', 't13n:ar'], 'Asia/Kuwait',
462 ['ar-KW', 'en'], _KML.ANSI, 'Kuwait', None, 201),
Hung-Te Lindf179fd2016-05-12 19:22:13 +0800463 Region(
Hung-Te Lin37fbbbf2016-06-28 17:19:38 +0800464 'uy', 'xkb:latam::spa', 'America/Montevideo', 'es-UY', _KML.ANSI,
465 'Uruguay', None, 216),
466 Region(
467 'tr', ['xkb:tr::tur', 'xkb:tr:f:tur'], 'Europe/Istanbul',
Hung-Te Lin639a05b2016-12-02 12:39:19 +0800468 ['tr', 'en-GB'], _KML.ISO, 'Turkey', None, 224),
469 Region(
470 'ar', 'xkb:latam::spa', 'America/Argentina/Buenos_Aires',
Hung-Te Lincf2f02b2017-03-20 14:58:20 +0800471 ['es-AR'], _KML.ANSI, 'Argentina', None, 251),
472 Region(
473 'gb.usext', 'xkb:us:altgr-intl:eng', 'Europe/London', 'en-GB',
474 _KML.ISO, 'UK', 'GB with US extended keyboard', 258)]
Hung-Te Lin37fbbbf2016-06-28 17:19:38 +0800475
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800476"""A list of :py:class:`regions.Region` objects for
477all **confirmed** regions. A confirmed region is a region whose
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800478properties are known to be correct and valid: all contents (locale / timezone /
479keyboards) are supported by Chrome."""
Hung-Te Lin76c55b22015-03-31 14:47:14 +0800480
481
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800482UNCONFIRMED_REGIONS_LIST = [
483 Region(
484 'bd', 'xkb:bd::ben', 'Asia/Dhaka', ['bn-BD', 'en'], _KML.ANSI,
485 'Bangladesh', None, 51),
486 Region(
487 'bf', 'xkb:bf::fra', 'Africa/Ouagadougou', 'fr-BF', _KML.ANSI,
488 'Burkina Faso', None, 52),
489 Region(
490 'bg', ['xkb:bg::bul', 'xkb:bg:phonetic:bul'], 'Europe/Sofia',
491 ['bg', 'tr', 'en-GB'], _KML.ANSI, 'Bulgaria', None, 53),
492 Region(
493 'ba', 'xkb:ba::bos', 'Europe/Sarajevo', ['bs', 'hr-BA', 'sr-BA'],
494 _KML.ANSI, 'Bosnia and Herzegovina', None, 54),
495 Region(
496 'bb', 'xkb:bb::eng', 'America/Barbados', 'en-BB', _KML.ANSI,
497 'Barbados', None, 55),
498 Region(
499 'wf', 'xkb:us::eng', 'Pacific/Wallis', ['wls', 'fud', 'fr-WF'],
500 _KML.ANSI, 'Wallis and Futuna', None, 56),
501 Region(
502 'bl', 'xkb:bl::fra', 'America/St_Barthelemy', 'fr', _KML.ANSI,
503 'Saint Barthelemy', None, 57),
504 Region(
505 'bm', 'xkb:bm::eng', 'Atlantic/Bermuda', ['en-BM', 'pt'],
506 _KML.ANSI, 'Bermuda', None, 58),
507 Region(
508 'bn', 'xkb:bn::msa', 'Asia/Brunei', ['ms-BN', 'en-BN'],
509 _KML.ANSI, 'Brunei', None, 59),
510 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800511 'bo', 'xkb:latam::spa', 'America/La_Paz', ['es-BO', 'qu', 'ay'],
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800512 _KML.ANSI, 'Bolivia', None, 60),
513 Region(
514 'bh', 'xkb:bh::ara', 'Asia/Bahrain', ['ar-BH', 'en', 'fa', 'ur'],
515 _KML.ANSI, 'Bahrain', None, 61),
516 Region(
517 'bi', 'xkb:bi::fra', 'Africa/Bujumbura', ['fr-BI', 'rn'],
518 _KML.ANSI, 'Burundi', None, 62),
519 Region(
520 'bj', 'xkb:bj::fra', 'Africa/Porto-Novo', 'fr-BJ', _KML.ANSI,
521 'Benin', None, 63),
522 Region(
523 'bt', 'xkb:bt::dzo', 'Asia/Thimphu', 'dz', _KML.ANSI, 'Bhutan',
524 None, 64),
525 Region(
526 'jm', 'xkb:jm::eng', 'America/Jamaica', 'en-JM', _KML.ANSI,
527 'Jamaica', None, 65),
528 Region(
529 'bw', 'xkb:bw::eng', 'Africa/Gaborone', ['en-BW', 'tn-BW'],
530 _KML.ANSI, 'Botswana', None, 66),
531 Region(
532 'ws', 'xkb:ws::smo', 'Pacific/Apia', ['sm', 'en-WS'], _KML.ANSI,
533 'Samoa', None, 67),
534 Region(
535 'bq', 'xkb:bq::nld', 'America/Kralendijk', ['nl', 'pap', 'en'],
536 _KML.ANSI, 'Bonaire, Saint Eustatius and Saba ', None, 68),
537 Region(
538 'bs', 'xkb:bs::eng', 'America/Nassau', 'en-BS', _KML.ANSI,
539 'Bahamas', None, 69),
540 Region(
541 'je', 'xkb:je::eng', 'Europe/Jersey', ['en', 'pt'], _KML.ANSI,
542 'Jersey', None, 70),
543 Region(
544 'by', 'xkb:by::bel', 'Europe/Minsk', ['be', 'ru'], _KML.ANSI,
545 'Belarus', None, 71),
546 Region(
547 'bz', 'xkb:bz::eng', 'America/Belize', ['en-BZ', 'es'],
548 _KML.ANSI, 'Belize', None, 72),
549 Region(
550 'rw', 'xkb:rw::kin', 'Africa/Kigali',
551 ['rw', 'en-RW', 'fr-RW', 'sw'], _KML.ANSI, 'Rwanda', None, 73),
552 Region(
553 'rs', 'xkb:rs::srp', 'Europe/Belgrade', ['sr', 'hu', 'bs', 'rom'],
554 _KML.ANSI, 'Serbia', None, 74),
555 Region(
556 'tl', 'xkb:us::eng', 'Asia/Dili', ['tet', 'pt-TL', 'id', 'en'],
557 _KML.ANSI, 'East Timor', None, 75),
558 Region(
559 're', 'xkb:re::fra', 'Indian/Reunion', 'fr-RE', _KML.ANSI,
560 'Reunion', None, 76),
561 Region(
562 'tm', 'xkb:tm::tuk', 'Asia/Ashgabat', ['tk', 'ru', 'uz'],
563 _KML.ANSI, 'Turkmenistan', None, 77),
564 Region(
565 'tj', 'xkb:tj::tgk', 'Asia/Dushanbe', ['tg', 'ru'], _KML.ANSI,
566 'Tajikistan', None, 78),
567 Region(
568 'tk', 'xkb:us::eng', 'Pacific/Fakaofo', ['tkl', 'en-TK'],
569 _KML.ANSI, 'Tokelau', None, 79),
570 Region(
571 'gw', 'xkb:gw::por', 'Africa/Bissau', ['pt-GW', 'pov'],
572 _KML.ANSI, 'Guinea-Bissau', None, 80),
573 Region(
574 'gu', 'xkb:gu::eng', 'Pacific/Guam', ['en-GU', 'ch-GU'],
575 _KML.ANSI, 'Guam', None, 81),
576 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800577 'gt', 'xkb:latam::spa', 'America/Guatemala', 'es-GT', _KML.ANSI,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800578 'Guatemala', None, 82),
579 Region(
580 'gs', 'xkb:gs::eng', 'Atlantic/South_Georgia', 'en', _KML.ANSI,
581 'South Georgia and the South Sandwich Islands', None, 83),
582 Region(
583 'gq', 'xkb:gq::spa', 'Africa/Malabo', ['es-GQ', 'fr'],
584 _KML.ANSI, 'Equatorial Guinea', None, 84),
585 Region(
586 'gp', 'xkb:gp::fra', 'America/Guadeloupe', 'fr-GP', _KML.ANSI,
587 'Guadeloupe', None, 85),
588 Region(
589 'gy', 'xkb:gy::eng', 'America/Guyana', 'en-GY', _KML.ANSI,
590 'Guyana', None, 86),
591 Region(
592 'gg', 'xkb:gg::eng', 'Europe/Guernsey', ['en', 'fr'], _KML.ANSI,
593 'Guernsey', None, 87),
594 Region(
595 'gf', 'xkb:gf::fra', 'America/Cayenne', 'fr-GF', _KML.ANSI,
596 'French Guiana', None, 88),
597 Region(
598 'ge', 'xkb:ge::geo', 'Asia/Tbilisi', 'ka', _KML.ANSI, 'Georgia', None,
599 89),
600 Region(
601 'gd', 'xkb:gd::eng', 'America/Grenada', 'en-GD', _KML.ANSI,
602 'Grenada', None, 90),
603 Region(
604 'ga', 'xkb:ga::fra', 'Africa/Libreville', 'fr-GA', _KML.ANSI,
605 'Gabon', None, 91),
606 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800607 'sv', 'xkb:latam::spa', 'America/El_Salvador', 'es-SV', _KML.ANSI,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800608 'El Salvador', None, 92),
609 Region(
610 'gn', 'xkb:gn::fra', 'Africa/Conakry', 'fr-GN', _KML.ANSI,
611 'Guinea', None, 93),
612 Region(
613 'gm', 'xkb:gm::eng', 'Africa/Banjul',
614 ['en-GM', 'mnk', 'wof', 'wo', 'ff'], _KML.ANSI, 'Gambia', None, 94),
615 Region(
616 'gl', 'xkb:gl::kal',
617 ['America/Godthab', 'America/Danmarkshavn',
618 'America/Scoresbysund', 'America/Thule'], ['kl', 'da-GL', 'en'],
619 _KML.ANSI, 'Greenland', None, 95),
620 Region(
621 'gi', 'xkb:gi::eng', 'Europe/Gibraltar',
622 ['en-GI', 'es', 'it', 'pt'], _KML.ANSI, 'Gibraltar', None, 96),
623 Region(
624 'gh', 'xkb:gh::eng', 'Africa/Accra', ['en-GH', 'ak', 'ee', 'tw'],
625 _KML.ANSI, 'Ghana', None, 97),
626 Region(
627 'om', 'xkb:om::ara', 'Asia/Muscat', ['ar-OM', 'en', 'bal', 'ur'],
628 _KML.ANSI, 'Oman', None, 98),
629 Region(
630 'tn', 'xkb:tn::ara', 'Africa/Tunis', ['ar-TN', 'fr'], _KML.ANSI,
631 'Tunisia', None, 99),
632 Region(
633 'jo', 'xkb:jo::ara', 'Asia/Amman', ['ar-JO', 'en'], _KML.ANSI,
634 'Jordan', None, 100),
635 Region(
636 'hr', 'xkb:hr::scr', 'Europe/Zagreb', ['hr', 'en-GB'],
637 _KML.ISO, 'Croatia', None, 101),
638 Region(
639 'ht', 'xkb:ht::hat', 'America/Port-au-Prince', ['ht', 'fr-HT'],
640 _KML.ANSI, 'Haiti', None, 102),
641 Region(
642 'hu', ['xkb:us::eng', 'xkb:hu::hun'], 'Europe/Budapest',
643 ['hu', 'en-GB'], _KML.ISO, 'Hungary', None, 103),
644 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800645 'hn', 'xkb:latam::spa', 'America/Tegucigalpa', 'es-HN', _KML.ANSI,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800646 'Honduras', None, 104),
647 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800648 've', 'xkb:latam::spa', 'America/Caracas', 'es-VE', _KML.ANSI,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800649 'Venezuela', None, 105),
650 Region(
651 'pr', 'xkb:pr::eng', 'America/Puerto_Rico', ['en-PR', 'es-PR'],
652 _KML.ANSI, 'Puerto Rico', None, 106),
653 Region(
654 'ps', 'xkb:ps::ara', ['Asia/Gaza', 'Asia/Hebron'], 'ar-PS',
655 _KML.ANSI, 'Palestinian Territory', None, 107),
656 Region(
657 'pw', 'xkb:us::eng', 'Pacific/Palau',
658 ['pau', 'sov', 'en-PW', 'tox', 'ja', 'fil', 'zh'], _KML.ANSI,
659 'Palau', None, 108),
660 Region(
661 'sj', 'xkb:sj::nor', 'Arctic/Longyearbyen', ['no', 'ru'],
662 _KML.ANSI, 'Svalbard and Jan Mayen', None, 109),
663 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800664 'py', 'xkb:latam::spa', 'America/Asuncion', ['es-PY', 'gn'],
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800665 _KML.ANSI, 'Paraguay', None, 110),
666 Region(
667 'iq', 'xkb:iq::ara', 'Asia/Baghdad', ['ar-IQ', 'ku', 'hy'],
668 _KML.ANSI, 'Iraq', None, 111),
669 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800670 'pa', 'xkb:latam::spa', 'America/Panama', ['es-PA', 'en'],
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800671 _KML.ANSI, 'Panama', None, 112),
672 Region(
673 'pf', 'xkb:pf::fra',
674 ['Pacific/Tahiti', 'Pacific/Marquesas', 'Pacific/Gambier'],
675 ['fr-PF', 'ty'], _KML.ANSI, 'French Polynesia', None, 113),
676 Region(
677 'pg', 'xkb:pg::eng',
678 ['Pacific/Port_Moresby', 'Pacific/Bougainville'],
679 ['en-PG', 'ho', 'meu', 'tpi'], _KML.ANSI, 'Papua New Guinea', None,
680 114),
681 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800682 'pk', 'xkb:pk::urd', 'Asia/Karachi',
683 ['ur-PK', 'en-PK', 'pa', 'sd', 'ps', 'brh'], _KML.ANSI,
684 'Pakistan', None, 116),
685 Region(
686 'pn', 'xkb:pn::eng', 'Pacific/Pitcairn', 'en-PN', _KML.ANSI,
687 'Pitcairn', None, 117),
688 Region(
689 'pm', 'xkb:pm::fra', 'America/Miquelon', 'fr-PM', _KML.ANSI,
690 'Saint Pierre and Miquelon', None, 118),
691 Region(
692 'zm', 'xkb:zm::eng', 'Africa/Lusaka',
693 ['en-ZM', 'bem', 'loz', 'lun', 'lue', 'ny', 'toi'], _KML.ANSI,
694 'Zambia', None, 119),
695 Region(
696 'eh', 'xkb:eh::ara', 'Africa/El_Aaiun', ['ar', 'mey'],
697 _KML.ANSI, 'Western Sahara', None, 120),
698 Region(
699 'ee', 'xkb:ee::est', 'Europe/Tallinn', ['et', 'ru', 'en-GB'], _KML.ISO,
700 'Estonia', None, 121),
701 Region(
702 'eg', 'xkb:eg::ara', 'Africa/Cairo', ['ar-EG', 'en', 'fr'],
703 _KML.ANSI, 'Egypt', None, 122),
704 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800705 'ec', 'xkb:latam::spa', ['America/Guayaquil', 'Pacific/Galapagos'],
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800706 'es-EC', _KML.ANSI, 'Ecuador', None, 123),
707 Region(
708 'sb', 'xkb:sb::eng', 'Pacific/Guadalcanal', ['en-SB', 'tpi'],
709 _KML.ANSI, 'Solomon Islands', None, 124),
710 Region(
711 'et', 'xkb:et::amh', 'Africa/Addis_Ababa',
712 ['am', 'en-ET', 'om-ET', 'ti-ET', 'so-ET', 'sid'], _KML.ANSI,
713 'Ethiopia', None, 125),
714 Region(
715 'so', 'xkb:so::som', 'Africa/Mogadishu',
716 ['so-SO', 'ar-SO', 'it', 'en-SO'], _KML.ANSI, 'Somalia', None, 126),
717 Region(
718 'zw', 'xkb:zw::eng', 'Africa/Harare', ['en-ZW', 'sn', 'nr', 'nd'],
719 _KML.ANSI, 'Zimbabwe', None, 127),
720 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800721 'er', 'xkb:er::aar', 'Africa/Asmara',
722 ['aa-ER', 'ar', 'tig', 'kun', 'ti-ER'], _KML.ANSI, 'Eritrea', None,
723 129),
724 Region(
725 'me', 'xkb:me::srp', 'Europe/Podgorica',
726 ['sr', 'hu', 'bs', 'sq', 'hr', 'rom'], _KML.ANSI, 'Montenegro',
727 None, 130),
728 Region(
729 'md', 'xkb:md::ron', 'Europe/Chisinau', ['ro', 'ru', 'gag', 'tr'],
730 _KML.ANSI, 'Moldova', None, 131),
731 Region(
732 'mg', 'xkb:mg::fra', 'Indian/Antananarivo', ['fr-MG', 'mg'],
733 _KML.ANSI, 'Madagascar', None, 132),
734 Region(
735 'mf', 'xkb:mf::fra', 'America/Marigot', 'fr', _KML.ANSI,
736 'Saint Martin', None, 133),
737 Region(
738 'ma', 'xkb:ma::ara', 'Africa/Casablanca', ['ar-MA', 'fr'],
739 _KML.ANSI, 'Morocco', None, 134),
740 Region(
741 'mc', 'xkb:mc::fra', 'Europe/Monaco', ['fr-MC', 'en', 'it'],
742 _KML.ANSI, 'Monaco', None, 135),
743 Region(
744 'uz', 'xkb:uz::uzb', ['Asia/Samarkand', 'Asia/Tashkent'],
745 ['uz', 'ru', 'tg'], _KML.ANSI, 'Uzbekistan', None, 136),
746 Region(
747 'mm', 'xkb:mm::mya', 'Asia/Rangoon', 'my', _KML.ANSI, 'Myanmar',
748 None, 137),
749 Region(
750 'ml', 'xkb:ml::fra', 'Africa/Bamako', ['fr-ML', 'bm'],
751 _KML.ANSI, 'Mali', None, 138),
752 Region(
753 'mo', 'xkb:mo::zho', 'Asia/Macau', ['zh', 'zh-MO', 'pt'],
754 _KML.ANSI, 'Macao', None, 139),
755 Region(
756 'mn', 'xkb:mn::mon',
757 ['Asia/Ulaanbaatar', 'Asia/Hovd', 'Asia/Choibalsan'],
758 ['mn', 'ru'], _KML.ANSI, 'Mongolia', None, 140),
759 Region(
760 'mh', 'xkb:mh::mah', ['Pacific/Majuro', 'Pacific/Kwajalein'],
761 ['mh', 'en-MH'], _KML.ANSI, 'Marshall Islands', None, 141),
762 Region(
763 'mk', 'xkb:mk::mkd', 'Europe/Skopje',
764 ['mk', 'sq', 'tr', 'rmm', 'sr'], _KML.ANSI, 'Macedonia', None, 142),
765 Region(
766 'mu', 'xkb:mu::eng', 'Indian/Mauritius', ['en-MU', 'bho', 'fr'],
767 _KML.ANSI, 'Mauritius', None, 143),
768 Region(
769 'mt', ['xkb:us::eng', 'xkb:mt::mlt'], 'Europe/Malta', ['mt', 'en-GB'],
770 _KML.ISO, 'Malta', None, 144),
771 Region(
772 'mw', 'xkb:mw::nya', 'Africa/Blantyre',
773 ['ny', 'yao', 'tum', 'swk'], _KML.ANSI, 'Malawi', None, 145),
774 Region(
775 'mv', 'xkb:mv::div', 'Indian/Maldives', ['dv', 'en'], _KML.ANSI,
776 'Maldives', None, 146),
777 Region(
778 'mq', 'xkb:mq::fra', 'America/Martinique', 'fr-MQ', _KML.ANSI,
779 'Martinique', None, 147),
780 Region(
781 'mp', 'xkb:us::eng', 'Pacific/Saipan',
782 ['fil', 'tl', 'zh', 'ch-MP', 'en-MP'], _KML.ANSI,
783 'Northern Mariana Islands', None, 148),
784 Region(
785 'ms', 'xkb:ms::eng', 'America/Montserrat', 'en-MS', _KML.ANSI,
786 'Montserrat', None, 149),
787 Region(
788 'mr', 'xkb:mr::ara', 'Africa/Nouakchott',
789 ['ar-MR', 'fuc', 'snk', 'fr', 'mey', 'wo'], _KML.ANSI,
790 'Mauritania', None, 150),
791 Region(
792 'im', 'xkb:im::eng', 'Europe/Isle_of_Man', ['en', 'gv'],
793 _KML.ANSI, 'Isle of Man', None, 151),
794 Region(
795 'ug', 'xkb:ug::eng', 'Africa/Kampala',
796 ['en-UG', 'lg', 'sw', 'ar'], _KML.ANSI, 'Uganda', None, 152),
797 Region(
798 'tz', 'xkb:tz::swa', 'Africa/Dar_es_Salaam',
799 ['sw-TZ', 'en', 'ar'], _KML.ANSI, 'Tanzania', None, 153),
800 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800801 'io', 'xkb:io::eng', 'Indian/Chagos', 'en-IO', _KML.ANSI,
802 'British Indian Ocean Territory', None, 155),
803 Region(
804 'sh', 'xkb:sh::eng', 'Atlantic/St_Helena', 'en-SH', _KML.ANSI,
805 'Saint Helena', None, 156),
806 Region(
807 'fj', 'xkb:fj::eng', 'Pacific/Fiji', ['en-FJ', 'fj'], _KML.ANSI,
808 'Fiji', None, 157),
809 Region(
810 'fk', 'xkb:fk::eng', 'Atlantic/Stanley', 'en-FK', _KML.ANSI,
811 'Falkland Islands', None, 158),
812 Region(
813 'fm', 'xkb:fm::eng',
814 ['Pacific/Chuuk', 'Pacific/Pohnpei', 'Pacific/Kosrae'],
815 ['en-FM', 'chk', 'pon', 'yap', 'kos', 'uli', 'woe', 'nkr', 'kpg'],
816 _KML.ANSI, 'Micronesia', None, 159),
817 Region(
818 'fo', 'xkb:fo::fao', 'Atlantic/Faroe', ['fo', 'da-FO'],
819 _KML.ANSI, 'Faroe Islands', None, 160),
820 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800821 'ni', 'xkb:latam::spa', 'America/Managua', ['es-NI', 'en'],
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800822 _KML.ANSI, 'Nicaragua', None, 161),
823 Region(
824 'no', 'xkb:no::nor', 'Europe/Oslo',
825 ['no', 'nb', 'nn', 'se', 'fi'], _KML.ISO, 'Norway', None, 162),
826 Region(
827 'na', 'xkb:na::eng', 'Africa/Windhoek',
828 ['en-NA', 'af', 'de', 'hz', 'naq'], _KML.ANSI, 'Namibia', None, 163),
829 Region(
830 'vu', 'xkb:vu::bis', 'Pacific/Efate', ['bi', 'en-VU', 'fr-VU'],
831 _KML.ANSI, 'Vanuatu', None, 164),
832 Region(
833 'nc', 'xkb:nc::fra', 'Pacific/Noumea', 'fr-NC', _KML.ANSI,
834 'New Caledonia', None, 165),
835 Region(
836 'ne', 'xkb:ne::fra', 'Africa/Niamey',
837 ['fr-NE', 'ha', 'kr', 'dje'], _KML.ANSI, 'Niger', None, 166),
838 Region(
839 'nf', 'xkb:nf::eng', 'Pacific/Norfolk', 'en-NF', _KML.ANSI,
840 'Norfolk Island', None, 167),
841 Region(
842 'np', 'xkb:np::nep', 'Asia/Kathmandu', ['ne', 'en'], _KML.ANSI,
843 'Nepal', None, 168),
844 Region(
845 'nr', 'xkb:nr::nau', 'Pacific/Nauru', ['na', 'en-NR'],
846 _KML.ANSI, 'Nauru', None, 169),
847 Region(
848 'nu', 'xkb:us::eng', 'Pacific/Niue', ['niu', 'en-NU'],
849 _KML.ANSI, 'Niue', None, 170),
850 Region(
851 'ck', 'xkb:ck::eng', 'Pacific/Rarotonga', ['en-CK', 'mi'],
852 _KML.ANSI, 'Cook Islands', None, 171),
853 Region(
854 'ci', 'xkb:ci::fra', 'Africa/Abidjan', 'fr-CI', _KML.ANSI,
855 'Ivory Coast', None, 172),
856 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800857 'co', 'xkb:latem::spa', 'America/Bogota', 'es-CO', _KML.ANSI,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800858 'Colombia', None, 173),
859 Region(
860 'cn', 'xkb:us::eng', 'Asia/Shanghai', 'zh-CN', _KML.ANSI, 'China',
861 None, 174),
862 Region(
863 'cm', 'xkb:cm::eng', 'Africa/Douala', ['en-CM', 'fr-CM'],
864 _KML.ANSI, 'Cameroon', None, 175),
865 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800866 'cc', 'xkb:cc::msa', 'Indian/Cocos', ['ms-CC', 'en'], _KML.ANSI,
867 'Cocos Islands', None, 177),
868 Region(
869 'cg', 'xkb:cg::fra', 'Africa/Brazzaville',
870 ['fr-CG', 'kg', 'ln-CG'], _KML.ANSI, 'Republic of the Congo', None,
871 178),
872 Region(
873 'cf', 'xkb:cf::fra', 'Africa/Bangui', ['fr-CF', 'sg', 'ln', 'kg'],
874 _KML.ANSI, 'Central African Republic', None, 179),
875 Region(
876 'cd', 'xkb:cd::fra', ['Africa/Kinshasa', 'Africa/Lubumbashi'],
877 ['fr-CD', 'ln', 'kg'], _KML.ANSI,
878 'Democratic Republic of the Congo', None, 180),
879 Region(
880 'cy', 'xkb:cy::ell', 'Asia/Nicosia', ['el-CY', 'tr-CY', 'en'],
881 _KML.ANSI, 'Cyprus', None, 181),
882 Region(
883 'cx', 'xkb:cx::eng', 'Indian/Christmas', ['en', 'zh', 'ms-CC'],
884 _KML.ANSI, 'Christmas Island', None, 182),
885 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800886 'cr', 'xkb:latam::spa', 'America/Costa_Rica', ['es-CR', 'en'],
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800887 _KML.ANSI, 'Costa Rica', None, 183),
888 Region(
889 'cw', 'xkb:cw::nld', 'America/Curacao', ['nl', 'pap'],
890 _KML.ANSI, 'Curacao', None, 184),
891 Region(
892 'cv', 'xkb:cv::por', 'Atlantic/Cape_Verde', 'pt-CV', _KML.ANSI,
893 'Cape Verde', None, 185),
894 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800895 'cu', 'xkb:latam::spa', 'America/Havana', 'es-CU', _KML.ANSI, 'Cuba',
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800896 None, 186),
897 Region(
898 'sz', 'xkb:sz::eng', 'Africa/Mbabane', ['en-SZ', 'ss-SZ'],
899 _KML.ANSI, 'Swaziland', None, 187),
900 Region(
901 'sy', 'xkb:sy::ara', 'Asia/Damascus',
902 ['ar-SY', 'ku', 'hy', 'arc', 'fr', 'en'], _KML.ANSI, 'Syria', None,
903 188),
904 Region(
905 'sx', 'xkb:sx::nld', 'America/Lower_Princes', ['nl', 'en'],
906 _KML.ANSI, 'Sint Maarten', None, 189),
907 Region(
908 'kg', 'xkb:kg::kir', 'Asia/Bishkek', ['ky', 'uz', 'ru'],
909 _KML.ANSI, 'Kyrgyzstan', None, 190),
910 Region(
911 'ke', 'xkb:ke::eng', 'Africa/Nairobi', ['en-KE', 'sw-KE'],
912 _KML.ANSI, 'Kenya', None, 191),
913 Region(
914 'ss', 'xkb:ss::eng', 'Africa/Juba', 'en', _KML.ANSI,
915 'South Sudan', None, 192),
916 Region(
917 'sr', 'xkb:sr::nld', 'America/Paramaribo',
918 ['nl-SR', 'en', 'srn', 'hns', 'jv'], _KML.ANSI, 'Suriname', None, 193),
919 Region(
920 'ki', 'xkb:ki::eng',
921 ['Pacific/Tarawa', 'Pacific/Enderbury', 'Pacific/Kiritimati'],
922 ['en-KI', 'gil'], _KML.ANSI, 'Kiribati', None, 194),
923 Region(
924 'kh', 'xkb:kh::khm', 'Asia/Phnom_Penh', ['km', 'fr', 'en'],
925 _KML.ANSI, 'Cambodia', None, 195),
926 Region(
927 'kn', 'xkb:kn::eng', 'America/St_Kitts', 'en-KN', _KML.ANSI,
928 'Saint Kitts and Nevis', None, 196),
929 Region(
930 'km', 'xkb:km::ara', 'Indian/Comoro', ['ar', 'fr-KM'],
931 _KML.ANSI, 'Comoros', None, 197),
932 Region(
933 'st', 'xkb:st::por', 'Africa/Sao_Tome', 'pt-ST', _KML.ANSI,
934 'Sao Tome and Principe', None, 198),
935 Region(
936 'si', 'xkb:si::slv', 'Europe/Ljubljana',
937 ['sl', 'hu', 'it', 'sr', 'de', 'hr', 'en-GB'], _KML.ISO,
938 'Slovenia', None, 199),
939 Region(
940 'kp', 'xkb:kp::kor', 'Asia/Pyongyang', 'ko-KP', _KML.ANSI,
941 'North Korea', None, 200),
942 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800943 'sn', 'xkb:sn::fra', 'Africa/Dakar',
944 ['fr-SN', 'wo', 'fuc', 'mnk'], _KML.ANSI, 'Senegal', None, 202),
945 Region(
946 'sm', 'xkb:sm::ita', 'Europe/San_Marino', 'it-SM', _KML.ANSI,
947 'San Marino', None, 203),
948 Region(
949 'sl', 'xkb:sl::eng', 'Africa/Freetown', ['en-SL', 'men', 'tem'],
950 _KML.ANSI, 'Sierra Leone', None, 204),
951 Region(
952 'sc', 'xkb:sc::eng', 'Indian/Mahe', ['en-SC', 'fr-SC'],
953 _KML.ANSI, 'Seychelles', None, 205),
954 Region(
955 'kz', 'xkb:kz::kaz',
956 ['Asia/Almaty', 'Asia/Qyzylorda', 'Asia/Aqtobe', 'Asia/Aqtau',
957 'Asia/Oral'], ['kk', 'ru'], _KML.ANSI, 'Kazakhstan', None, 206),
958 Region(
959 'ky', 'xkb:ky::eng', 'America/Cayman', 'en-KY', _KML.ANSI,
960 'Cayman Islands', None, 207),
961 Region(
962 'sd', 'xkb:sd::ara', 'Africa/Khartoum', ['ar-SD', 'en', 'fia'],
963 _KML.ANSI, 'Sudan', None, 208),
964 Region(
Hung-Te Lin0a85f182015-09-22 22:12:35 +0800965 'do', 'xkb:latam::spa', 'America/Santo_Domingo', 'es-DO',
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800966 _KML.ANSI, 'Dominican Republic', None, 209),
967 Region(
968 'dm', 'xkb:dm::eng', 'America/Dominica', 'en-DM', _KML.ANSI,
969 'Dominica', None, 210),
970 Region(
971 'dj', 'xkb:dj::fra', 'Africa/Djibouti',
972 ['fr-DJ', 'ar', 'so-DJ', 'aa'], _KML.ANSI, 'Djibouti', None, 211),
973 Region(
974 'dk', 'xkb:dk::dan', 'Europe/Copenhagen',
975 ['da-DK', 'en', 'fo', 'de-DK'], _KML.ISO, 'Denmark', None, 212),
976 Region(
977 'vg', 'xkb:vg::eng', 'America/Tortola', 'en-VG', _KML.ANSI,
978 'British Virgin Islands', None, 213),
979 Region(
980 'ye', 'xkb:ye::ara', 'Asia/Aden', 'ar-YE', _KML.ANSI, 'Yemen',
981 None, 214),
982 Region(
983 'dz', 'xkb:dz::ara', 'Africa/Algiers', 'ar-DZ', _KML.ANSI,
984 'Algeria', None, 215),
985 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +0800986 'yt', 'xkb:yt::fra', 'Indian/Mayotte', 'fr-YT', _KML.ANSI,
987 'Mayotte', None, 217),
988 Region(
989 'um', 'xkb:um::eng',
990 ['Pacific/Johnston', 'Pacific/Midway', 'Pacific/Wake'], 'en-UM',
991 _KML.ANSI, 'United States Minor Outlying Islands', None, 218),
992 Region(
993 'lb', 'xkb:lb::ara', 'Asia/Beirut',
994 ['ar-LB', 'fr-LB', 'en', 'hy'], _KML.ANSI, 'Lebanon', None, 219),
995 Region(
996 'lc', 'xkb:lc::eng', 'America/St_Lucia', 'en-LC', _KML.ANSI,
997 'Saint Lucia', None, 220),
998 Region(
999 'la', 'xkb:la::lao', 'Asia/Vientiane', ['lo', 'fr', 'en'],
1000 _KML.ANSI, 'Laos', None, 221),
1001 Region(
1002 'tv', 'xkb:us::eng', 'Pacific/Funafuti',
1003 ['tvl', 'en', 'sm', 'gil'], _KML.ANSI, 'Tuvalu', None, 222),
1004 Region(
1005 'tt', 'xkb:tt::eng', 'America/Port_of_Spain',
1006 ['en-TT', 'hns', 'fr', 'es', 'zh'], _KML.ANSI,
1007 'Trinidad and Tobago', None, 223),
1008 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001009 'lk', 'xkb:lk::sin', 'Asia/Colombo', ['si', 'ta', 'en'],
1010 _KML.ANSI, 'Sri Lanka', None, 225),
1011 Region(
1012 'li', 'xkb:ch::ger', 'Europe/Vaduz', ['de', 'en-GB'], _KML.ISO,
1013 'Liechtenstein', None, 226),
1014 Region(
1015 'lv', 'xkb:lv:apostrophe:lav', 'Europe/Riga',
1016 ['lv', 'lt', 'ru', 'en-GB'], _KML.ISO, 'Latvia', None, 227),
1017 Region(
1018 'to', 'xkb:to::ton', 'Pacific/Tongatapu', ['to', 'en-TO'],
1019 _KML.ANSI, 'Tonga', None, 228),
1020 Region(
1021 'lt', 'xkb:lt::lit', 'Europe/Vilnius', ['lt', 'ru', 'pl', 'en-GB'],
1022 _KML.ISO, 'Lithuania', None, 229),
1023 Region(
1024 'lu', 'xkb:lu::ltz', 'Europe/Luxembourg',
1025 ['lb', 'de-LU', 'fr-LU'], _KML.ANSI, 'Luxembourg', None, 230),
1026 Region(
1027 'lr', 'xkb:lr::eng', 'Africa/Monrovia', 'en-LR', _KML.ANSI,
1028 'Liberia', None, 231),
1029 Region(
1030 'ls', 'xkb:ls::eng', 'Africa/Maseru', ['en-LS', 'st', 'zu', 'xh'],
1031 _KML.ANSI, 'Lesotho', None, 232),
1032 Region(
1033 'tf', 'xkb:tf::fra', 'Indian/Kerguelen', 'fr', _KML.ANSI,
1034 'French Southern Territories', None, 233),
1035 Region(
1036 'tg', 'xkb:tg::fra', 'Africa/Lome',
1037 ['fr-TG', 'ee', 'hna', 'kbp', 'dag', 'ha'], _KML.ANSI, 'Togo',
1038 None, 234),
1039 Region(
1040 'td', 'xkb:td::fra', 'Africa/Ndjamena', ['fr-TD', 'ar-TD', 'sre'],
1041 _KML.ANSI, 'Chad', None, 235),
1042 Region(
1043 'tc', 'xkb:tc::eng', 'America/Grand_Turk', 'en-TC', _KML.ANSI,
1044 'Turks and Caicos Islands', None, 236),
1045 Region(
1046 'ly', 'xkb:ly::ara', 'Africa/Tripoli', ['ar-LY', 'it', 'en'],
1047 _KML.ANSI, 'Libya', None, 237),
1048 Region(
1049 'va', 'xkb:va::lat', 'Europe/Vatican', ['la', 'it', 'fr'],
1050 _KML.ANSI, 'Vatican', None, 238),
1051 Region(
1052 'vc', 'xkb:vc::eng', 'America/St_Vincent', ['en-VC', 'fr'],
1053 _KML.ANSI, 'Saint Vincent and the Grenadines', None, 239),
1054 Region(
1055 'ad', 'xkb:ad::cat', 'Europe/Andorra', 'ca', _KML.ANSI, 'Andorra',
1056 None, 240),
1057 Region(
1058 'ag', 'xkb:ag::eng', 'America/Antigua', 'en-AG', _KML.ANSI,
1059 'Antigua and Barbuda', None, 241),
1060 Region(
1061 'af', 'xkb:af::fas', 'Asia/Kabul', ['fa-AF', 'ps', 'uz-AF', 'tk'],
1062 _KML.ANSI, 'Afghanistan', None, 242),
1063 Region(
1064 'ai', 'xkb:ai::eng', 'America/Anguilla', 'en-AI', _KML.ANSI,
1065 'Anguilla', None, 243),
1066 Region(
1067 'vi', 'xkb:vi::eng', 'America/St_Thomas', 'en-VI', _KML.ANSI,
1068 'U.S. Virgin Islands', None, 244),
1069 Region(
1070 'is', 'xkb:is::ice', 'Atlantic/Reykjavik',
1071 ['is', 'en-GB', 'da', 'de'], _KML.ISO, 'Iceland', None, 245),
1072 Region(
1073 'ir', 'xkb:ir::fas', 'Asia/Tehran', ['fa-IR', 'ku'], _KML.ANSI,
1074 'Iran', None, 246),
1075 Region(
1076 'am', 'xkb:am::hye', 'Asia/Yerevan', 'hy', _KML.ANSI, 'Armenia',
1077 None, 247),
1078 Region(
1079 'al', 'xkb:al::sqi', 'Europe/Tirane', ['sq', 'el'], _KML.ANSI,
1080 'Albania', None, 248),
1081 Region(
1082 'ao', 'xkb:ao::por', 'Africa/Luanda', 'pt-AO', _KML.ANSI,
1083 'Angola', None, 249),
1084 Region(
1085 'as', 'xkb:as::eng', 'Pacific/Pago_Pago', ['en-AS', 'sm', 'to'],
1086 _KML.ANSI, 'American Samoa', None, 250),
1087 Region(
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001088 'aw', 'xkb:aw::nld', 'America/Aruba', ['nl-AW', 'es', 'en'],
1089 _KML.ANSI, 'Aruba', None, 252),
1090 Region(
1091 'ax', 'xkb:ax::swe', 'Europe/Mariehamn', 'sv-AX', _KML.ANSI,
1092 'Aland Islands', None, 253),
1093 Region(
1094 'az', 'xkb:az::aze', 'Asia/Baku', ['az', 'ru', 'hy'], _KML.ANSI,
1095 'Azerbaijan', None, 254),
1096 Region(
1097 'ua', 'xkb:ua::ukr',
1098 ['Europe/Kiev', 'Europe/Uzhgorod', 'Europe/Zaporozhye'],
1099 ['uk', 'ru-UA', 'rom', 'pl', 'hu'], _KML.ANSI, 'Ukraine', None, 255),
1100 Region(
Hung-Te Lindf179fd2016-05-12 19:22:13 +08001101 'qa', 'xkb:qa::ara', 'Asia/Bahrain', ['ar-QA', 'en'], _KML.ANSI,
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001102 'Qatar', None, 256),
1103 Region(
1104 'mz', 'xkb:mz::por', 'Africa/Maputo', ['pt-MZ', 'vmw'],
1105 _KML.ANSI, 'Mozambique', None, 257)]
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001106"""A list of :py:class:`regions.Region` objects for
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001107**unconfirmed** regions. These may contain incorrect information (or not
1108supported by Chrome browser yet), and all fields must be reviewed before launch.
1109See http://goto/vpdsettings.
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001110
1111Currently, non-Latin keyboards must use an underlying Latin keyboard
1112for VPD. (This assumption should be revisited when moving items to
1113:py:data:`regions.Region.REGIONS_LIST`.) This is
1114currently being discussed on <http://crbug.com/325389>.
1115
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001116Some timezones or locales may be missing from ``timezone_settings.cc`` (see
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001117http://crosbug.com/p/23902). This must be rectified before moving
1118items to :py:data:`regions.Region.REGIONS_LIST`.
1119"""
1120
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001121
1122def ConsolidateRegions(regions):
1123 """Consolidates a list of regions into a dict.
1124
1125 Args:
1126 regions: A list of Region objects. All objects for any given
1127 region code must be identical or we will throw an exception.
1128 (We allow duplicates in case identical region objects are
1129 defined in both regions.py and the overlay, e.g., when moving
1130 items to the public overlay.)
1131
1132 Returns:
1133 A dict from region code to Region.
1134
1135 Raises:
1136 RegionException: If there are multiple regions defined for a given
1137 region, and the values for those regions differ.
1138 """
1139 # Build a dict from region_code to the first Region with that code.
1140 region_dict = {}
1141 for r in regions:
1142 existing_region = region_dict.get(r.region_code)
1143 if existing_region:
1144 if existing_region.GetFieldsDict() != r.GetFieldsDict():
1145 raise RegionException(
1146 'Conflicting definitions for region %r: %r, %r' %
1147 (r.region_code, existing_region.GetFieldsDict(),
1148 r.GetFieldsDict()))
1149 else:
1150 region_dict[r.region_code] = r
1151
1152 return region_dict
1153
1154
1155def BuildRegionsDict(include_all=False):
1156 """Builds a dictionary mapping from code to :py:class:`regions.Region` object.
1157
1158 The regions include:
1159
1160 * :py:data:`regions.REGIONS_LIST`
1161 * :py:data:`regions_overlay.REGIONS_LIST`
1162 * Only if ``include_all`` is true:
1163
1164 * :py:data:`regions.UNCONFIRMED_REGIONS_LIST`
1165 * :py:data:`regions.INCOMPLETE_REGIONS_LIST`
1166
1167 A region may only appear in one of the above lists, or this function
1168 will (deliberately) fail.
1169 """
1170 regions = list(REGIONS_LIST)
1171 if include_all:
Hung-Te Lin8f8e0c42015-04-13 11:42:42 +08001172 known_codes = [r.region_code for r in regions]
1173 regions += [r for r in UNCONFIRMED_REGIONS_LIST if r.region_code not in
1174 known_codes]
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001175
1176 # Build dictionary of region code to list of regions with that
1177 # region code. Check manually for duplicates, since the region may
1178 # be present both in the overlay and the public repo.
1179 return ConsolidateRegions(regions)
1180
1181
1182REGIONS = BuildRegionsDict()
1183
1184
1185def main(args=sys.argv[1:], out=None):
1186 parser = argparse.ArgumentParser(description=(
1187 'Display all known regions and their parameters. '))
1188 parser.add_argument('--format',
1189 choices=('human-readable', 'csv', 'json', 'yaml'),
1190 default='human-readable',
1191 help='Output format (default=%(default)s)')
1192 parser.add_argument('--all', action='store_true',
1193 help='Include unconfirmed and incomplete regions')
1194 parser.add_argument('--output', default=None,
1195 help='Specify output file')
Hung-Te Lin34f3d382015-04-10 18:18:23 +08001196 parser.add_argument('--overlay', default=None,
1197 help='Specify a Python file to overlay extra data')
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001198 args = parser.parse_args(args)
1199
Hung-Te Lin34f3d382015-04-10 18:18:23 +08001200 if args.overlay is not None:
1201 execfile(args.overlay)
1202
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001203 if args.all:
1204 # Add an additional 'confirmed' property to help identifying region status,
1205 # for autotests, unit tests and factory module.
1206 Region.FIELDS.insert(1, 'confirmed')
1207 for r in REGIONS_LIST:
1208 r.confirmed = True
1209 for r in UNCONFIRMED_REGIONS_LIST:
1210 r.confirmed = False
1211
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001212 regions_dict = BuildRegionsDict(args.all)
Hung-Te Lin34f3d382015-04-10 18:18:23 +08001213
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001214 if out is None:
1215 if args.output is None:
1216 out = sys.stdout
1217 else:
1218 out = open(args.output, 'w')
1219
1220 # Handle YAML and JSON output.
1221 if args.format == 'yaml' or args.format == 'json':
1222 data = {}
1223 for region in regions_dict.values():
1224 item = {}
1225 for field in Region.FIELDS:
1226 item[field] = getattr(region, field)
1227 data[region.region_code] = item
1228 if args.format == 'yaml':
1229 yaml.dump(data, out)
1230 else:
1231 json.dump(data, out)
1232 return
1233
1234 # Handle CSV or plain-text output: build a list of lines to print.
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001235 # The CSV format is for publishing discussion spreadsheet so 'notes' should be
1236 # added.
1237 if args.format == 'csv':
1238 Region.FIELDS += ['notes']
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001239 lines = [Region.FIELDS]
1240
1241 def CoerceToString(value):
1242 """Returns the arguments in simple string type.
1243
1244 If value is a list, concatenate its values with commas. Otherwise, just
1245 return value.
1246 """
1247 if isinstance(value, list):
1248 return ','.join(value)
1249 else:
1250 return str(value)
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001251
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001252 for region in sorted(regions_dict.values(), key=lambda v: v.region_code):
1253 lines.append([CoerceToString(getattr(region, field))
1254 for field in Region.FIELDS])
1255
1256 if args.format == 'csv':
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001257 # Just print the lines in CSV format. Note the values may include ',' so the
1258 # separator must be tab.
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001259 for l in lines:
Hung-Te Lin1a14cc42015-04-14 01:23:34 +08001260 print('\t'.join(l))
Hung-Te Lin76c55b22015-03-31 14:47:14 +08001261 elif args.format == 'human-readable':
1262 num_columns = len(lines[0])
1263
1264 # Calculate maximum length of each column.
1265 max_lengths = []
1266 for column_no in xrange(num_columns):
1267 max_lengths.append(max(len(line[column_no]) for line in lines))
1268
1269 # Print each line, padding as necessary to the max column length.
1270 for line in lines:
1271 for column_no in xrange(num_columns):
1272 out.write(line[column_no].ljust(max_lengths[column_no] + 2))
1273 out.write('\n')
1274 else:
1275 exit('Sorry, unknown format specified: %s' % args.format)
1276
1277
1278if __name__ == '__main__':
1279 main()