v2.0.1 업데이트

This commit is contained in:
Gnill82
2025-10-29 15:35:54 +09:00
parent e189a64631
commit 0482c8299b
44 changed files with 89080 additions and 718 deletions

View File

@ -1,13 +0,0 @@
@echo off
chcp 65001 > nul
cd /d "%~dp0"
echo ========================================
echo DS_L10N - 미번역 항목 추출
echo ========================================
echo.
python ds_l10n.py extract
echo.
pause

View File

@ -1,13 +0,0 @@
@echo off
chcp 65001 > nul
cd /d "%~dp0"
echo ========================================
echo DS_L10N - 번역 검증
echo ========================================
echo.
python ds_l10n.py validate
echo.
pause

View File

@ -1,13 +0,0 @@
@echo off
chcp 65001 > nul
cd /d "%~dp0"
echo ========================================
echo DS_L10N - PO 파일 업데이트
echo ========================================
echo.
python ds_l10n.py update
echo.
pause

View File

@ -1,13 +0,0 @@
@echo off
chcp 65001 > nul
cd /d "%~dp0"
echo ========================================
echo DS_L10N - CSV 병합
echo ========================================
echo.
python ds_l10n.py merge
echo.
pause

View File

@ -1,13 +0,0 @@
@echo off
chcp 65001 > nul
cd /d "%~dp0"
echo ========================================
echo DS_L10N - 파일 정리
echo ========================================
echo.
python ds_l10n.py cleanup
echo.
pause

444
README.md
View File

@ -2,26 +2,35 @@
던전스토커즈 다국어 번역 통합 툴
---
## 📑 목차
1. [빠른 시작](#-빠른-시작)
2. [주요 기능](#-주요-기능)
3. [설치 및 설정](#-설치-및-설정)
4. [워크플로우](#-워크플로우)
5. [명령어 상세](#-명령어-상세)
6. [문제 해결](#-문제-해결)
7. [프로젝트 구조](#-프로젝트-구조)
---
## 🚀 빠른 시작
### 1. 라이브러리 설치
### 1. 라이브러리 설치 (최초 1회)
```bash
cd D:\Work\WorldStalker\DS_L10N
pip install -r requirements.txt
```
### 2. 배치 파일로 실행 (권장)
**설치되는 라이브러리**:
- `polib`: PO 파일 안정적 처리
- `PyYAML`: 설정 파일 관리
- `pandas`: 데이터 처리
더블클릭으로 실행:
- `1_미번역추출.bat` - 미번역 항목 추출
- `2_번역검증.bat` - 번역 검증 (신규)
- `3_PO업데이트.bat` - PO 파일 업데이트
- `4_CSV병합.bat` - CSV 병합
- `5_파일정리.bat` - 파일 정리 (신규)
- `전체워크플로우.bat` - 2~5 자동 실행
### 3. 명령어로 실행
### 2. 명령어 실행
```bash
python ds_l10n.py extract # 미번역 추출
@ -31,25 +40,256 @@ python ds_l10n.py merge # CSV 병합
python ds_l10n.py cleanup # 파일 정리
```
## 📚 상세 가이드
### 3. 도움말
자세한 사용법은 [`사용가이드.md`](사용가이드.md) 참조
```bash
python ds_l10n.py --help
python ds_l10n.py extract --help
```
## ✨ 주요 개선사항
---
### 기존 문제점
- ❌ 매번 파일/폴더 선택이 번거로움
- ❌ 번역 오류 사전 검증 불가
- ❌ po_update_from_tsv.py 가끔 오류 발생
- ❌ 결과물 파일이 너무 많이 쌓임
## ✨ 주요 기능
### 개선된 기능
-**자동 경로 인식** (config.yaml)
-**번역 검증 기능** (변수, 태그, 줄바꿈 확인)
-**polib 기반 안정적 업데이트**
-**자동 경로 인식** (`config.yaml` 기반)
-**번역 검증** (변수, 태그, 줄바꿈 확인)
-**안정적 업데이트** (polib 라이브러리 사용)
-**컬러 로그** (오류 원인 명확히 표시)
-**자동 백업** (업데이트 전)
-**자동 백업** (업데이트 전 자동 생성)
-**자동 파일 정리** (오래된 파일 보관)
-**원본 언어(ko) 업데이트 지원**
-**줄바꿈 이스케이프 자동 처리**
---
## 🔧 설치 및 설정
### config.yaml 설정
`config.yaml` 파일에서 경로와 동작 설정 (상대 경로 사용):
```yaml
paths:
unreal_localization: ../WorldStalker/Content/Localization/LocalExport
output_dir: ./output
logs_dir: ./logs
archive_dir: ./archive
languages:
source: ko # 원본 언어
targets: # 번역 대상 언어 (18개)
- en
- ja
- zh-Hans
- zh-Hant
# ... 기타 언어
validation:
check_variables: true # {Value} 변수 확인
check_rich_text_tags: true # <Red></> 태그 확인
check_newlines: true # \r\n 줄바꿈 확인
check_empty_translations: true # 빈 번역 확인
cleanup:
keep_recent_files: 5 # 최근 N개 파일만 유지
auto_archive: true # 오래된 파일 자동 보관
backup:
auto_backup_before_update: true # 업데이트 전 자동 백업
keep_backups_days: 7 # 백업 보관 기간
```
### 필요한 디렉토리 (자동 생성)
스크립트 실행 시 자동으로 생성됩니다:
- `output/` - 미번역 항목 TSV 파일
- `logs/` - 작업 로그 파일
- `archive/` - 오래된 파일 보관
---
## 📖 워크플로우
```
1⃣ 언리얼 에디터
└─ 현지화 대시보드 → 텍스트 수집 → 텍스트 익스포트
2⃣ 미번역 추출
python ds_l10n.py extract
└─ output/untranslated_YYYYMMDD_HHMMSS.tsv 생성
3⃣ 외부 번역 수행
└─ Google AI Studio 번역 앱 사용
└─ 번역업데이트.tsv에 결과 저장
4⃣ 번역 검증
python ds_l10n.py validate
└─ 변수, 태그, 줄바꿈 오류 확인
5⃣ PO 파일 업데이트
python ds_l10n.py update
└─ 자동 백업 + 모든 언어 PO 파일 업데이트 (ko 포함)
6⃣ 언리얼 에디터
└─ 현지화 대시보드 → PO 파일 임포트 → 텍스트 컴파일
7⃣ 사후 관리
python ds_l10n.py merge # CSV로 백업
python ds_l10n.py cleanup # 파일 정리
```
### 자동화 옵션
4~7단계 자동 실행:
```bash
python ds_l10n.py validate && python ds_l10n.py update && python ds_l10n.py merge && python ds_l10n.py cleanup
```
---
## 📝 명령어 상세
### 1. extract - 미번역 항목 추출
```bash
python ds_l10n.py extract
```
**기능**:
- 원본 언어(ko) PO 파일에서 msgstr이 비어있는 항목 추출
- TSV 형식으로 저장 (msgctxt, SourceLocation, msgid)
**출력**: `output/untranslated_YYYYMMDD_HHMMSS.tsv`
---
### 2. validate - 번역 검증
```bash
python ds_l10n.py validate [TSV파일]
```
**검증 항목**:
-**오류 (ERROR)**: 변수 누락/추가, 태그 불일치
- ⚠️ **경고 (WARNING)**: 줄바꿈 불일치 (UI 레이아웃 영향)
- **정보 (INFO)**: 길이 초과
**특징**:
- ko는 원본 언어로 검증에서 자동 제외
- msgid 컬럼이 없으면 ko 컬럼을 원본으로 사용
- 오류 발견 시 상세한 원인과 위치 표시
---
### 3. update - PO 파일 업데이트
```bash
python ds_l10n.py update [TSV파일]
python ds_l10n.py update --dry-run # 시뮬레이션 모드
```
**기능**:
- TSV 파일의 번역을 모든 언어의 PO 파일에 반영
- ko(원본 언어)도 함께 업데이트
- TSV의 `\r\n` 이스케이프 시퀀스를 자동으로 PO 형식으로 변환
- 업데이트 전 자동 백업 생성
**중요**: 원본 텍스트 수정 시 TSV의 ko 컬럼에 새 원본을 입력하면 자동으로 반영됩니다.
---
### 4. merge - CSV 병합
```bash
python ds_l10n.py merge
```
**기능**:
- 모든 언어의 PO 파일을 하나의 CSV로 병합
- Excel에서 편집 가능한 형식으로 저장
**출력**: `LocalExport/merged_po_entries_YYYYMMDD_HHMMSS.csv`
**CSV 구조**:
```
msgctxt | SourceLocation | ko | en | ja | zh-Hans | ...
```
**참고**: ko(원본 언어)가 en 앞에 위치하여 원본 확인이 용이합니다.
---
### 5. cleanup - 파일 정리
```bash
python ds_l10n.py cleanup
```
**정리 항목**:
- 📦 오래된 CSV/TSV 파일 → `archive/YYYYMM/` 폴더로 이동
- 🗑️ 7일 이상 된 백업 파일 삭제
- 🗑️ 30일 이상 된 로그 파일 삭제
---
## 🐛 문제 해결
### Q1. "모듈을 찾을 수 없습니다" 오류
```bash
pip install -r requirements.txt
```
### Q2. "PO 파일을 찾을 수 없습니다" 오류
`config.yaml`의 경로가 올바른지 확인:
```yaml
paths:
unreal_localization: ../WorldStalker/Content/Localization/LocalExport
```
### Q3. 업데이트 후에도 언리얼에서 번역이 안 보임
1. 언리얼 에디터에서 **PO 임포트** 실행
2. **텍스트 컴파일** 실행
3. 에디터 재시작
### Q4. 검증에서 오류가 발생함
**변수 누락 오류**: 원문의 `{Value}` 같은 변수를 번역문에 그대로 복사
**태그 불일치 오류**: 모든 `<TagName>`에 대응하는 `</>`가 있는지 확인
**줄바꿈 불일치 경고**: `\r\n` 위치를 원문과 동일하게 유지 (UI 레이아웃)
### Q5. 원본 언어(ko)를 수정하고 싶음
`번역업데이트.tsv`의 ko 컬럼에 수정된 원본을 입력하고:
```bash
python ds_l10n.py update # ko 포함 모든 언어 업데이트
```
### Q6. 코드 수정 후 반영이 안 됨
Python 캐시 문제일 수 있습니다:
```bash
# 방법 1: 캐시 삭제
find . -type d -name "__pycache__" -exec rm -rf {} +
# 방법 2: 캐시 무시 옵션
python -B ds_l10n.py merge
```
### Q7. Unicode/이모지 표시 오류
Windows 콘솔에서 이모지가 깨지는 경우:
- 로그 파일(`logs/`)에서는 정상적으로 표시됨
- Windows Terminal 사용 권장
---
## 📁 프로젝트 구조
@ -59,14 +299,7 @@ DS_L10N/
├── config.yaml # 설정 파일
├── 번역업데이트.tsv # 번역 입력 파일
├── requirements.txt # 필요 라이브러리
├── 사용가이드.md # 상세 매뉴얼
├── 1_미번역추출.bat # 배치 스크립트
├── 2_번역검증.bat
├── 3_PO업데이트.bat
├── 4_CSV병합.bat
├── 5_파일정리.bat
├── 전체워크플로우.bat
├── README.md # 이 문서
├── lib/ # 라이브러리 모듈
│ ├── config_loader.py # 설정 로더
@ -79,116 +312,69 @@ DS_L10N/
├── logs/ # 로그 파일 (자동 생성)
├── archive/ # 보관 파일 (자동 생성)
├── po_extract_untranslated.py # 기존 스크립트 (호환성 유지)
├── po_update_from_tsv.py # 기존 스크립트 (호환성 유지)
└── po_merge_to_csv.py # 기존 스크립트 (호환성 유지)
├── DS_Context.txt # 번역 문맥 가이드
├── DS_Terminology_DB.txt # 용어 데이터베이스
└── DS_Terminology_Guide.txt # 용어집 가이드
```
## 🔧 설정
---
`config.yaml` 파일에서 경로와 동작 설정:
## 💡 고급 사용법
```yaml
paths:
unreal_localization: ../WorldStalker/Content/Localization/LocalExport
output_dir: ./output
logs_dir: ./logs
### Dry-run 모드
validation:
check_variables: true
check_rich_text_tags: true
check_newlines: true
cleanup:
keep_recent_files: 5
auto_archive: true
```
## 🆚 기존 스크립트와 비교
| 기능 | 기존 | 신규 |
|------|------|------|
| 미번역 추출 | `po_extract_untranslated.py` | `ds_l10n.py extract` |
| 번역 검증 | ❌ 없음 | `ds_l10n.py validate` ✨ |
| PO 업데이트 | `po_update_from_tsv.py` | `ds_l10n.py update` |
| CSV 병합 | `po_merge_to_csv.py` | `ds_l10n.py merge` |
| 파일 정리 | ❌ 없음 | `ds_l10n.py cleanup` ✨ |
| 경로 관리 | GUI 선택 | config.yaml |
| 로그 | 기본 텍스트 | 컬러 + 아이콘 |
| 백업 | 수동 | 자동 |
| 안정성 | 정규식 파싱 | polib 라이브러리 |
## 📖 워크플로우
### 1단계: 언리얼 에디터
- 현지화 대시보드 → 텍스트 수집
- 텍스트 익스포트
### 2단계: 미번역 추출
```bash
python ds_l10n.py extract
```
### 3단계: 외부 번역
- Google AI Studio 번역 앱 사용
- 결과를 `번역업데이트.tsv`에 저장
### 4단계: 번역 검증
```bash
python ds_l10n.py validate
```
### 5단계: PO 업데이트
```bash
python ds_l10n.py update
```
### 6단계: 언리얼 에디터
- PO 파일 임포트
- 텍스트 컴파일
### 7단계: 사후 관리
```bash
python ds_l10n.py merge # CSV로 백업
python ds_l10n.py cleanup # 파일 정리
```
또는 **4~7단계 자동 실행**:
```bash
전체워크플로우.bat
```
## 💡 팁
### GUI 모드 사용
```bash
python ds_l10n.py extract --gui
```
### 시뮬레이션 모드
```bash
python ds_l10n.py update --dry-run
```
### 특정 파일 검증
실행 결과를 미리 확인 후 실제 업데이트 진행
### 커스텀 설정 파일
```bash
python ds_l10n.py validate output/untranslated_20251029_123456.tsv
python ds_l10n.py --config my_config.yaml extract
```
## 🐛 문제 해결
여러 프로젝트 관리 시 유용
### Jenkins/CI 통합
### "모듈을 찾을 수 없습니다"
```bash
pip install -r requirements.txt
cd DS_L10N
python ds_l10n.py validate || exit 1
python ds_l10n.py update || exit 1
```
### "PO 파일을 찾을 수 없습니다"
- `config.yaml`의 경로 확인
- 언리얼에서 텍스트 익스포트 완료 확인
---
### 업데이트 실패
- `logs/` 폴더의 최신 로그 파일 확인
- 실패 원인과 msgctxt 확인
## 🔗 관련 문서
- **번역 문맥 가이드**: `DS_Context.txt`
- **용어 데이터베이스**: `DS_Terminology_DB.txt`
- **용어집 가이드**: `DS_Terminology_Guide.txt`
---
## 🆕 버전 히스토리
### v2.0.1 (2025-10-29)
- 🐛 줄바꿈 이스케이프 버그 수정 (TSV `\r\n` → PO 정확한 변환)
- 🐛 검증 로직 수정 (실제 escape sequence 검사)
- ✨ CSV 병합 시 msgid 컬럼 제거
- ✨ CSV에서 ko가 en 앞에 위치하도록 변경
- 📝 배치 파일 제거 (CLI만 사용)
- 📝 README 간소화 및 업데이트
### v2.0 (2025-01-29)
- ✨ 통합 CLI 툴 구현 (`ds_l10n.py`)
- ✨ 번역 검증 기능 추가
- ✨ 자동 파일 정리 기능
- ✨ 컬러 로깅 시스템
- ✨ ko(원본 언어) 업데이트 지원
- 🐛 polib 기반으로 안정성 향상
- 🐛 Unicode/이모지 인코딩 문제 해결
---
## 📄 라이선스
@ -196,6 +382,6 @@ Copyright © 2025 OneUniverse. All rights reserved.
---
**버전**: 2.0
**최종 수정**: 2025-01-29
**작성자**: Claude Code + DS_L10N Team
**버전**: 2.0.1
**최종 수정**: 2025-10-29
**작성자**: DS_L10N Team

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -79,10 +79,11 @@ def command_extract(args, config, logger):
if count > 0:
logger.success(f'\n✅ 미번역 항목 {count}건 추출 완료')
logger.info(f'📄 출력 파일: {output_path}')
return True
else:
logger.info('추출할 미번역 항목이 없습니다.')
return False
logger.success(f'\n✅ 모든 텍스트가 번역되어 있습니다!')
logger.info('미번역 항목이 없습니다. 번역 작업이 완료된 상태입니다.')
return True
def command_validate(args, config, logger):
@ -116,11 +117,20 @@ def command_validate(args, config, logger):
exclude_columns = {'msgctxt', 'SourceLocation', 'msgid'}
lang_codes = [col for col in reader.fieldnames if col not in exclude_columns]
# 원본 언어 (ko가 source language)
source_lang = config.get('languages.source', 'ko')
for row in reader:
msgctxt = row.get('msgctxt', '')
msgid = row.get('msgid', '')
# msgid 컬럼이 있으면 사용, 없으면 source language(ko) 사용
msgid = row.get('msgid', '') or row.get(source_lang, '')
for lang in lang_codes:
# source language는 원본이므로 검증 스킵
if lang == source_lang:
continue
msgstr = row.get(lang, '')
if msgstr: # 번역문이 있는 경우만 검증
entries.append({

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -13,6 +13,15 @@ if sys.platform == 'win32':
import os
os.system('') # ANSI escape sequences 활성화
# UTF-8 콘솔 출력 설정
try:
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleCP(65001) # UTF-8 input
kernel32.SetConsoleOutputCP(65001) # UTF-8 output
except:
pass
# ANSI 컬러 코드
class Colors:
RESET = '\033[0m'
@ -113,8 +122,15 @@ class DSLogger:
self.logger.setLevel(logging.DEBUG)
self.logger.handlers.clear() # 기존 핸들러 제거
# 콘솔 핸들러
console_handler = logging.StreamHandler(sys.stdout)
# 콘솔 핸들러 (UTF-8 강제)
if sys.platform == 'win32':
# Windows에서 UTF-8 출력 스트림 사용
import io
console_stream = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', line_buffering=True)
else:
console_stream = sys.stdout
console_handler = logging.StreamHandler(console_stream)
console_handler.setLevel(getattr(logging, console_level.upper()))
console_handler.setFormatter(ColoredFormatter(colored=colored))
self.logger.addHandler(console_handler)

View File

@ -55,14 +55,16 @@ class POHandler:
if po is None:
return 0
# 미번역 항목 필터링
# 전체 항목 및 미번역 항목 필터링
total_entries = len([entry for entry in po if entry.msgid]) # msgid가 있는 항목만 카운트
untranslated = [entry for entry in po if not entry.msgstr.strip()]
if not untranslated:
self.logger.info('미번역 항목이 없습니다.')
translated_count = total_entries
self.logger.info(f'전체 {total_entries}개 항목 중 {translated_count}개 번역 완료 (100%)')
return 0
self.logger.info(f'미번역 항목 {len(untranslated)}건 발견')
self.logger.info(f'전체 {total_entries}개 항목 중 미번역 {len(untranslated)}건 발견')
# TSV 파일로 저장
self._save_to_tsv(untranslated, output_path)
@ -121,14 +123,7 @@ class POHandler:
key = (msgctxt_escaped, source_location_escaped)
if key not in merged_data:
merged_data[key] = {
'msgid': msgid_escaped,
'msgid_ko': None, # ko의 msgid를 별도로 저장
}
# ko 언어의 msgid는 별도로 저장
if lang_code == 'ko':
merged_data[key]['msgid_ko'] = msgid_escaped
merged_data[key] = {}
# 언어별 번역문 저장
merged_data[key][lang_code] = msgstr_escaped
@ -136,18 +131,13 @@ class POHandler:
# CSV 레코드 생성
records = []
for (msgctxt, source_location), data in merged_data.items():
# ko의 msgid가 있으면 우선 사용
msgid = data.get('msgid_ko') if data.get('msgid_ko') else data.get('msgid')
record = {
'msgctxt': msgctxt,
'SourceLocation': source_location,
'msgid': msgid,
}
# 언어별 번역 추가
for key, value in data.items():
if key not in ['msgid', 'msgid_ko']:
record[key] = value
records.append(record)
@ -160,10 +150,12 @@ class POHandler:
all_langs = set()
for record in records:
all_langs.update(record.keys())
all_langs -= {'msgctxt', 'SourceLocation', 'msgid'}
all_langs -= {'msgctxt', 'SourceLocation'}
# 선호 순서: ko를 맨 앞에, en을 두 번째로
source_lang = self.config.get('languages', {}).get('source', 'ko')
preferred_order = [source_lang] + self.config.get('languages', {}).get('targets', [])
# 선호 순서
preferred_order = self.config.get('languages', {}).get('targets', [])
ordered_langs = [lang for lang in preferred_order if lang in all_langs]
other_langs = sorted([lang for lang in all_langs if lang not in preferred_order])
final_langs = ordered_langs + other_langs
@ -172,7 +164,7 @@ class POHandler:
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w', newline='', encoding='utf-8-sig') as f:
fieldnames = ['msgctxt', 'SourceLocation', 'msgid'] + final_langs
fieldnames = ['msgctxt', 'SourceLocation'] + final_langs
writer = csv.DictWriter(f, fieldnames=fieldnames, quoting=csv.QUOTE_ALL)
writer.writeheader()
writer.writerows(records)
@ -323,6 +315,8 @@ class POHandler:
for lang in lang_codes:
msgstr = row.get(lang, '')
if msgstr: # 빈 문자열이 아니면 저장
# TSV의 이스케이프된 줄바꿈을 실제 escape sequence로 변환
msgstr = self._unescape_newlines(msgstr)
translations_by_lang[lang][msgctxt] = msgstr
except Exception as e:

View File

@ -180,15 +180,16 @@ class TranslationValidator:
"""줄바꿈 문자 확인"""
issues = []
# \r\n, \n, \r 개수 확인
orig_crlf = original.count('\\r\\n')
trans_crlf = translation.count('\\r\\n')
# 실제 escape sequence (\r\n, \n, \r) 개수 확인
# 주의: '\r\n'은 실제 CR+LF 문자 (2바이트), '\\r\\n'은 리터럴 문자열 (4바이트)
orig_crlf = original.count('\r\n')
trans_crlf = translation.count('\r\n')
orig_lf = original.count('\\n') - orig_crlf # \\r\\n에 포함된 \\n 제외
trans_lf = translation.count('\\n') - trans_crlf
orig_lf = original.count('\n') - orig_crlf # \r\n에 포함된 \n 제외
trans_lf = translation.count('\n') - trans_crlf
orig_cr = original.count('\\r') - orig_crlf # \\r\\n에 포함된 \\r 제외
trans_cr = translation.count('\\r') - trans_crlf
orig_cr = original.count('\r') - orig_crlf # \r\n에 포함된 \r 제외
trans_cr = translation.count('\r') - trans_crlf
if orig_crlf != trans_crlf or orig_lf != trans_lf or orig_cr != trans_cr:
issues.append(ValidationIssue(

View File

@ -1 +1,2 @@
msgctxt SourceLocation msgid ko en ja zh-Hans zh-Hant es-ES es-419 fr-FR de-DE ru-RU pt-BR pt-PT it-IT pl-PL tr-TR uk-UA vi-VN th
msgctxt SourceLocation ko en ja zh-Hans zh-Hant es-ES es-419 fr-FR de-DE ru-RU pt-BR pt-PT it-IT pl-PL tr-TR uk-UA vi-VN th
,UITitleAdventurerGuild /Game/Blueprints/DataTable/DT_StringTable.DT_StringTable 모험가 길드 Advent. Guild 冒険家ギルド 冒险家公会 冒險家公會 Gremio Avent. Gremio Avent. Guilde Avent. Abenteurergilde Гильдия Авант. Guilda Avent. Guilda Avent. Gilda Avvent. Gildia Awant. Macera Loncası Гільдія Авант. Hội Thám Hiểm กิลด์ผู้ผจญภัย
1 msgctxt SourceLocation msgid ko en ja zh-Hans zh-Hant es-ES es-419 fr-FR de-DE ru-RU pt-BR pt-PT it-IT pl-PL tr-TR uk-UA vi-VN th
2 ,UITitleAdventurerGuild /Game/Blueprints/DataTable/DT_StringTable.DT_StringTable 모험가 길드 Advent. Guild 冒険家ギルド 冒险家公会 冒險家公會 Gremio Avent. Gremio Avent. Guilde Avent. Abenteurergilde Гильдия Авант. Guilda Avent. Guilda Avent. Gilda Avvent. Gildia Awant. Macera Loncası Гільдія Авант. Hội Thám Hiểm กิลด์ผู้ผจญภัย

View File

@ -1,419 +0,0 @@
# DS_L10N 사용 가이드
던전 스토커즈 현지화 통합 툴
## 목차
1. [설치](#설치)
2. [설정](#설정)
3. [기본 사용법](#기본-사용법)
4. [개선된 워크플로우](#개선된-워크플로우)
5. [명령어 상세](#명령어-상세)
6. [문제 해결](#문제-해결)
---
## 설치
### 1. 필요 라이브러리 설치
```bash
cd D:\Work\WorldStalker\DS_L10N
pip install -r requirements.txt
```
설치되는 라이브러리:
- `polib`: PO 파일 안정적 처리
- `PyYAML`: 설정 파일 관리
- `pandas`: 데이터 처리 (기존 스크립트 호환)
### 2. 설정 파일 확인
`config.yaml` 파일에서 경로와 설정 확인:
```yaml
paths:
unreal_localization: ../WorldStalker/Content/Localization/LocalExport
output_dir: ./output
logs_dir: ./logs
...
```
모든 경로는 상대 경로로 설정되어 있으며, `DS_L10N` 폴더 기준입니다.
---
## 설정
### config.yaml 주요 설정
```yaml
# 검증 설정
validation:
check_variables: true # {Value} 같은 변수 일치 확인
check_rich_text_tags: true # <Red></> 태그 일치 확인
check_newlines: true # \r\n 줄바꿈 일치 확인
stop_on_validation_error: false # 검증 실패 시 중단 여부
# 자동 정리
cleanup:
keep_recent_files: 5 # 최근 N개 파일만 유지
auto_archive: true # 오래된 파일 자동 보관
```
필요에 따라 `config.yaml`을 수정하여 사용하세요.
---
## 기본 사용법
### 명령어 구조
```bash
python ds_l10n.py <명령어> [옵션]
```
### 주요 명령어
| 명령어 | 설명 | 기존 스크립트 대체 |
|--------|------|-------------------|
| `extract` | 미번역 항목 추출 | `po_extract_untranslated.py` |
| `validate` | 번역 검증 (신규) | - |
| `update` | PO 파일 업데이트 | `po_update_from_tsv.py` |
| `merge` | CSV 병합 | `po_merge_to_csv.py` |
| `cleanup` | 파일 정리 (신규) | - |
### 도움말 보기
```bash
python ds_l10n.py --help
python ds_l10n.py extract --help
```
---
## 개선된 워크플로우
### Before (기존 방식)
1. 언리얼 에디터: 텍스트 수집 → 익스포트
2. `po_extract_untranslated.py` 실행 → 파일 선택 (GUI)
3. 외부 번역 수행 (Google AI Studio 앱)
4. `번역업데이트.tsv`에 결과 저장
5. `po_update_from_tsv.py` 실행 → 파일/폴더 선택 (GUI)
6. 언리얼 에디터: PO 임포트 → 컴파일
7. `po_merge_to_csv.py` 실행 → 폴더 선택 (GUI)
**문제점**: 매번 파일/폴더 선택, 검증 부재, 오류 발생 시 원인 파악 어려움
### After (개선된 방식)
1. 언리얼 에디터: 텍스트 수집 → 익스포트
2. **`python ds_l10n.py extract`** - 미번역 추출
3. 외부 번역 수행
4. **`python ds_l10n.py validate`** - 번역 검증 ✨ 신규
5. **`python ds_l10n.py update`** - PO 업데이트
6. 언리얼 에디터: PO 임포트 → 컴파일
7. **`python ds_l10n.py merge`** - CSV 병합
8. **`python ds_l10n.py cleanup`** - 파일 정리 ✨ 신규
**개선점**:
- ✅ 경로 자동 인식 (config.yaml)
- ✅ 번역 검증 기능 추가
- ✅ 컬러 로그로 가독성 향상
- ✅ 자동 백업 생성
- ✅ 실패 원인 명확히 출력
- ✅ 오래된 파일 자동 정리
---
## 명령어 상세
### 1. extract - 미번역 항목 추출
```bash
# CLI 모드 (자동 경로)
python ds_l10n.py extract
# GUI 모드 (파일 선택)
python ds_l10n.py extract --gui
```
**출력**:
- `output/untranslated_YYYYMMDD_HHMMSS.tsv`
- msgctxt, SourceLocation, msgid 컬럼
**사용 시기**: 언리얼에서 텍스트 익스포트 후
---
### 2. validate - 번역 검증 ✨ 신규
```bash
# 기본 입력 파일 (번역업데이트.tsv)
python ds_l10n.py validate
# 특정 파일 지정
python ds_l10n.py validate output/untranslated_20251029_123456.tsv
```
**검증 항목**:
-**변수 누락**: `{Value}`, `{Count}` 등이 번역문에 없음
-**태그 불일치**: `<Red></>` 개수가 원문과 다름
- ⚠️ **줄바꿈 불일치**: `\r\n` 개수가 원문과 다름
- **길이 초과**: 번역문이 200자 초과 (설정 가능)
**출력 예시**:
```
🔍 번역 검증 결과
================================================================================
❌ 오류 (3건):
- en: DT_Skill.Fireball.Desc
분류: 변수 누락
문제: 누락된 변수: {Damage}
원문: {Damage} 피해를 입힙니다
번역: Deals damage
⚠️ 경고 (2건):
- ja: UI.Combat.AttackPower
분류: 태그 불일치
...
================================================================================
📊 통계:
- total: 241
- errors: 3
- warnings: 2
- passed: 238
✅ 검증 완료: 238건 통과 (경고 2건)
```
**사용 시기**: 외부 번역 완료 후, PO 업데이트 전
---
### 3. update - PO 파일 업데이트
```bash
# 기본 입력 파일 (번역업데이트.tsv)
python ds_l10n.py update
# 특정 파일 지정
python ds_l10n.py update translations/my_translations.tsv
# 시뮬레이션 모드 (실제 수정 안함)
python ds_l10n.py update --dry-run
```
**개선 사항**:
-**polib 사용**: 정규식 대신 안정적인 라이브러리
-**자동 백업**: 업데이트 전 `.backup_YYYYMMDD_HHMMSS.po` 생성
-**상세 로그**: 업데이트/스킵/실패 건수와 이유 출력
-**msgctxt 매칭**: 언리얼 해시 키로 정확히 매칭
**출력 예시**:
```
언어 처리 중: en
백업 생성: LocalExport.backup_20251029_123456.po
✅ en: 234건 업데이트
⏭️ en: 5건 스킵 (변경사항 없음)
언어 처리 중: ja
백업 생성: LocalExport.backup_20251029_123456.po
✅ ja: 230건 업데이트
❌ ja: 2건 실패
- ,ABC123...: PO 파일에서 msgctxt를 찾을 수 없음
📊 전체 업데이트 결과:
- 업데이트됨: 464
- 스킵됨: 5
- 실패: 2
- 처리 언어: 2
```
**사용 시기**: 번역 검증 완료 후
---
### 4. merge - CSV 병합
```bash
python ds_l10n.py merge
```
**출력**:
- `LocalExport/merged_po_entries_YYYYMMDD_HHMMSS.csv`
- 모든 언어의 번역을 하나의 CSV로 통합
**사용 시기**: PO 임포트/컴파일 후, 엑셀에서 관리할 때
---
### 5. cleanup - 파일 정리 ✨ 신규
```bash
python ds_l10n.py cleanup
```
**정리 항목**:
- 📦 오래된 CSV 파일 → `archive/YYYYMM/` 폴더로 이동
- 📦 오래된 미번역 TSV 파일 보관
- 🗑️ 7일 이상 된 백업 파일 삭제
- 🗑️ 30일 이상 된 로그 파일 삭제
**설정** (`config.yaml`):
```yaml
cleanup:
keep_recent_files: 5 # 최근 5개만 유지
keep_backups_days: 7 # 백업 보관 기간
delete_old_logs_days: 30 # 로그 보관 기간
```
**사용 시기**: 파일이 너무 많이 쌓였을 때
---
## 문제 해결
### Q1. 명령어 실행 시 "모듈을 찾을 수 없습니다" 오류
```bash
# 필요 라이브러리 재설치
pip install -r requirements.txt
```
### Q2. "PO 파일을 찾을 수 없습니다" 오류
`config.yaml`의 경로 설정 확인:
```yaml
paths:
unreal_localization: ../WorldStalker/Content/Localization/LocalExport
```
상대 경로가 올바른지 확인하세요.
### Q3. 업데이트 후에도 언리얼에서 번역이 안 보임
1. 언리얼 에디터에서 **PO 임포트** 실행
2. **텍스트 컴파일** 실행
3. 에디터 재시작
### Q4. 검증에서 많은 오류가 나옴
**변수 누락 오류**:
- 번역문에 `{Value}` 같은 변수를 포함시키지 않음
- 원문의 변수를 그대로 번역문에 복사
**태그 불일치 오류**:
- `<Red>강력한</>`처럼 여는 태그와 닫는 태그 개수 일치시키기
**줄바꿈 불일치 경고**:
- `\r\n` 위치를 원문과 동일하게 유지 (UI 레이아웃)
### Q5. 기존 GUI 스크립트를 계속 사용하고 싶음
기존 스크립트 파일은 그대로 유지됩니다:
- `po_extract_untranslated.py`
- `po_update_from_tsv.py`
- `po_merge_to_csv.py`
또는 `--gui` 옵션 사용:
```bash
python ds_l10n.py extract --gui
```
### Q6. 로그 파일이 너무 많이 쌓임
```bash
python ds_l10n.py cleanup
```
또는 `config.yaml`에서 자동 삭제 기간 조정:
```yaml
cleanup:
delete_old_logs_days: 7 # 7일로 단축
```
---
## 고급 사용법
### Dry-run 모드로 안전하게 테스트
```bash
# 실제 파일 수정 없이 시뮬레이션
python ds_l10n.py update --dry-run
```
### 커스텀 설정 파일 사용
```bash
python ds_l10n.py --config my_config.yaml extract
```
### 배치 스크립트로 자동화
`update_translations.bat`:
```batch
@echo off
cd /d D:\Work\WorldStalker\DS_L10N
echo [1/4] 번역 검증 중...
python ds_l10n.py validate
if errorlevel 1 (
echo 검증 실패! 번역을 확인하세요.
pause
exit /b 1
)
echo [2/4] PO 파일 업데이트 중...
python ds_l10n.py update
if errorlevel 1 (
echo 업데이트 실패!
pause
exit /b 1
)
echo [3/4] CSV 병합 중...
python ds_l10n.py merge
echo [4/4] 파일 정리 중...
python ds_l10n.py cleanup
echo.
echo ========================================
echo 모든 작업 완료!
echo ========================================
pause
```
---
## 로그 파일
모든 작업의 상세 로그는 `logs/` 폴더에 저장됩니다:
- `logs/workflow_YYYYMMDD_HHMMSS.log`
문제 발생 시 로그 파일을 확인하세요.
---
## 지원
문제가 발생하면:
1. 로그 파일 확인 (`logs/` 폴더)
2. `config.yaml` 설정 확인
3. 이 가이드의 "문제 해결" 섹션 참조
---
**버전**: 2.0
**최종 수정**: 2025-01-29
**작성자**: Claude Code + DS_L10N Team

View File

@ -1,70 +0,0 @@
@echo off
chcp 65001 > nul
cd /d "%~dp0"
echo ========================================
echo DS_L10N - 전체 워크플로우
echo ========================================
echo.
echo 이 스크립트는 다음 작업을 순차적으로 수행합니다:
echo 1. 번역 검증
echo 2. PO 파일 업데이트
echo 3. CSV 병합
echo 4. 파일 정리
echo.
echo ※ 언리얼 에디터에서 텍스트 익스포트를 먼저 완료해야 합니다.
echo ※ 번역업데이트.tsv 파일이 준비되어 있어야 합니다.
echo.
pause
echo.
echo ========================================
echo [1/4] 번역 검증 중...
echo ========================================
python ds_l10n.py validate
if errorlevel 1 (
echo.
echo ❌ 번역 검증 실패!
echo 번역업데이트.tsv 파일을 확인하고 오류를 수정하세요.
echo.
pause
exit /b 1
)
echo.
echo ========================================
echo [2/4] PO 파일 업데이트 중...
echo ========================================
python ds_l10n.py update
if errorlevel 1 (
echo.
echo ❌ PO 파일 업데이트 실패!
echo 로그 파일을 확인하세요.
echo.
pause
exit /b 1
)
echo.
echo ========================================
echo [3/4] CSV 병합 중...
echo ========================================
python ds_l10n.py merge
echo.
echo ========================================
echo [4/4] 파일 정리 중...
echo ========================================
python ds_l10n.py cleanup
echo.
echo ========================================
echo ✅ 전체 워크플로우 완료!
echo ========================================
echo.
echo 다음 단계:
echo 1. 언리얼 에디터로 돌아가기
echo 2. 현지화 대시보드에서 PO 파일 임포트
echo 3. 텍스트 컴파일
echo.
pause