]> git.openstreetmap.org Git - nominatim.git/blobdiff - nominatim/config.py
Merge pull request #2284 from lonvia/cleanup-word-frequency-computation
[nominatim.git] / nominatim / config.py
index 4fa887a1d10e84baefa5721ae28500a703dda7b3..d1df17b726bac3db70d7c8a788c98a9abbf4401b 100644 (file)
@@ -1,18 +1,23 @@
 """
 Nominatim configuration accessor.
 """
-import sys
+import logging
 import os
+from pathlib import Path
 
 from dotenv import dotenv_values
 
+from nominatim.errors import UsageError
+
+LOG = logging.getLogger()
+
 class Configuration:
     """ Load and manage the project configuration.
 
         Nominatim uses dotenv to configure the software. Configuration options
         are resolved in the following order:
 
-         * from the OS environment
+         * from the OS environment (or the dirctionary given in `environ`
          * from the .env file in the project directory of the installation
          * from the default installation in the configuration directory
 
@@ -20,20 +25,92 @@ class Configuration:
         avoid conflicts with other environment variables.
     """
 
-    def __init__(self, project_dir, config_dir):
+    def __init__(self, project_dir, config_dir, environ=None):
+        self.environ = environ or os.environ
+        self.project_dir = project_dir
+        self.config_dir = config_dir
         self._config = dotenv_values(str((config_dir / 'env.defaults').resolve()))
-        self._config.update(dotenv_values(str((project_dir / '.env').resolve())))
+        if project_dir is not None:
+            self._config.update(dotenv_values(str((project_dir / '.env').resolve())))
+
+        # Add defaults for variables that are left empty to set the default.
+        # They may still be overwritten by environment variables.
+        if not self._config['NOMINATIM_ADDRESS_LEVEL_CONFIG']:
+            self._config['NOMINATIM_ADDRESS_LEVEL_CONFIG'] = \
+                str(config_dir / 'address-levels.json')
+
+        class _LibDirs: # pylint: disable=too-few-public-methods
+            pass
+
+        self.lib_dir = _LibDirs()
+
+    def set_libdirs(self, **kwargs):
+        """ Set paths to library functions and data.
+        """
+        for key, value in kwargs.items():
+            setattr(self.lib_dir, key, Path(value).resolve())
 
     def __getattr__(self, name):
         name = 'NOMINATIM_' + name
 
-        return os.environ.get(name) or self._config[name]
+        return self.environ.get(name) or self._config[name]
+
+    def get_bool(self, name):
+        """ Return the given configuration parameter as a boolean.
+            Values of '1', 'yes' and 'true' are accepted as truthy values,
+            everything else is interpreted as false.
+        """
+        return self.__getattr__(name).lower() in ('1', 'yes', 'true')
+
+
+    def get_int(self, name):
+        """ Return the given configuration parameter as an int.
+        """
+        try:
+            return int(self.__getattr__(name))
+        except ValueError:
+            LOG.fatal("Invalid setting NOMINATIM_%s. Needs to be a number.", name)
+            raise UsageError("Configuration error.")
+
+
+    def get_libpq_dsn(self):
+        """ Get configured database DSN converted into the key/value format
+            understood by libpq and psycopg.
+        """
+        dsn = self.DATABASE_DSN
+
+        def quote_param(param):
+            key, val = param.split('=')
+            val = val.replace('\\', '\\\\').replace("'", "\\'")
+            if ' ' in val:
+                val = "'" + val + "'"
+            return key + '=' + val
+
+        if dsn.startswith('pgsql:'):
+            # Old PHP DSN format. Convert before returning.
+            return ' '.join([quote_param(p) for p in dsn[6:].split(';')])
+
+        return dsn
+
+
+    def get_import_style_file(self):
+        """ Return the import style file as a path object. Translates the
+            name of the standard styles automatically into a file in the
+            config style.
+        """
+        style = self.__getattr__('IMPORT_STYLE')
+
+        if style in ('admin', 'street', 'address', 'full', 'extratags'):
+            return self.config_dir / 'import-{}.style'.format(style)
+
+        return Path(style)
+
 
     def get_os_env(self):
         """ Return a copy of the OS environment with the Nominatim configuration
             merged in.
         """
-        env = dict(os.environ)
-        env.update(self._config)
+        env = dict(self._config)
+        env.update(self.environ)
 
         return env