]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/clicmd/args.py
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / nominatim / clicmd / args.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2022 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Provides custom functions over command-line arguments.
9 """
10 from typing import Optional, List, Dict, Any, Sequence, Tuple
11 import argparse
12 import logging
13 from pathlib import Path
14
15 from nominatim.errors import UsageError
16 from nominatim.config import Configuration
17 from nominatim.typing import Protocol
18
19 LOG = logging.getLogger()
20
21 class Subcommand(Protocol):
22     """
23     Interface to be implemented by classes implementing a CLI subcommand.
24     """
25
26     def add_args(self, parser: argparse.ArgumentParser) -> None:
27         """
28         Fill the given parser for the subcommand with the appropriate
29         parameters.
30         """
31
32     def run(self, args: 'NominatimArgs') -> int:
33         """
34         Run the subcommand with the given parsed arguments.
35         """
36
37
38 class NominatimArgs:
39     """ Customized namespace class for the nominatim command line tool
40         to receive the command-line arguments.
41     """
42     # Basic environment set by root program.
43     config: Configuration
44     project_dir: Path
45     module_dir: Path
46     osm2pgsql_path: Path
47     phplib_dir: Path
48     sqllib_dir: Path
49     data_dir: Path
50     config_dir: Path
51     phpcgi_path: Path
52
53     # Global switches
54     version: bool
55     subcommand: Optional[str]
56     command: Subcommand
57
58     # Shared parameters
59     osm2pgsql_cache: Optional[int]
60     socket_timeout: int
61
62     # Arguments added to all subcommands.
63     verbose: int
64     threads: Optional[int]
65
66     # Arguments to 'add-data'
67     file: Optional[str]
68     diff: Optional[str]
69     node: Optional[int]
70     way: Optional[int]
71     relation: Optional[int]
72     tiger_data: Optional[str]
73     use_main_api: bool
74
75     # Arguments to 'admin'
76     warm: bool
77     check_database: bool
78     migrate: bool
79     collect_os_info: bool
80     analyse_indexing: bool
81     target: Optional[str]
82     osm_id: Optional[str]
83     place_id: Optional[int]
84
85     # Arguments to 'import'
86     osm_file: List[str]
87     continue_at: Optional[str]
88     reverse_only: bool
89     no_partitions: bool
90     no_updates: bool
91     offline: bool
92     ignore_errors: bool
93     index_noanalyse: bool
94
95     # Arguments to 'index'
96     boundaries_only: bool
97     no_boundaries: bool
98     minrank: int
99     maxrank: int
100
101     # Arguments to 'export'
102     output_type: str
103     output_format: str
104     output_all_postcodes: bool
105     language: Optional[str]
106     restrict_to_country: Optional[str]
107     restrict_to_osm_node: Optional[int]
108     restrict_to_osm_way: Optional[int]
109     restrict_to_osm_relation: Optional[int]
110
111     # Arguments to 'refresh'
112     postcodes: bool
113     word_tokens: bool
114     word_counts: bool
115     address_levels: bool
116     functions: bool
117     wiki_data: bool
118     secondary_importance: bool
119     importance: bool
120     website: bool
121     diffs: bool
122     enable_debug_statements: bool
123     data_object: Sequence[Tuple[str, int]]
124     data_area: Sequence[Tuple[str, int]]
125
126     # Arguments to 'replication'
127     init: bool
128     update_functions: bool
129     check_for_updates: bool
130     once: bool
131     catch_up: bool
132     do_index: bool
133
134     # Arguments to 'serve'
135     server: str
136
137     # Arguments to 'special-phrases
138     import_from_wiki: bool
139     import_from_csv: Optional[str]
140     no_replace: bool
141
142     # Arguments to all query functions
143     format: str
144     addressdetails: bool
145     extratags: bool
146     namedetails: bool
147     lang: Optional[str]
148     polygon_output: Optional[str]
149     polygon_threshold: Optional[float]
150
151     # Arguments to 'search'
152     query: Optional[str]
153     street: Optional[str]
154     city: Optional[str]
155     county: Optional[str]
156     state: Optional[str]
157     country: Optional[str]
158     postalcode: Optional[str]
159     countrycodes: Optional[str]
160     exclude_place_ids: Optional[str]
161     limit: Optional[int]
162     viewbox: Optional[str]
163     bounded: bool
164     dedupe: bool
165
166     # Arguments to 'reverse'
167     lat: float
168     lon: float
169     zoom: Optional[int]
170
171     # Arguments to 'lookup'
172     ids: Sequence[str]
173
174     # Arguments to 'details'
175     object_class: Optional[str]
176
177
178     def osm2pgsql_options(self, default_cache: int,
179                           default_threads: int) -> Dict[str, Any]:
180         """ Return the standard osm2pgsql options that can be derived
181             from the command line arguments. The resulting dict can be
182             further customized and then used in `run_osm2pgsql()`.
183         """
184         return dict(osm2pgsql=self.config.OSM2PGSQL_BINARY or self.osm2pgsql_path,
185                     osm2pgsql_cache=self.osm2pgsql_cache or default_cache,
186                     osm2pgsql_style=self.config.get_import_style_file(),
187                     osm2pgsql_style_path=self.config.config_dir,
188                     threads=self.threads or default_threads,
189                     dsn=self.config.get_libpq_dsn(),
190                     forward_dependencies=self.config.get_bool('UPDATE_FORWARD_DEPENDENCIES'),
191                     flatnode_file=str(self.config.get_path('FLATNODE_FILE') or ''),
192                     tablespaces=dict(slim_data=self.config.TABLESPACE_OSM_DATA,
193                                      slim_index=self.config.TABLESPACE_OSM_INDEX,
194                                      main_data=self.config.TABLESPACE_PLACE_DATA,
195                                      main_index=self.config.TABLESPACE_PLACE_INDEX
196                                     )
197                    )
198
199
200     def get_osm_file_list(self) -> Optional[List[Path]]:
201         """ Return the --osm-file argument as a list of Paths or None
202             if no argument was given. The function also checks if the files
203             exist and raises a UsageError if one cannot be found.
204         """
205         if not self.osm_file:
206             return None
207
208         files = [Path(f) for f in self.osm_file]
209         for fname in files:
210             if not fname.is_file():
211                 LOG.fatal("OSM file '%s' does not exist.", fname)
212                 raise UsageError('Cannot access file.')
213
214         return files