Add dates, discipline fallbacks

This commit is contained in:
VityaSchel
2023-10-02 01:04:55 +04:00
parent de4208337e
commit f6daee6201
15 changed files with 592 additions and 219 deletions

View File

@@ -6,15 +6,15 @@ import { JSDOM } from 'jsdom'
import { content as mockContent } from './mock'
// ПС-7: 146
export async function getSchedule(groupID: number): Promise<Day[]> {
// 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' } }
export async function getSchedule(groupID: number, groupName: string): Promise<Day[]> {
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)
return parsePage(root, groupName)
} catch(e) {
console.error('Error while parsing lk.ks.psuti.ru')
throw e

View File

@@ -10,67 +10,69 @@ const dayTitleParser = (text: string) => {
}
const parseLesson = (row: Element): Lesson | null => {
const cells = Array.from(row.querySelectorAll(':scope > td'))
if (cells[3].textContent!.trim() === 'Свободное время') return null
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
const lesson: LessonObject = {}
const isChange = cells.every(td => td.getAttribute('bgcolor') === 'ffffbb')
try {
const cells = Array.from(row.querySelectorAll(':scope > td'))
if (cells[3].textContent!.trim() === 'Свободное время') return null
const timeCell = cells[1].childNodes
const [startTime, endTime] = timeCell[0].textContent!.trim().split(' ')
const time: Lesson['time'] = {
start: startTime ?? '',
end: endTime ?? ''
}
if (timeCell[2]) {
time.hint = timeCell[2].textContent!.trim()
}
lesson.isChange = cells.every(td => td.getAttribute('bgcolor') === 'ffffbb')
const subject = cells[3].childNodes[0].textContent!.trim()
let teacher: Lesson['teacher']
const teacherCell = cells[3].childNodes[2]
if (teacherCell) {
teacher = teacherCell.textContent!.trim()
}
const placeCell = cells[3].childNodes[3]
let place: Lesson['place']
if (placeCell) {
place = {
address: placeCell.childNodes[1].textContent!.trim(),
classroom: Number(placeCell.childNodes[3].textContent!.trim().match(/^Кабинет: (\d+)(-2)?$/)![1])
const timeCell = cells[1].childNodes
const [startTime, endTime] = timeCell[0].textContent!.trim().split(' ')
lesson.time = {
start: startTime ?? '',
end: endTime ?? ''
}
if (timeCell[2]) {
lesson.time.hint = timeCell[2].textContent!.trim()
}
}
const topic: Lesson['topic'] = cells[4].textContent!.trim()
try {
lesson.subject = cells[3].childNodes[0].textContent!.trim()
const resources: Lesson['resources'] = []
Array.from(cells[5].querySelectorAll('a'))
.forEach(a => {
resources.push({
type: 'link',
title: a.textContent!.trim(),
url: a.getAttribute('href')!
const teacherCell = cells[3].childNodes[2]
if (teacherCell) {
lesson.teacher = teacherCell.textContent!.trim()
}
const placeCell = cells[3].childNodes[3]
if (placeCell) {
lesson.place = {
address: placeCell.childNodes[1].textContent!.trim(),
classroom: placeCell.childNodes[3].textContent!.trim().match(/^Кабинет: ([^ ]+)(-2)?$/)![1]
}
}
} catch(e) {
console.error('Error while parsing discipline', e, cells[3].textContent?.trim())
lesson.fallbackDiscipline = cells[3].textContent?.trim()
}
lesson.topic = cells[4].textContent!.trim()
lesson.resources = []
Array.from(cells[5].querySelectorAll('a'))
.forEach(a => {
lesson.resources.push({
type: 'link',
title: a.textContent!.trim(),
url: a.getAttribute('href')!
})
})
})
return {
isChange,
time,
type: cells[2].textContent!.trim(),
subject,
...(teacher && { teacher }),
...(place && { place }),
...(topic && { topic }),
resources,
homework: cells[6].textContent!.trim()
return lesson
} catch(e) {
console.error('Error while parsing lesson in table', e, row.textContent?.trim())
return null
}
}
export function parsePage(document: Document): Day[] {
export function parsePage(document: Document, groupName: string): Day[] {
const tables = Array.from(document.querySelectorAll('body > table'))
const table = tables.find(table => table.querySelector(':scope > tbody > tr:first-child')?.textContent?.trim() === 'ПС-7')
const table = tables.find(table => table.querySelector(':scope > tbody > tr:first-child')?.textContent?.trim() === groupName)
const rows = Array.from(table!.children[0].children).filter(el => el.tagName === 'TR').slice(2)
const days = []