1 # SPDX-License-Identifier: GPL-3.0-or-later
3 # This file is part of Nominatim. (https://nominatim.org)
5 # Copyright (C) 2024 by the Nominatim developer community.
6 # For a full list of authors see the git log.
8 Provides custom functions over command-line arguments.
10 from typing import Optional, List, Dict, Any, Sequence, Tuple
13 from functools import reduce
14 from pathlib import Path
16 from nominatim_core.errors import UsageError
17 from nominatim_core.config import Configuration
18 from nominatim_core.typing import Protocol
20 LOG = logging.getLogger()
22 class Subcommand(Protocol):
24 Interface to be implemented by classes implementing a CLI subcommand.
27 def add_args(self, parser: argparse.ArgumentParser) -> None:
29 Fill the given parser for the subcommand with the appropriate
33 def run(self, args: 'NominatimArgs') -> int:
35 Run the subcommand with the given parsed arguments.
40 """ Customized namespace class for the nominatim command line tool
41 to receive the command-line arguments.
43 # Basic environment set by root program.
49 subcommand: Optional[str]
53 osm2pgsql_cache: Optional[int]
56 # Arguments added to all subcommands.
58 threads: Optional[int]
60 # Arguments to 'add-data'
65 relation: Optional[int]
66 tiger_data: Optional[str]
69 # Arguments to 'admin'
75 analyse_indexing: bool
78 place_id: Optional[int]
80 # Arguments to 'import'
82 continue_at: Optional[str]
89 prepare_database: bool
91 # Arguments to 'index'
97 # Arguments to 'export'
100 output_all_postcodes: bool
101 language: Optional[str]
102 restrict_to_country: Optional[str]
104 # Arguments to 'convert'
107 # Arguments to 'refresh'
114 secondary_importance: bool
118 enable_debug_statements: bool
119 data_object: Sequence[Tuple[str, int]]
120 data_area: Sequence[Tuple[str, int]]
122 # Arguments to 'replication'
124 update_functions: bool
125 check_for_updates: bool
130 # Arguments to 'serve'
134 # Arguments to 'special-phrases
135 import_from_wiki: bool
136 import_from_csv: Optional[str]
139 # Arguments to all query functions
145 polygon_output: Optional[str]
146 polygon_threshold: Optional[float]
148 # Arguments to 'search'
150 amenity: Optional[str]
151 street: Optional[str]
153 county: Optional[str]
155 country: Optional[str]
156 postalcode: Optional[str]
157 countrycodes: Optional[str]
158 exclude_place_ids: Optional[str]
160 viewbox: Optional[str]
164 # Arguments to 'reverse'
168 layers: Optional[Sequence[str]]
170 # Arguments to 'lookup'
173 # Arguments to 'details'
174 object_class: Optional[str]
178 polygon_geojson: bool
179 group_hierarchy: bool
182 def osm2pgsql_options(self, default_cache: int,
183 default_threads: int) -> Dict[str, Any]:
184 """ Return the standard osm2pgsql options that can be derived
185 from the command line arguments. The resulting dict can be
186 further customized and then used in `run_osm2pgsql()`.
188 return dict(osm2pgsql=self.config.OSM2PGSQL_BINARY or self.config.lib_dir.osm2pgsql,
189 osm2pgsql_cache=self.osm2pgsql_cache or default_cache,
190 osm2pgsql_style=self.config.get_import_style_file(),
191 osm2pgsql_style_path=self.config.config_dir,
192 threads=self.threads or default_threads,
193 dsn=self.config.get_libpq_dsn(),
194 flatnode_file=str(self.config.get_path('FLATNODE_FILE') or ''),
195 tablespaces=dict(slim_data=self.config.TABLESPACE_OSM_DATA,
196 slim_index=self.config.TABLESPACE_OSM_INDEX,
197 main_data=self.config.TABLESPACE_PLACE_DATA,
198 main_index=self.config.TABLESPACE_PLACE_INDEX
203 def get_osm_file_list(self) -> Optional[List[Path]]:
204 """ Return the --osm-file argument as a list of Paths or None
205 if no argument was given. The function also checks if the files
206 exist and raises a UsageError if one cannot be found.
208 if not self.osm_file:
211 files = [Path(f) for f in self.osm_file]
213 if not fname.is_file():
214 LOG.fatal("OSM file '%s' does not exist.", fname)
215 raise UsageError('Cannot access file.')