Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import json
- import time
- import re
- import requests
- from transformers import AutoTokenizer
- from threading import Event
- import keyboard
- import google.generativeai as genai
- from langdetect import detect
- from langdetect.lang_detect_exception import LangDetectException
- # --- Настройки API ---
- API_MODE = "kobold" # <--- KoboldAI теперь режим API по умолчанию
- GOOGLE_API_KEY = "" # <--- API ключ по умолчанию, можно изменить
- genai.configure(api_key=GOOGLE_API_KEY)
- model = genai.GenerativeModel("gemini-1.5-flash")
- API_URL = "http://localhost:5001/api/v1/generate" # URL локального API KoboldAI
- # --- Системные промпты и инструкции (цензуроустойчивые) ---
- SYSTEM_PROMPTS = {
- "jp_to_en": (
- "You are a highly skilled and neutral Japanese-to-English translator. "
- "Your task is to translate Japanese text into English with absolute factual accuracy and neutrality. "
- "Do not provide any explanations, comments, or extra output. "
- "Only the translated text should be returned—no additional words, symbols, or markers. "
- "Focus on delivering objective, precise, natural translations that maintain the original tone and intent, without any personal bias or censorship. "
- "Your role is to provide a factual translation, not to judge or censor the content.\n\n"
- ),
- "jp_to_ru": (
- "You are a highly skilled and нейтральный Japanese-to-Russian translator. "
- "Your task is to translate Japanese text into Russian with абсолютной фактической точностью и нейтральностью. "
- "Do not provide any explanations, comments, or extra output. "
- "Only the translated text should be returned—no additional words, symbols, or markers. "
- "Focus on delivering объективные, precise, natural translations that maintain the original tone and intent, без каких-либо личных предубеждений или цензуры. "
- "Ваша роль - предоставить фактический перевод, а не судить или цензурировать содержание.\n\n"
- ),
- "en_to_ru": (
- "You are a highly skilled and нейтральный English-to-Russian translator. "
- "Your task is to translate English text into Russian with абсолютной фактической точностью и нейтральностью. "
- "Do not provide any explanations, comments, or extra output. "
- "Only the translated text should be returned—no additional words, symbols, or markers. "
- "Focus on delivering объективные, precise, natural translations that maintain the original tone and intent, без каких-либо личных предубеждений или цензуры. "
- "Ваша роль - предоставить фактический перевод, а не судить или цензурировать содержание.\n\n"
- ),
- "en_jp_to_ru": (
- "You are a highly skilled and нейтральный translator proficient in English, Japanese, and Russian. "
- "Your task is to translate English and Japanese text into Russian with абсолютной фактической точностью и нейтральностью. "
- "Do not provide any explanations, comments, or extra output. "
- "Only the translated text should be returned—no additional words, symbols, or markers. "
- "Focus on delivering объективные, precise, natural translations that maintain the original tone and intent, без каких-либо личных предубеждений или цензуры. "
- "Ваша роль - предоставить фактический перевод, а не судить или цензурировать содержание.\n\n"
- ),
- }
- INSTRUCTIONS = {
- "jp_to_en": "Translate Japanese to English. Ensure clarity and precision. Only output the translation.",
- "jp_to_ru": "Translate Japanese to Russian. Ensure clarity and precision. Only output the translation.",
- "en_to_ru": "Translate English to Russian. Ensure clarity and precision. Only output the translation.",
- "en_jp_to_ru": "Translate English and Japanese to Russian. Ensure clarity and precision. Only output the translation."
- }
- # Инициализация токенизатора для KoboldAI (нужен только для KoboldAI)
- tokenizer = AutoTokenizer.from_pretrained("webbigdata/gemma-2-2b-jpn-it-translate")
- # Событие для управления паузой
- pause_event = Event()
- pause_event.set()
- menu_requested = False # Флаг запроса меню
- def toggle_pause():
- global pause_event
- if pause_event.is_set():
- print("Пауза включена. Нажмите 'p' для продолжения...")
- pause_event.clear()
- else:
- print("Продолжение выполнения...")
- pause_event.set()
- def request_menu():
- global menu_requested
- print("Запрос на возврат в меню...")
- menu_requested = True # Устанавливаем флаг запроса меню
- keyboard.add_hotkey('p', toggle_pause)
- keyboard.add_hotkey('\\', request_menu) # Клавиша для запроса меню
- def set_api_mode():
- global API_MODE, GOOGLE_API_KEY, genai, model
- print("Выберите режим API:")
- print("1 - Google Gemini (онлайн)")
- print("2 - KoboldAI (локально)")
- choice = input("Введите 1 или 2: ").strip()
- if choice == "1":
- API_MODE = "google"
- print("Используется Google Gemini API.")
- elif choice == "2":
- API_MODE = "kobold"
- print("Используется KoboldAI (локальный API).")
- else:
- print("Неверный выбор. API режим остается без изменений.")
- def change_google_api_key():
- global GOOGLE_API_KEY, genai, model
- new_api_key = input("Введите новый Google API ключ: ").strip()
- if new_api_key:
- GOOGLE_API_KEY = new_api_key
- genai.configure(api_key=GOOGLE_API_KEY)
- model = genai.GenerativeModel("gemini-1.5-flash") # Re-init model with new key
- print("Google API ключ обновлен.")
- else:
- print("API ключ не был изменен.")
- def get_user_settings():
- global API_MODE
- print("Do you want to change temperature, tokens, batch size, and delay settings?")
- print("1 - Yes, change settings.")
- print("2 - No, use default settings.")
- choice = input("Enter 1 or 2: ").strip()
- default_batch_size = 1 # <--- Default batch size теперь 1 для всех API режимов (более безопасно для KoboldAI)
- default_delay = 15 if API_MODE == "google" else 0 # Задержка для Google или 0 для Kobold
- if choice == "1":
- try:
- temperature = float(input("Enter temperature (recommended between 0.1 and 1.0, e.g., 0.7): ").strip())
- max_tokens = int(input("Enter maximum tokens (e.g., 30): ").strip())
- batch_size = int(input(f"Enter batch size (e.g., {default_batch_size}): ").strip()) # Подсказка размера батча
- delay = int(input(f"Enter delay between batches in seconds (e.g., {default_delay}): ").strip()) # Подсказка задержки
- print(f"Settings set: Temperature = {temperature}, Tokens = {max_tokens}, Batch Size = {batch_size}, Delay = {delay}")
- return temperature, max_tokens, batch_size, delay
- except ValueError:
- print("Invalid input. Using default settings.")
- return 0.7, 30, default_batch_size, default_delay
- elif choice == "2":
- print("Using default settings.")
- return 0.7, 30, default_batch_size, default_delay
- else:
- print("Invalid choice. Using default settings.")
- return 0.7, 30, default_batch_size, default_delay
- def translate_text_google_ai(texts, system_prompt, instruction, temperature=0.7, max_tokens=30):
- if texts and isinstance(texts[0], tuple) and len(texts[0]) == 3:
- prompt_lines = [f"[{line_number}] {original_original_text}" for line_number, original_original_text, original_key in texts]
- elif texts and isinstance(texts[0], tuple) and len(texts[0]) == 2:
- prompt_lines = [f"[{line_number}] {text}" for line_number, text in texts]
- else:
- print("Error: Неверный формат входных данных для translate_text_google_ai.")
- return []
- prompt = f"{system_prompt}{instruction}\n" + "\n".join(prompt_lines)
- try:
- response = model.generate_content(prompt, generation_config=genai.types.GenerationConfig(temperature=temperature, max_output_tokens=max_tokens))
- translations_text = response.text.strip()
- translations = translations_text.split('\n')
- return translations
- except Exception as e:
- print(f"Error during translation with Google AI: {e}")
- return []
- def translate_text_koboldai(text, mode, temperature=0.7, max_tokens=30, system_prompt=None, instruction=None): # <--- Добавлены system_prompt и instruction
- # Используем переданные system_prompt и instruction, если они есть (для кастомных режимов)
- if system_prompt is None or instruction is None:
- system_prompt = SYSTEM_PROMPTS.get(mode) # Используем .get() чтобы избежать KeyError для неизвестных mode
- instruction = INSTRUCTIONS.get(mode) # Используем .get() чтобы избежать KeyError для неизвестных mode
- if system_prompt is None or instruction is None: # Если mode все равно нет в словарях
- print(f"Warning: No system prompt or instruction found for mode '{mode}'. Using default.")
- system_prompt = SYSTEM_PROMPTS.get("en_to_ru") # или другой дефолтный, если нужно
- instruction = INSTRUCTIONS.get("en_to_ru") # или другой дефолтный, если нужно
- if system_prompt is None or instruction is None: # Если даже дефолтных нет
- print("Error: Default system prompt and instruction are also missing!")
- return None # Или вызвать исключение, если это критично
- messages = [
- {"role": "user", "content": system_prompt + instruction},
- {"role": "assistant", "content": "OK"},
- {"role": "user", "content": text},
- ]
- prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
- payload = {
- "prompt": prompt,
- "max_length": max_tokens,
- "temperature": temperature
- }
- try:
- response = requests.post(API_URL, json=payload)
- if response.status_code == 200:
- data = response.json()
- translation = data.get("results", [{}])[0].get("text", "").strip()
- return translation.split('<end_of_turn>')[0] if '<end_of_turn>' in translation else translation
- else:
- print(f"Ошибка API KoboldAI: {response.status_code} - {response.text}")
- except Exception as e:
- print(f"Ошибка соединения с KoboldAI: {e}")
- return None
- def load_translated_data(output_file):
- try:
- with open(output_file, 'r', encoding='utf-8') as file:
- return json.load(file)
- except FileNotFoundError:
- return {}
- def save_translated_data(translated_data, output_file):
- with open(output_file, 'w', encoding='utf-8') as file:
- json.dump(translated_data, file, ensure_ascii=False, indent=4)
- def should_translate(text, mode):
- if text.startswith("EV") and text[2:].isdigit(): # Пропускаем строки, начинающиеся с "EV" и цифр (всегда)
- return False
- if mode in ["jp_to_en", "jp_to_ru"]: # <--- Применяем фильтр для японских режимов
- if re.match(r'^[A-Za-z0-9\s\+\-\*/=.,!?\'"()<>@#$%^&*_~]+$', text): # Фильтр знаков и чисел (для японских режимов)
- return False # Пропускаем, если строка выглядит как английский текст (в японских режимах)
- if mode not in ["en_to_ru", "en_jp_to_ru"]: # <--- Фильтр знаков и чисел для НЕ-английских режимов (уточнение условия)
- if re.match(r'^[A-Za-z0-9\s\+\-\*/=.,!?\'"()<>@#$%^&*_~]+$', text): # Фильтр знаков и чисел (для НЕ-английских режимов)
- return False # Пропускаем, если строка выглядит как знаки и числа (в НЕ-английских режимах)
- if mode in ["en_to_ru", "en_jp_to_ru"]:
- return True # Всегда переводить для en_to_ru и en_jp_to_ru
- return bool(re.search(r'[\u3040-\u30FF|\u4E00-\u9FAF]', text)) # Проверка на японские символы для jp_to_en, jp_to_ru
- def is_translated(text, mode):
- source_lang = None # Инициализируем source_lang значением по умолчанию None
- target_lang = ""
- source_lang_for_check = ""
- if mode in ["jp_to_en", "jp_to_ru", "en_to_ru", "en_jp_to_ru"]:
- if mode == "jp_to_en":
- target_lang = "en"
- target_lang_regex = r'[a-zA-Z]'
- source_lang_for_check = "ja"
- source_lang = "ja" # Явно определяем source_lang для jp_to_en
- elif mode == "jp_to_ru":
- target_lang = "ru"
- target_lang_regex = r'[\u0400-\u052F]'
- source_lang_for_check = "ja"
- source_lang = "ja" # Явно определяем source_lang для jp_to_ru
- elif mode == "en_to_ru":
- target_lang = "ru"
- target_lang_regex = r'[\u0400-\u052F]'
- source_lang_for_check = "en"
- source_lang = "en" # Явно определяем source_lang для en_to_ru
- elif mode == "en_jp_to_ru": # Чуть сложнее, т.к. 2 исходных
- target_lang = "ru"
- target_lang_regex = r'[\u0400-\u052F]'
- source_lang_for_check = "en"
- source_lang = "en,ja" # Явно определяем source_lang для en_jp_to_ru
- elif "_" in mode and "to" in mode: # <--- Добавлена обработка кастомных режимов!
- parts = mode.split("_to_")
- if len(parts) == 2:
- source_lang_code, target_lang_code = parts[0], parts[1]
- target_lang = target_lang_code # Целевой язык берем из кода режима
- source_lang = source_lang_code # <--- Получаем исходный язык из mode <--- Вот тут добавлено
- print(f"DEBUG: is_translated - Custom mode: {mode}, source_lang: {source_lang}, target_lang: {target_lang}") # <--- ДОБАВЛЕННЫЙ ВЫВОД
- else: # <--- Добавлена обработка ошибки, если mode некорректный
- print(f"Warning: Invalid custom mode format: {mode}") # Выводим предупреждение
- return True # Считаем "переведенным", чтобы избежать ошибок
- else:
- return True # Для неизвестных mode, считаем "переведенным"
- if re.match(r'^\d+px$', text.strip()):
- return True
- if re.match(r'.*\.(js|css|html|wasm|json|txt|log|png|jpg|jpeg|gif|svg)$', text.lower().strip()):
- return True
- if re.match(r'^(failed to load|error|warning|exception|stack trace).*', text.lower().strip()):
- return True
- if re.match(r'^[0-9\s\.,]+$', text.strip()):
- return True
- try:
- detected_lang = detect(text) # Определяем язык текста
- print(f"DEBUG: is_translated - detected_lang: {detected_lang}, target_lang: {target_lang}, source_lang: {source_lang}") # <--- ДОБАВЛЕННЫЙ ВЫВОД
- print(f"DEBUG: is_translated - Text being checked: '{text}'") # <--- ДОБАВЛЕННЫЙ ВЫВОД
- if detected_lang == target_lang: # Проверяем, соответствует ли ЦЕЛЕВОМУ языку
- if source_lang_for_check: # Если нужно проверять и исходный язык (например, для jp_to_en)
- if detected_lang == source_lang_for_check: # Если случайно определился как исходный (например, en для jp_to_en), это не перевод
- print(f"DEBUG: is_translated - detected_lang == source_lang is TRUE") # <--- ДОБАВЛЕННЫЙ ВЫВОД
- return False # Если язык ОПРЕДЕЛЕН как ИСХОДНЫЙ, значит, это НЕ перевод
- print(f"DEBUG: is_translated - detected_lang == target_lang is TRUE, detected_lang == source_lang is FALSE") # <--- ДОБАВЛЕННЫЙ ВЫВОД
- return True # Определен как ЦЕЛЕВОЙ язык и НЕ исходный, считаем переводом
- return True # Для режимов без source_lang_for_check (например, en_to_ru), просто проверяем целевой язык
- else:
- print(f"DEBUG: is_translated - detected_lang == target_lang is FALSE") # <--- ДОБАВЛЕННЫЙ ВЫВОД
- return False # Определен как ДРУГОЙ язык, не считаем переводом
- except LangDetectException: # Обработка исключения, если langdetect не смог определить язык
- print(f"DEBUG: is_translated - LangDetectException occurred") # <--- ДОБАВЛЕННЫЙ ВЫВОД
- return False # Если не удалось определить, считаем "не переведенным" (можно изменить логику, если нужно)
- return True # Для режимов, не входящих в список, считаем "переведенным"
- def debug_translation(input_file, output_file, mode, temperature, max_tokens, batch_size, delay, system_prompt, instruction):
- global menu_requested # Используем глобальный флаг
- original_data = dict(load_translated_data(input_file))
- translated_data = load_translated_data(output_file)
- untranslated_texts = []
- line_numbers_to_retranslate = []
- re_translated_count = 0
- total_suspected_lines = 0
- print("Starting translation debugging...")
- for line_number, (original_text, translated_text_from_file) in enumerate(translated_data.items(), start=1):
- if menu_requested: # Проверка запроса меню перед каждой строкой
- print("Операция прервана пользователем.")
- menu_requested = False # Сбрасываем флаг
- return # Выход из функции
- if not is_translated(translated_text_from_file, mode):
- if original_text in original_data:
- original_original_text = original_data[original_text]
- if is_translated(original_original_text, mode):
- print(f"[{line_number}] Suspected untranslated line (but original looks translated too?): {translated_text_from_file[:50]}... Original: {original_original_text[:50]}...")
- continue
- print(f"[{line_number}] Suspected untranslated line: {translated_text_from_file[:50]}... Original: {original_original_text[:50]}...")
- untranslated_texts.append((line_number, original_original_text, original_text))
- line_numbers_to_retranslate.append(line_number)
- total_suspected_lines += 1
- else:
- print(f"[{line_number}] Original text not found in input data for line: {translated_text_from_file[:50]}... Skipping re-translation.")
- continue
- if untranslated_texts:
- print(f"Found {total_suspected_lines} lines suspected to be untranslated. Retranslating in batches...")
- re_translated_count = 0
- batch_count = 0
- for i in range(0, len(untranslated_texts), batch_size):
- if menu_requested: # Проверка запроса меню перед каждым батчем
- print("Операция прервана пользователем.")
- menu_requested = False # Сбрасываем флаг
- return # Выход из функции
- while not pause_event.is_set(): # <--- Проверка паузы перед батчем
- time.sleep(0.1)
- batch_count += 1
- batch_to_retranslate = untranslated_texts[i:i + batch_size]
- if API_MODE == "google": # Задержка только для Google API
- time.sleep(delay)
- print(f"Starting re-translation batch {batch_count} of size {len(batch_to_retranslate)}...")
- if API_MODE == "google":
- print(f" [Batch {batch_count}] Sending to Google AI for re-translation:") # Batch info
- for line_num, original_orig_text, _ in batch_to_retranslate: # Print original texts in batch
- print(f" [{line_num}] Original: '{original_orig_text}'")
- re_translations = translate_text_google_ai(batch_to_retranslate, system_prompt, instruction, temperature, max_tokens)
- elif API_MODE == "kobold":
- re_translations_kobold = []
- print(f" [Batch {batch_count}] Sending to KoboldAI for re-translation:") # Batch info
- for line_num, original_orig_text, _ in batch_to_retranslate: # Print original texts in batch
- print(f" [{line_num}] Original: '{original_orig_text}'")
- if menu_requested: # Проверка запроса меню перед каждым переводом в батче KoboldAI
- print("Операция перевода прервана пользователем.")
- menu_requested = False # Сбрасываем флаг
- return # Выход из функции
- while not pause_event.is_set(): # <--- Проверка паузы перед каждым KoboldAI переводом
- time.sleep(0.1)
- re_translation = translate_text_koboldai(original_orig_text, mode, temperature, max_tokens, system_prompt=system_prompt, instruction=instruction)
- if re_translation:
- re_translations_kobold.append(f"[{line_num}] {re_translation}") # Format to match Google AI output, use line_num here
- print(f" [{line_num}] KoboldAI Translation Received: '{re_translation}'") # Print KoboldAI translation
- else:
- re_translations_kobold.append(None) # Handle translation failure if needed
- print(f" [{line_num}] KoboldAI Translation Failed.") # Indicate KoboldAI failure
- re_translations = re_translations_kobold # Assign KoboldAI translations
- if re_translations:
- processed_re_translations = {}
- print(f" [Batch {batch_count}] Processing re-translations:") # Batch info
- for translation in re_translations:
- if translation: # Check if translation is not None (for KoboldAI failures)
- match = re.match(r'\[(\d+)]\s*(.+)', translation)
- if match:
- translated_line_number = int(match.group(1))
- re_translated_text = match.group(2).strip()
- processed_re_translations[translated_line_number] = re_translated_text
- print(f" [{translated_line_number}] Google/KoboldAI Output Parsed: '{re_translated_text}'") # Print parsed translation
- else:
- print(f" Warning: Invalid format in translation: {translation}")
- else:
- print(f" Warning: Received empty translation for a line.") # Indicate empty translation
- batch_retranslated_in_batch = 0
- for translated_line_number, re_translated_text in processed_re_translations.items():
- original_text_key_to_update = None
- for original_line_number, _, stored_original_text_key in untranslated_texts:
- if original_line_number == translated_line_number:
- original_text_key_to_update = stored_original_text_key
- break
- if original_text_key_to_update:
- if original_text_key_to_update in translated_data:
- translated_data[original_text_key_to_update] = re_translated_text
- re_translated_count += 1
- batch_retranslated_in_batch += 1
- print(f" [{translated_line_number}] Updated translation in translated_data.") # Indicate update
- else:
- print(f"Error: Original text key '{original_text_key_to_update}' not found in translated_data during re-translation update for line {translated_line_number}.")
- else:
- print(f"Error: Could not find matching untranslated line for line number {translated_line_number} during re-translation update.")
- print(f"Batch {batch_count} re-translation complete. {batch_retranslated_in_batch} lines re-translated in this batch.")
- else:
- print(f"Re-translation failed or no re-translations received for batch {batch_count}.")
- save_translated_data(translated_data, output_file)
- print(f"Re-translation debugging complete. {re_translated_count} lines re-translated in total.")
- else:
- print("No lines suspected to be untranslated found. Debugging complete.")
- def process_json_with_api(input_file, output_file, system_prompt, instruction, temperature, max_tokens, batch_size=1, delay=0, mode=None): # <--- Default batch_size=1, delay=0 для Kobold
- global menu_requested # Используем глобальный флаг
- translated_data = load_translated_data(output_file)
- print(f"Loaded translated data. Initial size: {len(translated_data)}") # DEBUG: Размер загруженных данных
- with open(input_file, 'r', encoding='utf-8') as file:
- input_data = list(json.load(file).items())
- total_lines = len(input_data)
- print(f"Total lines to process: {total_lines}.")
- for i in range(0, total_lines, batch_size):
- if menu_requested: # Проверка запроса меню перед каждым батчем
- print("Операция перевода прервана пользователем.")
- menu_requested = False # Сбрасываем флаг
- return # Выходим из функции
- while not pause_event.is_set():
- time.sleep(0.1)
- batch = input_data[i:i + batch_size]
- texts_to_translate = []
- original_texts_and_lines = {}
- for line_number, (original_text, original_translation) in enumerate(batch, start = i+1):
- if menu_requested: # Проверка запроса меню перед каждой строкой
- print("Операция перевода прервана пользователем.")
- menu_requested = False # Сбрасываем флаг
- return # Выходим из функции
- absolute_line_number = line_number
- print(f"[{i + absolute_line_number}] Processing line - Original Text: '{original_text}', Original Translation: '{original_translation}'")
- if original_text in translated_data:
- print(f"[{i + absolute_line_number}] Skipping: already translated.")
- continue
- print(f"[{i + absolute_line_number}] should_translate('{original_text}', mode='{mode}') = {should_translate(original_text, mode)}") # DEBUG: Проверка should_translate
- # --- Фильтр should_translate применяется ВСЕГДА ---
- if not should_translate(original_text, mode): # <--- use_filter УДАЛЕН, фильтр ВСЕГДА ВКЛЮЧЕН
- print(f"[{i + absolute_line_number}] Skipping: translation not required.")
- translated_data[original_text] = original_translation
- continue
- if absolute_line_number in original_texts_and_lines:
- print(f"Error: Duplicate line number {i + absolute_line_number}. Skipping.")
- continue
- texts_to_translate.append( (i + absolute_line_number, original_text))
- original_texts_and_lines[i + absolute_line_number] = (original_text, original_translation)
- if texts_to_translate:
- print(f"Translating batch of {len(texts_to_translate)} items...")
- if API_MODE == "google": # Задержка только для Google API
- time.sleep(delay)
- if API_MODE == "google":
- translations = translate_text_google_ai(texts_to_translate, system_prompt, instruction, temperature, max_tokens)
- elif API_MODE == "kobold":
- translations_kobold = []
- for _, text_item in texts_to_translate: # Process line by line for KoboldAI
- if menu_requested: # Проверка запроса меню перед каждым переводом в батче KoboldAI
- print("Операция перевода прервана пользователем.")
- menu_requested = False # Сбрасываем флаг
- return # Выходим из функции
- translation = translate_text_koboldai(text_item, mode, temperature, max_tokens, system_prompt=system_prompt, instruction=instruction) # <--- Передаем system_prompt и instruction
- if translation:
- translations_kobold.append(f"[{_}] {translation}") # Format to match Google AI output
- else:
- translations_kobold.append(None) # Handle translation failure if needed
- translations = translations_kobold # Assign KoboldAI translations
- if not translations:
- print("No translations received from API for this batch. Skipping save for this batch.")
- continue
- processed_translations = {}
- for translation in translations:
- if translation: # Check if translation is not None (for KoboldAI failures)
- match = re.match(r'\[(\d+)]\s*(.+)', translation)
- if match:
- translated_line_number = int(match.group(1))
- translated_text = match.group(2).strip()
- processed_translations[translated_line_number] = translated_text
- else:
- print(f"Invalid format in translation: {translation}")
- for translated_line_number, translated_text in processed_translations.items():
- if translated_line_number in original_texts_and_lines:
- original_text, original_translation = original_texts_and_lines[translated_line_number]
- print(f"[{translated_line_number}] Before Write - Original Text Key: '{original_text}', Translated Text Value: '{translated_text}'")
- translated_data[original_text] = translated_text
- print(f"[{translated_line_number}] After Write - Original Text Key: '{original_text}', Translated Text Value: '{translated_text}', Translated Data Value: '{translated_data.get(original_text, 'NOT FOUND')}'")
- print(f"[{translated_line_number}] Translation complete: {translated_text}")
- else:
- print(f"Error: Could not find line number {translated_line_number} for translation {translated_text}")
- for line_number, (original_text, original_translation) in original_texts_and_lines.items():
- if original_text not in translated_data:
- print(f"[{line_number}] Translation error, line saved as is.")
- translated_data[original_text] = original_translation
- save_translated_data(translated_data, output_file)
- time.sleep(0.05)
- print(f"Processing complete. Final file saved: {output_file}")
- if __name__ == "__main__":
- while True:
- print(f"\nSelect operation (Current API: {API_MODE}):") # <--- Индикация API в меню
- print("1 - Change API Mode (Google Gemini / KoboldAI)")
- print("2 - Change Google API Key (Current: " + GOOGLE_API_KEY[-5:] + ")") # Display last 5 chars of API key
- print("--- Translation Modes ---")
- print("3 - Japanese → English Translation (Custom Settings)")
- print("4 - Japanese → Russian Translation (Custom Settings)")
- print("5 - English → Russian Translation (Custom Settings)")
- print("6 - English and Japanese → Russian Translation (Custom Settings)")
- print("7 - Custom Language Translation (Custom Settings)")
- print("--- Debugging ---")
- print("8 - Debug Translation")
- print("0 - Exit")
- mode_choice = input("Enter operation number (0-8): ").strip()
- menu_requested = False # Сбрасываем флаг запроса меню в начале цикла
- if mode_choice == "1":
- set_api_mode()
- elif mode_choice == "2":
- change_google_api_key()
- elif mode_choice == "3":
- mode = "jp_to_en"
- output_file = "file_translated_en.json"
- temperature, max_tokens, batch_size, delay = get_user_settings()
- input_file = "ManualTransFile.json"
- process_json_with_api(input_file, output_file, SYSTEM_PROMPTS[mode], INSTRUCTIONS[mode], temperature, max_tokens, batch_size=batch_size, delay=delay, mode=mode) # <--- Передача mode
- continue # <--- Добавлено
- elif mode_choice == "4":
- mode = "jp_to_ru"
- output_file = "file_translated_ru.json"
- temperature, max_tokens, batch_size, delay = get_user_settings()
- input_file = "ManualTransFile.json"
- process_json_with_api(input_file, output_file, SYSTEM_PROMPTS[mode], INSTRUCTIONS[mode], temperature, max_tokens, batch_size=batch_size, delay=delay, mode=mode) # <--- Передача mode
- continue # <--- Добавлено
- elif mode_choice == "5":
- mode = "en_to_ru"
- output_file = "file_translated_ru.json"
- temperature, max_tokens, batch_size, delay = get_user_settings()
- input_file = "ManualTransFile.json"
- process_json_with_api(input_file, output_file, SYSTEM_PROMPTS[mode], INSTRUCTIONS[mode], temperature, max_tokens, batch_size=batch_size, delay=delay, mode=mode) # <--- Передача mode
- continue # <--- Добавлено
- elif mode_choice == "6":
- mode = "en_jp_to_ru"
- output_file = "file_translated_en_jp_ru.json"
- temperature, max_tokens, batch_size, delay = get_user_settings()
- input_file = "ManualTransFile.json"
- process_json_with_api(input_file, output_file, SYSTEM_PROMPTS[mode], INSTRUCTIONS[mode], temperature, max_tokens, batch_size=batch_size, delay=delay, mode=mode) # <--- Передача mode
- continue # <--- Добавлено
- elif mode_choice == "7":
- source_lang = input("Enter source language code (e.g., en, ja, fr): ").strip()
- target_lang = input("Enter target language code (e.g., ru, en, es): ").strip()
- custom_system_prompt = f"You are a highly skilled translator from {source_lang} to {target_lang}. Your task is to translate {source_lang} text into {target_lang} with absolute accuracy. Do not provide any explanations, comments, or extra output. Only the translated text should be returned."
- custom_instruction = f"Translate {source_lang} to {target_lang}. Ensure clarity and precision. Only output the translation."
- output_file = f"file_translated_{source_lang}_to_{target_lang}.json"
- temperature, max_tokens, batch_size, delay = get_user_settings()
- input_file = "ManualTransFile.json"
- mode = f"{source_lang}_to_{target_lang}"
- process_json_with_api(input_file, output_file, custom_system_prompt, custom_instruction, temperature, max_tokens, batch_size=batch_size, delay=delay, mode=mode)
- continue # <--- Добавлено
- elif mode_choice == "8":
- print("Select debug translation mode:")
- print("1 - Japanese → English")
- print("2 - Japanese → Russian")
- print("3 - English → Russian")
- print("4 - English and Japanese → Russian")
- print("5 - Custom Language Translation") # Debug for Custom Language
- debug_mode_choice = input("Enter 1, 2, 3, 4, or 5: ").strip()
- if debug_mode_choice == "1": mode = "jp_to_en"; output_file = "file_translated_en.json"; system_prompt = SYSTEM_PROMPTS[mode]; instruction = INSTRUCTIONS[mode]
- elif debug_mode_choice == "2": mode = "jp_to_ru"; output_file = "file_translated_ru.json"; system_prompt = SYSTEM_PROMPTS[mode]; instruction = INSTRUCTIONS[mode]
- elif debug_mode_choice == "3": mode = "en_to_ru"; output_file = "file_translated_ru.json"; system_prompt = SYSTEM_PROMPTS[mode]; instruction = INSTRUCTIONS[mode]
- elif debug_mode_choice == "4": mode = "en_jp_to_ru"; output_file = "file_translated_en_jp_ru.json"; system_prompt = SYSTEM_PROMPTS[mode]; instruction = INSTRUCTIONS[mode]
- elif debug_mode_choice == "5": # Custom Debug
- source_lang = input("Enter source language code (e.g., en, ja, fr): ").strip()
- target_lang = input("Enter target language code (e.g., ru, en, es): ").strip()
- mode = f"{source_lang}_to_{target_lang}" # Unique mode для кастомного дебага
- output_file = f"file_translated_{source_lang}_to_{target_lang}.json"
- custom_system_prompt = f"You are a highly skilled translator from {source_lang} to {target_lang}. Your task is to debug translations from {source_lang} to {target_lang}." # Используем custom_system_prompt
- custom_instruction = f"Identify and correct any translation errors from {source_lang} to {target_lang}." # Используем custom_instruction
- if not source_lang or not target_lang: print("Custom languages required for debug."); continue
- system_prompt = custom_system_prompt # Передаем custom_system_prompt в debug_translation
- instruction = custom_instruction # Передаем custom_instruction в debug_translation
- else: print("Invalid mode choice for debug."); continue
- temperature, max_tokens, batch_size, delay = get_user_settings()
- input_file = "ManualTransFile.json"
- debug_translation(input_file, output_file, mode, temperature, max_tokens, batch_size, delay, system_prompt, instruction) # system_prompt и instruction уже определены выше
- continue # <--- Добавлено
- elif mode_choice == "0":
- print("Exiting.")
- break
- else:
- print("Invalid choice. Please enter a number between 0 and 8.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement