import * as cheerio from "cheerio"; const titleTranslations = { "Klasse(n)": "class", Datum: "date", Stunde: "lesson", "(Lehrer)": "teacher", Vertreter: "changedTeacher", Fach: "subject", Raum: "room", Art: "type", Text: "notes", }; export function parseSubstitutionPlan(html) { const infos = {}; const $ = cheerio.load(html); const data = []; const tables = $("table.mon_list"); tables.each((tableIndex, tableElement) => { // Extract the date, weekday and a/b week from the title const title = $(tableElement) .parent() .siblings(".mon_title") .text() .split(" "); const rawDate = title[0]; const date = rawDate .split(".") .reverse() .map((e) => e.padStart(2, 0)) .join("-"); if (tableIndex == 0) { infos.date = new Date(date).setUTCHours(0, 0, 0, 0); infos.week = title[3]; // Get the export timestamp const rawTimestamp = $(".mon_head") .first() .find("td") .text() .split("Stand: ")[1] .replace(/[\s\n]*$/g, ""); const exportDate = rawTimestamp .split(" ")[0] .split(".") .reverse() .join("-"); const timestamp = exportDate + " " + rawTimestamp.split(" ")[1]; infos.updatedAt = new Date(timestamp).getTime(); } else { // If there are multiple days in one file, // ignore all except the first one if (new Date(date).setUTCHours(0, 0, 0, 0) != infos.date) { return; } } const titles = []; const titleElements = $(tableElement).find("tr.list th"); titleElements.each((index, titleElement) => { const title = $(titleElement).text(); titles[index] = titleTranslations[title]; }); const subsitutionTable = $(tableElement).find("tr.list"); // Loop through each table row subsitutionTable.each((_rowcnt, row) => { const rowData = {}; // Find the columns and ignore empty ones const columns = $(row).find("td"); if (columns.text() == "") return; // Ignore columns that include "Keine Vertretungen" // to have an empty array if there are no substitutions if (columns.text().includes("Keine Vertretungen")) return; columns.each((columncnt, column) => { const text = $(column).text(); // Clean the text by removing new lines, tabs, ... var cleantext = text.replace(/^\n\s*/g, "").replace(/\s*$/, ""); if (cleantext == "" || cleantext == "---") cleantext = null; const columntitle = titles[columncnt]; rowData[columntitle] = cleantext; }); // Split change if it spans over multiple lessons const rawLesson = rowData.lesson || "0"; const fromToLessons = rawLesson.match(/\d+/g).map(Number); const from = fromToLessons[0]; const to = fromToLessons[1] || fromToLessons[0]; // Generate numbers from `from` to `to` const lessons = Array(to - from + 1) .fill() .map((_e, i) => i + from); // Create new change for each lesson the change spans over for (const lesson of lessons) { rowData.lesson = lesson; data.push({ ...rowData }); } }); }); infos.changes = data; return infos; }