번역툴 2.0 업데이트

This commit is contained in:
Gnill82
2025-10-29 13:32:42 +09:00
parent fbef7989e4
commit e189a64631
24 changed files with 2486 additions and 1 deletions

193
lib/logger.py Normal file
View File

@ -0,0 +1,193 @@
"""
Colored Console Logger for DS_L10N
컬러 콘솔 로깅 시스템
"""
import logging
import sys
from datetime import datetime
from pathlib import Path
from typing import Optional
# Windows에서 ANSI 컬러 지원 활성화
if sys.platform == 'win32':
import os
os.system('') # ANSI escape sequences 활성화
# ANSI 컬러 코드
class Colors:
RESET = '\033[0m'
BOLD = '\033[1m'
# 기본 색상
BLACK = '\033[30m'
RED = '\033[31m'
GREEN = '\033[32m'
YELLOW = '\033[33m'
BLUE = '\033[34m'
MAGENTA = '\033[35m'
CYAN = '\033[36m'
WHITE = '\033[37m'
# 밝은 색상
BRIGHT_RED = '\033[91m'
BRIGHT_GREEN = '\033[92m'
BRIGHT_YELLOW = '\033[93m'
BRIGHT_BLUE = '\033[94m'
BRIGHT_MAGENTA = '\033[95m'
BRIGHT_CYAN = '\033[96m'
BRIGHT_WHITE = '\033[97m'
# 이모지 아이콘
class Icons:
SUCCESS = ''
ERROR = ''
WARNING = '⚠️'
INFO = ''
ROCKET = '🚀'
GEAR = '⚙️'
FILE = '📄'
FOLDER = '📁'
CHART = '📊'
SEARCH = '🔍'
CLEAN = '🧹'
BACKUP = '💾'
CLOCK = '⏱️'
class ColoredFormatter(logging.Formatter):
"""컬러 로그 포매터"""
LEVEL_COLORS = {
'DEBUG': Colors.CYAN,
'INFO': Colors.BLUE,
'WARNING': Colors.YELLOW,
'ERROR': Colors.RED,
'CRITICAL': Colors.BRIGHT_RED + Colors.BOLD,
'SUCCESS': Colors.GREEN,
}
LEVEL_ICONS = {
'DEBUG': Icons.GEAR,
'INFO': Icons.INFO,
'WARNING': Icons.WARNING,
'ERROR': Icons.ERROR,
'CRITICAL': Icons.ERROR,
'SUCCESS': Icons.SUCCESS,
}
def __init__(self, colored=True):
super().__init__()
self.colored = colored
def format(self, record):
if self.colored:
level_color = self.LEVEL_COLORS.get(record.levelname, '')
level_icon = self.LEVEL_ICONS.get(record.levelname, '')
reset = Colors.RESET
# 타임스탬프
timestamp = datetime.fromtimestamp(record.created).strftime('%Y-%m-%d %H:%M:%S')
# 레벨명 포맷
level_name = f"{level_color}{record.levelname:<8}{reset}"
# 메시지
message = record.getMessage()
return f"[{timestamp}] {level_icon} {level_name} {message}"
else:
timestamp = datetime.fromtimestamp(record.created).strftime('%Y-%m-%d %H:%M:%S')
return f"[{timestamp}] [{record.levelname:<8}] {record.getMessage()}"
class DSLogger:
"""DS_L10N 전용 로거"""
def __init__(self, name: str = 'DS_L10N',
console_level: str = 'INFO',
file_level: str = 'DEBUG',
log_file: Optional[Path] = None,
colored: bool = True):
self.logger = logging.getLogger(name)
self.logger.setLevel(logging.DEBUG)
self.logger.handlers.clear() # 기존 핸들러 제거
# 콘솔 핸들러
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(getattr(logging, console_level.upper()))
console_handler.setFormatter(ColoredFormatter(colored=colored))
self.logger.addHandler(console_handler)
# 파일 핸들러
if log_file:
log_file.parent.mkdir(parents=True, exist_ok=True)
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setLevel(getattr(logging, file_level.upper()))
file_handler.setFormatter(ColoredFormatter(colored=False))
self.logger.addHandler(file_handler)
# SUCCESS 레벨 추가 (INFO와 WARNING 사이)
logging.addLevelName(25, 'SUCCESS')
def debug(self, message: str):
self.logger.debug(message)
def info(self, message: str):
self.logger.info(message)
def success(self, message: str):
self.logger.log(25, message)
def warning(self, message: str):
self.logger.warning(message)
def error(self, message: str):
self.logger.error(message)
def critical(self, message: str):
self.logger.critical(message)
def separator(self, char: str = '=', length: int = 80):
"""구분선 출력"""
self.logger.info(char * length)
def section(self, title: str, icon: str = Icons.ROCKET):
"""섹션 제목 출력"""
self.separator()
self.logger.info(f"{icon} {title}")
self.separator()
def stats(self, **kwargs):
"""통계 정보 출력"""
self.logger.info(f"{Icons.CHART} 통계:")
for key, value in kwargs.items():
self.logger.info(f" - {key}: {value}")
# 전역 로거 인스턴스
_global_logger: Optional[DSLogger] = None
def get_logger() -> DSLogger:
"""전역 로거 가져오기"""
global _global_logger
if _global_logger is None:
_global_logger = DSLogger()
return _global_logger
def init_logger(config: dict, log_file: Optional[Path] = None) -> DSLogger:
"""로거 초기화"""
global _global_logger
logging_config = config.get('logging', {})
_global_logger = DSLogger(
console_level=logging_config.get('console_level', 'INFO'),
file_level=logging_config.get('file_level', 'DEBUG'),
log_file=log_file,
colored=logging_config.get('colored_output', True)
)
return _global_logger