kone
소미소프트

소미소프트

파일 구글 번역기) kr_tr_7.pyw

04/22/2026, 20:36:11
유틸
12242 views · 9 likes
양식
<div>
    <table><tbody><tr><th colspan="2"><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></th></tr><tr><td colspan="2"><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></td></tr><tr><td><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></td><td><p style="margin: 0.5rem 0px;">=</p></td></tr><tr><td><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></td><td><p style="margin: 0.5rem 0px;">=</p></td></tr><tr><td><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></td><td><p style="margin: 0.5rem 0px;">=</p></td></tr><tr><th colspan="2"><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></th></tr><tr><td colspan="2"><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></td></tr><tr><th colspan="2"><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></th></tr><tr><td colspan="2"><p style="margin: 0.5rem 0px; display: flex; justify-content: center; align-items: center;">=</p></td></tr></tbody></table>
</div>

kr_tr_7.pyw

링크

aHR0cHM6Ly90cmFuc2Zlci5pdC90L2REQmhxZjVYa1JBSg==

단일로도 어느정도 쓸 수 있을텐데,
게임 번역하려면 추출한 다음 사용하는게 안정적이고 빠름

파이썬 설치되어 있어야 함
그록이 자꾸 바쁘다고 팅겨서 제미니에게 부탁함

AI 번역 돌릴줄 모르거나
컴 사양이 안되는 경우 쓸만할듯

코드
import os
import re
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext, ttk
import threading
import urllib.parse
import requests
import time

def google_translate(text, src='ja', dest='ko'):
    if not text.strip(): return text
    if not re.search(r'[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]', text):
        return text

    try:
        url = f"https://translate.googleapis.com/translate_a/single?client=gtx&sl={src}&tl={dest}&dt=t&q={urllib.parse.quote(text)}"
        headers = {'User-Agent': 'Mozilla/5.0'}
        res = requests.get(url, headers=headers, timeout=5)
        res.raise_for_status()
        
        parts = res.json()[0]
        result = "".join([p[0] for p in parts if p and p[0]]).strip()
        
        # 마침표 보정 로직
        if not text.strip().endswith('.') and result.endswith('.'):
            result = result[:-1].strip()
            
        return result if result else text
    except Exception:
        return text

class AdvancedTranslator:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("하위 폴더 통합 번역기 v8.0 (큰따옴표 지원)")
        self.root.geometry("800x650")

        config_frame = tk.Frame(self.root)
        config_frame.pack(fill="x", padx=10, pady=5)

        # 구분자를 세미콜론(;)으로 사용하고 기본값에 큰따옴표(") 추가
        tk.Label(config_frame, text="번역 제외 문자 (';'로 구분):").grid(row=0, column=0, sticky="w")
        self.exclude_entry = tk.Entry(config_frame, width=50)
        self.exclude_entry.insert(0, '「; 」; <; >; "; ---; \\n; \\i; ,; [; ]; (; ); :; …; !; \\; :; (; ); ,') 
        self.exclude_entry.grid(row=0, column=1, padx=5, sticky="w")

        self.btn = tk.Button(self.root, text="폴더 선택 (하위 폴더 포함 번역 시작)", command=self.start_thread, 
                             height=2, bg="#4CAF50", fg="white", font=("맑은 고딕", 10, "bold"))
        self.btn.pack(fill="x", padx=10, pady=5)

        self.notebook = ttk.Notebook(self.root)
        self.notebook.pack(fill="both", expand=True, padx=10, pady=10)

        self.log_area = scrolledtext.ScrolledText(self.notebook, bg="#1e1e1e", fg="#ffffff", font=("맑은 고딕", 12))
        self.monitor_area = scrolledtext.ScrolledText(self.notebook, bg="#2d2d2d", fg="#a6e22e", font=("맑은 고딕", 12))
        
        self.notebook.add(self.log_area, text=" 전체 진행 로그 ")
        self.notebook.add(self.monitor_area, text=" 실시간 번역 비교 ")

        self.jp_pattern = re.compile(r'[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]')

    def start_thread(self):
        path = filedialog.askdirectory()
        if not path: return
        self.btn.config(state='disabled')
        threading.Thread(target=self.process, args=(path,), daemon=True).start()

    def split_and_translate(self, text, exclude_chars):
        if not exclude_chars:
            return google_translate(text)

        # 특수 문자 및 큰따옴표를 안전하게 정규식 패턴으로 변환
        pattern = '|'.join(re.escape(char) for char in exclude_chars)
        tokens = re.split(f'({pattern})', text)
        
        translated_tokens = []
        for token in tokens:
            if not token: continue # 빈 문자열 건너뜀
            
            if token in exclude_chars:
                translated_tokens.append(token)
            elif self.jp_pattern.search(token):
                # 실제 번역 수행 (일본어 -> 한국어)
                translated_tokens.append(google_translate(token, src='ja', dest='ko'))
                time.sleep(0.15) 
            else:
                translated_tokens.append(token)
        
        return "".join(translated_tokens)

    def process(self, root_path):
        raw_excludes = self.exclude_entry.get().split(";")
        exclude_chars = [x.strip() for x in raw_excludes if x.strip()]
        
        all_files = []
        for root, dirs, files in os.walk(root_path):
            for file in files:
                if file.lower().endswith(('.txt', '.json', '.ini', '.csv')):
                    all_files.append(os.path.join(root, file))

        parent_dir = os.path.dirname(root_path)
        folder_name = os.path.basename(root_path)
        out_root_dir = os.path.join(parent_dir, f"{folder_name}_Translated")
        
        self.log_insert(f"🚀 총 {len(all_files)}개의 파일을 찾았습니다.\n")
        self.log_insert(f"🏠 저장 위치: {out_root_dir}\n{'-'*50}\n")

        for i, file_path in enumerate(all_files):
            rel_path = os.path.relpath(file_path, root_path)
            save_path = os.path.join(out_root_dir, rel_path)
            os.makedirs(os.path.dirname(save_path), exist_ok=True)
            
            self.log_insert(f"📄 [{i+1}/{len(all_files)}] {rel_path} 번역 중...\n")
            
            content_lines = []
            for enc in ['shift_jis', 'utf-8-sig', 'cp932', 'utf-8', 'euc-kr']:
                try:
                    with open(file_path, 'r', encoding=enc) as f:
                        content_lines = f.readlines()
                    break
                except: continue

            translated_lines = []
            for line in content_lines:
                if self.jp_pattern.search(line):
                    origin = line.rstrip('\n\r')
                    translated = self.split_and_translate(origin, exclude_chars)
                    self.monitor_insert(f"파일: {rel_path}\n원문: {origin}\n번역: {translated}\n{'-'*20}\n")
                    translated_lines.append(translated + '\n')
                else:
                    translated_lines.append(line)

            with open(save_path, 'w', encoding='utf-8-sig') as f:
                f.writelines(translated_lines)

        self.btn.config(state='normal')
        messagebox.showinfo("완료", "큰따옴표를 포함한 모든 파일 번역이 완료되었습니다.")

    def log_insert(self, msg):
        self.log_area.insert(tk.END, msg)
        self.log_area.see(tk.END)

    def monitor_insert(self, msg):
        self.monitor_area.insert(tk.END, msg)
        self.monitor_area.see(tk.END)

if __name__ == "__main__":
    app = AdvancedTranslator()
    app.root.mainloop()
9
8 comments
Sign in to comment
04/22
번역 라이브러리는 googletrans==3.1.0a0 이거 인가…?
04/23
제미니에게 뭐라고 했더니 라이브러리 안 쓰는거 같음
ja 대신 en 하면 영어도 될라나
04/23
그건 대부분 영어로 이루어져있기 때문에 제외 단어 엄청 등록하는거 아니면 불가능할걸 게임 터짐
04/23
추출 상태로 돌리면 가능은 할거임 통으로 돌리면 터진다는 뜻
Sign in to comment
섀도우버스WB 카드 누패
유틸
나나바
05/27 1696 9
방주 해제 스크립트 공유
유틸
ddiff
05/26 2539 9
unholy maiden seed of profanity모드 1.4
유틸
leessss25
05/26 1973 13
[복구]섹타듀벨리 모드팩
유틸
continuereset
05/26 4998 20
[그냥복구/본체없음] 배덕의 달콤함에 물든 마나카. 여기서 받은 모드팩
유틸
루파조아
05/26 2944 9
FORTUNE BRIDE ~절정개안의 의식~ 노모 패치
유틸
미스터장
05/24 6360 33
(코이카츠) 엔드필드 프리셋 공유
유틸
pst0025
05/23 8745 65
EnigmaVBUnpacker (MV MZ 언팩) 웹버전 오픈
유틸
mrpls
05/23 4163 15
파일/ 압축/ 폴더 제목의 품번 괄호 삭제해주는 유틸
유틸
몬스터가아니다신이다
05/23 2805 2
[패치만] 시니시스타2 따거 MOD
유틸
하우두유두
05/22 13966 50
(수정 사항3)내가 쓸려고 만든 코드 검색용 + 파일관리
유틸
ATTAA
05/21 3946 14
[노모패치] 갓 딴 임신시키기 좋은 날
유틸
나나바
05/21 9757 39
zenpy 폰트 설치기
유틸
thxl23
05/20 3496 6
내가 쓸려고 만든 유틸 프로그램임
유틸
몬스터가아니다신이다
05/20 3970 6
내가 쓸려고 만든 DLsite 코드 검색 용
유틸
ATTAA
05/19 5968 7
내가 쓸려고 만든 유니티 버전별 폰트랑 어디서 구해온거 (오토트랜스용)
유틸
neighborsbear
05/19 6873 4
[요청복구] 감옥용사 1.20 조이플 구동패치
유틸
ssddttj
05/17 3097 5
누군가 쓸 마법의하나 マホウノハナ 0.9e 실시간 번역용 프리패쳐 파일
유틸
ㅇㅇ
05/17 7094 8
키리키리 엔진 ScnEditorGUI 개선판 (scn 암호화 파일 에디터)
유틸
joyed47106
05/16 6665 7
시니시스타 2 업뎃기념 모드 모음
유틸
sims9876
05/16 20798 105
(코이카츠) 버튜버 프리셋 공유 ver.2
유틸
pst0025
05/16 13295 51
(코이카츠) 버튜버 프리셋 공유 (복구)
유틸
pst0025
05/16 14207 64
WebP_Converter 코네 다운로드하다 WebP 불편해서 만든 프로그램
유틸
noname
05/15 12733 16
(코이카츠) 최근에 풀린 프리셋 공유
유틸
pst0025
05/15 12603 34
[RPG Maker MV/MZ 실시간 번역기] 4.0 출시
유틸
mrpls
05/15 22669 70
내가 쓰려고 만든 동음 정리 유틸
유틸
yeppi
05/15 8104 24
Texture Tool for Unity 6 ( Mono / IL2CPP ) v0.1.1 최초 배포 버전
유틸
argoklarke
05/14 15108 28
(코이카츠) 학원마스 프리셋 공유
유틸
pst0025
05/14 15531 43
(코이카츠) 프리셋 공유
유틸
pst0025
05/14 11269 58
comfyui를 이용해서 배경음을 식질해보자
유틸
프로베스트캣
05/14 20792 13