kone
sub_icon

소미소프트

파일 구글 번역기) kr_tr_7.pyw

2026-04-22 20:36:11
유틸
조회 12142 · 좋아요 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
[ai번역]アナタのミスは上司であるワタシがなんとかします。
동인
doumaro
04.30 10132 32
[ai번역]聖華女学院公認竿おじさん
동인
doumaro
04.30 16120 77
[Renpy/Zenpy 기번] Friendship with Benefits 2 [v1.2.0/완결]
번역
leavel13245
04.30 30457 69
[ai번역]継母は教え子
동인
doumaro
04.30 8883 27
[ai번역]Muchimuchi Oku-sama, Dokidoki _Nama_ Haishin ~Haishin-sha ga Tomo Haha datta Baai~
동인
doumaro
04.30 14392 39
[ai번역]Zetsurin Oji-san to Osananajimi no Musume no, Sukebe na Suujitsukan. Day 2
동인
doumaro
04.30 12768 49
[ai번역] Zetsurin Oji-san to Osananajimi no Musume no, Sukebe na Suujitsukan
동인
doumaro
04.30 11312 59
주관적인 2026년 4분기 최고 기대작
정보
dfgdsfg
04.30 16260 76
[영상/미번] 유인·구속, 가슴을 만져지는 실력파 스파이의 존엄을 무너뜨리는 조교- 모션코믹
영상
우유
04.30 24624 128
[영상/미번] 아기 슬라임과 마법학교 학생의 훈훈한 일상♪ 모션코믹
영상
우유
04.30 18164 128
ai, 이터널 리턴) 수영복 아비게일과 순애 임신 섹스
야짤
kjh9304
04.30 11941 73
NAKK 팬박스 모음 + 4월 보이스 추가 업뎃
영상
noongkk
04.30 24678 153
[らすく] 절정 느릿느릿 빔
동인
qew123
04.30 26842 60
청아)수간)성처리 당번 이리야 미유
영상
이상한 사람
04.30 29064 81
[Matanonki] 밤시중(미요토기) (블루 아카이브)
동인
ㅇㅇ
04.30 19754 81
성진우 & 차해인 (나 혼자만 레벨업)
영상
브레머튼
04.30 37873 208
[구매보급/번역요청]RJ059871, RJ081915
미번
ziririri123
04.30 14461 35
[구매보급/번역요청/버전업] NTR 던전 1.2.0 RJ01499588
미번
babagumba
04.30 10757 35
RPG Maker MV/MZ 실시간 번역기 3.1 (구동휘정3 대응 -3)
유틸
mrpls
04.30 17119 36
ai)투명 오나홀
야짤
gpsel157
04.30 13120 30
[영상] [청아/가학물][번역요청] 수란아 시리즈 총집편 2
영상
우라
04.30 25244 130
[구매보급] [자막] RJ422081
소리
puella
04.30 11735 69
[한글자막]다키마쿠라 여친 -Pretty Holic- ~꼬~옥 밀착하며 곁잠 섹스해 주는 느슨하고 귀여운 후배~
소리
키리안
04.30 19127 105
[한국어판] 모든 캐릭터 푹 빠짐 불가피!! ○○ 특화 미경험 소녀들과 P활보다 LOVE하자?♪ 올해 겨울은 이거 하나로 몸도 마음도 따끈따끈♪
소리
dasdaa
04.30 25234 179
(eGlhb2NodW4=) 유부녀 쨔스 파티 모음집 1~18 +EX 1,2
영상
칸라드
04.30 36247 215
[구매보급,번역요청] 搾精義母に生種付け
동인
yaoino
04.30 7288 20
[구매보급/번역요청]RJ01591409 구련휘정 퀄터 알루미네스 & 탄젤 EG
미번
gre0204
04.30 24524 147
[구매보급,번역요청] 엄마 나이대의 마마와 노콘 섹스해서 임신시켜버리는 책 3
동인
yaoino
04.30 18660 32
밀팩 신작
정보
왈랄ㄹ랄루
04.30 12954 44
[구매보급]거유수문장에의한 도스케베 배틀 ♪ 역으로 반격하고 임신시켰다♪
소리
이름뭐하지
04.30 16996 53