kone
sub_icon

소미소프트

파일 구글 번역기) kr_tr_7.pyw

2026-04-22 20:36:11
유틸
조회 12200 · 좋아요 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
(한글자막) 쉽게 휩쓸리는 폭유 메이드씨가 임신 할 때까지
영상
꽃사슴
05.06 21609 145
[기계번역] Love & Jealousy [Act 4]
번역
karuparu13
05.06 23556 77
[구매보급] [44Gv44GE44Gt ] 철도가키
영상
바람
05.06 33760 159
[5/5] 엽빛나 (ZZZ)
영상
브레머튼
05.06 13024 102
(한글자막) 쉽게 휩쓸리는 무뚝뚝한 폭유 아가씨가 임신 할 때까지
영상
꽃사슴
05.06 25379 141
[미번/번역요청][matsuzawa muni]Nikutai Hensai ~Shakkin Jigoku no China Musume~ | Debt Repayment In Kind
동인
오곡아줌마
05.06 10865 21
[한글패치]기계 소녀가 엮어내는 계보 vol.1-리오나의 착정 실험실_수정2
번역
아르
05.06 59941 164
[나의 히어로 아카데미아] 랙돌X데쿠
영상
Ghost
05.06 27755 141
[기번]Bondage Club
번역
브브븟
05.06 37278 170
🔞버그를 수정했고, 마지막 그림 공부를 했습니다.
창작
폭8맛
05.06 4296 17
Br@n)벽람항로 하우덴 리우 + 통합편집
영상
비밀봉투
05.06 13047 92
[구매보급]【저음 오호성】 무표정한 후배 - 엄청 야한 마코토의 구애 격렬한 절정 섹스
소리
이름뭐하지
05.06 9332 73
보추)[Locon]궁도 남자 총집편
동인
요요코코
05.06 15292 33
AI, 청아) 메스가키 참교육
야짤
miso5
05.06 14391 94
[구매보급]마성의 제자 - 아이 있는 교사를 사랑하는 천진난만한 여고생의 역 네토리
소리
이름뭐하지
05.06 7246 69
영화관에서 제인 도 & 와이즈 (ZZZ)
영상
브레머튼
05.06 12640 85
[귀 핧기 특화] 핥기 페티시 × 프린세스 ~귀 안쪽까지 "평생 너무 좋아"를 핧짝 흘려보내는 신혼 페로러브 밀착 아가 만들기~
소리
maruran
05.06 8154 81
[v1.286 patreon반영(5/7) , v1.282(5/6)] 비월선행록 번역파일만 [AI 직접 번역]
번역
handlejk
05.06 63981 298
[신작/4K48FPS] 고백 1
영상
쿠지락스
05.06 18647 137
[신작/4K48FPS] 성광섬희 포니 세레스 2
영상
쿠지락스
05.06 18567 162
[신작/4K48FPS] 나의 이상적인 이세계 생활 4
영상
쿠지락스
05.06 13723 168
[신작/4K48FPS] 쉬운 암컷들의 나날 2
영상
쿠지락스
05.06 25652 323
[신작/4K48FPS] 치매문릉 1
영상
쿠지락스
05.06 18540 225
[신작/4K48FPS] 레이카는 화려한 나의 여왕 3
영상
쿠지락스
05.06 12276 148
벨 (ZZZ)
영상
브레머튼
05.06 12172 95
[신작/4K48FPS] 끝내 아내가 되어 1
영상
쿠지락스
05.06 15376 140
[신작/4K48FPS] 사랑은 갸루에서 시작되는 운명 1
영상
쿠지락스
05.06 23036 224
[신작/4K48FPS] 거유 두 명이 없으면 안 서는 남편을 위해 친구를 데리고 온 아내 1,2
영상
쿠지락스
05.06 23523 409
(코이카츠) 소전 캐릭 2명 프리셋
유틸
pst0025
05.06 6637 21
오나홀 형태따기 샘플이 되어준 심술궂고 쿨한 후배OL의 조롱과 거짓신음 오나홓 대딸
소리
maruran
05.06 17343 79