import type { Graduation } from "./graduation-common.ts"; import { Student } from "./student-common.ts"; import { getUserIconUrl, getCourseParticipantsUrl } from "./utils-prod.js"; import { fetchGraduation } from "./graduation-prod.ts"; declare module "./student-common.ts" { interface Student { getGraduation(): Promise; getIconUrl(): Promise; } } Student.prototype.getGraduation = function () { return fetchGraduation(this); }; Student.prototype.getIconUrl = function () { return getUserIconUrl(this.id); }; // Cache the fetched students. let students: Array | null = null; const idRegex = /id=(\d+)/; async function _fetchStudents() { const res = await fetch(getCourseParticipantsUrl()); const doc = new DOMParser().parseFromString(await res.text(), "text/html"); const table = doc.querySelector("tbody")!; const fetchedStudents: Array = []; table.querySelectorAll("tr").forEach((row) => { if (row.classList.contains("emptyrow")) return; const roleCell = row.querySelector(".c4")!; // TODO(muhq): Is this locale dependent? if (roleCell.innerHTML.includes("Lehrer")) { return; } const nameCell = row.querySelector(".c1")!; let name; const c = nameCell.firstChild!.firstChild! as HTMLElement; if (c.tagName == "SPAN") name = c.title; else name = nameCell.innerText; const profileUrl = nameCell.querySelector("a.aabtn")!.href; const match = idRegex.exec(profileUrl); if (match === null) { console.error("Profile Regex did not match"); return; } const id = match[1]; const groupCell = row.querySelector(".c5")!; const group = groupCell.querySelector("a.quickeditlink")!.textContent; fetchedStudents.push(new Student(Number(id), name, group)); }); return fetchedStudents; } async function fetchStudents(idFilter?: number, nameFilter?: string, groupFilter?: string) { if (students === null) { const studentsPromise = _fetchStudents(); const storedStudents = localStorage.getItem("students"); if (storedStudents !== null && storedStudents.length > 0) { studentsPromise.then((fetched) => localStorage.setItem("students", JSON.stringify(fetched))); students = []; for (const o of JSON.parse(storedStudents)) { students.push(new Student(o.id, o.name, o.group)); } } else { students = await studentsPromise; localStorage.setItem("students", JSON.stringify(students)); } } return students.filter( (s) => (typeof idFilter === "undefined" || s.id === idFilter) && (typeof nameFilter === "undefined" || s.name.includes(nameFilter)) && (typeof groupFilter === "undefined" || s.group.includes(groupFilter)), ); } async function fetchStudent(idFilter?: number, nameFilter?: string, groupFilter?: string) { const students = await fetchStudents(idFilter, nameFilter, groupFilter); return students[0]; } export { Student, fetchStudents, fetchStudent };