Files
faction_war_dispatch_bot/config.py
2026-01-28 16:13:32 -05:00

124 lines
3.7 KiB
Python

from pathlib import Path
import json
import os
from dotenv import load_dotenv
# Load environment variables from .env file (if it exists)
load_dotenv()
class DynamicConfig:
"""Dynamic configuration that reloads from JSON on each access"""
def __init__(self):
self._json_cache = None
self._cache_time = 0
def _load_from_json(self):
"""Load config from JSON file if it exists"""
path = Path("data/config.json")
if not path.exists():
return {}
try:
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
return data.get("config", {})
except Exception as e:
print(f"Error loading config from JSON: {e}")
return {}
def _get_value(self, key: str, default, is_int: bool = False):
"""Get config value with priority: env vars > json > defaults"""
# 1. Try environment variable first (highest priority)
env_val = os.getenv(key)
if env_val is not None:
return int(env_val) if is_int else env_val
# 2. Try JSON config (reload from file each time)
json_config = self._load_from_json()
json_val = json_config.get(key)
if json_val is not None:
return json_val
# 3. Use default
return default
def reload(self):
"""Force reload of JSON config (called after settings update)"""
# Just clear cache - next access will reload
self._json_cache = None
print("[CONFIG] Configuration reloaded from file")
# Torn API
@property
def TORN_API_KEY(self):
return self._get_value("TORN_API_KEY", "YOUR_TORN_API_KEY_HERE")
# FFScouter API
@property
def FFSCOUTER_KEY(self):
return self._get_value("FFSCOUTER_KEY", "YOUR_FFSCOUTER_KEY_HERE")
# Discord Bot
@property
def DISCORD_TOKEN(self):
return self._get_value("DISCORD_TOKEN", "YOUR_DISCORD_BOT_TOKEN_HERE")
@property
def ALLOWED_CHANNEL_ID(self):
return self._get_value("ALLOWED_CHANNEL_ID", 0, is_int=True)
# Intervals
@property
def HIT_CHECK_INTERVAL(self):
return self._get_value("HIT_CHECK_INTERVAL", 60, is_int=True)
@property
def REASSIGN_DELAY(self):
return self._get_value("REASSIGN_DELAY", 120, is_int=True)
# Bot Assignment Settings
@property
def ASSIGNMENT_TIMEOUT(self):
return self._get_value("ASSIGNMENT_TIMEOUT", 60, is_int=True)
@property
def ASSIGNMENT_REMINDER(self):
return self._get_value("ASSIGNMENT_REMINDER", 45, is_int=True)
# Chain Timer Settings
@property
def CHAIN_TIMER_THRESHOLD(self):
return self._get_value("CHAIN_TIMER_THRESHOLD", 5, is_int=True)
# Authentication
@property
def AUTH_PASSWORD(self):
return self._get_value("AUTH_PASSWORD", "YOUR_AUTH_PASSWORD_HERE")
@property
def JWT_SECRET(self):
return self._get_value("JWT_SECRET", "your-secret-key-change-this")
# Create global config instance
config = DynamicConfig()
# Export reload function
def reload_config():
"""Reload configuration from file"""
config.reload()
# For backward compatibility, access config properties directly
# Code using "from config import TORN_API_KEY" needs to be changed to use config.TORN_API_KEY
# But we can't do that without breaking existing code, so we need a different approach
# Instead, we'll make these read from the config instance each time they're accessed
# by using __getattr__ at the module level
def __getattr__(name):
"""Dynamically fetch config values when accessed as module attributes"""
if hasattr(config, name):
return getattr(config, name)
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")