from configparser import RawConfigParser from os import environ from .maybe import Maybe from pathlib import Path from itertools import chain from dataclasses import dataclass from typing import Optional _config_file_name = 'client.properties' @dataclass class Config: server_url: str auth_server_url: str repo_folders: tuple[Path, ...] client_id: str client_secret: Optional[str] config_file_candidates = [ (Maybe.of(Path('/etc') / 'jpacrepo' / _config_file_name) .filter(Path.exists)), (Maybe.of_nullable(environ.get('XDG_CONFIG_HOME', None)) .map(Path) .map(lambda xdg_config_home: xdg_config_home / 'jpacrepo' / _config_file_name) .filter(Path.exists)), (Maybe.of_nullable(environ['HOME']) .map(Path) .map(lambda home: home / '.config' / _config_file_name) .filter(Path.exists)) ] def load_configuration() -> Config: main_section = 'main' server_url: Optional[str] = None auth_server_url: Optional[str] = None repo_folders: list[Path] = [] client_id: Optional[str] = None client_secret: Optional[str] = None for config_file_maybe in config_file_candidates: def process_configuration(config_file: Path) -> None: nonlocal server_url, auth_server_url, client_id, client_secret config = RawConfigParser() with open(config_file, 'r') as lines: config.read_file(chain((f'[{main_section}]',), lines)) (Maybe.of_nullable(config.get(main_section, 'RepoFolder', fallback=None)) .map(lambda v: v.format(**environ)) .map(Path) .if_present(repo_folders.append)) server_url = config.get(main_section, 'ServerURL', fallback=server_url) auth_server_url = config.get(main_section, 'AuthServerURL', fallback=auth_server_url) client_id = config.get(main_section, 'ClientId', fallback=client_id) client_secret = config.get(main_section, 'ClientSecret', fallback=client_secret) config_file_maybe.if_present(process_configuration) return Config(server_url=server_url or 'https://woggioni.net/jpacrepo/', auth_server_url=auth_server_url or 'https://woggioni.net/auth/realms/woggioni.net', repo_folders=tuple(repo_folders) or (Path('/var/cache/pacman/pkg'),), client_id=client_id or 'jpacrepo-client', client_secret=Maybe.of_nullable(client_secret) .map(lambda v: v.format(**environ)) .or_else(None) )