| """
|
| SETTINGS & CONFIGURATION MANAGEMENT
|
| Handles user preferences, system settings, Discord bot configuration, etc.
|
| """
|
|
|
| import json
|
| import os
|
| from datetime import datetime
|
| from typing import Dict, Optional, Any
|
| from pathlib import Path
|
| import logging
|
|
|
| logger = logging.getLogger(__name__)
|
|
|
|
|
| class SettingsManager:
|
| """Manages all application and user settings"""
|
|
|
| def __init__(self, data_dir='noahski_data'):
|
| self.data_dir = Path(data_dir)
|
| self.settings_dir = self.data_dir / 'settings'
|
| self.settings_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
| self.global_settings_file = self.settings_dir / 'global_settings.json'
|
|
|
|
|
| self.user_settings_dir = self.settings_dir / 'users'
|
| self.user_settings_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
| self.global_settings = self._load_global_settings()
|
|
|
| logger.info("✅ Settings Manager initialized")
|
|
|
| def _load_global_settings(self) -> Dict:
|
| """Load global settings from file"""
|
| if self.global_settings_file.exists():
|
| try:
|
| with open(self.global_settings_file, 'r', encoding='utf-8') as f:
|
| return json.load(f)
|
| except Exception as e:
|
| logger.error(f"Failed to load global settings: {e}")
|
|
|
|
|
| defaults = {
|
| 'app_name': 'NoahsKI',
|
| 'version': '6.0',
|
| 'timezone': 'UTC',
|
| 'max_users': 100,
|
| 'debug_mode': False,
|
| 'enable_logging': True,
|
| 'enable_cache': True,
|
| 'cache_ttl': 86400,
|
| 'rate_limit_enabled': True,
|
| 'rate_limit_requests': 100,
|
| 'rate_limit_window': 3600,
|
| 'image_generation_enabled': True,
|
| 'web_search_enabled': True,
|
| 'code_generation_enabled': True,
|
| 'file_processing_enabled': True,
|
| 'features': {
|
| 'discord_bot': True,
|
| 'web_search': True,
|
| 'image_generation': True,
|
| 'code_execution': False,
|
| 'voice_synthesis': False,
|
| 'speech_recognition': False,
|
| 'video_processing': False
|
| }
|
| }
|
|
|
| self._save_global_settings(defaults)
|
| return defaults
|
|
|
| def _save_global_settings(self, settings: Dict):
|
| """Save global settings to file"""
|
| try:
|
| with open(self.global_settings_file, 'w', encoding='utf-8') as f:
|
| json.dump(settings, f, indent=2, ensure_ascii=False)
|
| except Exception as e:
|
| logger.error(f"Failed to save global settings: {e}")
|
|
|
| def get_global_setting(self, key: str, default=None) -> Any:
|
| """Get a global setting"""
|
| return self.global_settings.get(key, default)
|
|
|
| def set_global_setting(self, key: str, value: Any) -> bool:
|
| """Set a global setting"""
|
| try:
|
| self.global_settings[key] = value
|
| self._save_global_settings(self.global_settings)
|
| logger.info(f"✅ Global setting '{key}' updated")
|
| return True
|
| except Exception as e:
|
| logger.error(f"Failed to set global setting '{key}': {e}")
|
| return False
|
|
|
| def get_user_settings(self, email: str) -> Dict:
|
| """Get all settings for a user"""
|
| user_settings_file = self.user_settings_dir / f"{email}.json"
|
|
|
| if user_settings_file.exists():
|
| try:
|
| with open(user_settings_file, 'r', encoding='utf-8') as f:
|
| return json.load(f)
|
| except Exception as e:
|
| logger.error(f"Failed to load user settings for {email}: {e}")
|
|
|
|
|
| defaults = {
|
| 'email': email,
|
| 'created_at': datetime.now().isoformat(),
|
| 'theme': 'dark',
|
| 'language': 'de',
|
| 'timezone': 'UTC',
|
| 'notifications_enabled': True,
|
| 'email_notifications': False,
|
| 'auto_save': True,
|
| 'discord_bot': {
|
| 'enabled': False,
|
| 'prefix': '!',
|
| 'status': 'online',
|
| 'status_text': 'mit NoahsKI',
|
| 'intents': ['messages', 'reactions', 'guild_messages']
|
| },
|
| 'chat': {
|
| 'theme': 'dark',
|
| 'font_size': 16,
|
| 'show_timestamps': True,
|
| 'show_sources': True,
|
| 'auto_scroll': True
|
| },
|
| 'privacy': {
|
| 'save_chat_history': True,
|
| 'allow_feedback': True,
|
| 'allow_analytics': False,
|
| 'data_retention_days': 90
|
| },
|
| 'preferences': {
|
| 'agi_enabled': True,
|
| 'show_reasoning': False,
|
| 'auto_complete': True,
|
| 'spell_check': True
|
| },
|
| 'developer': {
|
| 'show_logs': False,
|
| 'show_debug': False,
|
| 'api_key': None,
|
| 'webhook_url': None
|
| }
|
| }
|
|
|
| self._save_user_settings(email, defaults)
|
| return defaults
|
|
|
| def _save_user_settings(self, email: str, settings: Dict):
|
| """Save user settings to file"""
|
| try:
|
| user_settings_file = self.user_settings_dir / f"{email}.json"
|
| with open(user_settings_file, 'w', encoding='utf-8') as f:
|
| json.dump(settings, f, indent=2, ensure_ascii=False)
|
| except Exception as e:
|
| logger.error(f"Failed to save user settings for {email}: {e}")
|
|
|
| def update_user_settings(self, email: str, updates: Dict) -> Dict:
|
| """Update specific user settings"""
|
| try:
|
| settings = self.get_user_settings(email)
|
|
|
|
|
| for key, value in updates.items():
|
| if key in settings and isinstance(settings[key], dict) and isinstance(value, dict):
|
| settings[key].update(value)
|
| else:
|
| settings[key] = value
|
|
|
| settings['updated_at'] = datetime.now().isoformat()
|
| self._save_user_settings(email, settings)
|
|
|
| logger.info(f"✅ Settings updated for user: {email}")
|
| return {'success': True, 'settings': settings}
|
| except Exception as e:
|
| logger.error(f"Failed to update settings for {email}: {e}")
|
| return {'success': False, 'error': str(e)}
|
|
|
| def get_user_setting(self, email: str, key: str, default=None) -> Any:
|
| """Get a specific user setting"""
|
| settings = self.get_user_settings(email)
|
|
|
|
|
| if '.' in key:
|
| keys = key.split('.')
|
| value = settings
|
| for k in keys:
|
| if isinstance(value, dict):
|
| value = value.get(k)
|
| else:
|
| return default
|
| return value if value is not None else default
|
|
|
| return settings.get(key, default)
|
|
|
| def set_user_setting(self, email: str, key: str, value: Any) -> bool:
|
| """Set a specific user setting"""
|
| try:
|
| settings = self.get_user_settings(email)
|
|
|
|
|
| if '.' in key:
|
| keys = key.split('.')
|
| current = settings
|
| for k in keys[:-1]:
|
| if k not in current:
|
| current[k] = {}
|
| current = current[k]
|
| current[keys[-1]] = value
|
| else:
|
| settings[key] = value
|
|
|
| self._save_user_settings(email, settings)
|
| return True
|
| except Exception as e:
|
| logger.error(f"Failed to set user setting '{key}' for {email}: {e}")
|
| return False
|
|
|
| def apply_discord_settings(self, email: str, discord_settings: Dict) -> Dict:
|
| """Apply Discord bot settings"""
|
| try:
|
| result = self.update_user_settings(email, {
|
| 'discord_bot': discord_settings
|
| })
|
|
|
| if result['success']:
|
| logger.info(f"✅ Discord settings applied for: {email}")
|
|
|
|
|
| return result
|
| except Exception as e:
|
| logger.error(f"Failed to apply Discord settings: {e}")
|
| return {'success': False, 'error': str(e)}
|
|
|
| def apply_theme(self, email: str, theme: str) -> bool:
|
| """Apply theme setting"""
|
| if theme not in ['light', 'dark', 'auto']:
|
| logger.warning(f"Invalid theme: {theme}")
|
| return False
|
|
|
| return self.set_user_setting(email, 'theme', theme)
|
|
|
| def apply_language(self, email: str, language: str) -> bool:
|
| """Apply language setting"""
|
| if language not in ['de', 'en', 'fr', 'es', 'ja', 'zh']:
|
| logger.warning(f"Invalid language: {language}")
|
| return False
|
|
|
| return self.set_user_setting(email, 'language', language)
|
|
|
| def apply_chat_settings(self, email: str, chat_settings: Dict) -> bool:
|
| """Apply chat UI settings"""
|
| return self.update_user_settings(email, {
|
| 'chat': chat_settings
|
| }).get('success', False)
|
|
|
| def apply_privacy_settings(self, email: str, privacy_settings: Dict) -> bool:
|
| """Apply privacy settings"""
|
| return self.update_user_settings(email, {
|
| 'privacy': privacy_settings
|
| }).get('success', False)
|
|
|
| def export_user_data(self, email: str) -> Dict:
|
| """Export all user data"""
|
| try:
|
| settings = self.get_user_settings(email)
|
| return {
|
| 'success': True,
|
| 'email': email,
|
| 'exported_at': datetime.now().isoformat(),
|
| 'settings': settings
|
| }
|
| except Exception as e:
|
| logger.error(f"Failed to export user data for {email}: {e}")
|
| return {'success': False, 'error': str(e)}
|
|
|
| def reset_user_settings(self, email: str) -> bool:
|
| """Reset user settings to defaults"""
|
| try:
|
| user_settings_file = self.user_settings_dir / f"{email}.json"
|
| if user_settings_file.exists():
|
| user_settings_file.unlink()
|
|
|
|
|
| self.get_user_settings(email)
|
| logger.info(f"✅ Settings reset for user: {email}")
|
| return True
|
| except Exception as e:
|
| logger.error(f"Failed to reset settings for {email}: {e}")
|
| return False
|
|
|
| def get_all_user_emails(self) -> list:
|
| """Get list of all users with settings"""
|
| try:
|
| emails = [f.stem for f in self.user_settings_dir.glob('*.json')]
|
| return emails
|
| except Exception as e:
|
| logger.error(f"Failed to get user list: {e}")
|
| return []
|
|
|
| def get_settings_summary(self) -> Dict:
|
| """Get summary of all settings"""
|
| return {
|
| 'global_settings_file': str(self.global_settings_file),
|
| 'user_settings_dir': str(self.user_settings_dir),
|
| 'total_users': len(self.get_all_user_emails()),
|
| 'global_settings_keys': list(self.global_settings.keys()),
|
| 'timestamp': datetime.now().isoformat()
|
| }
|
|
|
|
|
|
|
| _settings_manager = None
|
|
|
|
|
| def get_settings_manager() -> SettingsManager:
|
| """Get singleton settings manager"""
|
| global _settings_manager
|
| if _settings_manager is None:
|
| _settings_manager = SettingsManager()
|
| return _settings_manager
|
|
|
|
|
| def init_settings_manager(data_dir='noahski_data') -> SettingsManager:
|
| """Initialize settings manager with custom data directory"""
|
| global _settings_manager
|
| _settings_manager = SettingsManager(data_dir)
|
| return _settings_manager
|
|
|