"""Phone number geocoding functionality
>>> import phonenumbers
>>> from phonenumbers.geocoder import description_for_number
>>> from phonenumbers.util import u
>>> gb_number = phonenumbers.parse("+442083612345", "GB")
>>> de_number = phonenumbers.parse("0891234567", "DE")
>>> ch_number = phonenumbers.parse("0431234567", "CH")
>>> str(description_for_number(gb_number, "en"))
'London'
>>> str(description_for_number(gb_number, "fr")) # fall back to English
'London'
>>> str(description_for_number(gb_number, "en", region="GB"))
'London'
>>> str(description_for_number(gb_number, "en", region="US")) # fall back to country
'United Kingdom'
>>> str(description_for_number(de_number, "en"))
'Munich'
>>> u('M\u00fcnchen') == description_for_number(de_number, "de")
True
>>> u('Z\u00fcrich') == description_for_number(ch_number, "de")
True
>>> str(description_for_number(ch_number, "en"))
'Zurich'
>>> str(description_for_number(ch_number, "fr"))
'Zurich'
>>> str(description_for_number(ch_number, "it"))
'Zurigo'
"""
# Based very loosely on original Java code:
# java/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
# Copyright (C) 2009-2011 The Libphonenumber Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from .util import prnt, unicod, u, U_EMPTY_STRING
from .phonenumberutil import region_code_for_number, PhoneNumberType
from .phonenumberutil import country_mobile_token, national_significant_number, number_type
from .phonenumberutil import region_code_for_country_code, region_codes_for_country_code
from .phonenumberutil import is_valid_number_for_region, parse, NumberParseException
from .phonenumberutil import is_number_type_geographical
from .prefix import _prefix_description_for_number
try:
from .geodata import GEOCODE_DATA, GEOCODE_LONGEST_PREFIX
from .geodata.locale import LOCALE_DATA
except ImportError: # pragma no cover
# Before the generated code exists, the geodata/ directory is empty.
# The generation process imports this module, creating a circular
# dependency. The hack below works around this.
import os
import sys
if (os.path.basename(sys.argv[0]) == "buildmetadatafromxml.py" or
os.path.basename(sys.argv[0]) == "buildprefixdata.py"):
prnt("Failed to import generated data (but OK as during autogeneration)", file=sys.stderr)
GEOCODE_DATA = {'1': {'en': u('United States')}}
GEOCODE_LONGEST_PREFIX = 1
LOCALE_DATA = {'US': {'en': u('United States')}}
else:
raise
__all__ = ['country_name_for_number', 'description_for_valid_number', 'description_for_number']
def country_name_for_number(numobj, lang, script=None, region=None):
"""Returns the customary display name in the given language for the given
territory the given PhoneNumber object is from. If it could be from many
territories, nothing is returned.
Arguments:
numobj -- The PhoneNumber object for which we want to get a text description.
lang -- A 2-letter lowercase ISO 639-1 language code for the language in
which the description should be returned (e.g. "en")
script -- A 4-letter titlecase (first letter uppercase, rest lowercase)
ISO script code as defined in ISO 15924, separated by an
underscore (e.g. "Hant")
region -- A 2-letter uppercase ISO 3166-1 country code (e.g. "GB")
The script and region parameters are currently ignored.
Returns a text description in the given language code, for the given phone
number's region, or an empty string if no description is available."""
region_codes = region_codes_for_country_code(numobj.country_code)
if len(region_codes) == 1:
return _region_display_name(region_codes[0], lang, script, region)
else:
region_where_number_is_valid = u("ZZ")
for region_code in region_codes:
if is_valid_number_for_region(numobj, region_code):
# If the number has already been found valid for one region,
# then we don't know which region it belongs to so we return
# nothing.
if region_where_number_is_valid != u("ZZ"):
return U_EMPTY_STRING
region_where_number_is_valid = region_code
return _region_display_name(region_where_number_is_valid, lang, script, region)
def _region_display_name(region_code, lang, script=None, region=None):
if region_code in LOCALE_DATA:
# The Locale data has a set of names for this region, in various languages.
name = LOCALE_DATA[region_code].get(lang, "")
if name.startswith('*'):
# If the location name is "*