kone
sub_icon

소미소프트

파일 구글 번역기) kr_tr_7.pyw

2026-04-22 20:36:11
유틸
조회 12122 · 좋아요 9
양식
<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개
댓글 쓰기
04.22
번역 라이브러리는 googletrans==3.1.0a0 이거 인가…?
04.23
제미니에게 뭐라고 했더니 라이브러리 안 쓰는거 같음
ja 대신 en 하면 영어도 될라나
04.23
그건 대부분 영어로 이루어져있기 때문에 제외 단어 엄청 등록하는거 아니면 불가능할걸 게임 터짐
04.23
추출 상태로 돌리면 가능은 할거임 통으로 돌리면 터진다는 뜻
0 / 500
엘렌 오랄 & 핸드잡 (ZZZ)
영상
브레머튼
04.28 24451 131
ai, 이터널 리턴) 수영복 마를렌과 순애 섹스
야짤
kjh9304
04.28 15539 69
[구매보급][버전업][DLC포함] 타락신관: 여동생과 악마의 혈통 v1.3.2 steam 04/26/1237
번역
Ghost
04.28 125679 629
Shaggy Susu 신작 원신 감우
영상
ㅇㅇ
04.28 16660 142
[미번보급] お姉ちゃんにはナイショの同居生活——血より濃いミルクティー関係
미번
karoru
04.28 17797 29
(구매보급/ai 번역/NTL/트름 주의) 【NTR 타락】남자친구가 있는 오만한 미나토구 여성을 감금하고 7일간 훈육하다~
소리
Ghost
04.28 14880 74
직번) [AI번역] [Punifuka Ume] 누님계의 유부녀는 배신의 끝에 네토라레 당한다
동인
코코네
04.28 29807 106
타락신관 DLC 추가된점 및 여관 이벤트 분기점 공략 및 후기
후기 및 공략
asdf788
04.28 25989 47
[메이초기주쿠] 【루나와 색욕의 고도】 제작 #3
정보
날개 로봇
04.28 11408 17
【초밀착 속삭임】 파파♡~ 몽글몽글 F컵의 의붓딸에게서 계속 달콤달콤 속삭임♡ 엄마가 잠든 옆에서 밀착 처벌 아이 만들기 에치♡~ 【듬뿍 무성음】
소리
키리안
04.28 12898 108
[Migihaji] 러브가 아니라면 프리섹스 1~2
동인
ㅇㅇ
04.28 40187 203
[수정알림] 대리업로드 번역게임 수정된거 재업
번역
미스터장
04.28 37546 110
[직번] [Kagto] 반찬 당번의 성태 - 딸감 여신 마치다짱
동인
acefs
04.28 40373 180
[4K] 타카기 양, 이미지 비디오(?)에 출연하다
영상
실루엣21
04.28 31468 131
(노모화) [Shiwasu No Okina] 그녀 그이 그녀 -단행본 버전 작업중-
동인
xbox
04.28 18458 70
[Gamogamo] 이웃집의 음침퇴폐(다우너) 모녀에게 착정당하는 이야기
동인
ㅇㅇ
04.28 35085 234
내가 맛있게 먹었던거 복구 (청아)
복구
순애좋아
04.28 83483 336
[구매보급] [버전업] RJ01588884 외 1
미번
gkqisq
04.28 13921 46
[구매보급]왕궁 여자 기사의 처녀 연애 - 마지못해 그녀는 당신을 사랑한다
소리
이름뭐하지
04.28 10244 56
[구매보급] 【한국어 자막판】 【1시간 50분】 당신을 놓아주지 않아! 초밀착♪ 달콤한 속삭임 변태 체험판〜3명의 히로인 모음집〜
소리
puella
04.28 17456 73
[AI] 내 여자친구가 지배 어플로 NTR 방송되고 있는데
번역
미식이네
04.28 67810 221
[구매보급] [버전업] RJ01582213 라스티던전2 ver1.0h 2026.04.25
미번
gkqisq
04.28 11559 48
[구매보급] [버전업] [청아] RJ157224 공원장난 한국어 ver.MAKO 1.3 (Type A) 23.11.11
미번
gkqisq
04.28 12884 44
(초스압,스토리스포x)性処理用勇者 성처리용용사 후기 및 짧공략
후기 및 공략
끄얽돍
04.28 13684 21
[AI번역] [kojirou] 환상거유
동인
cjd08
04.28 11771 36
자동 소미 해적판의 해적판의 해적판 (260503 13:58 v1.3.5 업데이트)
유틸
bellbell
04.28 13371 38
Re:Dive 뉴토끼
일반
의인화
04.28 24304 204
어떤 버튜버 사진들~
야짤
지나가던허접a
04.28 15517 31
[구매보급]서머 폴리
소리
이름뭐하지
04.28 13814 74
리오 - Chill like that
영상
Poznan
04.28 24137 89