简体   繁体   中英

convert translated country-names to alpha2 with pycountry and gettext

I'm trying to let my users search for data by country. The users will type in the country name in their native languages. However my database only contains the alpha2 codes for each country.

My current approach:

user_input = "France"
country_code = pycountry.countries.get(name=user_input).alpha2 # u'FR'

this works fine if the user input is made in English. Since the data is shown in the users preferred language, she will expect to search for it in her preferred language as well.

By using gettext with pycountry's locales I'm able to show the country-names in the users preferred language:

# example for a German user
gettext.translation('iso3166', pycountry.LOCALES_DIR, languages=['de']).install()
country_code = 'FR'
country = _(pycountry.countries.get(alpha2=country_code).name) # 'Frankreich'

now I'm searching for a way to translate the users input back to english (assume there are no typos) and fetch the country code from it:

user_input = "Frankreich"
translated_user_input = ??? # 'France'
country_code = pycountry.countries.get(name=translated_user_input).alpha2 # u'FR'

Has anyone a good idea, how to achieve this? Ideally by only using gettext and pycountry?

I found a solution, which might not be exactly performance optimized, but works and is not too ugly:

user_input = "Frankreich"
country_code = ''.join([country.alpha2 for country in pycountry.countries if _(country.name) == user_input]) # u'FR'

Here is my solution, there is a lot to improve regarding performance, but it is working. the input is

  1. country name in some language
  2. language identifier in pycountry
import pycountry
import gettext

    def map_country_code(self, country_name, language):
        try:
            # todo:  when languages = en the program fails!
            # todo: this methode takes to much time, is it o(n2) have to think on a better system+
            if country_name is None:
                return None
            german = gettext.translation('iso3166', pycountry.LOCALES_DIR, languages=[language])
            german.install()
            _ = german.gettext
            for english_country in pycountry.countries:
                country_name = country_name.lower()
                german_country = _(english_country.name).lower()
                if german_country == country_name:
                    return english_country.alpha_3
        except Exception as e:
            self.log.error(e, exc_info=True)
            return False

It seems like gettext doesn't have a native support (!?) to reverse the translation (I really hope I am wrong about this, it seems like a normal functionality).

My solution is to create a new gettext object and switch the translation around. All the translation objects are found in the ._catalog dictionary. So I swap the keys for the entries.

import pycountry
import gettext
import copy
eng_to_german = gettext.translation('iso3166', pycountry.LOCALES_DIR,languages=['de'])
eng_to_german.install()
german_to_eng = copy.copy(eng_to_german) #Make a copy
german_to_eng._catalog = {} #Remove the catalog

for key in eng_to_german._catalog.keys():
    german_to_eng._catalog[eng_to_german._catalog[key]] = key #replace the key with the entry and vice versa

#Verify
_ = german_to_eng.gettext
translated_string = _("Frankreich")
print(translated_string) #This should print "France"

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM