Files
kspguti-schedule/old/old-schedule.txt
kilyabin 16bba463eb feat: добавлено предупреждение о fallback кэше и debug опции
Основные изменения:

- Предупреждение о неактуальности расписания:
  * Добавлен баннер предупреждения при использовании fallback кэша
  * Добавлено toast уведомление о возможной неактуальности данных
  * Баннер показывает возраст кэша в удобочитаемом формате
  * Автоскролл с учетом рендеринга баннера

- Debug опции в админ-панели:
  * Добавлена секция с аккордеоном для debug опций (только в dev режиме)
  * Опции: принудительное использование кэша, пустое расписание, ошибка, таймаут, информация о кэше
  * Все опции с тумблерами для удобного управления
  * API endpoint обновлен для поддержки debug настроек

- Структурные изменения:
  * Создан компонент Accordion для shadcn/ui
  * Расширены типы AppSettings для поддержки debug опций
  * Компонент баннера размещен внутри Schedule компонента (следуя правилам проекта)
  * Добавлен файл .cursorrules с правилами для AI ассистента

- Исправления:
  * Исправлена сериализация undefined значений в getServerSideProps
  * Улучшена логика автоскролла при использовании fallback кэша
  * Убраны лишние отступы у баннера предупреждения

- Зависимости:
  * Добавлен @radix-ui/react-accordion для компонента аккордеона

- Прочие изменения:
  * Обновлены настройки в settings.json
  * Изменения в старых файлах (old/README.md, old/old-schedule.txt)
  * Обновления в API endpoints админ-панели
2025-12-02 01:05:36 +04:00

67 lines
2.6 KiB
Plaintext
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 { Day } from '@/shared/model/day'
import { parsePage } from '@/app/parser/schedule'
import contentTypeParser from 'content-type'
import { JSDOM } from 'jsdom'
// import { content as mockContent } from './mock'
import { reportParserError } from '@/app/logger'
// import { groups } from '@/shared/data/groups'
// const fetchingGroups: {
// [groupID: number]: boolean
// } = Object.fromEntries(Object.values(groups).map(([gId]) => [gId, false]))
// const callbacks: {
// [groupID: number]: Set<{ resolve: (days: Day[]) => void, reject: (e: unknown) => void }>
// } = Object.fromEntries(Object.values(groups).map(([gId]) => [gId, new Set()]))
export async function getSchedule(groupID: number, groupName: string): Promise<Day[]> {
// if (fetchingGroups[groupID]) {
// return new Promise((resolve, reject) => {
// callbacks[groupID].add({
// resolve: (days: Day[]) => resolve(days),
// reject
// })
// })
// } else {
// fetchingGroups[groupID] = true
// }
// try {
// const result = await parseSchedule(groupID, groupName)
// fetchingGroups[groupID] = false
// Array.from(callbacks[groupID].values()).forEach(({ resolve }) => resolve(result))
// callbacks[groupID].clear()
// return result
// } catch(e) {
// fetchingGroups[groupID] = false
// console.log(Array.from(callbacks[groupID].values()).length)
// Array.from(callbacks[groupID].values()).forEach(({ reject }) => reject(e))
// callbacks[groupID].clear()
// throw e
// }
}
export async function parseSchedule(groupID: number, groupName: string) {
const page = await fetch(`${process.env.PROXY_URL ?? 'https://lk.ks.psuti.ru'}/?mn=2&obj=${groupID}`)
// const page = { text: async () => mockContent, status: 200, headers: { get: (s: string) => s && 'text/html' } }
const content = await page.text()
const contentType = page.headers.get('content-type')
if (page.status === 200 && contentType && contentTypeParser.parse(contentType).type === 'text/html') {
try {
const root = new JSDOM(content).window.document
return parsePage(root, groupName)
} catch (e) {
console.error('Error while parsing lk.ks.psuti.ru')
reportParserError(new Date().toISOString(), 'Не удалось сделать парсинг для группы', groupName)
throw e
}
} else {
console.error(page.status, contentType)
console.error(content.length > 500 ? content.slice(0, 500 - 3) + '...' : content)
reportParserError(new Date().toISOString(), 'Не удалось получить страницу для группы', groupName)
throw new Error('Error while fetching lk.ks.psuti.ru')
}
}