diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..7c0a0efb --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class + +# Secrets +config/config_secrets.json + +# Environment +.env +.venv +env/ +venv/ +ENV/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo \ No newline at end of file diff --git a/config/config.json b/config/config.json index 7d434ab8..1f49432e 100644 --- a/config/config.json +++ b/config/config.json @@ -17,7 +17,6 @@ "update_interval": 1 }, "weather": { - "api_key": "YOUR_OPENWEATHERMAP_API_KEY", "update_interval": 300, "units": "imperial", "display_format": "{temp}°F\n{condition}" diff --git a/config/config_secrets.template.json b/config/config_secrets.template.json new file mode 100644 index 00000000..6153736f --- /dev/null +++ b/config/config_secrets.template.json @@ -0,0 +1,5 @@ +{ + "weather": { + "api_key": "YOUR_OPENWEATHERMAP_API_KEY" + } +} \ No newline at end of file diff --git a/src/config_manager.py b/src/config_manager.py index 2aca9d42..9fe0e817 100644 --- a/src/config_manager.py +++ b/src/config_manager.py @@ -3,23 +3,42 @@ import os from typing import Dict, Any class ConfigManager: - def __init__(self, config_path: str = "../config/config.json"): + def __init__(self, config_path: str = "../config/config.json", secrets_path: str = "../config/config_secrets.json"): self.config_path = config_path + self.secrets_path = secrets_path self.config: Dict[str, Any] = {} self.load_config() def load_config(self) -> None: - """Load configuration from JSON file.""" + """Load configuration from JSON files.""" try: + # Load main config with open(self.config_path, 'r') as f: self.config = json.load(f) - except FileNotFoundError: - print(f"Configuration file not found at {self.config_path}") - raise + + # Load and merge secrets if they exist + if os.path.exists(self.secrets_path): + with open(self.secrets_path, 'r') as f: + secrets = json.load(f) + # Deep merge secrets into config + self._deep_merge(self.config, secrets) + + except FileNotFoundError as e: + if str(e).find('config_secrets.json') == -1: # Only raise if main config is missing + print(f"Configuration file not found at {self.config_path}") + raise except json.JSONDecodeError: print("Error parsing configuration file") raise + def _deep_merge(self, target: Dict, source: Dict) -> None: + """Deep merge source dict into target dict.""" + for key, value in source.items(): + if key in target and isinstance(target[key], dict) and isinstance(value, dict): + self._deep_merge(target[key], value) + else: + target[key] = value + def get_timezone(self) -> str: """Get the configured timezone.""" return self.config.get('timezone', 'UTC')