-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun.py
More file actions
404 lines (338 loc) · 19.5 KB
/
run.py
File metadata and controls
404 lines (338 loc) · 19.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
1C Help Parser - Главный скрипт запуска
"""
import os
import sys
import argparse
import json
from datetime import datetime
from pathlib import Path
def check_dependencies():
"""Проверяет наличие необходимых зависимостей"""
try:
import bs4
print("✅ BeautifulSoup4 установлен")
except ImportError:
print("❌ BeautifulSoup4 не установлен")
print("Установите: pip install beautifulsoup4")
return False
try:
import lxml
print("✅ lxml установлен")
except ImportError:
print("⚠️ lxml не установлен (рекомендуется для лучшей производительности)")
print("Установите: pip install lxml")
return True
def cleanup_data():
"""Очищает ненужные файлы из папки data"""
import glob
files_to_remove = [
"data/1c_summary.json",
"data/context_chunks/",
"data/hbk_analysis.json"
]
print("🧹 Очистка ненужных файлов...")
for pattern in files_to_remove:
if pattern.endswith('/'):
# Удаляем папку
if os.path.exists(pattern):
import shutil
shutil.rmtree(pattern)
print(f"🗑️ Удалена папка: {pattern}")
else:
# Удаляем файл
if os.path.exists(pattern):
os.remove(pattern)
print(f"🗑️ Удален файл: {pattern}")
print("✅ Очистка завершена")
def run_parser(zip_file, max_files=None, use_improved=True):
"""Запускает парсинг файла"""
print(f"🔍 Анализ структуры: {zip_file}")
os.system(f"set PYTHONPATH=src && python src/parsers/hbk_parser.py {zip_file}")
print(f"📝 Извлечение синтаксиса: {zip_file}")
if max_files:
os.system(f"set PYTHONPATH=src && python src/parsers/bsl_syntax_extractor.py {zip_file} --max-files {max_files}")
else:
os.system(f"set PYTHONPATH=src && python src/parsers/bsl_syntax_extractor.py {zip_file}")
# Определяем имя JSON файла
base_name = Path(zip_file).stem
json_file = f"data/bsl_syntax_{base_name}.json" if "root" in base_name else "data/bsl_syntax.json"
md_file = json_file.replace('.json', '.md')
if os.path.exists(json_file):
print(f"🔄 Создание контекста: {json_file}")
# Создаем только основные файлы: JSON, TXT и поисковый индекс
os.system(f"set PYTHONPATH=src && python src/converters/context_converter.py {json_file} json,txt,search_index")
# Удаляем промежуточные файлы после конвертации
if os.path.exists(json_file):
os.remove(json_file)
print(f"🗑️ Удален промежуточный файл: {json_file}")
if os.path.exists(md_file):
os.remove(md_file)
print(f"🗑️ Удален промежуточный файл: {md_file}")
else:
print(f"⚠️ Файл {json_file} не найден")
def create_optimized_version():
"""Создает оптимизированную версию из полного контекста"""
print("Загружаем полный контекст...")
try:
with open('data/1c_context.json', 'r', encoding='utf-8') as f:
full_data = json.load(f)
print(f"Загружено {len(full_data['context_items'])} элементов")
except FileNotFoundError:
print("❌ Файл data/1c_context.json не найден!")
print("Сначала создайте полную версию: python run.py --full")
return
except Exception as e:
print(f"❌ Ошибка загрузки: {e}")
return
# Приоритеты категорий (высокий -> низкий)
priorities = {
'methods': 1, # Высокий приоритет
'functions': 2, # Высокий приоритет
'operators': 3, # Высокий приоритет
'objects': 4, # Средний приоритет
'properties': 5 # Низкий приоритет
}
# Максимальное количество элементов по категориям
limits = {
'methods': 100, # Все методы
'functions': 100, # Все функции
'operators': 20, # Все операторы
'objects': 1000, # Топ-1000 объектов
'properties': 20 # Топ-20 свойств
}
# Группируем элементы по категориям
categories = {}
for item in full_data['context_items']:
category = item['category']
if category not in categories:
categories[category] = []
categories[category].append(item)
print("Группировка по категориям:")
for category, items in categories.items():
print(f" {category}: {len(items)} элементов")
# Сортируем категории по приоритету
sorted_categories = sorted(categories.keys(), key=lambda x: priorities.get(x, 999))
optimized_items = []
for category in sorted_categories:
items = categories[category]
limit = limits.get(category, 100)
print(f"Обрабатываем категорию: {category} (лимит: {limit} элементов)")
# Сортируем элементы по важности
scored_items = []
for item in items:
score = 0
# Наличие методов (высокий вес)
if item['metadata'].get('methods'):
score += len(item['metadata']['methods']) * 10
# Наличие синтаксиса (средний вес)
if item['metadata'].get('syntax') or item['metadata'].get('syntax_variants'):
score += 5
# Наличие параметров (средний вес)
if item['metadata'].get('parameters') or item['metadata'].get('parameters_by_variant'):
score += 3
# Наличие примеров (низкий вес)
if item['metadata'].get('example'):
score += 1
# Наличие описания (базовый вес)
if item['content']:
score += 1
scored_items.append((item, score))
# Сортируем по убыванию важности
scored_items.sort(key=lambda x: x[1], reverse=True)
# Берем топ элементы
top_items = [item for item, score in scored_items[:limit]]
optimized_items.extend(top_items)
print(f" Выбрано {len(top_items)} элементов")
# Создаем оптимизированный контекст
optimized_data = {
'metadata': {
'source': '1C BSL Documentation (Optimized)',
'generated_at': datetime.now().isoformat(),
'total_items': len(optimized_items),
'categories': list(set(item['category'] for item in optimized_items)),
'optimization': 'Приоритетные элементы с лимитами по категориям',
'original_size': len(full_data['context_items']),
'compression_ratio': f"{len(optimized_items) / len(full_data['context_items']) * 100:.1f}%"
},
'context_items': optimized_items
}
# Сохраняем оптимизированную версию
output_file = 'data/1c_context_optimized.json'
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(optimized_data, f, ensure_ascii=False, indent=2)
print(f"\n=== Оптимизация завершена ===")
print(f"Исходный размер: {len(full_data['context_items'])} элементов")
print(f"Оптимизированный размер: {len(optimized_items)} элементов")
print(f"Степень сжатия: {len(optimized_items) / len(full_data['context_items']) * 100:.1f}%")
print(f"Файл сохранен: {output_file}")
# Проверяем, что файл создался
if os.path.exists(output_file):
file_size = os.path.getsize(output_file) / 1024 / 1024
print(f"Размер файла: {file_size:.2f} MB")
else:
print("ОШИБКА: Файл не создался!")
# Создаем текстовую версию
content = "# Оптимизированная документация синтаксиса 1С (BSL)\n\n"
content += "Этот файл содержит приоритетные элементы документации по синтаксису языка 1С:Предприятие.\n"
content += "Используйте эту информацию для ответов на вопросы о программировании в 1С.\n\n"
content += "=" * 80 + "\n\n"
for item in optimized_items:
content += item['content']
content += "\n\n" + "=" * 80 + "\n\n"
txt_file = 'data/1c_context_optimized.txt'
with open(txt_file, 'w', encoding='utf-8') as f:
f.write(content)
print(f"Текстовая версия сохранена: {txt_file}")
def create_max_split_version(max_file_size_kb=50, max_items_per_file=50, verbose=False):
"""Создает максимальную версию в разбитом виде"""
print("Создание максимальной разбитой версии...")
# Проверяем наличие основного файла
if not os.path.exists("data/1c_context.json"):
print("❌ Файл data/1c_context.json не найден!")
print("Сначала запустите парсинг документации")
return
try:
from src.converters.max_split_converter import MaxSplitConverter
converter = MaxSplitConverter("data/1c_context.json", max_file_size_kb, max_items_per_file, verbose)
converter.convert()
print("✅ Максимальная разбитая версия создана: data/max_split/")
except Exception as e:
print(f"❌ Ошибка при создании максимальной разбитой версии: {e}")
def create_optimized_split_version(max_file_size_kb=50, max_items_per_file=50, verbose=False):
"""Создает оптимизированную версию в разбитом виде"""
print("Создание оптимизированной разбитой версии...")
# Проверяем наличие основного файла
if not os.path.exists("data/1c_context.json"):
print("❌ Файл data/1c_context.json не найден!")
print("Сначала запустите парсинг документации")
return
try:
from src.converters.optimized_split_converter import OptimizedSplitConverter
converter = OptimizedSplitConverter("data/1c_context.json", max_file_size_kb, max_items_per_file, verbose)
converter.convert()
print("✅ Оптимизированная разбитая версия создана: data/optimized_split/")
except Exception as e:
print(f"❌ Ошибка при создании оптимизированной разбитой версии: {e}")
def run_demo(context_file):
"""Запускает демонстрацию"""
if "optimized" in context_file:
print("🚀 Демонстрация оптимизированного контекста")
print("Запуск примеров поиска...")
os.system(f"set PYTHONPATH=src && python src/demos/optimized_demo.py {context_file} --examples")
elif "root" in context_file:
print("🌐 Демонстрация файла оглавления (английский)")
os.system(f"set PYTHONPATH=src && python src/demos/test_root_demo.py {context_file}")
else:
print("🇷🇺 Демонстрация основного файла (русский)")
os.system(f"set PYTHONPATH=src && python src/demos/llm_context_demo.py {context_file}")
def main():
parser = argparse.ArgumentParser(description="1C Help Parser - Парсер документации 1С")
parser.add_argument("--file", "-f", help="Путь к ZIP файлу для парсинга")
parser.add_argument("--demo", "-d", help="Путь к JSON файлу для демонстрации")
parser.add_argument("--check", "-c", action="store_true", help="Проверить зависимости")
parser.add_argument("--auto", action="store_true", help="Автоматический режим без интерактивного ввода")
parser.add_argument("--full", action="store_true", help="Обработать всю документацию (все файлы)")
parser.add_argument("--optimized", action="store_true", help="Создать оптимизированную версию (приоритетные элементы)")
parser.add_argument("--basic", action="store_true", help="Использовать базовую версию парсера")
parser.add_argument("--mode", choices=["max", "optimized", "max-split", "optimized-split"],
default="optimized", help="Режим экспорта")
parser.add_argument("--max-file-size", type=int, default=50,
help="Максимальный размер файла в KB (для split режимов)")
parser.add_argument("--max-items-per-file", type=int, default=50,
help="Максимальное количество элементов на файл (для split режимов)")
parser.add_argument("--verbose", "-v", action="store_true",
help="Подробный вывод (показывать каждый экспортированный файл)")
args = parser.parse_args()
print("🔧 1C Help Parser")
print("=" * 50)
# Проверка зависимостей
if args.check:
check_dependencies()
return
# Обработка конкретного файла
if args.file:
if not os.path.exists(args.file):
print(f"❌ Файл не найден: {args.file}")
return
use_improved = not args.basic
run_parser(args.file, use_improved=use_improved)
# Демонстрация
elif args.demo:
if not os.path.exists(args.demo):
print(f"❌ Файл не найден: {args.demo}")
return
run_demo(args.demo)
# Автоматический режим
elif args.auto:
print("🤖 Автоматический режим - обработка основного файла")
run_parser("data/rebuilt.shcntx_ru.zip")
# Полная обработка
elif args.full:
print("🚀 Полная обработка - все файлы документации")
run_parser("data/rebuilt.shcntx_ru.zip", max_files=None)
# Обработка устаревших флагов
elif args.optimized:
print("🎯 Создание оптимизированной версии (1 файл)")
create_optimized_version()
# Обработка режимов экспорта (только если явно указан --mode)
elif args.mode and args.mode != "optimized": # Проверяем, что режим явно указан
if args.mode == "max":
print("📊 Создание максимальной версии (1 файл)")
# Максимальная версия уже создана при парсинге
if os.path.exists("data/1c_context.json"):
print("✅ Максимальная версия уже существует: data/1c_context.json")
else:
print("❌ Сначала создайте полную версию: python run.py --full")
elif args.mode == "optimized":
print("🎯 Создание оптимизированной версии (1 файл)")
create_optimized_version()
elif args.mode == "max-split":
print("📊 Создание максимальной разбитой версии")
create_max_split_version(args.max_file_size, args.max_items_per_file, args.verbose)
elif args.mode == "optimized-split":
print("🎯 Создание оптимизированной разбитой версии")
create_optimized_split_version(args.max_file_size, args.max_items_per_file, args.verbose)
# Интерактивный режим (когда нет других аргументов)
else:
# Проверка зависимостей для интерактивного режима
check_dependencies()
print("\n🎯 Выберите действие:")
print("1. Обработать документацию (shcntx_ru.zip) - первые 500 файлов")
print("2. Обработать всю документацию (shcntx_ru.zip) - все файлы")
print("3. Создать оптимизированную версию (1 файл)")
print("4. Создать максимальную разбитую версию (множество файлов)")
print("5. Создать оптимизированную разбитую версию (множество файлов)")
print("6. Демонстрация оптимизированного контекста")
print("7. Проверить зависимости")
print("8. Очистить ненужные файлы")
print("0. Выход")
choice = input("\nВведите номер (0-8): ").strip()
if choice == "1":
run_parser("data/rebuilt.shcntx_ru.zip", max_files=500)
elif choice == "2":
run_parser("data/rebuilt.shcntx_ru.zip", max_files=None)
elif choice == "3":
create_optimized_version()
elif choice == "4":
create_max_split_version()
elif choice == "5":
create_optimized_split_version()
elif choice == "6":
if os.path.exists("data/1c_context_optimized.json"):
run_demo("data/1c_context_optimized.json")
else:
print("❌ Файл data/1c_context_optimized.json не найден!")
print("Сначала создайте оптимизированную версию")
elif choice == "7":
check_dependencies()
elif choice == "8":
cleanup_data()
elif choice == "0":
print("👋 До свидания!")
else:
print("❌ Неверный выбор")
if __name__ == "__main__":
main()