]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/clicmd/args.py
4457db5fcb457d800fd40265f8a009a7704f9ae3
[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     importance: bool
119     website: bool
120     diffs: bool
121     enable_debug_statements: bool
122     data_object: Sequence[Tuple[str, int]]
123     data_area: Sequence[Tuple[str, int]]
124
125     # Arguments to 'replication'
126     init: bool
127     update_functions: bool
128     check_for_updates: bool
129     once: bool
130     catch_up: bool
131     do_index: bool
132
133     # Arguments to 'serve'
134     server: str
135
136     # Arguments to 'special-phrases
137     import_from_wiki: bool
138     import_from_csv: Optional[str]
139     no_replace: bool
140
141     # Arguments to all query functions
142     format: str
143     addressdetails: bool
144     extratags: bool
145     namedetails: bool
146     lang: Optional[str]
147     polygon_output: Optional[str]
148     polygon_threshold: Optional[float]
149
150     # Arguments to 'search'
151     query: Optional[str]
152     street: Optional[str]
153     city: Optional[str]
154     county: Optional[str]
155     state: Optional[str]
156     country: Optional[str]
157     postalcode: Optional[str]
158     countrycodes: Optional[str]
159     exclude_place_ids: Optional[str]
160     limit: Optional[int]
161     viewbox: Optional[str]
162     bounded: bool
163     dedupe: bool
164
165     # Arguments to 'reverse'
166     lat: float
167     lon: float
168     zoom: Optional[int]
169
170     # Arguments to 'lookup'
171     ids: Sequence[str]
172
173     # Arguments to 'details'
174     object_class: Optional[str]
175
176
177     def osm2pgsql_options(self, default_cache: int,
178                           default_threads: int) -> Dict[str, Any]:
179         """ Return the standard osm2pgsql options that can be derived
180             from the command line arguments. The resulting dict can be
181             further customized and then used in `run_osm2pgsql()`.
182         """
183         return dict(osm2pgsql=self.config.OSM2PGSQL_BINARY or self.osm2pgsql_path,
184                     osm2pgsql_cache=self.osm2pgsql_cache or default_cache,
185                     osm2pgsql_style=self.config.get_import_style_file(),
186                     threads=self.threads or default_threads,
187                     dsn=self.config.get_libpq_dsn(),
188                     flatnode_file=str(self.config.get_path('FLATNODE_FILE') or ''),
189                     tablespaces=dict(slim_data=self.config.TABLESPACE_OSM_DATA,
190                                      slim_index=self.config.TABLESPACE_OSM_INDEX,
191                                      main_data=self.config.TABLESPACE_PLACE_DATA,
192                                      main_index=self.config.TABLESPACE_PLACE_INDEX
193                                     )
194                    )
195
196
197     def get_osm_file_list(self) -> Optional[List[Path]]:
198         """ Return the --osm-file argument as a list of Paths or None
199             if no argument was given. The function also checks if the files
200             exist and raises a UsageError if one cannot be found.
201         """
202         if not self.osm_file:
203             return None
204
205         files = [Path(f) for f in self.osm_file]
206         for fname in files:
207             if not fname.is_file():
208                 LOG.fatal("OSM file '%s' does not exist.", fname)
209                 raise UsageError('Cannot access file.')
210
211         return files