Add configuration management and improve argument validation logic
- Introduced `DirectoryManager` to handle configuration directory creation. - Added `ConfigManager` with singleton design to manage config reading. - Expanded argument validation in `Application` to refine error checks. - Updated dependencies to include `rich`, `tomli`, and `tomli_w`. - Adjusted setup logic to prompt users about missing configurations.
This commit is contained in:
parent
fac9a70548
commit
855f367727
|
|
@ -17,6 +17,10 @@ classifiers = [
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"tomli",
|
||||||
|
"tomli_w",
|
||||||
|
"rich"
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,26 @@
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
import rich
|
||||||
|
|
||||||
|
from metar_navigate.utils import ConfigManager
|
||||||
|
|
||||||
class Application:
|
class Application:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.parser = None
|
self.parser = None
|
||||||
self.args = None
|
self.args = None
|
||||||
|
self.config = ConfigManager()
|
||||||
|
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self._validate_args()
|
self._validate_args()
|
||||||
|
|
||||||
|
if self.config.read_config() is None:
|
||||||
|
rich.print("[bold red]No config file found. Please run metarNavigate --configure[/bold red] ")
|
||||||
|
|
||||||
def _validate_args(self):
|
def _validate_args(self):
|
||||||
self.parser = argparse.ArgumentParser()
|
self.parser = argparse.ArgumentParser()
|
||||||
self.parser.add_argument("--no-tui", action="store_true", help="disables the TUI")
|
self.parser.add_argument("--no-tui", action="store_true", help="disables the TUI")
|
||||||
|
self.parser.add_argument("--configure", "-c" ,action="store_true", help="runs the configuration wizard")
|
||||||
self.parser.add_argument("--detailed", action="store_true", help="displays more detailed METAR Breakdown "
|
self.parser.add_argument("--detailed", action="store_true", help="displays more detailed METAR Breakdown "
|
||||||
"(Only available with --no-tui flag)")
|
"(Only available with --no-tui flag)")
|
||||||
self.parser.add_argument("-t", "--type", choices=["TAF", "METAR"], default="METAR", help="Select the Type "
|
self.parser.add_argument("-t", "--type", choices=["TAF", "METAR"], default="METAR", help="Select the Type "
|
||||||
|
|
@ -22,14 +30,36 @@ class Application:
|
||||||
|
|
||||||
self.args = self.parser.parse_args()
|
self.args = self.parser.parse_args()
|
||||||
|
|
||||||
if self.args.no_tui and not self.args.ICAO:
|
|
||||||
self.parser.error("--no-tui requires an ICAO code")
|
|
||||||
|
|
||||||
|
if self.args.configure and self.args.ICAO:
|
||||||
|
self.parser.error("--configure não aceita código ICAO")
|
||||||
|
|
||||||
|
|
||||||
|
if self.args.configure and self.args.detailed:
|
||||||
|
self.parser.error("--configure não pode ser usado com --detailed")
|
||||||
|
|
||||||
|
|
||||||
|
if self.args.configure and ('--type' in sys.argv or '-t' in sys.argv):
|
||||||
|
self.parser.error("--configure não pode ser usado com --type/-t")
|
||||||
|
|
||||||
|
|
||||||
|
if self.args.no_tui and not self.args.configure and not self.args.ICAO:
|
||||||
|
self.parser.error("--no-tui requer código ICAO (exceto quando usado com --configure)")
|
||||||
|
|
||||||
|
|
||||||
if self.args.ICAO and not self.args.no_tui:
|
if self.args.ICAO and not self.args.no_tui:
|
||||||
self.parser.error("ICAO code only required with --no-tui flag")
|
self.parser.error("Código ICAO só pode ser usado com --no-tui")
|
||||||
if not self.args.no_tui and self.args.detailed:
|
|
||||||
self.parser.error("--detailed flag only available with --no-tui flag")
|
|
||||||
|
if self.args.detailed and not self.args.no_tui:
|
||||||
|
self.parser.error("--detailed requer --no-tui")
|
||||||
|
|
||||||
|
|
||||||
if not self.args.no_tui and ('--type' in sys.argv or '-t' in sys.argv):
|
if not self.args.no_tui and ('--type' in sys.argv or '-t' in sys.argv):
|
||||||
self.parser.error("--type or -t flag only available with --no-tui flag")
|
self.parser.error("--type/-t requer --no-tui")
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
from .directory_manager import DirectoryManager
|
||||||
|
from .config_manager import ConfigManager
|
||||||
|
|
||||||
|
__all__ = ["DirectoryManager", "ConfigManager"]
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import tomli
|
||||||
|
|
||||||
|
from metar_navigate.utils import DirectoryManager
|
||||||
|
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
|
class SingletonMeta(type):
|
||||||
|
_instances = {}
|
||||||
|
_lock: Lock = Lock()
|
||||||
|
|
||||||
|
def __call__(cls, *args, **kwargs):
|
||||||
|
with cls._lock:
|
||||||
|
if cls not in cls._instances:
|
||||||
|
instance = super().__call__(*args, **kwargs)
|
||||||
|
cls._instances[cls] = instance
|
||||||
|
return cls._instances[cls]
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigManager(metaclass=SingletonMeta):
|
||||||
|
def __init__(self):
|
||||||
|
self.config_dir = DirectoryManager.get_config_directory()
|
||||||
|
self.__data = None
|
||||||
|
|
||||||
|
def read_config(self):
|
||||||
|
if os.path.exists(f"{self.config_dir}/config.toml"):
|
||||||
|
try:
|
||||||
|
with open(f"{self.config_dir}/config.toml", "rb") as f:
|
||||||
|
data = tomli.load(f)
|
||||||
|
except tomli.TOMLDecodeError as e:
|
||||||
|
raise ValueError(f"Invalid TOML file; {e}")
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f"Error reading config file; {e}")
|
||||||
|
|
||||||
|
self.__data = data
|
||||||
|
return self.__data
|
||||||
|
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
class DirectoryManager:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_config_directory()-> Path:
|
||||||
|
home = Path.home()
|
||||||
|
config_dir = home / ".METARNavigate"
|
||||||
|
config_dir.mkdir(exist_ok=True)
|
||||||
|
os.chmod(config_dir,0o644)
|
||||||
|
return config_dir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue