| #!/usr/bin/env python3 | |
| """Region database generator from public documents.""" | |
| from __future__ import print_function | |
| import pycountry | |
| # Load existing database. | |
| import regions | |
| def LoadZoneTable(): | |
| # zone.tab from http://www.iana.org/time-zones | |
| zones = {} | |
| with open("zone.tab") as f: | |
| for line in f: | |
| if line.startswith("#"): | |
| continue | |
| # format: code coordinates TZ comments | |
| code, unused, tz = line.split("\t")[0:3] | |
| if code not in zones: | |
| zones[code] = [] | |
| zones[code] += [tz.strip()] | |
| return zones | |
| def LoadCountryTable(tzinfo): | |
| # http://download.geonames.org/export/dump/countryInfo.txt | |
| new_regions = {} | |
| skip_regions = ( | |
| # reserved regions | |
| ["BV", "HM", "CS", "XK", "AN"] | |
| # broken data | |
| + ["HM", "AQ"] | |
| # We only have ca.variants in region database. | |
| + ["CA"] | |
| ) | |
| with open("countryInfo.txt") as f: | |
| for line in f: | |
| if line.startswith("#"): | |
| continue | |
| # format: [0]ISO3166-1a2, [4]Country, [5]Capital, [15]Languages | |
| data = line.split("\t") | |
| code = data[0] | |
| if code in skip_regions: | |
| continue | |
| if code not in tzinfo: | |
| exit("Region code <%s> has no timezone info!" % code) | |
| # Try to build XKB. | |
| kbd_region = code.lower() | |
| lang = data[15].partition(",")[0].partition("-")[0] | |
| if len(lang) != 2: | |
| lang = "en" | |
| kbd_region = "us" | |
| new_regions[code] = dict( | |
| region_code=code.lower(), | |
| description=data[4], | |
| keyboards=str( | |
| "xkb:%s::%s" | |
| % ( | |
| kbd_region, | |
| pycountry.languages.get(alpha2=lang).terminology, | |
| ) | |
| ), | |
| time_zones=tzinfo[code], | |
| locales=data[15].strip(",").split(","), | |
| ) | |
| return new_regions | |
| def main(): | |
| def flat(v): | |
| if type(v) is list and len(v) == 1: | |
| return v[0] | |
| return v | |
| tzinfo = LoadZoneTable() | |
| for region in LoadCountryTable(tzinfo).values(): | |
| code = region["region_code"] | |
| if code in regions.REGIONS: | |
| continue | |
| # Region takes: code, kbd, tz, locale, layout, description, comment, | |
| # regdomain. | |
| print( | |
| "Region('%s', %r, %r, %r, _KML.ANSI, '%s')," | |
| % ( | |
| code, | |
| region["keyboards"], | |
| flat(region["time_zones"]), | |
| flat(region["locales"]), | |
| region["description"], | |
| ) | |
| ) | |
| if __name__ == "__main__": | |
| main() |