kone
sub_icon

소미소프트

파일 구글 번역기) kr_tr_7.pyw

2026-04-22 20:36:11
유틸
조회 12143 · 좋아요 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.01 14697 31
[미번, 복구]アナル触手ゲーム 捕らえた魔法使いのケツ穴で卵を育てろ!!
미번
ruel-x
05.01 16586 38
【유부녀 음란 보지 네토리】 연애 풍속 diary 유부녀 바니걸 소프 아가씨 미츠하의 덥수룩한 음모 보지
소리
shiroi
05.01 13947 100
[기번] RJ01310014 Caught a Cat Miko! ~Live2D Tentacle Game
번역
FGFFG0829
05.01 46734 144
[후타] 프리렌 & 아우라
영상
브레머튼
05.01 25926 129
[충간] 벨 & 니콜 & 비비안 - 비치 파티
영상
브레머튼
05.01 16337 61
[미번/구매보급] 사랑하는 선생님에게 젖꼭지 고문당하는 소녀 (愛しの先生に乳首責めされちゃう女の子)
미번
nxsolo
05.01 15309 42
염월선행록 한패 나올 때 까지 숨 참는다
일반
nxsolo
05.01 7626 34
[AI번역/이미지번역] 마도사 카나데의 후타나리 던전 Quest V1.2 KOR
번역
jpjp112
05.01 48713 233
(AI번역,미검수)(후타나리, 펨보이, 후타나리 NTR) Futa Familly 0.245
번역
Onko
05.01 44250 116
[구매보급][한국어 자막판][지뢰계×러브러브×신음]병들고 연약한 아리아짱에게 무너지다. 언제 어디서든지 러브러브한 섹스
소리
민초드래곤
05.01 8671 86
염월선행록 하는 법
정보
mdabedlehm
05.01 12370 21
[Sevengar] 갈색 쿨계 코스녀, 감사제 후 반성 벌칙 섹스
동인
ll사사라ll
05.01 26671 92
[미번/번역요청] 야리나리 ヤリたければ、ナリあがれ! RJ01249935
미번
rlans
05.01 9603 52
mmd 자작 영상
영상
pst0025
05.01 14358 59
사이클론 신작 게임 정보 간단요약
정보
ㅇㅇ
05.01 9736 31
[ai번역]ムチ肉ヘブンでパンパンパン + イラストカード
동인
doumaro
05.01 22884 65
야앵기담 근황
정보
sorbe123
05.01 5423 17
[ai번역]あなた…ごめんね。私…ホントの幸せ見つけちゃった。
동인
doumaro
05.01 20288 48
[ai번역]KNUCKLE HEAD寝取られ人妻総集編
동인
doumaro
05.01 16806 66
(미번, AI, NTR) [Shirokurosuki] 포니테일쨩은 애널에 지지않아! 1, 2
동인
츠바키미유
05.01 18005 35
minus8) 효과음 추가
영상
rlans
05.01 21610 89
[SG9seUNjQ2M=] Your Secret Memory 01~12
영상
류제로
05.01 23638 87
90일, 2.24 GB, 본문 참조, 추가 복구 없음) FZ d_728516
복구
ㅇㅇ
04.30 26717 60
[ai번역]クール系年上バリキャリ彼女 尊厳破壊和姦 1-2
동인
doumaro
04.30 15449 51
[ai번역]Ibitsu Seiso na Yowa Ki Kanojo Gouin Motokare ni Netorareru_. _ Una ragazza pura ma infedele
동인
doumaro
04.30 21363 56
[ai번역]Boku no Suki na Kyonyuu Osananajimi ga Charao Senpai no Kanojo ni Natta Hi 2(ai翻译)
동인
doumaro
04.30 9163 25
[ai번역]Boku no Suki na Kyonyuu Osananajimi ga Charao Senpai no Kanojo ni Natta Hi
동인
doumaro
04.30 12614 24
[ai번역]Yokyuu Fuman na Hitozuma ga Gym de Shiriatta Wakai Otoko ni Netorareru Hanashi _ 欲求不滿的人妻被健身房認識的年輕男人強睡奪走的故事
동인
doumaro
04.30 15133 36
[ai번역]ojousama senshi nooburu ~icharabu sais○ nante ariemasen wa~
동인
doumaro
04.30 27457 86