-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparseEatTimings.ts
More file actions
100 lines (85 loc) · 3.71 KB
/
parseEatTimings.ts
File metadata and controls
100 lines (85 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import {HTMLElement} from "node-html-parser";
import EatTiming from "../types/eatTiming";
import Timing from "../types/timing";
import ClassEatTimings from "../types/classEatTimings";
const timeRegExp = /\d{1,2}:\d{2}/g, classesRegExp = /(\d{1,2})([а-яё]+)/g;
type AddToAllTask = {
eatType: string, eatTiming: EatTiming
};
export type ClassesEatTimings = Map<string, ClassEatTimings>;
export default function parseEatTimings(page: HTMLElement, timings: Array<Timing>): ClassesEatTimings {
let table = page.querySelector("table.eat");
if (!table) return new Map();
let eatType: string | undefined;
let allKnownClasses = new Set<string>();
let classesEatTimings = new Map<string, Partial<ClassEatTimings>>();
let addToAllTasks = new Array<AddToAllTask>();
table.getElementsByTagName("tr").forEach(row => {
let cells = row.getElementsByTagName("td");
if (cells.length === 1) {
eatType = cells[0].text.toLowerCase().trim();
}
else if (cells.length === 2) {
let times = cells[0].text.match(timeRegExp),
startTime = times?.[0],
afterLesson = timings.findIndex(timing => timing.end == startTime),
endTime;
if (times && times.length > 1) endTime = times[1];
else if (afterLesson != -1) endTime = timings[afterLesson + 1]?.start;
let eatTiming: EatTiming | undefined;
if (startTime && endTime && afterLesson != -1) eatTiming = new EatTiming(startTime, endTime, afterLesson);
else return;
let classes = new Array<string>();
for (let classesGroups of cells[1].text.matchAll(classesRegExp)) {
let classesNumber = classesGroups[1];
for (let classLetter of classesGroups[2]) {
let className = `${classesNumber}${classLetter}`;
classes.push(className);
allKnownClasses.add(className);
if (eatTiming && eatType) addEatTiming(className, eatTiming, eatType, classesEatTimings);
}
}
if (classes.length == 0 && eatType) addToAllTasks.push({eatType, eatTiming});
}
});
addToAllTasks.forEach(addToAllTask =>
allKnownClasses.forEach(className =>
addEatTiming(className, addToAllTask.eatTiming, addToAllTask.eatType, classesEatTimings)
)
);
let fullClassesEatTimings = new Array<[string, ClassEatTimings]>();
classesEatTimings.forEach((classEatTimings, className) => {
if (typeof classEatTimings.breakfast !== "undefined"
&& typeof classEatTimings.dinner !== "undefined"
&& typeof classEatTimings.afternoonSnack !== "undefined"
) {
fullClassesEatTimings.push([className, {
breakfast: classEatTimings.breakfast,
dinner: classEatTimings.dinner,
afternoonSnack: classEatTimings.afternoonSnack
}]);
}
});
return new Map(fullClassesEatTimings);
}
function addEatTiming (
className: string,
eatTiming: EatTiming,
eatType: string,
classesEatTimings: Map<string, Partial<ClassEatTimings>>
) {
let classEatTimings: Partial<ClassEatTimings> | undefined = classesEatTimings.get(className);
if (classEatTimings === undefined) classEatTimings = {};
switch (eatType) {
case "завтрак":
classEatTimings.breakfast = eatTiming;
break;
case "обед":
classEatTimings.dinner = eatTiming;
break;
case "полдник":
classEatTimings.afternoonSnack = eatTiming;
break;
}
classesEatTimings.set(className, classEatTimings);
}