test5 / update_data.py
vydrking's picture
Upload 18 files
2fc8dc5 verified
import json
import os
import sys
from typing import List, Dict, Tuple
from scraper.html_scraper import HTMLScraper
from scraper.pdf_parser import PDFParser
from scraper.normalize import DataNormalizer
from retriever import Retriever
def update_data_async():
try:
print('Начинаем обновление данных...')
# Проверяем, есть ли уже данные
if check_data_exists():
print('Данные уже существуют, пропускаем обновление')
return
# Создаем тестовые данные для быстрого старта
print('Создание тестовых данных...')
normalizer = DataNormalizer()
# Тестовые курсы
test_courses = [
{
'id': 'ai_1_1',
'program_id': 'ai',
'semester': 1,
'name': 'Машинное обучение',
'credits': 6,
'hours': 108,
'type': 'required',
'short_desc': 'Основы машинного обучения, алгоритмы классификации и регрессии'
},
{
'id': 'ai_1_2',
'program_id': 'ai',
'semester': 1,
'name': 'Глубокое обучение',
'credits': 4,
'hours': 72,
'type': 'required',
'short_desc': 'Нейронные сети, CNN, RNN, трансформеры'
},
{
'id': 'ai_2_1',
'program_id': 'ai',
'semester': 2,
'name': 'Обработка естественного языка',
'credits': 5,
'hours': 90,
'type': 'required',
'short_desc': 'Методы обработки текста, токенизация, эмбеддинги'
},
{
'id': 'ai_product_1_1',
'program_id': 'ai_product',
'semester': 1,
'name': 'Продуктовая аналитика',
'credits': 6,
'hours': 108,
'type': 'required',
'short_desc': 'Анализ продуктовых метрик, A/B тестирование'
},
{
'id': 'ai_product_1_2',
'program_id': 'ai_product',
'semester': 1,
'name': 'Управление проектами',
'credits': 4,
'hours': 72,
'type': 'required',
'short_desc': 'Методологии управления проектами, Agile, Scrum'
}
]
print(f'Нормализация {len(test_courses)} курсов...')
normalized_courses = normalizer.normalize_courses(test_courses)
save_courses(normalized_courses)
print('Создание индекса...')
retriever = Retriever()
retriever.build_or_load_index(normalized_courses)
stats = normalizer.get_statistics(normalized_courses)
print(f'Статистика: {stats}')
print('Обновление данных завершено успешно!')
except Exception as e:
print(f'Ошибка обновления данных: {e}')
raise
def save_courses(courses: List[Dict], output_path: str = 'data/processed/courses.json'):
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(courses, f, ensure_ascii=False, indent=2)
print(f'Курсы сохранены в {output_path}')
def check_data_exists() -> bool:
programs_path = 'data/processed/programs.json'
courses_path = 'data/processed/courses.json'
index_path = 'data/index/index.faiss'
return all(os.path.exists(path) for path in [programs_path, courses_path, index_path])
def load_existing_data() -> Tuple[Dict, List[Dict]]:
programs = {}
courses = []
try:
with open('data/processed/programs.json', 'r', encoding='utf-8') as f:
programs = json.load(f)
except FileNotFoundError:
print('Файл programs.json не найден')
try:
with open('data/processed/courses.json', 'r', encoding='utf-8') as f:
courses = json.load(f)
except FileNotFoundError:
print('Файл courses.json не найден')
return programs, courses
def initialize_data():
if check_data_exists():
print('Данные уже существуют, загружаем...')
programs, courses = load_existing_data()
if courses:
retriever = Retriever()
retriever.build_or_load_index(courses)
print(f'Загружено {len(courses)} курсов')
else:
print('Курсы не найдены, запускаем обновление...')
update_data_async()
else:
print('Данные не найдены, запускаем первичное обновление...')
update_data_async()
def main():
if len(sys.argv) > 1 and sys.argv[1] == '--force':
print('Принудительное обновление данных...')
update_data_async()
else:
initialize_data()
if __name__ == '__main__':
main()