kone
소미소프트

소미소프트

파일 구글 번역기) kr_tr_7.pyw

04/22/2026, 20:36:11
유틸
12256 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
다키스트 던전 Anaertailin 몬스터 컬렉션/NPC NSFW 모음
유틸
삐뉴
07/28/25 10991 27
미리보기 관련 유저스크립트
유틸
cloud67p
07/28/25 2494 3
Base64 링크 자동번역 확장 프로그램
유틸
blacklink
07/25/25 6094 15
카린 전용치트 Karryn's Prison 전용치트 ver1.4d
유틸
4HHHH
07/22/25 18525 22
이제 다운받은 망가도 히토미를 보듯이!
유틸
blacklink
07/21/25 8366 17
RPG MV 치트 플러그인 개조 버전 v2.1
유틸
4HHHH
07/19/25 21641 30
[노모이미지파일만] 카바씨네의 즐거운 투병 생활UC
유틸
미스터장
07/17/25 9027 23
goodbyedpi
유틸
unkown453645
07/15/25 6087 23
mpv(영상플레이어)
유틸
unkown453645
07/15/25 4327 9
로케일 에뮬
유틸
unkown453645
07/15/25 4712 15
아랄트랜스
유틸
unkown453645
07/15/25 3857 12
투투컨
유틸
unkown453645
07/15/25 4376 11
간단한 자동 RJ/VJ 코드 링커
유틸
traffica9
07/15/25 4373 7
webp -> jpg 이미지 변환기
유틸
anaweak
07/15/25 3213 13
루저메이커 뷰지 모델링
유틸
vneldzhffk
07/14/25 3921 3
드래곤 콩키스타 스탠딩 일러스트 가슴 흔들림 모드 번역
유틸
미스터장
07/11/25 11245 49
다키스트 세일 기념 NSFW 스킨/모드
유틸
삐뉴
07/11/25 8258 27
시니시스타2 모드 관련 편집 모드툴?
유틸
무슨소리니
07/11/25 5522 13
한여름의 절정 캐릭터 공유2
유틸
mola245
07/10/25 11057 30
요즘 애용하고있는 랜덤 파일 선택기
유틸
skdyd
07/07/25 4241 13
한여름의 절정 공홈에서 퍼온 캐릭터카드
유틸
ㅇㅇ
07/05/25 7841 15
MaidenSnowEve 메이든스노우이브 어느 전야제, 보이스팩 + 양덕모드
유틸
eyjafjalia
07/04/25 5232 13
[2026-01-11] 히토미 다운로더 코네용
유틸
kts
07/03/25 22432 66
Sexbound(스타바운드)통팩 V0.2 ,Lustiest Lair 1.6 메가-커스텀 팩(2025.09.30까지)
유틸
파에톤1호팬
07/02/25 15036 24
[업뎃] base64 자동 복호화 1.4.15
유틸
arcjay
07/01/25 18690 35
개념글 앞에 ⭐️ 붙이기 스크립트
유틸
963
06/30/25 4029 13
[복구]+@ 시니시스타 2 모드 모음(1.07)
유틸
sims9876
06/29/25 38058 39
웨일 브라우저 로컬 저장소 이미지 번역용 로컬 서버
유틸
LRMGC
06/29/25 3735 10
구버전 알만툴 게임에 더 나은 전체화면 적용 시키는 유틸리티
유틸
jpjp112
06/22/25 4817 11
[업뎃] base64 자동복호화
유틸
arcjay
06/15/25 16217 29