]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/config.py
271d2d4d4ee20b0d37fde49de1429b5b9da7f0fc
[nominatim.git] / nominatim / config.py
1 """
2 Nominatim configuration accessor.
3 """
4 import logging
5 import os
6 from pathlib import Path
7
8 from dotenv import dotenv_values
9
10 LOG = logging.getLogger()
11
12 class Configuration:
13     """ Load and manage the project configuration.
14
15         Nominatim uses dotenv to configure the software. Configuration options
16         are resolved in the following order:
17
18          * from the OS environment
19          * from the .env file in the project directory of the installation
20          * from the default installation in the configuration directory
21
22         All Nominatim configuration options are prefixed with 'NOMINATIM_' to
23         avoid conflicts with other environment variables.
24     """
25
26     def __init__(self, project_dir, config_dir):
27         self.project_dir = project_dir
28         self.config_dir = config_dir
29         self._config = dotenv_values(str((config_dir / 'env.defaults').resolve()))
30         if project_dir is not None:
31             self._config.update(dotenv_values(str((project_dir / '.env').resolve())))
32
33         # Add defaults for variables that are left empty to set the default.
34         # They may still be overwritten by environment variables.
35         if not self._config['NOMINATIM_ADDRESS_LEVEL_CONFIG']:
36             self._config['NOMINATIM_ADDRESS_LEVEL_CONFIG'] = \
37                 str(config_dir / 'address-levels.json')
38
39
40     def __getattr__(self, name):
41         name = 'NOMINATIM_' + name
42
43         return os.environ.get(name) or self._config[name]
44
45     def get_bool(self, name):
46         """ Return the given configuration parameter as a boolean.
47             Values of '1', 'yes' and 'true' are accepted as truthy values,
48             everything else is interpreted as false.
49         """
50         return self.__getattr__(name).lower() in ('1', 'yes', 'true')
51
52
53     def get_int(self, name):
54         """ Return the given configuration parameter as an int.
55         """
56         try:
57             return int(self.__getattr__(name))
58         except ValueError:
59             LOG.fatal("Invalid setting NOMINATIM_%s. Needs to be a number.", name)
60             raise
61
62
63     def get_libpq_dsn(self):
64         """ Get configured database DSN converted into the key/value format
65             understood by libpq and psycopg.
66         """
67         dsn = self.DATABASE_DSN
68
69         def quote_param(param):
70             key, val = param.split('=')
71             val = val.replace('\\', '\\\\').replace("'", "\\'")
72             if ' ' in val:
73                 val = "'" + val + "'"
74             return key + '=' + val
75
76         if dsn.startswith('pgsql:'):
77             # Old PHP DSN format. Convert before returning.
78             return ' '.join([quote_param(p) for p in dsn[6:].split(';')])
79
80         return dsn
81
82
83     def get_import_style_file(self):
84         """ Return the import style file as a path object. Translates the
85             name of the standard styles automatically into a file in the
86             config style.
87         """
88         style = self.__getattr__('IMPORT_STYLE')
89
90         if style in ('admin', 'street', 'address', 'full', 'extratags'):
91             return self.config_dir / 'import-{}.style'.format(style)
92
93         return Path(style)
94
95
96     def get_os_env(self):
97         """ Return a copy of the OS environment with the Nominatim configuration
98             merged in.
99         """
100         env = dict(self._config)
101         env.update(os.environ)
102
103         return env