import os, pyinotify, sys from configparser import ConfigParser, ParsingError from subprocess import run, PIPE from auto_cpufreq.config.config_event_handler import ConfigEventHandler def find_config_file(args_config_file) -> str: """ Find the config file to use. Look for a config file in the following priorization order: 1. Command line argument 2. User config file 3. System config file :param args_config_file: Path to the config file provided as a command line argument :return: The path to the config file to use """ # Prepare paths # use $SUDO_USER or $USER to get home dir since sudo can't access # user env vars home = run(["getent passwd ${SUDO_USER:-$USER} | cut -d: -f6"], shell=True, stdout=PIPE, universal_newlines=True ).stdout.rstrip() user_config_dir = os.getenv("XDG_CONFIG_HOME", default=os.path.join(home, ".config")) user_config_file = os.path.join(user_config_dir, "auto-cpufreq/auto-cpufreq.conf") system_config_file = "/etc/auto-cpufreq.conf" if args_config_file is not None: # (1) Command line argument was specified # Check if the config file path points to a valid file if os.path.isfile(args_config_file): return args_config_file else: # Not a valid file print(f"Config file specified with '--config {args_config_file}' not found.") sys.exit(1) elif os.path.isfile(user_config_file): return user_config_file # (2) User config file else: return system_config_file # (3) System config file (default if nothing else is found) class _Config: def __init__(self) -> None: self.path: str = "" self._config: ConfigParser = ConfigParser() self.watch_manager: pyinotify.WatchManager = pyinotify.WatchManager() self.config_handler = ConfigEventHandler(self) # check for file changes using threading self.notifier: pyinotify.ThreadedNotifier = pyinotify.ThreadedNotifier(self.watch_manager, self.config_handler) def set_path(self, path: str) -> None: self.path = path mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY | pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO self.watch_manager.add_watch(os.path.dirname(path), mask=mask) if os.path.isfile(path): self.update_config() def has_config(self) -> bool: return os.path.isfile(self.path) def get_config(self) -> ConfigParser: return self._config def update_config(self) -> None: # create new ConfigParser to prevent old data from remaining self._config = ConfigParser() try: self._config.read(self.path) except ParsingError as e: print(f"The following error occured while parsing the config file: \n{repr(e)}") config = _Config()