[PATCH 2/3] Hook the Geolocation module to Anaconda

Martin Kolman mkolman at gmail.com
Thu Apr 11 13:39:33 UTC 2013


First, the module is initilized and asynchronous location info
refresh is started. Then once the welcome spoke is initialized,
it asks the geolocation module for the territory code.
If the code is unknown (either due to the lookup not returning
any result or still being in progress), default language value is used.

Also, if geolocation returns more than one language, default
langugae is used. This is because some countries, such as Switzerland,
have more than one locale and there is no clear priority which one to
use.

There is a boot option called "geoloc", that can be
used to configure the geolocation module.

It currently supports these values:
not set - use geolocation with default provider
"0" - don't use geolocation
"provider_mirror_manager" - use the Fedora MirrorManager as the
                          geolocation provider (default)
"provider_hostip" - use Hostip.info as geolocation provider

The "provider_*" strings are defined by the "GEOLOC_PROVIDER_*"
constants in the constants module.

Signed-off-by: Martin Kolman <mkolman at gmail.com>
---
 anaconda                            | 26 ++++++++++++++++++++
 pyanaconda/ui/gui/spokes/welcome.py | 47 +++++++++++++++++++++++++++++--------
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/anaconda b/anaconda
index b553de3..fab30d6 100755
--- a/anaconda
+++ b/anaconda
@@ -274,6 +274,9 @@ def parseOptions(argv=None, cmdline=None):
     op.add_option("--noiscsi", dest="iscsi", action="store_false", default=False)
     op.add_option("--iscsi", action="store_true")
 
+    # Geolocation
+    op.add_option("--geoloc")
+
     # Miscellaneous
     op.add_option("--module", action="append", default=[])
     op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False)
@@ -659,6 +662,7 @@ if __name__ == "__main__":
 
     from pyanaconda import constants
     from pyanaconda import addons
+    from pyanaconda import geoloc
 
     # do this early so we can set flags before initializing logging
     from pyanaconda.flags import flags, can_touch_runtime_system
@@ -1016,6 +1020,28 @@ if __name__ == "__main__":
 
     atexit.register(exitHandler, ksdata.reboot, anaconda.storage)
 
+    # check if geolocation should be enabled for this type of installation
+    use_geolocation = True
+    if flags.imageInstall or flags.dirInstall:
+        use_geolocation = False
+    # and also check if it was not disabled by boot options or a CLI argument
+    elif opts.geoloc == "0":
+        use_geolocation = False
+
+    if use_geolocation:
+        provider_id = constants.GEOLOC_DEFAULT_PROVIDER
+        # check if a provider was specified by an option
+        if opts.geoloc is not None:
+            parsed_id = geoloc.get_provider_id_from_option(opts.geoloc)
+            if parsed_id is None:
+                log.error('geoloc: wrong provider id specified: %s' %
+                        opts.geoloc)
+            else:
+                provider_id = parsed_id           
+        # instantiate the geolocation module and start location data refresh
+        geoloc.init_geolocation(provider_id=provider_id)
+        geoloc.refresh()
+    
     # setup ntp servers and start NTP daemon if not requested otherwise
     if can_touch_runtime_system("start chronyd"):
         if anaconda.ksdata.timezone.ntpservers:
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index 402ff05..92b95c1 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -38,6 +38,10 @@ from pyanaconda.product import distributionText, isFinal, productName, productVe
 from pyanaconda import keyboard
 from pyanaconda import timezone
 from pyanaconda import flags
+from pyanaconda import geoloc
+
+import logging
+log = logging.getLogger("anaconda")
 
 __all__ = ["WelcomeLanguageSpoke", "LanguageSpoke"]
 
@@ -66,11 +70,18 @@ class LanguageMixIn(object):
         if flags.flags.automatedInstall:
             return
 
-        #TODO: better use GeoIP data once it is available
-        if self.language.territory and not self.data.timezone.timezone:
+        lang_timezone = None
+        # check the geolocation data for territory code
+        geoloc_territory = geoloc.get_territory_code()
+        if geoloc_territory:
+            lang_timezone = timezone.get_preferred_timezone(geoloc_territory)
+        # if no data is provided by Geolocation,
+        # try to get timezone from the current language
+        elif self.language.territory and not self.data.timezone.timezone:
             lang_timezone = timezone.get_preferred_timezone(self.language.territory)
-            if lang_timezone:
-                self.data.timezone.timezone = lang_timezone
+
+        if lang_timezone:
+            self.data.timezone.timezone = lang_timezone
 
         lang_country = self.language.preferred_locale.territory
         self._set_keyboard_defaults(store[itr][1], lang_country)
@@ -137,12 +148,22 @@ class LanguageMixIn(object):
         self._selection = self.builder.get_object(self._selectionName)
         self._view = self.builder.get_object(self._viewName)
 
-        # TODO We can use the territory from geoip here
+        # We can use the territory from geolocation here
         # to preselect the translation, when it's available.
-        # Until then, use None.
-        territory = None
+        territory = geoloc.get_territory_code()
         self.language = Language(LOCALE_PREFERENCES, territory=territory)
-
+        # check if there is one and only one locale for the territory
+        if len(self.language.preferred_locales) != 1:
+            log.info(_("Didn't get a single locale from Geolocation,"
+                        " falling back to default locale."))           
+            self.language = Language(LOCALE_PREFERENCES, territory=None)
+            # Explanation:
+            # Some territories have multiple locales,
+            # for example, the Switzerland has:
+            # de_CH, it_CH and fr_CH
+            # As there is no clear order of preference for them,
+            # it is safer to just fall back to the default locale.            
+        
         # fill the list with available translations
         for _code, trans in sorted(self.language.translations.items()):
             self._addLanguage(store, trans.display_name,
@@ -151,8 +172,14 @@ class LanguageMixIn(object):
         # select the preferred translation if there wasn't any
         (store, itr) = self._selection.get_selected()
         if not itr:
-            lang = self.data.lang.lang or \
-                   self.language.preferred_translation.short_name
+            # check if a language was set by kickstart
+            # NOTE: seen means the language was "seen" in
+            # kickstart or boot option, so it overrides
+            # the language detected by geolocation
+            if self.data.lang.lang and self.data.lang.seen:
+                lang = self.data.lang.lang
+            else:
+                lang = self.language.preferred_translation.short_name            
             self._selectLanguage(store, lang)
 
         self._languageStoreFilter.set_visible_func(self._matchesEntry, None)
-- 
1.8.1.4



More information about the anaconda-patches mailing list