mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
git ignore secrets
set up git ignore secrets to not leak API keys
This commit is contained in:
20
.gitignore
vendored
Normal file
20
.gitignore
vendored
Normal file
@@ -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
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
"update_interval": 1
|
"update_interval": 1
|
||||||
},
|
},
|
||||||
"weather": {
|
"weather": {
|
||||||
"api_key": "YOUR_OPENWEATHERMAP_API_KEY",
|
|
||||||
"update_interval": 300,
|
"update_interval": 300,
|
||||||
"units": "imperial",
|
"units": "imperial",
|
||||||
"display_format": "{temp}°F\n{condition}"
|
"display_format": "{temp}°F\n{condition}"
|
||||||
|
|||||||
5
config/config_secrets.template.json
Normal file
5
config/config_secrets.template.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"weather": {
|
||||||
|
"api_key": "YOUR_OPENWEATHERMAP_API_KEY"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,23 +3,42 @@ import os
|
|||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
|
|
||||||
class ConfigManager:
|
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.config_path = config_path
|
||||||
|
self.secrets_path = secrets_path
|
||||||
self.config: Dict[str, Any] = {}
|
self.config: Dict[str, Any] = {}
|
||||||
self.load_config()
|
self.load_config()
|
||||||
|
|
||||||
def load_config(self) -> None:
|
def load_config(self) -> None:
|
||||||
"""Load configuration from JSON file."""
|
"""Load configuration from JSON files."""
|
||||||
try:
|
try:
|
||||||
|
# Load main config
|
||||||
with open(self.config_path, 'r') as f:
|
with open(self.config_path, 'r') as f:
|
||||||
self.config = json.load(f)
|
self.config = json.load(f)
|
||||||
except FileNotFoundError:
|
|
||||||
print(f"Configuration file not found at {self.config_path}")
|
# Load and merge secrets if they exist
|
||||||
raise
|
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:
|
except json.JSONDecodeError:
|
||||||
print("Error parsing configuration file")
|
print("Error parsing configuration file")
|
||||||
raise
|
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:
|
def get_timezone(self) -> str:
|
||||||
"""Get the configured timezone."""
|
"""Get the configured timezone."""
|
||||||
return self.config.get('timezone', 'UTC')
|
return self.config.get('timezone', 'UTC')
|
||||||
|
|||||||
Reference in New Issue
Block a user