중복 파일 삭제
This commit is contained in:
@ -1,122 +0,0 @@
|
|||||||
import polib
|
|
||||||
import pandas as pd
|
|
||||||
from datetime import datetime
|
|
||||||
import os
|
|
||||||
import tkinter as tk
|
|
||||||
from tkinter import filedialog
|
|
||||||
import csv
|
|
||||||
|
|
||||||
def merge_po_to_csv_literal():
|
|
||||||
"""
|
|
||||||
사용자가 선택한 폴더의 모든 .po 파일을 하나의 CSV 파일로 병합합니다.
|
|
||||||
|
|
||||||
- [최종 수정] 줄바꿈 제어 문자(\\n, \\r)를 '\\n', '\\r' 문자열로 명시적으로
|
|
||||||
치환하여 CSV에 기록되도록 합니다.
|
|
||||||
- 모든 필드를 큰따옴표로 감싸 데이터 무결성을 강화합니다.
|
|
||||||
- UTF-8 with BOM 인코딩을 사용하여 Excel 호환성을 높입니다.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
root = tk.Tk()
|
|
||||||
root.withdraw()
|
|
||||||
|
|
||||||
root_folder = filedialog.askdirectory(title="언어 폴더들이 있는 루트 폴더를 선택하세요")
|
|
||||||
|
|
||||||
if not root_folder:
|
|
||||||
print("폴더를 선택하지 않아 스크립트를 종료합니다.")
|
|
||||||
return
|
|
||||||
|
|
||||||
po_file_name = 'LocalExport.po'
|
|
||||||
|
|
||||||
lang_folders = []
|
|
||||||
for item in os.listdir(root_folder):
|
|
||||||
item_path = os.path.join(root_folder, item)
|
|
||||||
po_path = os.path.join(item_path, po_file_name)
|
|
||||||
if os.path.isdir(item_path) and os.path.isfile(po_path):
|
|
||||||
lang_folders.append(item)
|
|
||||||
|
|
||||||
if not lang_folders:
|
|
||||||
print(f"오류: 선택한 폴더 '{root_folder}'에서 '{po_file_name}' 파일을 포함하는 하위 폴더를 찾을 수 없습니다.")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"탐지된 언어 폴더: {', '.join(lang_folders)}")
|
|
||||||
|
|
||||||
merged_data = {}
|
|
||||||
for lang_code in lang_folders:
|
|
||||||
po_file_path = os.path.join(root_folder, lang_code, po_file_name)
|
|
||||||
try:
|
|
||||||
po = polib.pofile(po_file_path)
|
|
||||||
for entry in po:
|
|
||||||
# --- 핵심 수정 부분 ---
|
|
||||||
# polib이 제어 문자로 변환한 줄바꿈을 다시 문자열로 치환합니다.
|
|
||||||
# 안전을 위해 msgctxt, msgid, msgstr 모두에 적용합니다.
|
|
||||||
|
|
||||||
# msgctxt가 없을 경우 NoneType 오류 방지
|
|
||||||
msgctxt_str = entry.msgctxt if entry.msgctxt else "NoContext"
|
|
||||||
msgctxt_str = msgctxt_str.replace('\r', '\\r').replace('\n', '\\n')
|
|
||||||
|
|
||||||
msgid_str = entry.msgid.replace('\r', '\\r').replace('\n', '\\n')
|
|
||||||
msgstr_str = entry.msgstr.replace('\r', '\\r').replace('\n', '\\n')
|
|
||||||
|
|
||||||
source_location_str = entry.occurrences[0][0] if entry.occurrences else "NoSourceLocation"
|
|
||||||
# source_location은 경로이므로 줄바꿈이 없을 가능성이 높지만, 안정성을 위해 추가
|
|
||||||
source_location_str = source_location_str.replace('\r', '\\r').replace('\n', '\\n')
|
|
||||||
|
|
||||||
data_key = (msgctxt_str, msgid_str, source_location_str)
|
|
||||||
|
|
||||||
if data_key not in merged_data:
|
|
||||||
merged_data[data_key] = {}
|
|
||||||
|
|
||||||
merged_data[data_key][lang_code] = msgstr_str
|
|
||||||
# --- 수정 완료 ---
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"오류: {po_file_path} 파일 처리 중 문제 발생: {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
records = []
|
|
||||||
for (msgctxt, msgid, source_location), translations in merged_data.items():
|
|
||||||
record = {
|
|
||||||
'msgctxt': msgctxt,
|
|
||||||
'SourceLocation': source_location,
|
|
||||||
'msgid': msgid,
|
|
||||||
}
|
|
||||||
record.update(translations)
|
|
||||||
records.append(record)
|
|
||||||
|
|
||||||
df = pd.DataFrame(records)
|
|
||||||
|
|
||||||
if df.empty:
|
|
||||||
print("병합할 데이터가 없습니다.")
|
|
||||||
return
|
|
||||||
|
|
||||||
base_columns = ['msgctxt', 'SourceLocation', 'msgid']
|
|
||||||
lang_columns = [col for col in df.columns if col not in base_columns]
|
|
||||||
preferred_order = [
|
|
||||||
'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'
|
|
||||||
]
|
|
||||||
ordered_langs = [lang for lang in preferred_order if lang in lang_columns]
|
|
||||||
other_langs = sorted([lang for lang in lang_columns if lang not in preferred_order])
|
|
||||||
final_columns = base_columns + ordered_langs + other_langs
|
|
||||||
df = df[final_columns]
|
|
||||||
|
|
||||||
now = datetime.now()
|
|
||||||
timestamp = now.strftime("%Y%m%d_%H%M%S")
|
|
||||||
output_filename = f'merged_po_entries_literal_{timestamp}.csv'
|
|
||||||
output_path = os.path.join(root_folder, output_filename)
|
|
||||||
|
|
||||||
df.to_csv(
|
|
||||||
output_path,
|
|
||||||
index=False,
|
|
||||||
encoding='utf-8-sig',
|
|
||||||
quoting=csv.QUOTE_ALL
|
|
||||||
)
|
|
||||||
|
|
||||||
print(f"\n성공: CSV 파일이 다음 경로에 저장되었습니다.\n{output_path}")
|
|
||||||
print("\n이제 CSV 파일의 셀 안에 \\r\\n이 문자열로 보존됩니다.")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"스크립트 실행 중 예기치 않은 오류가 발생했습니다: {e}")
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
merge_po_to_csv_literal()
|
|
||||||
Reference in New Issue
Block a user