Initial commit
This commit is contained in:
0
from_ai.txt
Normal file
0
from_ai.txt
Normal file
146
main.py
Normal file
146
main.py
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
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()
|
||||||
15307
raw_cache.json
Normal file
15307
raw_cache.json
Normal file
File diff suppressed because it is too large
Load Diff
138160
result.json
Normal file
138160
result.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user