kone
sub_icon

소미소프트

파일 구글 번역기) kr_tr_7.pyw

2026-04-22 20:36:11
유틸
조회 12219 · 좋아요 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
[복구] 에이메스 & 린네 (명조) 복구 영상 3개
영상
브레머튼
05.08 19374 79
[AI][패치만] RJ01549336 알미오시온의 의술사 ver 1.044
번역
lovesccubus
05.08 67635 309
[국산 우리 농수간물]수간 커미션 모음집
야짤
412343
05.08 14306 68
ai, 찢) 이블린과 휴일에 데이트 후 잔뜩 연인섹스 했다
야짤
kjh9304
05.08 11979 121
[구매보급] [버전업] RJ01491971 마을의 간판녀가 권력자의 눈에 띄게 되는 이야기 26.05.07
미번
gkqisq
05.08 13665 44
[AI번역-노모 풀컬러] Master Works + Master Piece[수정]
동인
mybest
05.08 38395 163
[AI번역-♥개추♥][Okayusan] ★지금까지 가장 좋았던 섹스★(노모)
동인
mybest
05.08 26668 82
[미번/번역요청]NymPri_Alpha_080h[님포](5월 패치) 적용
미번
우욿
05.07 10463 26
[RJ01042589]사막 왕국과 노예 사냥 V3.1.0 (현재 메인스토리 완료까지 멈춤 수정 )
번역
sawsd
05.07 39119 125
(노모화) [Shiwasu No Okina] '에로♡삐삐' 단행본 완료 [Decensored]
동인
xbox
05.07 15385 85
[나의 히어로 아카데미아](재업) 랙돌x데쿠 + 서비스 신(청소) + 화질 up
영상
Ghost
05.07 22176 159
[RJ01575169/이미지번역/기게번역] 가출 딸, 주웠습니다. (2026.05.07)
번역
candle
05.07 87596 397
[버전업 알림] 이케부쿠로 섹스로이드 학원 v1.3.1
번역
jaaxmaster
05.07 50671 203
[요청복구] 236799 그녀가 노예가 된 이유 - 여도적실피와잠들지않는섬 -
복구
VoTaeBe
05.07 34438 60
[Asani nemuru]부모님이 심취한 노출교에 강제 입교당한 소녀
동인
요요코코
05.07 36703 65
[구매보급]NO라고 말할 수 없는 무방비 JK와 농후한 씨받이 연인 섹스
소리
이름뭐하지
05.07 14788 48
[번역](ahemaru) - 하이엘프 여왕과 공주가 성범죄자를 응징한다. 라는 내용의 만화
동인
핥는맛
05.07 32702 189
[미번/구매보급] 绯月仙行录 비월선행록 간체자 V1.287 버그수정본
미번
흑토끼
05.07 30377 101
[일부90일]요청복구 5게 +최신화 완료+
복구
Ghost
05.07 54723 111
(명조) 히유키
영상
브레머튼
05.07 16386 112
수나 (ZZZ)
영상
브레머튼
05.07 17443 101
RJ01037663) 서큐버스 장군의 병력 증산소
복구
양겜소믈리에
05.07 28377 80
[Liyoosa]불법 카지노에서 정체가 탄로나 조교당하는 여주인공
동인
요요코코
05.07 42435 171
[ai번역] 발기부전 밖에 태어나지 않는 섬에서 유일한 절륜 2
동인
yaoino
05.07 30950 56
[복구] 신데렐라(니케) 복구 영상
영상
브레머튼
05.07 16808 56
[구매 보급] RJ01485652 終末のオルターエゴイズム
미번
salrami5752
05.07 8904 30
[요청복구][게임녹화]리본 아일랜드
영상
komet52
05.07 22470 41
AI, 셀레스포니아) 유리 캡슐 구속 (촉수, 보테배 주의)
야짤
miso5
05.07 18663 86
[AI번역][Tachi Iyashi] Maso Mesu Happy Acme (decensored)
동인
mybest
05.07 26599 92
점장인데도 소악마 알바 전속 자지가 되어버렸습니다. CV. 야나기 히토미
소리
maruran
05.07 6877 55