最後活躍 3 weeks ago

修訂 4d410ddd302aab3f6329819700dea6f6e089b77c

fix_mojibake.py 原始檔案
1#!/usr/bin/env python3
2import sys
3import os
4import argparse
5from pathlib import Path
6
7def fix_mojibake_utf8(input_path, output_path=None):
8 """
9 Исправляет текст, который был сохранён как UTF-8, но прочитан как ISO-8859-1
10 """
11 try:
12 # Читаем файл как бинарный
13 with open(input_path, 'rb') as f:
14 raw_bytes = f.read()
15
16 # Исправляем mojibake
17 fixed_text = raw_bytes.decode('utf-8').encode('latin-1').decode('utf-8')
18
19 return fixed_text
20
21 except UnicodeDecodeError:
22 # Если не получается исправить как mojibake, пробуем прочитать как обычный UTF-8
23 try:
24 with open(input_path, 'r', encoding='utf-8') as f:
25 return f.read()
26 except:
27 with open(input_path, 'r', encoding='latin-1') as f:
28 return f.read()
29 except Exception as e:
30 print(f"✗ Ошибка при обработке {input_path}: {e}")
31 return None
32
33def process_file(input_file, output_file):
34 """Обрабатывает один файл"""
35 fixed_text = fix_mojibake_utf8(input_file)
36 if fixed_text is None:
37 return False
38
39 # Записываем исправленный текст
40 with open(output_file, 'w', encoding='utf-8') as f:
41 f.write(fixed_text)
42
43 return True
44
45def process_directory(input_dir, prefix="_"):
46 """Обрабатывает все HTML файлы в каталоге"""
47 input_dir = Path(input_dir)
48
49 if not input_dir.exists():
50 print(f"✗ Каталог не найден: {input_dir}")
51 return False
52
53 if not input_dir.is_dir():
54 print(f"✗ Это не каталог: {input_dir}")
55 return False
56
57 # Ищем все HTML файлы
58 html_files = list(input_dir.glob("*.html")) + list(input_dir.glob("*.htm"))
59
60 if not html_files:
61 print(f"✗ В каталоге {input_dir} не найдено HTML файлов")
62 return False
63
64 print(f"Найдено {len(html_files)} HTML файлов для обработки")
65 print("-" * 50)
66
67 processed = 0
68 for input_file in html_files:
69 # Создаем имя выходного файла с префиксом
70 output_file = input_file.with_name(f"{prefix}{input_file.name}")
71
72 print(f"Обработка: {input_file.name}{output_file.name}")
73
74 if process_file(input_file, output_file):
75 processed += 1
76 else:
77 print(f" ✗ Ошибка при обработке {input_file.name}")
78
79 print("-" * 50)
80 print(f"✓ Обработано файлов: {processed}/{len(html_files)}")
81 return True
82
83def main():
84 parser = argparse.ArgumentParser(
85 description='Исправляет mojibake (UTF-8, прочитанный как Latin-1) в файлах'
86 )
87 parser.add_argument('input', help='Входной файл или каталог')
88 parser.add_argument('output', nargs='?', help='Выходной файл (только для обработки одного файла)')
89 parser.add_argument('--prefix', default='_', help='Префикс для обработанных файлов (по умолчанию: _)')
90
91 args = parser.parse_args()
92
93 input_path = Path(args.input)
94
95 # Проверяем, является ли вход каталогом
96 if input_path.is_dir():
97 print(f"📁 Обработка каталога: {input_path}")
98 process_directory(input_path, args.prefix)
99 else:
100 # Обработка одного файла
101 if not input_path.exists():
102 print(f"✗ Файл не найден: {input_path}")
103 sys.exit(1)
104
105 if not args.output:
106 print("✗ Для обработки одного файла нужно указать выходной файл")
107 print("Использование: python script.py input.html output.html")
108 sys.exit(1)
109
110 print(f"📄 Обработка файла: {input_path}")
111 if process_file(input_path, args.output):
112 print(f"✓ Файл сохранен: {args.output}")
113
114 # Показываем превью
115 with open(args.output, 'r', encoding='utf-8') as f:
116 content = f.read(500)
117 print("\nПревью (первые 500 символов):")
118 print("-" * 50)
119 print(content)
120 print("-" * 50)
121 else:
122 print(f"✗ Не удалось обработать файл")
123
124if __name__ == "__main__":
125 main()