Files
vstu_compat_v1/main.py
2026-03-21 15:47:00 +03:00

146 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import os
import hashlib
import requests
from datetime import datetime
# Конфигурация
URL_PARSER_ROOT = "https://fazziclay.com/api/v1/vstu_schedule_parser_v2/parser.json"
BASE_URL_FILES = "https://fazziclay.com/api/v1/vstu_schedule_parser_v2/parsed/"
FILE_RESULT = "result.json"
FILE_CACHE = "raw_cache.json"
FILE_TO_AI = "to_ai.txt"
FILE_FROM_AI = "from_ai.txt"
def get_raw_hash(raw_list):
normalized = "|".join(sorted([str(i).strip() for i in raw_list]))
return hashlib.sha1(normalized.encode('utf-8')).hexdigest()
def load_json(filename, default):
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as f:
try: return json.load(f)
except: return default
return default
def save_json(filename, data):
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def process_ai_input(cache):
if not os.path.exists(FILE_FROM_AI): return cache
with open(FILE_FROM_AI, 'r', encoding='utf-8') as f:
content = f.read().strip()
if not content: return cache
try:
new_data = json.loads(content)
for r_hash, resolved_obj in new_data.items():
cache[r_hash] = resolved_obj
print(f"[*] Добавлено {len(new_data)} записей из ИИ в кэш.")
with open(FILE_FROM_AI, 'w', encoding='utf-8') as f: f.write("")
except Exception as e:
print(f"[!] Ошибка парсинга from_ai.txt: {e}")
return cache
def main():
print(f"--- Система Совместимости V1-V2 [{datetime.now().strftime('%H:%M:%S')}] ---")
cache = load_json(FILE_CACHE, {})
cache = process_ai_input(cache)
save_json(FILE_CACHE, cache)
try:
parser_data = requests.get(URL_PARSER_ROOT).json()
except Exception as e:
print(f"[!] Ошибка сети: {e}"); return
final_groups = {}
unknown_raws = {}
for file_info in parser_data.get("all_files", []):
file_url = f"{BASE_URL_FILES}{requests.utils.quote(file_info['json_represent'])}"
print(f"[*] Рендеринг: {file_info['json_represent']}")
try: faculty_data = requests.get(file_url).json()
except: continue
sheets = faculty_data.get("sheets", {})
for sheet_data in sheets.values():
groups = sheet_data.get("groups", {})
for group_id, group_data in groups.items():
# Инициализация группы в формате V1
if group_id not in final_groups:
final_groups[group_data["name"]] = {
"name": group_data["name"],
"facultet": faculty_data['excel']['facultet'],
"position": group_data.get("position"),
"position_human": group_data.get("position_human"),
"slots": {},
"data_source_hash": "TODO"
}
slots = group_data.get("slots", {})
for slot_key, pair_value in slots.items():
if not isinstance(pair_value, dict): continue
if slot_key not in final_groups[group_data["name"]]["slots"]:
final_groups[group_data["name"]]["slots"][slot_key] = {}
for pair_key, pair_data in pair_value.items():
# Фильтр мета-ключей (пропускаем excel_range и т.д.)
if not (isinstance(pair_key, str) and '-' in pair_key): continue
# НОВЫЙ БЛОК: Обработка списка событий (если пара раздвоена)
# Превращаем всё в список, даже если там один объект
events = pair_data if isinstance(pair_data, list) else [pair_data]
for i, event in enumerate(events):
# Если событий больше одного, добавляем суффикс к ключу (напр. "5-6_1")
current_pair_id = pair_key if i == 0 else f"{pair_key}_{i}"
# Теперь event — это гарантированно словарь
if not isinstance(event, dict): continue
raw_list = event.get("raw", [])
r_hash = get_raw_hash(raw_list)
if r_hash in cache:
res = cache[r_hash]
# Парсим списки
locs = [l.strip() for l in res.get("location", "").split(",")] if res.get("location") and res.get("location") != "Не указана" else []
leads = [l.strip() for l in res.get("teacher", "").split(",")] if res.get("teacher") and res.get("teacher") != "Не указан" else []
# Записываем в финальную структуру
final_groups[group_data["name"]]["slots"][slot_key][current_pair_id] = {
"discipline_name": res.get("subject", "Не указан"),
"locations": locs,
"leads": leads,
"is_solid": event.get("is_solid", True),
"is_flow": event.get("is_flow", False),
"raw": raw_list,
"weekday": event.get("weekday"),
"weeknum": event.get("weeknum"),
"excel_range": event.get("excel_range"),
"excel_pos": event.get("excel_pos")
}
else:
unknown_raws[r_hash] = raw_list
# Управление to_ai.txt
if unknown_raws:
save_json(FILE_TO_AI, unknown_raws)
print(f"[!] Найдено {len(unknown_raws)} новых записей. См. {FILE_TO_AI}")
else:
with open(FILE_TO_AI, 'w', encoding='utf-8') as f: f.write("")
# Сохранение итогового результата
output = {
"actual_at": int(datetime.now().timestamp()),
"groups": final_groups
}
save_json(FILE_RESULT, output)
print(f"[*] Успешно: {FILE_RESULT} обновлен.")
if __name__ == "__main__":
main()