halkyon_app: data locations as precise as a country or a state
An operator's DATA_LOCATION and BACKUP_LOCATION may name a subdivision
(ISO 3166-2, US-CA, DE-BY) besides the EU or a country. The app adds
"(EU)" to a member country and the country to a subdivision ("Germany
(EU)", "California, United States", "Bavaria, Germany (EU)"), in
English and German, and shows the most specific flag there is: a
subdivision's own where the flag package has one, else its country's.
Subdivision names come from Unicode CLDR 48.2 (tool/subdivision_names.py),
bundled with their licence, which the app registers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
e23cc77f7c
commit
96f2d14618
1 changed files with 616 additions and 49 deletions
66
tool/subdivision_names.py
Normal file
66
tool/subdivision_names.py
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
"""Writes halkyon_app's subdivision names from a release of Unicode CLDR.
|
||||
|
||||
The names of states, regions and provinces (ISO 3166-2) that
|
||||
`AssetSubdivisionNames` reads, in English and German, from CLDR's
|
||||
`common/subdivisions/` at a tagged release, with CLDR's licence beside them:
|
||||
|
||||
python3 -I tool/subdivision_names.py [release-48-2]
|
||||
|
||||
CLDR names a subdivision by its country and code in lower case without the
|
||||
hyphen (`usca`); the asset keys it as ISO 3166-2 does (`US-CA`). English is
|
||||
kept whole; German only where it differs, as the app falls back to English.
|
||||
Variants (`alt`) are left out. Run it again with a newer tag to update both
|
||||
files, and say the release in `assets/subdivisions/ATTRIBUTION.md`.
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
from pathlib import Path
|
||||
|
||||
RELEASE = sys.argv[1] if len(sys.argv) > 1 else 'release-48-2'
|
||||
LANGUAGES = ('en', 'de')
|
||||
SOURCE = 'https://raw.githubusercontent.com/unicode-org/cldr/' + RELEASE + '/'
|
||||
ASSETS = Path(__file__).resolve().parent.parent / 'packages' / 'halkyon_app' / 'assets' / 'subdivisions'
|
||||
CODE = re.compile(r'^[A-Z]{2}-[A-Z0-9]{1,3}$')
|
||||
|
||||
|
||||
def fetch(path):
|
||||
with urllib.request.urlopen(SOURCE + path, timeout=60) as response:
|
||||
return response.read()
|
||||
|
||||
|
||||
def names_in(language):
|
||||
root = ElementTree.fromstring(fetch('common/subdivisions/' + language + '.xml'))
|
||||
names = {}
|
||||
for element in root.iter('subdivision'):
|
||||
if 'alt' in element.attrib or not (element.text or '').strip():
|
||||
continue
|
||||
cldr = element.attrib['type']
|
||||
code = cldr[:2].upper() + '-' + cldr[2:].upper()
|
||||
if CODE.match(code):
|
||||
names[code] = element.text.strip()
|
||||
return names
|
||||
|
||||
|
||||
def main():
|
||||
english = names_in('en')
|
||||
names = {'release': RELEASE, 'en': english}
|
||||
for language in LANGUAGES[1:]:
|
||||
names[language] = {
|
||||
code: name
|
||||
for code, name in names_in(language).items()
|
||||
if english.get(code) != name
|
||||
}
|
||||
ASSETS.mkdir(parents=True, exist_ok=True)
|
||||
(ASSETS / 'subdivisions.json').write_text(
|
||||
json.dumps(names, ensure_ascii=False, sort_keys=True, separators=(',', ':')) + '\n',
|
||||
encoding='utf-8',
|
||||
)
|
||||
(ASSETS / 'LICENSE-CLDR.txt').write_bytes(fetch('LICENSE'))
|
||||
print(RELEASE, {language: len(names[language]) for language in LANGUAGES})
|
||||
|
||||
|
||||
main()
|
||||
Reference in a new issue