]> 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     analyse_indexing: bool
80     target: Optional[str]
81     osm_id: Optional[str]
82     place_id: Optional[int]
83
84     # Arguments to 'import'
85     osm_file: List[str]
86     continue_at: Optional[str]
87     reverse_only: bool
88     no_partitions: bool
89     no_updates: bool
90     offline: bool
91     ignore_errors: bool
92     index_noanalyse: bool
93
94     # Arguments to 'index'
95     boundaries_only: bool
96     no_boundaries: bool
97     minrank: int
98     maxrank: int
99
100     # Arguments to 'export'
101     output_type: str
102     output_format: str
103     output_all_postcodes: bool
104     language: Optional[str]
105     restrict_to_country: Optional[str]
106     restrict_to_osm_node: Optional[int]
107     restrict_to_osm_way: Optional[int]
108     restrict_to_osm_relation: Optional[int]
109
110     # Arguments to 'refresh'
111     postcodes: bool
112     word_tokens: bool
113     word_counts: bool
114     address_levels: bool
115     functions: bool
116     wiki_data: bool
117     importance: bool
118     website: bool
119     diffs: bool
120     enable_debug_statements: bool
121     data_object: Sequence[Tuple[str, int]]
122     data_area: Sequence[Tuple[str, int]]
123
124     # Arguments to 'replication'
125     init: bool
126     update_functions: bool
127     check_for_updates: bool
128     once: bool
129     catch_up: bool
130     do_index: bool
131
132     # Arguments to 'serve'
133     server: str
134
135     # Arguments to 'special-phrases
136     import_from_wiki: bool
137     import_from_csv: Optional[str]
138     no_replace: bool
139
140     # Arguments to all query functions
141     format: str
142     addressdetails: bool
143     extratags: bool
144     namedetails: bool
145     lang: Optional[str]
146     polygon_output: Optional[str]
147     polygon_threshold: Optional[float]
148
149     # Arguments to 'search'
150     query: Optional[str]
151     street: Optional[str]
152     city: Optional[str]
153     county: Optional[str]
154     state: Optional[str]
155     country: Optional[str]
156     postalcode: Optional[str]
157     countrycodes: Optional[str]
158     exclude_place_ids: Optional[str]
159     limit: Optional[int]
160     viewbox: Optional[str]
161     bounded: bool
162     dedupe: bool
163
164     # Arguments to 'reverse'
165     lat: float
166     lon: float
167     zoom: Optional[int]
168
169     # Arguments to 'lookup'
170     ids: Sequence[str]
171
172     # Arguments to 'details'
173     object_class: Optional[str]
174
175
176     def osm2pgsql_options(self, default_cache: int,
177                           default_threads: int) -> Dict[str, Any]:
178         """ Return the standard osm2pgsql options that can be derived
179             from the command line arguments. The resulting dict can be
180             further customized and then used in `run_osm2pgsql()`.
181         """
182         return dict(osm2pgsql=self.config.OSM2PGSQL_BINARY or self.osm2pgsql_path,
183                     osm2pgsql_cache=self.osm2pgsql_cache or default_cache,
184                     osm2pgsql_style=self.config.get_import_style_file(),
185                     threads=self.threads or default_threads,
186                     dsn=self.config.get_libpq_dsn(),
187                     flatnode_file=str(self.config.get_path('FLATNODE_FILE') or ''),
188                     tablespaces=dict(slim_data=self.config.TABLESPACE_OSM_DATA,
189                                      slim_index=self.config.TABLESPACE_OSM_INDEX,
190                                      main_data=self.config.TABLESPACE_PLACE_DATA,
191                                      main_index=self.config.TABLESPACE_PLACE_INDEX
192                                     )
193                    )
194
195
196     def get_osm_file_list(self) -> Optional[List[Path]]:
197         """ Return the --osm-file argument as a list of Paths or None
198             if no argument was given. The function also checks if the files
199             exist and raises a UsageError if one cannot be found.
200         """
201         if not self.osm_file:
202             return None
203
204         files = [Path(f) for f in self.osm_file]
205         for fname in files:
206             if not fname.is_file():
207                 LOG.fatal("OSM file '%s' does not exist.", fname)
208                 raise UsageError('Cannot access file.')
209
210         return files