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.
 
  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'
 
  74     analyse_indexing: bool
 
  77     place_id: Optional[int]
 
  79     # Arguments to 'import'
 
  81     continue_at: Optional[str]
 
  89     # Arguments to 'index'
 
  95     # Arguments to 'export'
 
  98     output_all_postcodes: bool
 
  99     language: Optional[str]
 
 100     restrict_to_country: Optional[str]
 
 101     restrict_to_osm_node: Optional[int]
 
 102     restrict_to_osm_way: Optional[int]
 
 103     restrict_to_osm_relation: Optional[int]
 
 105     # Arguments to 'refresh'
 
 112     secondary_importance: bool
 
 116     enable_debug_statements: bool
 
 117     data_object: Sequence[Tuple[str, int]]
 
 118     data_area: Sequence[Tuple[str, int]]
 
 120     # Arguments to 'replication'
 
 122     update_functions: bool
 
 123     check_for_updates: bool
 
 128     # Arguments to 'serve'
 
 132     # Arguments to 'special-phrases
 
 133     import_from_wiki: bool
 
 134     import_from_csv: Optional[str]
 
 137     # Arguments to all query functions
 
 143     polygon_output: Optional[str]
 
 144     polygon_threshold: Optional[float]
 
 146     # Arguments to 'search'
 
 148     street: Optional[str]
 
 150     county: Optional[str]
 
 152     country: Optional[str]
 
 153     postalcode: Optional[str]
 
 154     countrycodes: Optional[str]
 
 155     exclude_place_ids: Optional[str]
 
 157     viewbox: Optional[str]
 
 161     # Arguments to 'reverse'
 
 166     # Arguments to 'lookup'
 
 169     # Arguments to 'details'
 
 170     object_class: Optional[str]
 
 174     polygon_geojson: bool
 
 175     group_hierarchy: bool
 
 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()`.
 
 184         return dict(osm2pgsql=self.config.OSM2PGSQL_BINARY or self.config.lib_dir.osm2pgsql,
 
 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                     flatnode_file=str(self.config.get_path('FLATNODE_FILE') or ''),
 
 191                     tablespaces=dict(slim_data=self.config.TABLESPACE_OSM_DATA,
 
 192                                      slim_index=self.config.TABLESPACE_OSM_INDEX,
 
 193                                      main_data=self.config.TABLESPACE_PLACE_DATA,
 
 194                                      main_index=self.config.TABLESPACE_PLACE_INDEX
 
 199     def get_osm_file_list(self) -> Optional[List[Path]]:
 
 200         """ Return the --osm-file argument as a list of Paths or None
 
 201             if no argument was given. The function also checks if the files
 
 202             exist and raises a UsageError if one cannot be found.
 
 204         if not self.osm_file:
 
 207         files = [Path(f) for f in self.osm_file]
 
 209             if not fname.is_file():
 
 210                 LOG.fatal("OSM file '%s' does not exist.", fname)
 
 211                 raise UsageError('Cannot access file.')