1
0

feat: Absences
All checks were successful
Remote Deploy / deploy (push) Successful in 4s

This commit is contained in:
2025-08-31 16:35:22 +02:00
parent fc8d4d3545
commit 4985d574d5
6 changed files with 374 additions and 26 deletions

View File

@@ -1,7 +1,9 @@
const XLSX = require('xlsx');
const fs = require("fs");
const parseAbsence = require('./utils/parseAbsence');
const parseTeachers = require('./utils/parseTeachers');
function parseThisShit(downloadedFilePath) {
async function parseThisShit(downloadedFilePath) {
const workbook = XLSX.readFile(downloadedFilePath);
const sheetNames = workbook.SheetNames;
@@ -60,7 +62,7 @@ function parseThisShit(downloadedFilePath) {
// For each class
let classI = 0;
for (const matchingKey of matchingKeys) {
const allKeys = Object.keys(currentSheet).filter(key => key !== matchingKey && key.endsWith(matchingKey.replace(/[a-z]/gi, '')));
const allKeys = Object.keys(currentSheet).filter(key => key !== matchingKey && key.replace(/[a-z]/gi, '') == matchingKey.replace(/[a-z]/gi, ''));
const final2 = [];
@@ -86,6 +88,24 @@ function parseThisShit(downloadedFilePath) {
classI++;
}
// ABSENCE
final[finalIndex]["ABSENCE"] = [];
const absenceKey = Object.keys(currentSheet).find(key => {
const value = (typeof currentSheet[key].v == "string" ? currentSheet[key].v : "").trim().toLowerCase();
return value == "absence";
});
const teacherMap = await parseTeachers();
const allAbsenceKeys = Object.keys(currentSheet).filter(key => key !== absenceKey && key.replace(/[a-z]/gi, '') == absenceKey.replace(/[a-z]/gi, ''));
for (const absenceKeyCur of allAbsenceKeys) {
const value = currentSheet[absenceKeyCur]["v"].trim();
if (value.length === 0) {
continue;
}
const data = parseAbsence(value, teacherMap);
final[finalIndex]["ABSENCE"].push(data);
}
finalIndex++;
}
@@ -119,3 +139,5 @@ function parseThisShit(downloadedFilePath) {
}
module.exports = parseThisShit;
// parseThisShit("downloads/table.xlsx");

View File

@@ -144,7 +144,7 @@ async function clearDownloadsFolder() {
console.log('Waiting for file:', downloadedFilePath);
await waitForFile(downloadedFilePath);
parseThisShit(downloadedFilePath);
await parseThisShit(downloadedFilePath);
await clearDownloadsFolder();

View File

@@ -0,0 +1,44 @@
function parseAbsence(str, teacherMap) {
str = str.trim().replace(/\s+/g, " ");
const result = {
teacher: null, // String or null
teacherCode: null, // String or null
type: null, // "wholeDay" | "range" | "single" | "invalid"
hours: null // { from: number, to: number } or number
};
// Regex patterns (with flexible spaces)
const wholeDayPattern = /^([A-Za-z]+)$/;
const rangePattern = /^(\d+)\s*-\s*(\d+)\s+([A-Za-z]+)$/;
const singleHourPattern = /^(\d+)\s+([A-Za-z]+)$/;
if (rangePattern.test(str)) {
const [, from, to, teacherCode] = str.match(rangePattern);
result.teacher = teacherMap[teacherCode.toLowerCase()];
result.teacherCode = teacherCode;
result.type = "range";
result.hours = { from: parseInt(from), to: parseInt(to) };
}
else if (singleHourPattern.test(str)) {
const [, hour, teacherCode] = str.match(singleHourPattern);
result.teacher = teacherMap[teacherCode.toLowerCase()];
result.teacherCode = teacherCode;
result.type = "single";
result.hours = parseInt(hour);
}
else if (wholeDayPattern.test(str)) {
const [, teacherCode] = str.match(wholeDayPattern);
result.teacher = teacherMap[teacherCode.toLowerCase()];
result.teacherCode = teacherCode;
result.type = "wholeDay";
}
else {
result.type = "invalid";
result.original = str;
}
return result;
}
module.exports = parseAbsence;

View File

@@ -0,0 +1,25 @@
const { default: axios } = require("axios");
const cheerio = require("cheerio");
async function parseTeachers() {
const url = "https://spsejecna.cz/ucitel";
const { data } = await axios.get(url);
const $ = cheerio.load(data);
const map = {};
$("main .contentLeftColumn li, main .contentRightColumn li").each((_, el) => {
const link = $(el).find("a");
const href = link.attr("href"); // e.g. "/ucitel/PA"
const text = link.text().trim(); // e.g. "Ing. Bc. Šárka Páltiková"
if (href) {
const key = href.split("/").pop().toLowerCase(); // get "pa"
map[key] = text;
}
});
return map;
}
module.exports = parseTeachers;