import { getUserIconUrl, getCourseParticipantsUrl } from "./config.js"; import { fetchGraduation } from "./graduation-common.js"; /** * Class to represent Students. */ class Student { graduation = null; constructor(id, name, groups) { this.id = id; this.name = name; this.groups = groups; } async getIconUrl() { return await getUserIconUrl(this.id); } getGroupName() { return `g${this.id}${this.name.replace(' ', '')}`; } getRealGroups() { if(typeof this.groups === "string") { return [this.groups]; } return this.groups.filter((g) => g !== this.getGroupName()); } async getGraduation() { if(!this.graduation) { // fetchGraduation(this) sets this.graduation await fetchGraduation(this); } return this.graduation; } } async function fetchStudent(idFilter, nameFilter, groupFilter) { const students = await fetchStudents(idFilter, nameFilter, groupFilter); return students[0]; } // Cache the fetched students. let students = []; const idRegex = /id=(\d+)/; async function fetchStudents(idFilter, nameFilter, groupFilter) { if (students.size) { return students; } const res = await fetch(getCourseParticipantsUrl()); const doc = new DOMParser().parseFromString(await res.text(), "text/html"); const table = doc.querySelector("tbody"); 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; if (nameCell.firstChild.firstChild.tagName == "SPAN") name = nameCell.firstChild.firstChild.title; else name = nameCell.innerText; const profileUrl = nameCell.querySelector("a.aabtn").href; const match = idRegex.exec(profileUrl); const id = match[1]; const groupCell = row.querySelector(".c5"); const groupsText = groupCell.querySelector("a.quickeditlink").textContent; const groups = groupsText.trim().split(", "); if ((!idFilter || id === idFilter) && (!nameFilter || name.includes(nameFilter)) && (!groupFilter || groups.filter((g) => g.includes(groupFilter)))) { students.push(new Student(id, name, groups)); } }); return students; } export { Student, fetchStudents, fetchStudent };