diff --git a/settings.json b/settings.json
index 4f76642..47db0d5 100644
--- a/settings.json
+++ b/settings.json
@@ -1,7 +1,7 @@
{
"weekNavigationEnabled": false,
"debug": {
- "forceCache": true,
+ "forceCache": false,
"forceEmpty": false,
"forceError": false,
"forceTimeout": false,
diff --git a/src/app/parser/schedule.ts b/src/app/parser/schedule.ts
index a236c48..d46bf95 100644
--- a/src/app/parser/schedule.ts
+++ b/src/app/parser/schedule.ts
@@ -239,9 +239,11 @@ const parseLesson = (row: Element): Lesson | null => {
try {
const cells = Array.from(row.querySelectorAll(':scope > td'))
- if (!cells[3] || cells[3].textContent?.trim() === 'Свободное время') return null
-
+
lesson.isChange = cells.every(td => td.getAttribute('bgcolor') === 'ffffbb')
+
+ // Пропускаем урок только если это НЕ замена И в ячейке "Свободное время"
+ if (!cells[3] || (!lesson.isChange && cells[3].textContent?.trim() === 'Свободное время')) return null
if (!cells[1] || !cells[1].childNodes[0]) {
return null
@@ -261,38 +263,138 @@ const parseLesson = (row: Element): Lesson | null => {
}
try {
- if (!cells[3].childNodes[0]) {
- throw new Error('Subject node not found')
- }
- lesson.subject = cells[3].childNodes[0].textContent!.trim()
-
- const teacherCell = cells[3].childNodes[2]
- if (teacherCell) {
- lesson.teacher = teacherCell.textContent!.trim()
+ const disciplineCell = cells[3]
+ if (!disciplineCell) {
+ throw new Error('Discipline cell not found')
}
- const placeCell = cells[3].childNodes[3]
-
- if (placeCell && placeCell.childNodes.length > 0) {
- const addressNode = placeCell.childNodes[1]
- const classroomNode = placeCell.childNodes[3]
+ const cellText = disciplineCell.textContent || ''
+ const cellHTML = disciplineCell.innerHTML || ''
+
+ // Проверяем, является ли это заменой "Свободное время" на пару
+ const isFreeTimeReplacement = lesson.isChange &&
+ (cellText.includes('Свободное время') && cellText.includes('Замена') && cellText.includes('на:'))
+
+ if (isFreeTimeReplacement) {
+ // Для замены "свободное время" на пару нужно парсить данные после "на:"
+ // Структура: "Замена Свободное время на:
название
преподаватель адрес
кабинет
- if (addressNode && classroomNode) {
- const address = addressNode.textContent?.trim()
- const classroomText = classroomNode.textContent?.trim()
- const classroomMatch = classroomText?.match(/^Кабинет: ([^ ]+)(-2)?$/)
+ // Используем HTML парсинг для извлечения данных после "на:"
+ const afterOnIndex = cellHTML.indexOf('на:')
+ if (afterOnIndex !== -1) {
+ const afterOn = cellHTML.substring(afterOnIndex + 3) // +3 для "на:"
- if (address && classroomMatch) {
- lesson.place = {
- address,
- classroom: classroomMatch[1]
+ // Пропускаем первый
(он идет сразу после "на:")
+ const firstBrIndex = afterOn.indexOf('
тега
+ const firstBrEnd = afterOn.indexOf('>', firstBrIndex) + 1
+ const afterFirstBr = afterOn.substring(firstBrEnd)
+
+ // Извлекаем название предмета (текст до следующего
)
+ const secondBrIndex = afterFirstBr.indexOf('
]+>/g, '').trim()
+
+ // Извлекаем преподавателя (текст между вторым
и или следующим
)
+ const secondBrEnd = afterFirstBr.indexOf('>', secondBrIndex) + 1
+ const afterSecondBr = afterFirstBr.substring(secondBrEnd)
+
+ const fontIndex = afterSecondBr.indexOf(']+>/g, '').trim()
+ } else {
+ // Если нет , преподаватель может быть до следующего
или до конца
+ const thirdBrIndex = afterSecondBr.indexOf('
]+>/g, '').trim()
+ } else {
+ lesson.teacher = afterSecondBr.replace(/<[^>]+>/g, '').trim()
+ }
+ }
+ } else {
+ // Если нет второго
, название предмета может быть до или до конца
+ const fontIndex = afterFirstBr.indexOf(']+>/g, '').trim()
+ } else {
+ lesson.subject = afterFirstBr.replace(/<[^>]+>/g, '').trim()
+ }
+ }
+ }
+
+ // Ищем адрес и кабинет внутри
+ const fontMatch = afterOn.match(/]*>([\s\S]*?)<\/font>/i)
+ if (fontMatch) {
+ const fontContent = fontMatch[1]
+ // Ищем паттерн:
адрес
Кабинет: номер
+ // Сначала убираем все теги и разбиваем по
+ const cleanContent = fontContent.replace(/<[^>]+>/g, '|').split('|').filter(p => p.trim())
+ // Ищем адрес (первая непустая часть) и кабинет (часть с "Кабинет:")
+ for (let i = 0; i < cleanContent.length; i++) {
+ const part = cleanContent[i].trim()
+ if (part && !part.includes('Кабинет:')) {
+ const nextPart = cleanContent[i + 1]?.trim() || ''
+ const classroomMatch = nextPart.match(/Кабинет:\s*([^\s]+)/i)
+ if (classroomMatch) {
+ lesson.place = {
+ address: part,
+ classroom: classroomMatch[1]
+ }
+ break
+ }
+ }
+ }
+ } else {
+ // Если нет , ищем адрес и кабинет напрямую в тексте после "на:"
+ const addressMatch = afterOn.match(/([^<]+?)(?:
]*>|\s+)Кабинет:\s*([^<\s]+)/i)
+ if (addressMatch) {
+ lesson.place = {
+ address: addressMatch[1].replace(/<[^>]+>/g, '').trim(),
+ classroom: addressMatch[2].trim()
+ }
+ }
+ }
+ }
+ } else {
+ // Обычный парсинг для нормальных пар
+ if (!disciplineCell.childNodes[0]) {
+ throw new Error('Subject node not found')
+ }
+ lesson.subject = disciplineCell.childNodes[0].textContent!.trim()
+
+ const teacherCell = disciplineCell.childNodes[2]
+ if (teacherCell) {
+ lesson.teacher = teacherCell.textContent!.trim()
+ }
+
+ const placeCell = disciplineCell.childNodes[3]
+
+ if (placeCell && placeCell.childNodes.length > 0) {
+ const addressNode = placeCell.childNodes[1]
+ const classroomNode = placeCell.childNodes[3]
+
+ if (addressNode && classroomNode) {
+ const address = addressNode.textContent?.trim()
+ const classroomText = classroomNode.textContent?.trim()
+ const classroomMatch = classroomText?.match(/^Кабинет: ([^ ]+)(-2)?$/)
+
+ if (address && classroomMatch) {
+ lesson.place = {
+ address,
+ classroom: classroomMatch[1]
+ }
}
}
}
}
} catch(e) {
- console.error('Error while parsing discipline', e, cells[3].textContent?.trim())
- lesson.fallbackDiscipline = cells[3].textContent?.trim()
+ console.error('Error while parsing discipline', e, cells[3]?.textContent?.trim())
+ lesson.fallbackDiscipline = cells[3]?.textContent?.trim()
}
if (cells[4]) {
diff --git a/src/shared/data/settings.json b/src/shared/data/settings.json
index 4f76642..47db0d5 100644
--- a/src/shared/data/settings.json
+++ b/src/shared/data/settings.json
@@ -1,7 +1,7 @@
{
"weekNavigationEnabled": false,
"debug": {
- "forceCache": true,
+ "forceCache": false,
"forceEmpty": false,
"forceError": false,
"forceTimeout": false,