feat(parser): update group parsing to handle special cases and improve regex patterns
feat(parser): enhance details extraction for lessons, including handling of subgroups and room moves feat(timetable): integrate room and teacher retrieval based on week context test(parser): add tests for group parsing with special characters and room move scenarios test(formats): implement tests for various lesson formats and their expected outputs feat(rooms): introduce room management functions for handling moves and week-based plans
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// third-party clients use it instead of re-implementing the white/green week rules.
|
||||
import { semesterView, addDays, weekday, weekIndexOf } from "../shared/weeks.js";
|
||||
import { lessonKey, subgroupsOf } from "../shared/lessons.js";
|
||||
import { occurrence, peopleAndRooms, roomsOn } from "./directory.js";
|
||||
import { occurrence, peopleAndRooms, roomsOn, teachersOn, movedOn } from "./directory.js";
|
||||
import { apiError } from "./errors.js";
|
||||
|
||||
const MAX_DAYS = 62;
|
||||
@@ -10,9 +10,10 @@ const MAX_DAYS = 62;
|
||||
const MAX_SEMESTER_DAYS = 200;
|
||||
const DAY_MS = 86_400_000;
|
||||
|
||||
function lessonOut(lesson, group, people, date, status, calendar) {
|
||||
// On a date: the room and teacher of that day and week ("1-9н. 502н", a move on 26.10).
|
||||
function lessonOut(lesson, group, people, date, status, calendar, week = null) {
|
||||
const bell = calendar?.bells.find((b) => b.start === lesson.start);
|
||||
const rooms = date ? roomsOn(people, date) : people.rooms;
|
||||
const rooms = date ? roomsOn(people, date, week) : people.rooms;
|
||||
return {
|
||||
key: lessonKey(lesson, group),
|
||||
start: lesson.start,
|
||||
@@ -20,9 +21,9 @@ function lessonOut(lesson, group, people, date, status, calendar) {
|
||||
pair: bell?.pair ?? null,
|
||||
subject: lesson.subject,
|
||||
type: lesson.type,
|
||||
teachers: people.teachers,
|
||||
teachers: date ? teachersOn(people, week) : people.teachers,
|
||||
rooms,
|
||||
roomMoved: Boolean(date && rooms !== people.rooms),
|
||||
roomMoved: Boolean(date && movedOn(people, date)),
|
||||
distance: people.distance,
|
||||
condition: lesson.condition,
|
||||
variant: lesson.variant,
|
||||
@@ -37,9 +38,23 @@ function lessonOut(lesson, group, people, date, status, calendar) {
|
||||
* days: one entry per date from `from`, with the lessons that take place that day.
|
||||
* weekly: the Word rows by weekday, for when dates cannot be calculated.
|
||||
*/
|
||||
const groupKey = (g) => g.toLowerCase().replace(/[\s\-–]/g, "");
|
||||
|
||||
export function timetable({ file, schedule, calendar, group, from, days, range, today, session: extra = [] }) {
|
||||
if (!schedule.groups.includes(group)) {
|
||||
throw apiError(404, "group_not_found", `В документе нет группы ${group}.`);
|
||||
// The same group written another way: "24-ИЯ(РА)и-1" for "24-ИЯ (РА)и-1".
|
||||
const same = schedule.groups.find((g) => groupKey(g) === groupKey(group));
|
||||
// A name parser 13 split into groups: a client may still keep "24-ИЯ(РА)".
|
||||
const split = schedule.groups.filter((g) => groupKey(g).startsWith(groupKey(group)));
|
||||
if (same) group = same;
|
||||
else
|
||||
throw apiError(
|
||||
404,
|
||||
"group_not_found",
|
||||
split.length
|
||||
? `Группа ${group} теперь разделена: ${split.join(", ")}. Выберите свою в списке групп.`
|
||||
: `В документе нет группы ${group}.`,
|
||||
);
|
||||
}
|
||||
let count = Math.min(Math.max(Number(days) || 7, 1), MAX_DAYS);
|
||||
const lessons = schedule.lessons.filter((l) => l.groups.includes(group));
|
||||
@@ -90,7 +105,7 @@ export function timetable({ file, schedule, calendar, group, from, days, range,
|
||||
for (const entry of entries) {
|
||||
const status = occurrence(entry, date, calendar, views);
|
||||
if (status === "yes" || status === "maybe")
|
||||
dayLessons.push(lessonOut(entry.lesson, group, entry, date, status, calendar));
|
||||
dayLessons.push(lessonOut(entry.lesson, group, entry, date, status, calendar, week));
|
||||
}
|
||||
// Session events printed with their own date need no week table.
|
||||
for (const entry of extra)
|
||||
|
||||
Reference in New Issue
Block a user