#!/usr/bin/env python3 # -*- coding: utf-8 -*- r""" names.py — сбор уникальных имён спикеров из .nsv файлов в CSV-таблицу для перевода, и обратное применение переведённых имён в .nsv файлы. Файлы .nsv всегда в UTF-8 (пишутся convert.py/translate.py) — здесь нет нужды в автоопределении кодировки, в отличие от более ранней версии этого скрипта, где угадывание cp932/shift_jis/utf-8 могло молча испортить текст на символах вроде "①", которых нет в cp932, но которые cp932 способен "прочитать" без ошибки, просто дав кракозябры. """ import csv from pathlib import Path from nsv_io import load_nsv_file, save_nsv_file def get_target_dir(): folder_input = input("Укажите путь к папке с .nsv файлами [по умолчанию: translate]: ").strip() folder_path = folder_input.strip('"\'') if folder_input else "translate" target_dir = Path(folder_path) if not target_dir.is_dir(): print(f"Ошибка: папка '{target_dir}' не найдена.\n") return None return target_dir def mode_extract(): target_dir = get_target_dir() if not target_dir: return nsv_files = list(target_dir.rglob("*.nsv")) if not nsv_files: print(f"В папке '{target_dir}' не найдено файлов .nsv.\n") return print(f"Найдено .nsv файлов: {len(nsv_files)}. Сбор имён...") unique_speakers = set() for file_path in nsv_files: try: entries = load_nsv_file(file_path) except Exception as e: print(f"Пропуск файла {file_path.name} (не удалось прочитать: {e})") continue for e in entries: speaker = e.get("speaker") if speaker is not None and speaker.strip(): unique_speakers.add(speaker.strip()) output_csv = Path(__file__).resolve().parent / "namestable.csv" sorted_speakers = sorted(unique_speakers) with open(output_csv, "w", encoding="utf-8-sig", newline="") as f: writer = csv.writer(f) writer.writerow(["Original", "Translated"]) for speaker in sorted_speakers: writer.writerow([speaker, ""]) print(f"\nГотово! Уникальных имён собрано: {len(sorted_speakers)}") print(f"Файл сохранён: {output_csv}\n") def mode_apply(): csv_path = Path(__file__).resolve().parent / "namestable.csv" if not csv_path.is_file(): print(f"Ошибка: файл '{csv_path.name}' рядом со скриптом не найден.\n") return translation_map = {} with open(csv_path, "r", encoding="utf-8-sig") as f: reader = csv.DictReader(f) for row in reader: orig = row.get("Original", "").strip() trans = row.get("Translated", "").strip() if orig and trans: translation_map[orig] = trans if not translation_map: print("В таблице namestable.csv нет заполненных колонок 'Translated'. Нечего применять.\n") return print(f"Загружено переводов для замены: {len(translation_map)}") target_dir = get_target_dir() if not target_dir: return nsv_files = list(target_dir.rglob("*.nsv")) if not nsv_files: print(f"В папке '{target_dir}' не найдено файлов .nsv.\n") return print(f"Обработка {len(nsv_files)} файлов...") total_replaced = 0 modified_files = 0 for file_path in nsv_files: try: entries = load_nsv_file(file_path) except Exception as e: print(f"Пропуск {file_path.name}: не удалось прочитать ({e}).") continue replaced_in_file = 0 for e in entries: speaker = e.get("speaker") if speaker is not None: raw_val = speaker.strip() if raw_val in translation_map: e["speaker"] = translation_map[raw_val] replaced_in_file += 1 if replaced_in_file > 0: save_nsv_file(file_path, entries) total_replaced += replaced_in_file modified_files += 1 print(f"\nГотово!") print(f"Изменено файлов: {modified_files}") print(f"Всего произведено замен: {total_replaced}\n") def main(): while True: print("=== Меню ===") print("1. Собрать уникальные имена в namestable.csv") print("2. Применить перевод из namestable.csv обратно в .nsv") print("0. Выход") choice = input("Выберите действие [1/2/0]: ").strip() print() if choice == "1": mode_extract() elif choice == "2": mode_apply() elif choice == "0": break else: print("Неверный ввод, попробуйте снова.\n") if __name__ == "__main__": main()