kone
sub_icon

소미소프트

파일 구글 번역기) kr_tr_7.pyw

2026-04-22 20:36:11
유틸
조회 12182 · 좋아요 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
[번역요청] [Yoshizou888] NTR 판타지 - 부패와 지배의 연쇄
미번
Ed
05.04 13183 35
Comfyui 재밋내
야짤
zerocoke
05.04 7828 17
[어린이날 기념 복구] RJ150996 마립 서큐버스 요마원 1.6
복구
blackmalangcalf
05.04 33848 68
[AI번역] 역겨운 거근 아저씨가 여자친구를 네토라레하는 이야기! 거근이 최고!
동인
gkcuwuwlltnnrra
05.04 22351 66
어린이날 기념,후원보급) meatloaf 2024/4 ~2026/4
영상
쩝냡
05.04 26309 159
(청아 gif) 나는 빵빵단인데 이거 페도임
야짤
hannanas
05.04 15489 31
염월선행록 translation-cache.log 5월10일자 갱신 마지막
유틸
보바도사
05.04 8647 39
직번)[transistor baby]성재의 처녀 아스트레이아1~4편
동인
돋돋돋돋돋
05.04 21712 86
문제가 됐던 파일 및 암호화 관련 내용
정보
미스터장
05.04 9753 53
(한글자막) 친구네 집 메이드가 너무 내 취향이라서, 내 암컷으로 만들어버렸습니다
영상
꽃사슴
05.04 28375 185
[구매보급] [AI 번역] [개조버전] 견습 모비와 순풍을 기다리는 섬 RJ01042745
번역
V
05.04 35617 219
[미번] RJ01549336 알미오시온의 의술사 アルミオシオンの医術師 v1.00
미번
핏짜허엇
05.04 33684 172
[ai딸깍번역]동경하는 스승의 복제체 상대로 하고 싶었던거 전부 하는 이야기
동인
rlans
05.04 42083 315
[구매보급] 마조 시바키 라디오 시리즈 (1~3)
소리
summer4552
05.04 7727 42
후기) 색귀, 쯔꾸르 역사상 goat.
후기 및 공략
parmisgood
05.04 8793 31
횡령을 들켜 상사가 시키는 대로 하게 되는 경리 1p
야짤
요요코코
05.04 11020 29
[복구] RJ105442 암즈 디바이서 (arms devicer) v1.4 KR
복구
meruna00
05.04 15322 60
청아, AI번역) [직번] 구축함 하츠유키 이야기 (Wancho)
동인
rapbit
05.04 9904 22
minus8) 효과음 추가
영상
rlans
05.04 21112 97
(로리/임신) 아크메시아 발매일 결정!
정보
라임무르
05.04 13721 18
90일, 미번+번역) RJ425610 마도술사 미사
복구
ㅇㅇ
05.04 21027 56
[アブジャン] 레나쇼타 ー디지케모 누나와 H한 합체ー
영상
cupapan
05.04 23723 45
90일) RJ195455 미츠루기 코토노가 변태가 되어 버린 이야기 v1.10.7z
복구
ㅇㅇ
05.04 21059 37
(구매보급,버전업)RJ01613299 음최도시 휴포니즘
미번
gkawkek23
05.04 12363 44
[직번] Nunnu) - 좋아하는 미라이가 다른 녀석 책상에서 모서리 자위라니 말도 안 돼
동인
유의
05.04 23606 150
[직번] [Yesman] 잘생긴 왕자님 스타일 여자 AV타락 인생종료편
동인
maha1004
05.04 23839 75
[구매보급] [번역요청 시크릿 바이스 ~이계의 낙원~
미번
howl17
05.04 12757 27
미번에 올라왔던 문제의 파일 구동 해봤음
정보
미스터장
05.04 11281 43
보지고등학교 야짤 시리즈 모음
야짤
berryzz
05.04 17783 84
[구매보급]신성한 발키리의 굴욕 더러운 자지 청소
소리
이름뭐하지
05.04 11725 60