kone
sub_icon

소미소프트

파일 구글 번역기) kr_tr_7.pyw

2026-04-22 20:36:11
유틸
조회 12180 · 좋아요 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.13 12915 74
[ai번역 - 노모] 세이카 여학원 공인 자지 아저씨 1~7
동인
mybest
05.13 30018 128
기번) Orange Piece 모음집 총 10개
번역
playthesean
05.13 33703 83
N.T.Resort에 오신 것을 환영합니다 신정보
정보
ㅇㅇ
05.13 14445 50
[구매보급] 바이러스님의 전신 해킹 쾌락 지배~ 속은 컴퓨터군은 바이러스 투성이♪~
소리
summer4552
05.13 12625 42
Ie 3갸루 단편
동인
SK
05.13 38559 276
【한국어 자막판】 섹스프렌드 겸임 친구 시리즈(2,3,4편)
소리
뒷담난쟁이로야족
05.13 18497 97
ntr레슨 후속작) ntr축구 체험판 공개 및 출시 d30
정보
머겅머겅
05.13 13630 20
[번역] 토끼 구멍
야짤
마법우엉
05.13 12169 82
[번역](청아)오빠는 퇴마인이 되어도 끝났다
동인
마법우엉
05.13 31430 106
[구매보급] [버전업] RJ01526327 어서오세요! 어린이 만들기 온천 마을 1.01
미번
gkqisq
05.13 18266 45
[기번/검수][iapoc]-유두 자극 레즈 에스테에 어서 오세요
동인
serdic
05.13 30501 145
[구매보급]【달콤한 오호】 성녀가 노예가 되어서 사봤다~ 조르게 하고 오호 목소리 섹스~
소리
이름뭐하지
05.13 22380 58
kajiking - 고도 카즈사 음문이 새겨지다 2.5
동인
qew123
05.13 24045 99
[버전업알림,손번역] 세뇌 어플 2 ver.1.2.1 (26.05.13)
번역
미스터장
05.13 46846 315
직번) [choukutetsushitsugan] 암퇘지 낙인
동인
qlalfsla
05.13 42894 278
AI, 셀레스포니아) 연구소의 인증 시스템
야짤
miso5
05.13 17895 96
[복구] 카프카 영상 복구
영상
브레머튼
05.13 17209 63
(오호고에/음어)雲八はち성우 작품 4개
소리
딸딸이의황태자
05.13 13818 66
[ai번역-노모 단행본] 가출 갸루랑 질내사정 잔뜩 해서 동거 생활 시작했습니다.
동인
mybest
05.13 24944 66
[알림] 비월선행록 이미지 번역 1.289 대응
번역
argoklarke
05.13 38838 116
[AI번역][RJ220780] 야리친 가정교사 네토리 보고 (패치파일만)
번역
호빵할배
05.13 36955 109
나오기를 ㅈㄴ 기대하는 작품
정보
존경합니다행님덜
05.13 12927 28
[RJ01624439] 뭔가 이야기가 있을 때는 "절대 혀를 내밀어야 해"라며, 포근한 메이드와 순수한 사랑을 나누는 달콤한 ‘키스 하메이드’ 생활
소리
돈이조아
05.13 12603 92
미번) 묘쌤은 이렇게 박혔다 3
동인
kjalar
05.13 21512 39
[재업/AI번역/riboshika][NTR] 자궁이 관통될 때까지♥︎
동인
gaymaster
05.13 25946 58
[밀프/쇼타/서양](보루토) 왕자지 보루토 : 사쿠라의 병원
영상
Ghost
05.13 39505 286
Church of Desires 손번역이 완료되었습니다.(후타, 음마화)[RJ01617031]
번역
sesv3030
05.13 56004 253
(구매보급,버전업,공식번역)세뇌앱2 ver1.2.1
번역
Gope
05.13 28420 210
[ai번역=오오토리 마히로] 나의 이세계 하렘 3
동인
mybest
05.13 21374 43