KManager / core /paths.py
StarrySkyWorld's picture
Initial commit
494c89b
"""
Централизованное управление путями
Все пути в одном месте для удобства
"""
import os
import platform
from pathlib import Path
from typing import Optional
class Paths:
"""Singleton для управления всеми путями в системе"""
_instance: Optional['Paths'] = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._init_paths()
return cls._instance
def _init_paths(self):
"""Инициализация всех путей"""
self.os_type = platform.system().lower()
self.home = Path.home()
# =====================================================================
# Project paths
# =====================================================================
self.autoreg_dir = Path(__file__).parent.parent
self.project_dir = self.autoreg_dir.parent
# =====================================================================
# User data paths (~/.kiro-manager-wb/)
# =====================================================================
self.user_data_dir = self.home / '.kiro-manager-wb'
self.tokens_dir = self.user_data_dir / 'tokens'
self.backups_dir = self.user_data_dir / 'backups'
self.logs_dir = self.user_data_dir / 'logs'
self.cache_dir = self.user_data_dir / 'cache'
self.debug_sessions_dir = self.user_data_dir / 'debug_sessions'
# Files
self.accounts_file = self.user_data_dir / 'accounts.json'
self.settings_file = self.user_data_dir / 'settings.json'
self.log_file = self.logs_dir / 'autoreg.log'
# =====================================================================
# AWS SSO cache (~/.aws/sso/cache/)
# =====================================================================
self.aws_dir = self.home / '.aws'
self.aws_sso_cache = self.aws_dir / 'sso' / 'cache'
self.kiro_token_file = self.aws_sso_cache / 'kiro-auth-token.json'
# =====================================================================
# Kiro IDE paths
# =====================================================================
if self.os_type == 'windows':
appdata = os.environ.get('APPDATA', '')
self.kiro_data_dir = Path(appdata) / 'Kiro' if appdata else None
elif self.os_type == 'darwin': # macOS
self.kiro_data_dir = self.home / 'Library' / 'Application Support' / 'Kiro'
else: # Linux
self.kiro_data_dir = self.home / '.config' / 'Kiro'
if self.kiro_data_dir:
self.kiro_user_dir = self.kiro_data_dir / 'User'
self.kiro_global_storage = self.kiro_user_dir / 'globalStorage'
self.kiro_storage_json = self.kiro_global_storage / 'storage.json'
self.kiro_state_db = self.kiro_global_storage / 'state.vscdb'
self.kiro_agent_storage = self.kiro_global_storage / 'kiro.kiroagent'
else:
self.kiro_user_dir = None
self.kiro_global_storage = None
self.kiro_storage_json = None
self.kiro_state_db = None
self.kiro_agent_storage = None
# =====================================================================
# Kiro installation path
# =====================================================================
self.kiro_install_path: Optional[Path] = None
if self.os_type == 'windows':
possible_paths = [
Path(os.environ.get('LOCALAPPDATA', '')) / 'Programs' / 'kiro',
Path(os.environ.get('PROGRAMFILES', '')) / 'Kiro',
]
# Additional paths for non-standard installations
for drive in ['C:', 'D:', 'E:', 'S:', 'F:', 'G:']:
possible_paths.append(Path(drive) / 'Kiro')
possible_paths.append(Path(drive) / 'Programs' / 'Kiro')
possible_paths.append(Path(drive) / 'kiro')
elif self.os_type == 'darwin':
possible_paths = [
Path('/Applications/Kiro.app/Contents/Resources/app'),
self.home / 'Applications' / 'Kiro.app' / 'Contents' / 'Resources' / 'app',
]
else: # Linux
possible_paths = [
Path('/usr/share/kiro'),
Path('/opt/kiro'),
self.home / '.local' / 'share' / 'kiro',
]
for path in possible_paths:
if path.exists():
self.kiro_install_path = path
break
# =====================================================================
# Kiro settings (~/.kiro/)
# =====================================================================
self.kiro_settings_dir = self.home / '.kiro' / 'settings'
self.kiro_mcp_config = self.kiro_settings_dir / 'mcp.json'
# Ensure directories exist
self._ensure_dirs()
def _ensure_dirs(self):
"""Создаёт необходимые директории"""
dirs_to_create = [
self.user_data_dir,
self.tokens_dir,
self.backups_dir,
self.logs_dir,
self.cache_dir,
self.debug_sessions_dir,
self.aws_sso_cache,
]
for dir_path in dirs_to_create:
dir_path.mkdir(parents=True, exist_ok=True)
# =========================================================================
# Helper methods
# =========================================================================
def is_kiro_installed(self) -> bool:
"""Проверяет установлен ли Kiro"""
return self.kiro_data_dir is not None and self.kiro_data_dir.exists()
def get_token_file(self, name: str) -> Path:
"""Возвращает путь к файлу токена"""
if not name.endswith('.json'):
name = f"token-{name}.json"
return self.tokens_dir / name
def get_backup_file(self, prefix: str, ext: str = 'json') -> Path:
"""Генерирует путь для нового бэкапа с timestamp"""
from datetime import datetime
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
return self.backups_dir / f"{prefix}-{timestamp}.{ext}"
def get_client_registration_file(self, client_id_hash: str) -> Path:
"""Возвращает путь к файлу регистрации клиента"""
return self.aws_sso_cache / f"{client_id_hash}.json"
def list_tokens(self) -> list[Path]:
"""Возвращает список всех файлов токенов"""
return list(self.tokens_dir.glob('token-*.json'))
def list_backups(self, prefix: str = None) -> list[Path]:
"""Возвращает список бэкапов"""
pattern = f"{prefix}-*.json" if prefix else "*.json"
return sorted(self.backups_dir.glob(pattern), reverse=True)
# Singleton instance
_paths: Optional[Paths] = None
def get_paths() -> Paths:
"""Получить singleton instance Paths"""
global _paths
if _paths is None:
_paths = Paths()
return _paths