- Updated `.dockerignore` to include additional development and temporary files, enhancing build efficiency. - Modified `.gitignore` to remove unnecessary entries and streamline ignored files. - Enhanced `docker-compose.yml` with health checks, resource limits, and improved environment variable handling for better service management. - Refactored `Dockerfile.bot` to utilize a multi-stage build for optimized image size and security. - Improved `Makefile` with new commands for deployment, migration, and backup, along with enhanced help documentation. - Updated `requirements.txt` to include new dependencies for environment variable management. - Refactored metrics handling in the bot to ensure proper initialization and collection.
92 lines
3.2 KiB
Python
92 lines
3.2 KiB
Python
"""
|
|
Configuration management for the Telegram bot.
|
|
Supports both environment variables and .env files.
|
|
"""
|
|
|
|
import os
|
|
from typing import Dict, Any, Optional
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
class ConfigManager:
|
|
"""Manages bot configuration with environment variable support."""
|
|
|
|
def __init__(self, env_file: str = ".env"):
|
|
self.env_file = env_file
|
|
self._load_env()
|
|
|
|
def _load_env(self):
|
|
"""Load configuration from .env file if exists."""
|
|
# Load from .env file if exists
|
|
if os.path.exists(self.env_file):
|
|
load_dotenv(self.env_file)
|
|
|
|
def get(self, section: str, key: str, default: Any = None) -> str:
|
|
"""Get configuration value with environment variable override."""
|
|
# Check environment variable first
|
|
env_key = f"{section.upper()}_{key.upper()}"
|
|
env_value = os.getenv(env_key)
|
|
if env_value is not None:
|
|
return env_value
|
|
|
|
# Fall back to direct environment variable
|
|
direct_env_value = os.getenv(key.upper())
|
|
if direct_env_value is not None:
|
|
return direct_env_value
|
|
|
|
return default
|
|
|
|
def getboolean(self, section: str, key: str, default: bool = False) -> bool:
|
|
"""Get boolean configuration value."""
|
|
value = self.get(section, key, str(default))
|
|
if isinstance(value, bool):
|
|
return value
|
|
return value.lower() in ('true', '1', 'yes', 'on')
|
|
|
|
def getint(self, section: str, key: str, default: int = 0) -> int:
|
|
"""Get integer configuration value."""
|
|
value = self.get(section, key, str(default))
|
|
try:
|
|
return int(value)
|
|
except (ValueError, TypeError):
|
|
return default
|
|
|
|
def get_all_settings(self) -> Dict[str, Dict[str, Any]]:
|
|
"""Get all settings as dictionary."""
|
|
settings = {}
|
|
|
|
# Telegram секция
|
|
settings['Telegram'] = {
|
|
'bot_token': self.get('Telegram', 'bot_token', ''),
|
|
'listen_bot_token': self.get('Telegram', 'listen_bot_token', ''),
|
|
'test_bot_token': self.get('Telegram', 'test_bot_token', ''),
|
|
'preview_link': self.getboolean('Telegram', 'preview_link', False),
|
|
'main_public': self.get('Telegram', 'main_public', ''),
|
|
'group_for_posts': self.getint('Telegram', 'group_for_posts', 0),
|
|
'group_for_message': self.getint('Telegram', 'group_for_message', 0),
|
|
'group_for_logs': self.getint('Telegram', 'group_for_logs', 0),
|
|
'important_logs': self.getint('Telegram', 'important_logs', 0),
|
|
'archive': self.getint('Telegram', 'archive', 0),
|
|
'test_group': self.getint('Telegram', 'test_group', 0)
|
|
}
|
|
|
|
# Settings секция
|
|
settings['Settings'] = {
|
|
'logs': self.getboolean('Settings', 'logs', False),
|
|
'test': self.getboolean('Settings', 'test', False)
|
|
}
|
|
|
|
return settings
|
|
|
|
|
|
# Global config instance
|
|
_config_instance: Optional[ConfigManager] = None
|
|
|
|
|
|
def get_config() -> ConfigManager:
|
|
"""Get global configuration instance."""
|
|
global _config_instance
|
|
if _config_instance is None:
|
|
_config_instance = ConfigManager()
|
|
return _config_instance
|