1 # SPDX-License-Identifier: GPL-2.0-only
 
   3 # This file is part of Nominatim. (https://nominatim.org)
 
   5 # Copyright (C) 2022 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 pathlib import Path
 
  15 from nominatim.errors import UsageError
 
  16 from nominatim.config import Configuration
 
  17 from nominatim.typing import Protocol
 
  19 LOG = logging.getLogger()
 
  21 class Subcommand(Protocol):
 
  23     Interface to be implemented by classes implementing a CLI subcommand.
 
  26     def add_args(self, parser: argparse.ArgumentParser) -> None:
 
  28         Fill the given parser for the subcommand with the appropriate
 
  32     def run(self, args: 'NominatimArgs') -> int:
 
  34         Run the subcommand with the given parsed arguments.
 
  39     """ Customized namespace class for the nominatim command line tool
 
  40         to receive the command-line arguments.
 
  42     # Basic environment set by root program.
 
  55     subcommand: Optional[str]
 
  59     osm2pgsql_cache: Optional[int]
 
  62     # Arguments added to all subcommands.
 
  64     threads: Optional[int]
 
  66     # Arguments to 'add-data'
 
  71     relation: Optional[int]
 
  72     tiger_data: Optional[str]
 
  75     # Arguments to 'admin'
 
  80     analyse_indexing: bool
 
  83     place_id: Optional[int]
 
  85     # Arguments to 'import'
 
  87     continue_at: Optional[str]
 
  95     # Arguments to 'index'
 
 101     # Arguments to 'export'
 
 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]
 
 111     # Arguments to 'refresh'
 
 121     enable_debug_statements: bool
 
 122     data_object: Sequence[Tuple[str, int]]
 
 123     data_area: Sequence[Tuple[str, int]]
 
 125     # Arguments to 'replication'
 
 127     update_functions: bool
 
 128     check_for_updates: bool
 
 133     # Arguments to 'serve'
 
 136     # Arguments to 'special-phrases
 
 137     import_from_wiki: bool
 
 138     import_from_csv: Optional[str]
 
 141     # Arguments to all query functions
 
 147     polygon_output: Optional[str]
 
 148     polygon_threshold: Optional[float]
 
 150     # Arguments to 'search'
 
 152     street: Optional[str]
 
 154     county: Optional[str]
 
 156     country: Optional[str]
 
 157     postalcode: Optional[str]
 
 158     countrycodes: Optional[str]
 
 159     exclude_place_ids: Optional[str]
 
 161     viewbox: Optional[str]
 
 165     # Arguments to 'reverse'
 
 170     # Arguments to 'lookup'
 
 173     # Arguments to 'details'
 
 174     object_class: Optional[str]
 
 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()`.
 
 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
 
 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.
 
 202         if not self.osm_file:
 
 205         files = [Path(f) for f in self.osm_file]
 
 207             if not fname.is_file():
 
 208                 LOG.fatal("OSM file '%s' does not exist.", fname)
 
 209                 raise UsageError('Cannot access file.')